Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  * nf_nat_snmp_basic.c
  3  *
  4  * Basic SNMP Application Layer Gateway
  5  *
  6  * This IP NAT module is intended for use with SNMP network
  7  * discovery and monitoring applications where target networks use
  8  * conflicting private address realms.
  9  *
 10  * Static NAT is used to remap the networks from the view of the network
 11  * management system at the IP layer, and this module remaps some application
 12  * layer addresses to match.
 13  *
 14  * The simplest form of ALG is performed, where only tagged IP addresses
 15  * are modified.  The module does not need to be MIB aware and only scans
 16  * messages at the ASN.1/BER level.
 17  *
 18  * Currently, only SNMPv1 and SNMPv2 are supported.
 19  *
 20  * More information on ALG and associated issues can be found in
 21  * RFC 2962
 22  *
 23  * The ASB.1/BER parsing code is derived from the gxsnmp package by Gregory
 24  * McLean & Jochen Friedrich, stripped down for use in the kernel.
 25  *
 26  * Copyright (c) 2000 RP Internet (www.rpi.net.au).
 27  *
 28  * This program is free software; you can redistribute it and/or modify
 29  * it under the terms of the GNU General Public License as published by
 30  * the Free Software Foundation; either version 2 of the License, or
 31  * (at your option) any later version.
 32  * This program is distributed in the hope that it will be useful,
 33  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 34  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 35  * GNU General Public License for more details.
 36  * You should have received a copy of the GNU General Public License
 37  * along with this program; if not, write to the Free Software
 38  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 39  *
 40  * Author: James Morris <jmorris@intercode.com.au>
 41  */
 42 #include <linux/module.h>
 43 #include <linux/moduleparam.h>
 44 #include <linux/types.h>
 45 #include <linux/kernel.h>
 46 #include <linux/in.h>
 47 #include <linux/ip.h>
 48 #include <linux/udp.h>
 49 #include <net/checksum.h>
 50 #include <net/udp.h>
 51 
 52 #include <net/netfilter/nf_nat.h>
 53 #include <net/netfilter/nf_conntrack_helper.h>
 54 #include <net/netfilter/nf_nat_helper.h>
 55 
 56 MODULE_LICENSE("GPL");
 57 MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
 58 MODULE_DESCRIPTION("Basic SNMP Application Layer Gateway");
 59 MODULE_ALIAS("ip_nat_snmp_basic");
 60 
 61 #define SNMP_PORT 161
 62 #define SNMP_TRAP_PORT 162
 63 #define NOCT1(n) (*(u8 *)(n))
 64 
 65 static int debug;
 66 static DEFINE_SPINLOCK(snmp_lock);
 67 
 68 /*
 69  * Application layer address mapping mimics the NAT mapping, but
 70  * only for the first octet in this case (a more flexible system
 71  * can be implemented if needed).
 72  */
 73 struct oct1_map
 74 {
 75         u_int8_t from;
 76         u_int8_t to;
 77 };
 78 
 79 
 80 /*****************************************************************************
 81  *
 82  * Basic ASN.1 decoding routines (gxsnmp author Dirk Wisse)
 83  *
 84  *****************************************************************************/
 85 
 86 /* Class */
 87 #define ASN1_UNI        0       /* Universal */
 88 #define ASN1_APL        1       /* Application */
 89 #define ASN1_CTX        2       /* Context */
 90 #define ASN1_PRV        3       /* Private */
 91 
 92 /* Tag */
 93 #define ASN1_EOC        0       /* End Of Contents */
 94 #define ASN1_BOL        1       /* Boolean */
 95 #define ASN1_INT        2       /* Integer */
 96 #define ASN1_BTS        3       /* Bit String */
 97 #define ASN1_OTS        4       /* Octet String */
 98 #define ASN1_NUL        5       /* Null */
 99 #define ASN1_OJI        6       /* Object Identifier  */
100 #define ASN1_OJD        7       /* Object Description */
101 #define ASN1_EXT        8       /* External */
102 #define ASN1_SEQ        16      /* Sequence */
103 #define ASN1_SET        17      /* Set */
104 #define ASN1_NUMSTR     18      /* Numerical String */
105 #define ASN1_PRNSTR     19      /* Printable String */
106 #define ASN1_TEXSTR     20      /* Teletext String */
107 #define ASN1_VIDSTR     21      /* Video String */
108 #define ASN1_IA5STR     22      /* IA5 String */
109 #define ASN1_UNITIM     23      /* Universal Time */
110 #define ASN1_GENTIM     24      /* General Time */
111 #define ASN1_GRASTR     25      /* Graphical String */
112 #define ASN1_VISSTR     26      /* Visible String */
113 #define ASN1_GENSTR     27      /* General String */
114 
115 /* Primitive / Constructed methods*/
116 #define ASN1_PRI        0       /* Primitive */
117 #define ASN1_CON        1       /* Constructed */
118 
119 /*
120  * Error codes.
121  */
122 #define ASN1_ERR_NOERROR                0
123 #define ASN1_ERR_DEC_EMPTY              2
124 #define ASN1_ERR_DEC_EOC_MISMATCH       3
125 #define ASN1_ERR_DEC_LENGTH_MISMATCH    4
126 #define ASN1_ERR_DEC_BADVALUE           5
127 
128 /*
129  * ASN.1 context.
130  */
131 struct asn1_ctx
132 {
133         int error;                      /* Error condition */
134         unsigned char *pointer;         /* Octet just to be decoded */
135         unsigned char *begin;           /* First octet */
136         unsigned char *end;             /* Octet after last octet */
137 };
138 
139 /*
140  * Octet string (not null terminated)
141  */
142 struct asn1_octstr
143 {
144         unsigned char *data;
145         unsigned int len;
146 };
147 
148 static void asn1_open(struct asn1_ctx *ctx,
149                       unsigned char *buf,
150                       unsigned int len)
151 {
152         ctx->begin = buf;
153         ctx->end = buf + len;
154         ctx->pointer = buf;
155         ctx->error = ASN1_ERR_NOERROR;
156 }
157 
158 static unsigned char asn1_octet_decode(struct asn1_ctx *ctx, unsigned char *ch)
159 {
160         if (ctx->pointer >= ctx->end) {
161                 ctx->error = ASN1_ERR_DEC_EMPTY;
162                 return 0;
163         }
164         *ch = *(ctx->pointer)++;
165         return 1;
166 }
167 
168 static unsigned char asn1_tag_decode(struct asn1_ctx *ctx, unsigned int *tag)
169 {
170         unsigned char ch;
171 
172         *tag = 0;
173 
174         do
175         {
176                 if (!asn1_octet_decode(ctx, &ch))
177                         return 0;
178                 *tag <<= 7;
179                 *tag |= ch & 0x7F;
180         } while ((ch & 0x80) == 0x80);
181         return 1;
182 }
183 
184 static unsigned char asn1_id_decode(struct asn1_ctx *ctx,
185                                     unsigned int *cls,
186                                     unsigned int *con,
187                                     unsigned int *tag)
188 {
189         unsigned char ch;
190 
191         if (!asn1_octet_decode(ctx, &ch))
192                 return 0;
193 
194         *cls = (ch & 0xC0) >> 6;
195         *con = (ch & 0x20) >> 5;
196         *tag = (ch & 0x1F);
197 
198         if (*tag == 0x1F) {
199                 if (!asn1_tag_decode(ctx, tag))
200                         return 0;
201         }
202         return 1;
203 }
204 
205 static unsigned char asn1_length_decode(struct asn1_ctx *ctx,
206                                         unsigned int *def,
207                                         unsigned int *len)
208 {
209         unsigned char ch, cnt;
210 
211         if (!asn1_octet_decode(ctx, &ch))
212                 return 0;
213 
214         if (ch == 0x80)
215                 *def = 0;
216         else {
217                 *def = 1;
218 
219                 if (ch < 0x80)
220                         *len = ch;
221                 else {
222                         cnt = (unsigned char) (ch & 0x7F);
223                         *len = 0;
224 
225                         while (cnt > 0) {
226                                 if (!asn1_octet_decode(ctx, &ch))
227                                         return 0;
228                                 *len <<= 8;
229                                 *len |= ch;
230                                 cnt--;
231                         }
232                 }
233         }
234 
235         /* don't trust len bigger than ctx buffer */
236         if (*len > ctx->end - ctx->pointer)
237                 return 0;
238 
239         return 1;
240 }
241 
242 static unsigned char asn1_header_decode(struct asn1_ctx *ctx,
243                                         unsigned char **eoc,
244                                         unsigned int *cls,
245                                         unsigned int *con,
246                                         unsigned int *tag)
247 {
248         unsigned int def, len;
249 
250         if (!asn1_id_decode(ctx, cls, con, tag))
251                 return 0;
252 
253         def = len = 0;
254         if (!asn1_length_decode(ctx, &def, &len))
255                 return 0;
256 
257         /* primitive shall be definite, indefinite shall be constructed */
258         if (*con == ASN1_PRI && !def)
259                 return 0;
260 
261         if (def)
262                 *eoc = ctx->pointer + len;
263         else
264                 *eoc = NULL;
265         return 1;
266 }
267 
268 static unsigned char asn1_eoc_decode(struct asn1_ctx *ctx, unsigned char *eoc)
269 {
270         unsigned char ch;
271 
272         if (eoc == NULL) {
273                 if (!asn1_octet_decode(ctx, &ch))
274                         return 0;
275 
276                 if (ch != 0x00) {
277                         ctx->error = ASN1_ERR_DEC_EOC_MISMATCH;
278                         return 0;
279                 }
280 
281                 if (!asn1_octet_decode(ctx, &ch))
282                         return 0;
283 
284                 if (ch != 0x00) {
285                         ctx->error = ASN1_ERR_DEC_EOC_MISMATCH;
286                         return 0;
287                 }
288                 return 1;
289         } else {
290                 if (ctx->pointer != eoc) {
291                         ctx->error = ASN1_ERR_DEC_LENGTH_MISMATCH;
292                         return 0;
293                 }
294                 return 1;
295         }
296 }
297 
298 static unsigned char asn1_null_decode(struct asn1_ctx *ctx, unsigned char *eoc)
299 {
300         ctx->pointer = eoc;
301         return 1;
302 }
303 
304 static unsigned char asn1_long_decode(struct asn1_ctx *ctx,
305                                       unsigned char *eoc,
306                                       long *integer)
307 {
308         unsigned char ch;
309         unsigned int  len;
310 
311         if (!asn1_octet_decode(ctx, &ch))
312                 return 0;
313 
314         *integer = (signed char) ch;
315         len = 1;
316 
317         while (ctx->pointer < eoc) {
318                 if (++len > sizeof (long)) {
319                         ctx->error = ASN1_ERR_DEC_BADVALUE;
320                         return 0;
321                 }
322 
323                 if (!asn1_octet_decode(ctx, &ch))
324                         return 0;
325 
326                 *integer <<= 8;
327                 *integer |= ch;
328         }
329         return 1;
330 }
331 
332 static unsigned char asn1_uint_decode(struct asn1_ctx *ctx,
333                                       unsigned char *eoc,
334                                       unsigned int *integer)
335 {
336         unsigned char ch;
337         unsigned int  len;
338 
339         if (!asn1_octet_decode(ctx, &ch))
340                 return 0;
341 
342         *integer = ch;
343         if (ch == 0) len = 0;
344         else len = 1;
345 
346         while (ctx->pointer < eoc) {
347                 if (++len > sizeof (unsigned int)) {
348                         ctx->error = ASN1_ERR_DEC_BADVALUE;
349                         return 0;
350                 }
351 
352                 if (!asn1_octet_decode(ctx, &ch))
353                         return 0;
354 
355                 *integer <<= 8;
356                 *integer |= ch;
357         }
358         return 1;
359 }
360 
361 static unsigned char asn1_ulong_decode(struct asn1_ctx *ctx,
362                                        unsigned char *eoc,
363                                        unsigned long *integer)
364 {
365         unsigned char ch;
366         unsigned int  len;
367 
368         if (!asn1_octet_decode(ctx, &ch))
369                 return 0;
370 
371         *integer = ch;
372         if (ch == 0) len = 0;
373         else len = 1;
374 
375         while (ctx->pointer < eoc) {
376                 if (++len > sizeof (unsigned long)) {
377                         ctx->error = ASN1_ERR_DEC_BADVALUE;
378                         return 0;
379                 }
380 
381                 if (!asn1_octet_decode(ctx, &ch))
382                         return 0;
383 
384                 *integer <<= 8;
385                 *integer |= ch;
386         }
387         return 1;
388 }
389 
390 static unsigned char asn1_octets_decode(struct asn1_ctx *ctx,
391                                         unsigned char *eoc,
392                                         unsigned char **octets,
393                                         unsigned int *len)
394 {
395         unsigned char *ptr;
396 
397         *len = 0;
398 
399         *octets = kmalloc(eoc - ctx->pointer, GFP_ATOMIC);
400         if (*octets == NULL) {
401                 if (net_ratelimit())
402                         printk("OOM in bsalg (%d)\n", __LINE__);
403                 return 0;
404         }
405 
406         ptr = *octets;
407         while (ctx->pointer < eoc) {
408                 if (!asn1_octet_decode(ctx, (unsigned char *)ptr++)) {
409                         kfree(*octets);
410                         *octets = NULL;
411                         return 0;
412                 }
413                 (*len)++;
414         }
415         return 1;
416 }
417 
418 static unsigned char asn1_subid_decode(struct asn1_ctx *ctx,
419                                        unsigned long *subid)
420 {
421         unsigned char ch;
422 
423         *subid = 0;
424 
425         do {
426                 if (!asn1_octet_decode(ctx, &ch))
427                         return 0;
428 
429                 *subid <<= 7;
430                 *subid |= ch & 0x7F;
431         } while ((ch & 0x80) == 0x80);
432         return 1;
433 }
434 
435 static unsigned char asn1_oid_decode(struct asn1_ctx *ctx,
436                                      unsigned char *eoc,
437                                      unsigned long **oid,
438                                      unsigned int *len)
439 {
440         unsigned long subid;
441         unsigned int  size;
442         unsigned long *optr;
443 
444         size = eoc - ctx->pointer + 1;
445 
446         /* first subid actually encodes first two subids */
447         if (size < 2 || size > ULONG_MAX/sizeof(unsigned long))
448                 return 0;
449 
450         *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC);
451         if (*oid == NULL) {
452                 if (net_ratelimit())
453                         printk("OOM in bsalg (%d)\n", __LINE__);
454                 return 0;
455         }
456 
457         optr = *oid;
458 
459         if (!asn1_subid_decode(ctx, &subid)) {
460                 kfree(*oid);
461                 *oid = NULL;
462                 return 0;
463         }
464 
465         if (subid < 40) {
466                 optr [0] = 0;
467                 optr [1] = subid;
468         } else if (subid < 80) {
469                 optr [0] = 1;
470                 optr [1] = subid - 40;
471         } else {
472                 optr [0] = 2;
473                 optr [1] = subid - 80;
474         }
475 
476         *len = 2;
477         optr += 2;
478 
479         while (ctx->pointer < eoc) {
480                 if (++(*len) > size) {
481                         ctx->error = ASN1_ERR_DEC_BADVALUE;
482                         kfree(*oid);
483                         *oid = NULL;
484                         return 0;
485                 }
486 
487                 if (!asn1_subid_decode(ctx, optr++)) {
488                         kfree(*oid);
489                         *oid = NULL;
490                         return 0;
491                 }
492         }
493         return 1;
494 }
495 
496 /*****************************************************************************
497  *
498  * SNMP decoding routines (gxsnmp author Dirk Wisse)
499  *
500  *****************************************************************************/
501 
502 /* SNMP Versions */
503 #define SNMP_V1                         0
504 #define SNMP_V2C                        1
505 #define SNMP_V2                         2
506 #define SNMP_V3                         3
507 
508 /* Default Sizes */
509 #define SNMP_SIZE_COMM                  256
510 #define SNMP_SIZE_OBJECTID              128
511 #define SNMP_SIZE_BUFCHR                256
512 #define SNMP_SIZE_BUFINT                128
513 #define SNMP_SIZE_SMALLOBJECTID         16
514 
515 /* Requests */
516 #define SNMP_PDU_GET                    0
517 #define SNMP_PDU_NEXT                   1
518 #define SNMP_PDU_RESPONSE               2
519 #define SNMP_PDU_SET                    3
520 #define SNMP_PDU_TRAP1                  4
521 #define SNMP_PDU_BULK                   5
522 #define SNMP_PDU_INFORM                 6
523 #define SNMP_PDU_TRAP2                  7
524 
525 /* Errors */
526 #define SNMP_NOERROR                    0
527 #define SNMP_TOOBIG                     1
528 #define SNMP_NOSUCHNAME                 2
529 #define SNMP_BADVALUE                   3
530 #define SNMP_READONLY                   4
531 #define SNMP_GENERROR                   5
532 #define SNMP_NOACCESS                   6
533 #define SNMP_WRONGTYPE                  7
534 #define SNMP_WRONGLENGTH                8
535 #define SNMP_WRONGENCODING              9
536 #define SNMP_WRONGVALUE                 10
537 #define SNMP_NOCREATION                 11
538 #define SNMP_INCONSISTENTVALUE          12
539 #define SNMP_RESOURCEUNAVAILABLE        13
540 #define SNMP_COMMITFAILED               14
541 #define SNMP_UNDOFAILED                 15
542 #define SNMP_AUTHORIZATIONERROR         16
543 #define SNMP_NOTWRITABLE                17
544 #define SNMP_INCONSISTENTNAME           18
545 
546 /* General SNMP V1 Traps */
547 #define SNMP_TRAP_COLDSTART             0
548 #define SNMP_TRAP_WARMSTART             1
549 #define SNMP_TRAP_LINKDOWN              2
550 #define SNMP_TRAP_LINKUP                3
551 #define SNMP_TRAP_AUTFAILURE            4
552 #define SNMP_TRAP_EQPNEIGHBORLOSS       5
553 #define SNMP_TRAP_ENTSPECIFIC           6
554 
555 /* SNMPv1 Types */
556 #define SNMP_NULL                0
557 #define SNMP_INTEGER             1    /* l  */
558 #define SNMP_OCTETSTR            2    /* c  */
559 #define SNMP_DISPLAYSTR          2    /* c  */
560 #define SNMP_OBJECTID            3    /* ul */
561 #define SNMP_IPADDR              4    /* uc */
562 #define SNMP_COUNTER             5    /* ul */
563 #define SNMP_GAUGE               6    /* ul */
564 #define SNMP_TIMETICKS           7    /* ul */
565 #define SNMP_OPAQUE              8    /* c  */
566 
567 /* Additional SNMPv2 Types */
568 #define SNMP_UINTEGER            5    /* ul */
569 #define SNMP_BITSTR              9    /* uc */
570 #define SNMP_NSAP               10    /* uc */
571 #define SNMP_COUNTER64          11    /* ul */
572 #define SNMP_NOSUCHOBJECT       12
573 #define SNMP_NOSUCHINSTANCE     13
574 #define SNMP_ENDOFMIBVIEW       14
575 
576 union snmp_syntax
577 {
578         unsigned char uc[0];    /* 8 bit unsigned */
579         char c[0];              /* 8 bit signed */
580         unsigned long ul[0];    /* 32 bit unsigned */
581         long l[0];              /* 32 bit signed */
582 };
583 
584 struct snmp_object
585 {
586         unsigned long *id;
587         unsigned int id_len;
588         unsigned short type;
589         unsigned int syntax_len;
590         union snmp_syntax syntax;
591 };
592 
593 struct snmp_request
594 {
595         unsigned long id;
596         unsigned int error_status;
597         unsigned int error_index;
598 };
599 
600 struct snmp_v1_trap
601 {
602         unsigned long *id;
603         unsigned int id_len;
604         unsigned long ip_address;       /* pointer  */
605         unsigned int general;
606         unsigned int specific;
607         unsigned long time;
608 };
609 
610 /* SNMP types */
611 #define SNMP_IPA    0
612 #define SNMP_CNT    1
613 #define SNMP_GGE    2
614 #define SNMP_TIT    3
615 #define SNMP_OPQ    4
616 #define SNMP_C64    6
617 
618 /* SNMP errors */
619 #define SERR_NSO    0
620 #define SERR_NSI    1
621 #define SERR_EOM    2
622 
623 static inline void mangle_address(unsigned char *begin,
624                                   unsigned char *addr,
625                                   const struct oct1_map *map,
626                                   __sum16 *check);
627 struct snmp_cnv
628 {
629         unsigned int class;
630         unsigned int tag;
631         int syntax;
632 };
633 
634 static struct snmp_cnv snmp_conv [] =
635 {
636         {ASN1_UNI, ASN1_NUL, SNMP_NULL},
637         {ASN1_UNI, ASN1_INT, SNMP_INTEGER},
638         {ASN1_UNI, ASN1_OTS, SNMP_OCTETSTR},
639         {ASN1_UNI, ASN1_OTS, SNMP_DISPLAYSTR},
640         {ASN1_UNI, ASN1_OJI, SNMP_OBJECTID},
641         {ASN1_APL, SNMP_IPA, SNMP_IPADDR},
642         {ASN1_APL, SNMP_CNT, SNMP_COUNTER},     /* Counter32 */
643         {ASN1_APL, SNMP_GGE, SNMP_GAUGE},       /* Gauge32 == Unsigned32  */
644         {ASN1_APL, SNMP_TIT, SNMP_TIMETICKS},
645         {ASN1_APL, SNMP_OPQ, SNMP_OPAQUE},
646 
647         /* SNMPv2 data types and errors */
648         {ASN1_UNI, ASN1_BTS, SNMP_BITSTR},
649         {ASN1_APL, SNMP_C64, SNMP_COUNTER64},
650         {ASN1_CTX, SERR_NSO, SNMP_NOSUCHOBJECT},
651         {ASN1_CTX, SERR_NSI, SNMP_NOSUCHINSTANCE},
652         {ASN1_CTX, SERR_EOM, SNMP_ENDOFMIBVIEW},
653         {0,       0,       -1}
654 };
655 
656 static unsigned char snmp_tag_cls2syntax(unsigned int tag,
657                                          unsigned int cls,
658                                          unsigned short *syntax)
659 {
660         struct snmp_cnv *cnv;
661 
662         cnv = snmp_conv;
663 
664         while (cnv->syntax != -1) {
665                 if (cnv->tag == tag && cnv->class == cls) {
666                         *syntax = cnv->syntax;
667                         return 1;
668                 }
669                 cnv++;
670         }
671         return 0;
672 }
673 
674 static unsigned char snmp_object_decode(struct asn1_ctx *ctx,
675                                         struct snmp_object **obj)
676 {
677         unsigned int cls, con, tag, len, idlen;
678         unsigned short type;
679         unsigned char *eoc, *end, *p;
680         unsigned long *lp, *id;
681         unsigned long ul;
682         long l;
683 
684         *obj = NULL;
685         id = NULL;
686 
687         if (!asn1_header_decode(ctx, &eoc, &cls, &con, &tag))
688                 return 0;
689 
690         if (cls != ASN1_UNI || con != ASN1_CON || tag != ASN1_SEQ)
691                 return 0;
692 
693         if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
694                 return 0;
695 
696         if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_OJI)
697                 return 0;
698 
699         if (!asn1_oid_decode(ctx, end, &id, &idlen))
700                 return 0;
701 
702         if (!asn1_header_decode(ctx, &end, &cls, &con, &tag)) {
703                 kfree(id);
704                 return 0;
705         }
706 
707         if (con != ASN1_PRI) {
708                 kfree(id);
709                 return 0;
710         }
711 
712         type = 0;
713         if (!snmp_tag_cls2syntax(tag, cls, &type)) {
714                 kfree(id);
715                 return 0;
716         }
717 
718         l = 0;
719         switch (type) {
720                 case SNMP_INTEGER:
721                         len = sizeof(long);
722                         if (!asn1_long_decode(ctx, end, &l)) {
723                                 kfree(id);
724                                 return 0;
725                         }
726                         *obj = kmalloc(sizeof(struct snmp_object) + len,
727                                        GFP_ATOMIC);
728                         if (*obj == NULL) {
729                                 kfree(id);
730                                 if (net_ratelimit())
731                                         printk("OOM in bsalg (%d)\n", __LINE__);
732                                 return 0;
733                         }
734                         (*obj)->syntax.l[0] = l;
735                         break;
736                 case SNMP_OCTETSTR:
737                 case SNMP_OPAQUE:
738                         if (!asn1_octets_decode(ctx, end, &p, &len)) {
739                                 kfree(id);
740                                 return 0;
741                         }
742                         *obj = kmalloc(sizeof(struct snmp_object) + len,
743                                        GFP_ATOMIC);
744                         if (*obj == NULL) {
745                                 kfree(id);
746                                 if (net_ratelimit())
747                                         printk("OOM in bsalg (%d)\n", __LINE__);
748                                 return 0;
749                         }
750                         memcpy((*obj)->syntax.c, p, len);
751                         kfree(p);
752                         break;
753                 case SNMP_NULL:
754                 case SNMP_NOSUCHOBJECT:
755                 case SNMP_NOSUCHINSTANCE:
756                 case SNMP_ENDOFMIBVIEW:
757                         len = 0;
758                         *obj = kmalloc(sizeof(struct snmp_object), GFP_ATOMIC);
759                         if (*obj == NULL) {
760                                 kfree(id);
761                                 if (net_ratelimit())
762                                         printk("OOM in bsalg (%d)\n", __LINE__);
763                                 return 0;
764                         }
765                         if (!asn1_null_decode(ctx, end)) {
766                                 kfree(id);
767                                 kfree(*obj);
768                                 *obj = NULL;
769                                 return 0;
770                         }
771                         break;
772                 case SNMP_OBJECTID:
773                         if (!asn1_oid_decode(ctx, end, (unsigned long **)&lp, &len)) {
774                                 kfree(id);
775                                 return 0;
776                         }
777                         len *= sizeof(unsigned long);
778                         *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC);
779                         if (*obj == NULL) {
780                                 kfree(lp);
781                                 kfree(id);
782                                 if (net_ratelimit())
783                                         printk("OOM in bsalg (%d)\n", __LINE__);
784                                 return 0;
785                         }
786                         memcpy((*obj)->syntax.ul, lp, len);
787                         kfree(lp);
788                         break;
789                 case SNMP_IPADDR:
790                         if (!asn1_octets_decode(ctx, end, &p, &len)) {
791                                 kfree(id);
792                                 return 0;
793                         }
794                         if (len != 4) {
795                                 kfree(p);
796                                 kfree(id);
797                                 return 0;
798                         }
799                         *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC);
800                         if (*obj == NULL) {
801                                 kfree(p);
802                                 kfree(id);
803                                 if (net_ratelimit())
804                                         printk("OOM in bsalg (%d)\n", __LINE__);
805                                 return 0;
806                         }
807                         memcpy((*obj)->syntax.uc, p, len);
808                         kfree(p);
809                         break;
810                 case SNMP_COUNTER:
811                 case SNMP_GAUGE:
812                 case SNMP_TIMETICKS:
813                         len = sizeof(unsigned long);
814                         if (!asn1_ulong_decode(ctx, end, &ul)) {
815                                 kfree(id);
816                                 return 0;
817                         }
818                         *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC);
819                         if (*obj == NULL) {
820                                 kfree(id);
821                                 if (net_ratelimit())
822                                         printk("OOM in bsalg (%d)\n", __LINE__);
823                                 return 0;
824                         }
825                         (*obj)->syntax.ul[0] = ul;
826                         break;
827                 default:
828                         kfree(id);
829                         return 0;
830         }
831 
832         (*obj)->syntax_len = len;
833         (*obj)->type = type;
834         (*obj)->id = id;
835         (*obj)->id_len = idlen;
836 
837         if (!asn1_eoc_decode(ctx, eoc)) {
838                 kfree(id);
839                 kfree(*obj);
840                 *obj = NULL;
841                 return 0;
842         }
843         return 1;
844 }
845 
846 static unsigned char snmp_request_decode(struct asn1_ctx *ctx,
847                                          struct snmp_request *request)
848 {
849         unsigned int cls, con, tag;
850         unsigned char *end;
851 
852         if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
853                 return 0;
854 
855         if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT)
856                 return 0;
857 
858         if (!asn1_ulong_decode(ctx, end, &request->id))
859                 return 0;
860 
861         if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
862                 return 0;
863 
864         if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT)
865                 return 0;
866 
867         if (!asn1_uint_decode(ctx, end, &request->error_status))
868                 return 0;
869 
870         if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
871                 return 0;
872 
873         if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT)
874                 return 0;
875 
876         if (!asn1_uint_decode(ctx, end, &request->error_index))
877                 return 0;
878 
879         return 1;
880 }
881 
882 /*
883  * Fast checksum update for possibly oddly-aligned UDP byte, from the
884  * code example in the draft.
885  */
886 static void fast_csum(__sum16 *csum,
887                       const unsigned char *optr,
888                       const unsigned char *nptr,
889                       int offset)
890 {
891         unsigned char s[4];
892 
893         if (offset & 1) {
894                 s[0] = s[2] = 0;
895                 s[1] = ~*optr;
896                 s[3] = *nptr;
897         } else {
898                 s[1] = s[3] = 0;
899                 s[0] = ~*optr;
900                 s[2] = *nptr;
901         }
902 
903         *csum = csum_fold(csum_partial(s, 4, ~csum_unfold(*csum)));
904 }
905 
906 /*
907  * Mangle IP address.
908  *      - begin points to the start of the snmp messgae
909  *      - addr points to the start of the address
910  */
911 static inline void mangle_address(unsigned char *begin,
912                                   unsigned char *addr,
913                                   const struct oct1_map *map,
914                                   __sum16 *check)
915 {
916         if (map->from == NOCT1(addr)) {
917                 u_int32_t old;
918 
919                 if (debug)
920                         memcpy(&old, (unsigned char *)addr, sizeof(old));
921 
922                 *addr = map->to;
923 
924                 /* Update UDP checksum if being used */
925                 if (*check) {
926                         fast_csum(check,
927                                   &map->from, &map->to, addr - begin);
928 
929                 }
930 
931                 if (debug)
932                         printk(KERN_DEBUG "bsalg: mapped %u.%u.%u.%u to "
933                                "%u.%u.%u.%u\n", NIPQUAD(old), NIPQUAD(*addr));
934         }
935 }
936 
937 static unsigned char snmp_trap_decode(struct asn1_ctx *ctx,
938                                       struct snmp_v1_trap *trap,
939                                       const struct oct1_map *map,
940                                       __sum16 *check)
941 {
942         unsigned int cls, con, tag, len;
943         unsigned char *end;
944 
945         if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
946                 return 0;
947 
948         if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_OJI)
949                 return 0;
950 
951         if (!asn1_oid_decode(ctx, end, &trap->id, &trap->id_len))
952                 return 0;
953 
954         if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
955                 goto err_id_free;
956 
957         if (!((cls == ASN1_APL && con == ASN1_PRI && tag == SNMP_IPA) ||
958               (cls == ASN1_UNI && con == ASN1_PRI && tag == ASN1_OTS)))
959                 goto err_id_free;
960 
961         if (!asn1_octets_decode(ctx, end, (unsigned char **)&trap->ip_address, &len))
962                 goto err_id_free;
963 
964         /* IPv4 only */
965         if (len != 4)
966                 goto err_addr_free;
967 
968         mangle_address(ctx->begin, ctx->pointer - 4, map, check);
969 
970         if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
971                 goto err_addr_free;
972 
973         if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT)
974                 goto err_addr_free;
975 
976         if (!asn1_uint_decode(ctx, end, &trap->general))
977                 goto err_addr_free;
978 
979         if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
980                 goto err_addr_free;
981 
982         if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT)
983                 goto err_addr_free;
984 
985         if (!asn1_uint_decode(ctx, end, &trap->specific))
986                 goto err_addr_free;
987 
988         if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
989                 goto err_addr_free;
990 
991         if (!((cls == ASN1_APL && con == ASN1_PRI && tag == SNMP_TIT) ||
992               (cls == ASN1_UNI && con == ASN1_PRI && tag == ASN1_INT)))
993                 goto err_addr_free;
994 
995         if (!asn1_ulong_decode(ctx, end, &trap->time))
996                 goto err_addr_free;
997 
998         return 1;
999 
1000 err_addr_free:
1001         kfree((unsigned long *)trap->ip_address);
1002 
1003 err_id_free:
1004         kfree(trap->id);
1005 
1006         return 0;
1007 }
1008 
1009 /*****************************************************************************
1010  *
1011  * Misc. routines
1012  *
1013  *****************************************************************************/
1014 
1015 static void hex_dump(unsigned char *buf, size_t len)
1016 {
1017         size_t i;
1018 
1019         for (i = 0; i < len; i++) {
1020                 if (i && !(i % 16))
1021                         printk("\n");
1022                 printk("%02x ", *(buf + i));
1023         }
1024         printk("\n");
1025 }
1026 
1027 /*
1028  * Parse and mangle SNMP message according to mapping.
1029  * (And this is the fucking 'basic' method).
1030  */
1031 static int snmp_parse_mangle(unsigned char *msg,
1032                              u_int16_t len,
1033                              const struct oct1_map *map,
1034                              __sum16 *check)
1035 {
1036         unsigned char *eoc, *end;
1037         unsigned int cls, con, tag, vers, pdutype;
1038         struct asn1_ctx ctx;
1039         struct asn1_octstr comm;
1040         struct snmp_object **obj;
1041 
1042         if (debug > 1)
1043                 hex_dump(msg, len);
1044 
1045         asn1_open(&ctx, msg, len);
1046 
1047         /*
1048          * Start of SNMP message.
1049          */
1050         if (!asn1_header_decode(&ctx, &eoc, &cls, &con, &tag))
1051                 return 0;
1052         if (cls != ASN1_UNI || con != ASN1_CON || tag != ASN1_SEQ)
1053                 return 0;
1054 
1055         /*
1056          * Version 1 or 2 handled.
1057          */
1058         if (!asn1_header_decode(&ctx, &end, &cls, &con, &tag))
1059                 return 0;
1060         if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT)
1061                 return 0;
1062         if (!asn1_uint_decode (&ctx, end, &vers))
1063                 return 0;
1064         if (debug > 1)
1065                 printk(KERN_DEBUG "bsalg: snmp version: %u\n", vers + 1);
1066         if (vers > 1)
1067                 return 1;
1068 
1069         /*
1070          * Community.
1071          */
1072         if (!asn1_header_decode (&ctx, &end, &cls, &con, &tag))
1073                 return 0;
1074         if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_OTS)
1075                 return 0;
1076         if (!asn1_octets_decode(&ctx, end, &comm.data, &comm.len))
1077                 return 0;
1078         if (debug > 1) {
1079                 unsigned int i;
1080 
1081                 printk(KERN_DEBUG "bsalg: community: ");
1082                 for (i = 0; i < comm.len; i++)
1083                         printk("%c", comm.data[i]);
1084                 printk("\n");
1085         }
1086         kfree(comm.data);
1087 
1088         /*
1089          * PDU type
1090          */
1091         if (!asn1_header_decode(&ctx, &eoc, &cls, &con, &pdutype))
1092                 return 0;
1093         if (cls != ASN1_CTX || con != ASN1_CON)
1094                 return 0;
1095         if (debug > 1) {
1096                 unsigned char *pdus[] = {
1097                         [SNMP_PDU_GET] = "get",
1098                         [SNMP_PDU_NEXT] = "get-next",
1099                         [SNMP_PDU_RESPONSE] = "response",
1100                         [SNMP_PDU_SET] = "set",
1101                         [SNMP_PDU_TRAP1] = "trapv1",
1102                         [SNMP_PDU_BULK] = "bulk",
1103                         [SNMP_PDU_INFORM] = "inform",
1104                         [SNMP_PDU_TRAP2] = "trapv2"
1105                 };
1106 
1107                 if (pdutype > SNMP_PDU_TRAP2)
1108                         printk(KERN_DEBUG "bsalg: bad pdu type %u\n", pdutype);
1109                 else
1110                         printk(KERN_DEBUG "bsalg: pdu: %s\n", pdus[pdutype]);
1111         }
1112         if (pdutype != SNMP_PDU_RESPONSE &&
1113             pdutype != SNMP_PDU_TRAP1 && pdutype != SNMP_PDU_TRAP2)
1114                 return 1;
1115 
1116         /*
1117          * Request header or v1 trap
1118          */
1119         if (pdutype == SNMP_PDU_TRAP1) {
1120                 struct snmp_v1_trap trap;
1121                 unsigned char ret = snmp_trap_decode(&ctx, &trap, map, check);
1122 
1123                 if (ret) {
1124                         kfree(trap.id);
1125                         kfree((unsigned long *)trap.ip_address);
1126                 } else
1127                         return ret;
1128 
1129         } else {
1130                 struct snmp_request req;
1131 
1132                 if (!snmp_request_decode(&ctx, &req))
1133                         return 0;
1134 
1135                 if (debug > 1)
1136                         printk(KERN_DEBUG "bsalg: request: id=0x%lx error_status=%u "
1137                         "error_index=%u\n", req.id, req.error_status,
1138                         req.error_index);
1139         }
1140 
1141         /*
1142          * Loop through objects, look for IP addresses to mangle.
1143          */
1144         if (!asn1_header_decode(&ctx, &eoc, &cls, &con, &tag))
1145                 return 0;
1146 
1147         if (cls != ASN1_UNI || con != ASN1_CON || tag != ASN1_SEQ)
1148                 return 0;
1149 
1150         obj = kmalloc(sizeof(struct snmp_object), GFP_ATOMIC);
1151         if (obj == NULL) {
1152                 if (net_ratelimit())
1153                         printk(KERN_WARNING "OOM in bsalg(%d)\n", __LINE__);
1154                 return 0;
1155         }
1156 
1157         while (!asn1_eoc_decode(&ctx, eoc)) {
1158                 unsigned int i;
1159 
1160                 if (!snmp_object_decode(&ctx, obj)) {
1161                         if (*obj) {
1162                                 kfree((*obj)->id);
1163                                 kfree(*obj);
1164                         }
1165                         kfree(obj);
1166                         return 0;
1167                 }
1168 
1169                 if (debug > 1) {
1170                         printk(KERN_DEBUG "bsalg: object: ");
1171                         for (i = 0; i < (*obj)->id_len; i++) {
1172                                 if (i > 0)
1173                                         printk(".");
1174                                 printk("%lu", (*obj)->id[i]);
1175                         }
1176                         printk(": type=%u\n", (*obj)->type);
1177 
1178                 }
1179 
1180                 if ((*obj)->type == SNMP_IPADDR)
1181                         mangle_address(ctx.begin, ctx.pointer - 4 , map, check);
1182 
1183                 kfree((*obj)->id);
1184                 kfree(*obj);
1185         }
1186         kfree(obj);
1187 
1188         if (!asn1_eoc_decode(&ctx, eoc))
1189                 return 0;
1190 
1191         return 1;
1192 }
1193 
1194 /*****************************************************************************
1195  *
1196  * NAT routines.
1197  *
1198  *****************************************************************************/
1199 
1200 /*
1201  * SNMP translation routine.
1202  */
1203 static int snmp_translate(struct nf_conn *ct,
1204                           enum ip_conntrack_info ctinfo,
1205                           struct sk_buff *skb)
1206 {
1207         struct iphdr *iph = ip_hdr(skb);
1208         struct udphdr *udph = (struct udphdr *)((__be32 *)iph + iph->ihl);
1209         u_int16_t udplen = ntohs(udph->len);
1210         u_int16_t paylen = udplen - sizeof(struct udphdr);
1211         int dir = CTINFO2DIR(ctinfo);
1212         struct oct1_map map;
1213 
1214         /*
1215          * Determine mappping for application layer addresses based
1216          * on NAT manipulations for the packet.
1217          */
1218         if (dir == IP_CT_DIR_ORIGINAL) {
1219                 /* SNAT traps */
1220                 map.from = NOCT1(&ct->tuplehash[dir].tuple.src.u3.ip);
1221                 map.to = NOCT1(&ct->tuplehash[!dir].tuple.dst.u3.ip);
1222         } else {
1223                 /* DNAT replies */
1224                 map.from = NOCT1(&ct->tuplehash[dir].tuple.src.u3.ip);
1225                 map.to = NOCT1(&ct->tuplehash[!dir].tuple.dst.u3.ip);
1226         }
1227 
1228         if (map.from == map.to)
1229                 return NF_ACCEPT;
1230 
1231         if (!snmp_parse_mangle((unsigned char *)udph + sizeof(struct udphdr),
1232                                paylen, &map, &udph->check)) {
1233                 if (net_ratelimit())
1234                         printk(KERN_WARNING "bsalg: parser failed\n");
1235                 return NF_DROP;
1236         }
1237         return NF_ACCEPT;
1238 }
1239 
1240 /* We don't actually set up expectations, just adjust internal IP
1241  * addresses if this is being NATted */
1242 static int help(struct sk_buff *skb, unsigned int protoff,
1243                 struct nf_conn *ct,
1244                 enum ip_conntrack_info ctinfo)
1245 {
1246         int dir = CTINFO2DIR(ctinfo);
1247         unsigned int ret;
1248         struct iphdr *iph = ip_hdr(skb);
1249         struct udphdr *udph = (struct udphdr *)((u_int32_t *)iph + iph->ihl);
1250 
1251         /* SNMP replies and originating SNMP traps get mangled */
1252         if (udph->source == htons(SNMP_PORT) && dir != IP_CT_DIR_REPLY)
1253                 return NF_ACCEPT;
1254         if (udph->dest == htons(SNMP_TRAP_PORT) && dir != IP_CT_DIR_ORIGINAL)
1255                 return NF_ACCEPT;
1256 
1257         /* No NAT? */
1258         if (!(ct->status & IPS_NAT_MASK))
1259                 return NF_ACCEPT;
1260 
1261         /*
1262          * Make sure the packet length is ok.  So far, we were only guaranteed
1263          * to have a valid length IP header plus 8 bytes, which means we have
1264          * enough room for a UDP header.  Just verify the UDP length field so we
1265          * can mess around with the payload.
1266          */
1267         if (ntohs(udph->len) != skb->len - (iph->ihl << 2)) {
1268                  if (net_ratelimit())
1269                          printk(KERN_WARNING "SNMP: dropping malformed packet "
1270                                 "src=%u.%u.%u.%u dst=%u.%u.%u.%u\n",
1271                                 NIPQUAD(iph->saddr), NIPQUAD(iph->daddr));
1272                  return NF_DROP;
1273         }
1274 
1275         if (!skb_make_writable(skb, skb->len))
1276                 return NF_DROP;
1277 
1278         spin_lock_bh(&snmp_lock);
1279         ret = snmp_translate(ct, ctinfo, skb);
1280         spin_unlock_bh(&snmp_lock);
1281         return ret;
1282 }
1283 
1284 static struct nf_conntrack_helper snmp_helper __read_mostly = {
1285         .max_expected           = 0,
1286         .timeout                = 180,
1287         .me                     = THIS_MODULE,
1288         .help                   = help,
1289         .name                   = "snmp",
1290         .tuple.src.l3num        = AF_INET,
1291         .tuple.src.u.udp.port   = __constant_htons(SNMP_PORT),
1292         .tuple.dst.protonum     = IPPROTO_UDP,
1293 };
1294 
1295 static struct nf_conntrack_helper snmp_trap_helper __read_mostly = {
1296         .max_expected           = 0,
1297         .timeout                = 180,
1298         .me                     = THIS_MODULE,
1299         .help                   = help,
1300         .name                   = "snmp_trap",
1301         .tuple.src.l3num        = AF_INET,
1302         .tuple.src.u.udp.port   = __constant_htons(SNMP_TRAP_PORT),
1303         .tuple.dst.protonum     = IPPROTO_UDP,
1304 };
1305 
1306 /*****************************************************************************
1307  *
1308  * Module stuff.
1309  *
1310  *****************************************************************************/
1311 
1312 static int __init nf_nat_snmp_basic_init(void)
1313 {
1314         int ret = 0;
1315 
1316         ret = nf_conntrack_helper_register(&snmp_helper);
1317         if (ret < 0)
1318                 return ret;
1319         ret = nf_conntrack_helper_register(&snmp_trap_helper);
1320         if (ret < 0) {
1321                 nf_conntrack_helper_unregister(&snmp_helper);
1322                 return ret;
1323         }
1324         return ret;
1325 }
1326 
1327 static void __exit nf_nat_snmp_basic_fini(void)
1328 {
1329         nf_conntrack_helper_unregister(&snmp_helper);
1330         nf_conntrack_helper_unregister(&snmp_trap_helper);
1331 }
1332 
1333 module_init(nf_nat_snmp_basic_init);
1334 module_exit(nf_nat_snmp_basic_fini);
1335 
1336 module_param(debug, int, 0600);
1337 
  This page was automatically generated by the LXR engine.