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