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