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