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