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