~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/ipv4/netfilter/nf_nat_snmp_basic.c

Version: ~ [ linux-5.4-rc3 ] ~ [ linux-5.3.6 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.79 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.149 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.196 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.196 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.75 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * nf_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, see <http://www.gnu.org/licenses/>.
 38  *
 39  * Author: James Morris <jmorris@intercode.com.au>
 40  *
 41  * Copyright (c) 2006-2010 Patrick McHardy <kaber@trash.net>
 42  */
 43 #include <linux/module.h>
 44 #include <linux/moduleparam.h>
 45 #include <linux/types.h>
 46 #include <linux/kernel.h>
 47 #include <linux/slab.h>
 48 #include <linux/in.h>
 49 #include <linux/ip.h>
 50 #include <linux/udp.h>
 51 #include <net/checksum.h>
 52 #include <net/udp.h>
 53 
 54 #include <net/netfilter/nf_nat.h>
 55 #include <net/netfilter/nf_conntrack_expect.h>
 56 #include <net/netfilter/nf_conntrack_helper.h>
 57 #include <net/netfilter/nf_nat_helper.h>
 58 #include <linux/netfilter/nf_conntrack_snmp.h>
 59 
 60 MODULE_LICENSE("GPL");
 61 MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
 62 MODULE_DESCRIPTION("Basic SNMP Application Layer Gateway");
 63 MODULE_ALIAS("ip_nat_snmp_basic");
 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 = 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 
239         /* don't trust len bigger than ctx buffer */
240         if (*len > ctx->end - ctx->pointer)
241                 return 0;
242 
243         return 1;
244 }
245 
246 static unsigned char asn1_header_decode(struct asn1_ctx *ctx,
247                                         unsigned char **eoc,
248                                         unsigned int *cls,
249                                         unsigned int *con,
250                                         unsigned int *tag)
251 {
252         unsigned int def, len;
253 
254         if (!asn1_id_decode(ctx, cls, con, tag))
255                 return 0;
256 
257         def = len = 0;
258         if (!asn1_length_decode(ctx, &def, &len))
259                 return 0;
260 
261         /* primitive shall be definite, indefinite shall be constructed */
262         if (*con == ASN1_PRI && !def)
263                 return 0;
264 
265         if (def)
266                 *eoc = ctx->pointer + len;
267         else
268                 *eoc = NULL;
269         return 1;
270 }
271 
272 static unsigned char asn1_eoc_decode(struct asn1_ctx *ctx, unsigned char *eoc)
273 {
274         unsigned char ch;
275 
276         if (eoc == NULL) {
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 
285                 if (!asn1_octet_decode(ctx, &ch))
286                         return 0;
287 
288                 if (ch != 0x00) {
289                         ctx->error = ASN1_ERR_DEC_EOC_MISMATCH;
290                         return 0;
291                 }
292                 return 1;
293         } else {
294                 if (ctx->pointer != eoc) {
295                         ctx->error = ASN1_ERR_DEC_LENGTH_MISMATCH;
296                         return 0;
297                 }
298                 return 1;
299         }
300 }
301 
302 static unsigned char asn1_null_decode(struct asn1_ctx *ctx, unsigned char *eoc)
303 {
304         ctx->pointer = eoc;
305         return 1;
306 }
307 
308 static unsigned char asn1_long_decode(struct asn1_ctx *ctx,
309                                       unsigned char *eoc,
310                                       long *integer)
311 {
312         unsigned char ch;
313         unsigned int  len;
314 
315         if (!asn1_octet_decode(ctx, &ch))
316                 return 0;
317 
318         *integer = (signed char) ch;
319         len = 1;
320 
321         while (ctx->pointer < eoc) {
322                 if (++len > sizeof (long)) {
323                         ctx->error = ASN1_ERR_DEC_BADVALUE;
324                         return 0;
325                 }
326 
327                 if (!asn1_octet_decode(ctx, &ch))
328                         return 0;
329 
330                 *integer <<= 8;
331                 *integer |= ch;
332         }
333         return 1;
334 }
335 
336 static unsigned char asn1_uint_decode(struct asn1_ctx *ctx,
337                                       unsigned char *eoc,
338                                       unsigned int *integer)
339 {
340         unsigned char ch;
341         unsigned int  len;
342 
343         if (!asn1_octet_decode(ctx, &ch))
344                 return 0;
345 
346         *integer = ch;
347         if (ch == 0) len = 0;
348         else len = 1;
349 
350         while (ctx->pointer < eoc) {
351                 if (++len > sizeof (unsigned int)) {
352                         ctx->error = ASN1_ERR_DEC_BADVALUE;
353                         return 0;
354                 }
355 
356                 if (!asn1_octet_decode(ctx, &ch))
357                         return 0;
358 
359                 *integer <<= 8;
360                 *integer |= ch;
361         }
362         return 1;
363 }
364 
365 static unsigned char asn1_ulong_decode(struct asn1_ctx *ctx,
366                                        unsigned char *eoc,
367                                        unsigned long *integer)
368 {
369         unsigned char ch;
370         unsigned int  len;
371 
372         if (!asn1_octet_decode(ctx, &ch))
373                 return 0;
374 
375         *integer = ch;
376         if (ch == 0) len = 0;
377         else len = 1;
378 
379         while (ctx->pointer < eoc) {
380                 if (++len > sizeof (unsigned long)) {
381                         ctx->error = ASN1_ERR_DEC_BADVALUE;
382                         return 0;
383                 }
384 
385                 if (!asn1_octet_decode(ctx, &ch))
386                         return 0;
387 
388                 *integer <<= 8;
389                 *integer |= ch;
390         }
391         return 1;
392 }
393 
394 static unsigned char asn1_octets_decode(struct asn1_ctx *ctx,
395                                         unsigned char *eoc,
396                                         unsigned char **octets,
397                                         unsigned int *len)
398 {
399         unsigned char *ptr;
400 
401         *len = 0;
402 
403         *octets = kmalloc(eoc - ctx->pointer, GFP_ATOMIC);
404         if (*octets == NULL)
405                 return 0;
406 
407         ptr = *octets;
408         while (ctx->pointer < eoc) {
409                 if (!asn1_octet_decode(ctx, ptr++)) {
410                         kfree(*octets);
411                         *octets = NULL;
412                         return 0;
413                 }
414                 (*len)++;
415         }
416         return 1;
417 }
418 
419 static unsigned char asn1_subid_decode(struct asn1_ctx *ctx,
420                                        unsigned long *subid)
421 {
422         unsigned char ch;
423 
424         *subid = 0;
425 
426         do {
427                 if (!asn1_octet_decode(ctx, &ch))
428                         return 0;
429 
430                 *subid <<= 7;
431                 *subid |= ch & 0x7F;
432         } while ((ch & 0x80) == 0x80);
433         return 1;
434 }
435 
436 static unsigned char asn1_oid_decode(struct asn1_ctx *ctx,
437                                      unsigned char *eoc,
438                                      unsigned long **oid,
439                                      unsigned int *len)
440 {
441         unsigned long subid;
442         unsigned long *optr;
443         size_t size;
444 
445         size = eoc - ctx->pointer + 1;
446 
447         /* first subid actually encodes first two subids */
448         if (size < 2 || size > ULONG_MAX/sizeof(unsigned long))
449                 return 0;
450 
451         *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC);
452         if (*oid == NULL)
453                 return 0;
454 
455         optr = *oid;
456 
457         if (!asn1_subid_decode(ctx, &subid)) {
458                 kfree(*oid);
459                 *oid = NULL;
460                 return 0;
461         }
462 
463         if (subid < 40) {
464                 optr[0] = 0;
465                 optr[1] = subid;
466         } else if (subid < 80) {
467                 optr[0] = 1;
468                 optr[1] = subid - 40;
469         } else {
470                 optr[0] = 2;
471                 optr[1] = subid - 80;
472         }
473 
474         *len = 2;
475         optr += 2;
476 
477         while (ctx->pointer < eoc) {
478                 if (++(*len) > size) {
479                         ctx->error = ASN1_ERR_DEC_BADVALUE;
480                         kfree(*oid);
481                         *oid = NULL;
482                         return 0;
483                 }
484 
485                 if (!asn1_subid_decode(ctx, optr++)) {
486                         kfree(*oid);
487                         *oid = NULL;
488                         return 0;
489                 }
490         }
491         return 1;
492 }
493 
494 /*****************************************************************************
495  *
496  * SNMP decoding routines (gxsnmp author Dirk Wisse)
497  *
498  *****************************************************************************/
499 
500 /* SNMP Versions */
501 #define SNMP_V1                         0
502 #define SNMP_V2C                        1
503 #define SNMP_V2                         2
504 #define SNMP_V3                         3
505 
506 /* Default Sizes */
507 #define SNMP_SIZE_COMM                  256
508 #define SNMP_SIZE_OBJECTID              128
509 #define SNMP_SIZE_BUFCHR                256
510 #define SNMP_SIZE_BUFINT                128
511 #define SNMP_SIZE_SMALLOBJECTID         16
512 
513 /* Requests */
514 #define SNMP_PDU_GET                    0
515 #define SNMP_PDU_NEXT                   1
516 #define SNMP_PDU_RESPONSE               2
517 #define SNMP_PDU_SET                    3
518 #define SNMP_PDU_TRAP1                  4
519 #define SNMP_PDU_BULK                   5
520 #define SNMP_PDU_INFORM                 6
521 #define SNMP_PDU_TRAP2                  7
522 
523 /* Errors */
524 #define SNMP_NOERROR                    0
525 #define SNMP_TOOBIG                     1
526 #define SNMP_NOSUCHNAME                 2
527 #define SNMP_BADVALUE                   3
528 #define SNMP_READONLY                   4
529 #define SNMP_GENERROR                   5
530 #define SNMP_NOACCESS                   6
531 #define SNMP_WRONGTYPE                  7
532 #define SNMP_WRONGLENGTH                8
533 #define SNMP_WRONGENCODING              9
534 #define SNMP_WRONGVALUE                 10
535 #define SNMP_NOCREATION                 11
536 #define SNMP_INCONSISTENTVALUE          12
537 #define SNMP_RESOURCEUNAVAILABLE        13
538 #define SNMP_COMMITFAILED               14
539 #define SNMP_UNDOFAILED                 15
540 #define SNMP_AUTHORIZATIONERROR         16
541 #define SNMP_NOTWRITABLE                17
542 #define SNMP_INCONSISTENTNAME           18
543 
544 /* General SNMP V1 Traps */
545 #define SNMP_TRAP_COLDSTART             0
546 #define SNMP_TRAP_WARMSTART             1
547 #define SNMP_TRAP_LINKDOWN              2
548 #define SNMP_TRAP_LINKUP                3
549 #define SNMP_TRAP_AUTFAILURE            4
550 #define SNMP_TRAP_EQPNEIGHBORLOSS       5
551 #define SNMP_TRAP_ENTSPECIFIC           6
552 
553 /* SNMPv1 Types */
554 #define SNMP_NULL                0
555 #define SNMP_INTEGER             1    /* l  */
556 #define SNMP_OCTETSTR            2    /* c  */
557 #define SNMP_DISPLAYSTR          2    /* c  */
558 #define SNMP_OBJECTID            3    /* ul */
559 #define SNMP_IPADDR              4    /* uc */
560 #define SNMP_COUNTER             5    /* ul */
561 #define SNMP_GAUGE               6    /* ul */
562 #define SNMP_TIMETICKS           7    /* ul */
563 #define SNMP_OPAQUE              8    /* c  */
564 
565 /* Additional SNMPv2 Types */
566 #define SNMP_UINTEGER            5    /* ul */
567 #define SNMP_BITSTR              9    /* uc */
568 #define SNMP_NSAP               10    /* uc */
569 #define SNMP_COUNTER64          11    /* ul */
570 #define SNMP_NOSUCHOBJECT       12
571 #define SNMP_NOSUCHINSTANCE     13
572 #define SNMP_ENDOFMIBVIEW       14
573 
574 union snmp_syntax
575 {
576         unsigned char uc[0];    /* 8 bit unsigned */
577         char c[0];              /* 8 bit signed */
578         unsigned long ul[0];    /* 32 bit unsigned */
579         long l[0];              /* 32 bit signed */
580 };
581 
582 struct snmp_object
583 {
584         unsigned long *id;
585         unsigned int id_len;
586         unsigned short type;
587         unsigned int syntax_len;
588         union snmp_syntax syntax;
589 };
590 
591 struct snmp_request
592 {
593         unsigned long id;
594         unsigned int error_status;
595         unsigned int error_index;
596 };
597 
598 struct snmp_v1_trap
599 {
600         unsigned long *id;
601         unsigned int id_len;
602         unsigned long ip_address;       /* pointer  */
603         unsigned int general;
604         unsigned int specific;
605         unsigned long time;
606 };
607 
608 /* SNMP types */
609 #define SNMP_IPA    0
610 #define SNMP_CNT    1
611 #define SNMP_GGE    2
612 #define SNMP_TIT    3
613 #define SNMP_OPQ    4
614 #define SNMP_C64    6
615 
616 /* SNMP errors */
617 #define SERR_NSO    0
618 #define SERR_NSI    1
619 #define SERR_EOM    2
620 
621 static inline void mangle_address(unsigned char *begin,
622                                   unsigned char *addr,
623                                   const struct oct1_map *map,
624                                   __sum16 *check);
625 struct snmp_cnv
626 {
627         unsigned int class;
628         unsigned int tag;
629         int syntax;
630 };
631 
632 static const struct snmp_cnv snmp_conv[] = {
633         {ASN1_UNI, ASN1_NUL, SNMP_NULL},
634         {ASN1_UNI, ASN1_INT, SNMP_INTEGER},
635         {ASN1_UNI, ASN1_OTS, SNMP_OCTETSTR},
636         {ASN1_UNI, ASN1_OTS, SNMP_DISPLAYSTR},
637         {ASN1_UNI, ASN1_OJI, SNMP_OBJECTID},
638         {ASN1_APL, SNMP_IPA, SNMP_IPADDR},
639         {ASN1_APL, SNMP_CNT, SNMP_COUNTER},     /* Counter32 */
640         {ASN1_APL, SNMP_GGE, SNMP_GAUGE},       /* Gauge32 == Unsigned32  */
641         {ASN1_APL, SNMP_TIT, SNMP_TIMETICKS},
642         {ASN1_APL, SNMP_OPQ, SNMP_OPAQUE},
643 
644         /* SNMPv2 data types and errors */
645         {ASN1_UNI, ASN1_BTS, SNMP_BITSTR},
646         {ASN1_APL, SNMP_C64, SNMP_COUNTER64},
647         {ASN1_CTX, SERR_NSO, SNMP_NOSUCHOBJECT},
648         {ASN1_CTX, SERR_NSI, SNMP_NOSUCHINSTANCE},
649         {ASN1_CTX, SERR_EOM, SNMP_ENDOFMIBVIEW},
650         {0,       0,       -1}
651 };
652 
653 static unsigned char snmp_tag_cls2syntax(unsigned int tag,
654                                          unsigned int cls,
655                                          unsigned short *syntax)
656 {
657         const struct snmp_cnv *cnv;
658 
659         cnv = snmp_conv;
660 
661         while (cnv->syntax != -1) {
662                 if (cnv->tag == tag && cnv->class == cls) {
663                         *syntax = cnv->syntax;
664                         return 1;
665                 }
666                 cnv++;
667         }
668         return 0;
669 }
670 
671 static unsigned char snmp_object_decode(struct asn1_ctx *ctx,
672                                         struct snmp_object **obj)
673 {
674         unsigned int cls, con, tag, len, idlen;
675         unsigned short type;
676         unsigned char *eoc, *end, *p;
677         unsigned long *lp, *id;
678         unsigned long ul;
679         long l;
680 
681         *obj = NULL;
682         id = NULL;
683 
684         if (!asn1_header_decode(ctx, &eoc, &cls, &con, &tag))
685                 return 0;
686 
687         if (cls != ASN1_UNI || con != ASN1_CON || tag != ASN1_SEQ)
688                 return 0;
689 
690         if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
691                 return 0;
692 
693         if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_OJI)
694                 return 0;
695 
696         if (!asn1_oid_decode(ctx, end, &id, &idlen))
697                 return 0;
698 
699         if (!asn1_header_decode(ctx, &end, &cls, &con, &tag)) {
700                 kfree(id);
701                 return 0;
702         }
703 
704         if (con != ASN1_PRI) {
705                 kfree(id);
706                 return 0;
707         }
708 
709         type = 0;
710         if (!snmp_tag_cls2syntax(tag, cls, &type)) {
711                 kfree(id);
712                 return 0;
713         }
714 
715         l = 0;
716         switch (type) {
717         case SNMP_INTEGER:
718                 len = sizeof(long);
719                 if (!asn1_long_decode(ctx, end, &l)) {
720                         kfree(id);
721                         return 0;
722                 }
723                 *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC);
724                 if (*obj == NULL) {
725                         kfree(id);
726                         return 0;
727                 }
728                 (*obj)->syntax.l[0] = l;
729                 break;
730         case SNMP_OCTETSTR:
731         case SNMP_OPAQUE:
732                 if (!asn1_octets_decode(ctx, end, &p, &len)) {
733                         kfree(id);
734                         return 0;
735                 }
736                 *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC);
737                 if (*obj == NULL) {
738                         kfree(p);
739                         kfree(id);
740                         return 0;
741                 }
742                 memcpy((*obj)->syntax.c, p, len);
743                 kfree(p);
744                 break;
745         case SNMP_NULL:
746         case SNMP_NOSUCHOBJECT:
747         case SNMP_NOSUCHINSTANCE:
748         case SNMP_ENDOFMIBVIEW:
749                 len = 0;
750                 *obj = kmalloc(sizeof(struct snmp_object), GFP_ATOMIC);
751                 if (*obj == NULL) {
752                         kfree(id);
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, &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                         return 0;
773                 }
774                 memcpy((*obj)->syntax.ul, lp, len);
775                 kfree(lp);
776                 break;
777         case SNMP_IPADDR:
778                 if (!asn1_octets_decode(ctx, end, &p, &len)) {
779                         kfree(id);
780                         return 0;
781                 }
782                 if (len != 4) {
783                         kfree(p);
784                         kfree(id);
785                         return 0;
786                 }
787                 *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC);
788                 if (*obj == NULL) {
789                         kfree(p);
790                         kfree(id);
791                         return 0;
792                 }
793                 memcpy((*obj)->syntax.uc, p, len);
794                 kfree(p);
795                 break;
796         case SNMP_COUNTER:
797         case SNMP_GAUGE:
798         case SNMP_TIMETICKS:
799                 len = sizeof(unsigned long);
800                 if (!asn1_ulong_decode(ctx, end, &ul)) {
801                         kfree(id);
802                         return 0;
803                 }
804                 *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC);
805                 if (*obj == NULL) {
806                         kfree(id);
807                         return 0;
808                 }
809                 (*obj)->syntax.ul[0] = ul;
810                 break;
811         default:
812                 kfree(id);
813                 return 0;
814         }
815 
816         (*obj)->syntax_len = len;
817         (*obj)->type = type;
818         (*obj)->id = id;
819         (*obj)->id_len = idlen;
820 
821         if (!asn1_eoc_decode(ctx, eoc)) {
822                 kfree(id);
823                 kfree(*obj);
824                 *obj = NULL;
825                 return 0;
826         }
827         return 1;
828 }
829 
830 static unsigned char snmp_request_decode(struct asn1_ctx *ctx,
831                                          struct snmp_request *request)
832 {
833         unsigned int cls, con, tag;
834         unsigned char *end;
835 
836         if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
837                 return 0;
838 
839         if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT)
840                 return 0;
841 
842         if (!asn1_ulong_decode(ctx, end, &request->id))
843                 return 0;
844 
845         if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
846                 return 0;
847 
848         if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT)
849                 return 0;
850 
851         if (!asn1_uint_decode(ctx, end, &request->error_status))
852                 return 0;
853 
854         if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
855                 return 0;
856 
857         if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT)
858                 return 0;
859 
860         if (!asn1_uint_decode(ctx, end, &request->error_index))
861                 return 0;
862 
863         return 1;
864 }
865 
866 /*
867  * Fast checksum update for possibly oddly-aligned UDP byte, from the
868  * code example in the draft.
869  */
870 static void fast_csum(__sum16 *csum,
871                       const unsigned char *optr,
872                       const unsigned char *nptr,
873                       int offset)
874 {
875         unsigned char s[4];
876 
877         if (offset & 1) {
878                 s[0] = ~0;
879                 s[1] = ~*optr;
880                 s[2] = 0;
881                 s[3] = *nptr;
882         } else {
883                 s[0] = ~*optr;
884                 s[1] = ~0;
885                 s[2] = *nptr;
886                 s[3] = 0;
887         }
888 
889         *csum = csum_fold(csum_partial(s, 4, ~csum_unfold(*csum)));
890 }
891 
892 /*
893  * Mangle IP address.
894  *      - begin points to the start of the snmp messgae
895  *      - addr points to the start of the address
896  */
897 static inline void mangle_address(unsigned char *begin,
898                                   unsigned char *addr,
899                                   const struct oct1_map *map,
900                                   __sum16 *check)
901 {
902         if (map->from == NOCT1(addr)) {
903                 u_int32_t old;
904 
905                 if (debug)
906                         memcpy(&old, addr, sizeof(old));
907 
908                 *addr = map->to;
909 
910                 /* Update UDP checksum if being used */
911                 if (*check) {
912                         fast_csum(check,
913                                   &map->from, &map->to, addr - begin);
914 
915                 }
916 
917                 if (debug)
918                         printk(KERN_DEBUG "bsalg: mapped %pI4 to %pI4\n",
919                                &old, addr);
920         }
921 }
922 
923 static unsigned char snmp_trap_decode(struct asn1_ctx *ctx,
924                                       struct snmp_v1_trap *trap,
925                                       const struct oct1_map *map,
926                                       __sum16 *check)
927 {
928         unsigned int cls, con, tag, len;
929         unsigned char *end;
930 
931         if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
932                 return 0;
933 
934         if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_OJI)
935                 return 0;
936 
937         if (!asn1_oid_decode(ctx, end, &trap->id, &trap->id_len))
938                 return 0;
939 
940         if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
941                 goto err_id_free;
942 
943         if (!((cls == ASN1_APL && con == ASN1_PRI && tag == SNMP_IPA) ||
944               (cls == ASN1_UNI && con == ASN1_PRI && tag == ASN1_OTS)))
945                 goto err_id_free;
946 
947         if (!asn1_octets_decode(ctx, end, (unsigned char **)&trap->ip_address, &len))
948                 goto err_id_free;
949 
950         /* IPv4 only */
951         if (len != 4)
952                 goto err_addr_free;
953 
954         mangle_address(ctx->begin, ctx->pointer - 4, map, check);
955 
956         if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
957                 goto err_addr_free;
958 
959         if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT)
960                 goto err_addr_free;
961 
962         if (!asn1_uint_decode(ctx, end, &trap->general))
963                 goto err_addr_free;
964 
965         if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
966                 goto err_addr_free;
967 
968         if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT)
969                 goto err_addr_free;
970 
971         if (!asn1_uint_decode(ctx, end, &trap->specific))
972                 goto err_addr_free;
973 
974         if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
975                 goto err_addr_free;
976 
977         if (!((cls == ASN1_APL && con == ASN1_PRI && tag == SNMP_TIT) ||
978               (cls == ASN1_UNI && con == ASN1_PRI && tag == ASN1_INT)))
979                 goto err_addr_free;
980 
981         if (!asn1_ulong_decode(ctx, end, &trap->time))
982                 goto err_addr_free;
983 
984         return 1;
985 
986 err_addr_free:
987         kfree((unsigned long *)trap->ip_address);
988 
989 err_id_free:
990         kfree(trap->id);
991 
992         return 0;
993 }
994 
995 /*****************************************************************************
996  *
997  * Misc. routines
998  *
999  *****************************************************************************/
1000 
1001 static void hex_dump(const unsigned char *buf, size_t len)
1002 {
1003         size_t i;
1004 
1005         for (i = 0; i < len; i++) {
1006                 if (i && !(i % 16))
1007                         printk("\n");
1008                 printk("%02x ", *(buf + i));
1009         }
1010         printk("\n");
1011 }
1012 
1013 /*
1014  * Parse and mangle SNMP message according to mapping.
1015  * (And this is the fucking 'basic' method).
1016  */
1017 static int snmp_parse_mangle(unsigned char *msg,
1018                              u_int16_t len,
1019                              const struct oct1_map *map,
1020                              __sum16 *check)
1021 {
1022         unsigned char *eoc, *end;
1023         unsigned int cls, con, tag, vers, pdutype;
1024         struct asn1_ctx ctx;
1025         struct asn1_octstr comm;
1026         struct snmp_object *obj;
1027 
1028         if (debug > 1)
1029                 hex_dump(msg, len);
1030 
1031         asn1_open(&ctx, msg, len);
1032 
1033         /*
1034          * Start of SNMP message.
1035          */
1036         if (!asn1_header_decode(&ctx, &eoc, &cls, &con, &tag))
1037                 return 0;
1038         if (cls != ASN1_UNI || con != ASN1_CON || tag != ASN1_SEQ)
1039                 return 0;
1040 
1041         /*
1042          * Version 1 or 2 handled.
1043          */
1044         if (!asn1_header_decode(&ctx, &end, &cls, &con, &tag))
1045                 return 0;
1046         if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT)
1047                 return 0;
1048         if (!asn1_uint_decode (&ctx, end, &vers))
1049                 return 0;
1050         if (debug > 1)
1051                 pr_debug("bsalg: snmp version: %u\n", vers + 1);
1052         if (vers > 1)
1053                 return 1;
1054 
1055         /*
1056          * Community.
1057          */
1058         if (!asn1_header_decode (&ctx, &end, &cls, &con, &tag))
1059                 return 0;
1060         if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_OTS)
1061                 return 0;
1062         if (!asn1_octets_decode(&ctx, end, &comm.data, &comm.len))
1063                 return 0;
1064         if (debug > 1) {
1065                 unsigned int i;
1066 
1067                 pr_debug("bsalg: community: ");
1068                 for (i = 0; i < comm.len; i++)
1069                         pr_cont("%c", comm.data[i]);
1070                 pr_cont("\n");
1071         }
1072         kfree(comm.data);
1073 
1074         /*
1075          * PDU type
1076          */
1077         if (!asn1_header_decode(&ctx, &eoc, &cls, &con, &pdutype))
1078                 return 0;
1079         if (cls != ASN1_CTX || con != ASN1_CON)
1080                 return 0;
1081         if (debug > 1) {
1082                 static const unsigned char *const pdus[] = {
1083                         [SNMP_PDU_GET] = "get",
1084                         [SNMP_PDU_NEXT] = "get-next",
1085                         [SNMP_PDU_RESPONSE] = "response",
1086                         [SNMP_PDU_SET] = "set",
1087                         [SNMP_PDU_TRAP1] = "trapv1",
1088                         [SNMP_PDU_BULK] = "bulk",
1089                         [SNMP_PDU_INFORM] = "inform",
1090                         [SNMP_PDU_TRAP2] = "trapv2"
1091                 };
1092 
1093                 if (pdutype > SNMP_PDU_TRAP2)
1094                         pr_debug("bsalg: bad pdu type %u\n", pdutype);
1095                 else
1096                         pr_debug("bsalg: pdu: %s\n", pdus[pdutype]);
1097         }
1098         if (pdutype != SNMP_PDU_RESPONSE &&
1099             pdutype != SNMP_PDU_TRAP1 && pdutype != SNMP_PDU_TRAP2)
1100                 return 1;
1101 
1102         /*
1103          * Request header or v1 trap
1104          */
1105         if (pdutype == SNMP_PDU_TRAP1) {
1106                 struct snmp_v1_trap trap;
1107                 unsigned char ret = snmp_trap_decode(&ctx, &trap, map, check);
1108 
1109                 if (ret) {
1110                         kfree(trap.id);
1111                         kfree((unsigned long *)trap.ip_address);
1112                 } else
1113                         return ret;
1114 
1115         } else {
1116                 struct snmp_request req;
1117 
1118                 if (!snmp_request_decode(&ctx, &req))
1119                         return 0;
1120 
1121                 if (debug > 1)
1122                         pr_debug("bsalg: request: id=0x%lx error_status=%u "
1123                         "error_index=%u\n", req.id, req.error_status,
1124                         req.error_index);
1125         }
1126 
1127         /*
1128          * Loop through objects, look for IP addresses to mangle.
1129          */
1130         if (!asn1_header_decode(&ctx, &eoc, &cls, &con, &tag))
1131                 return 0;
1132 
1133         if (cls != ASN1_UNI || con != ASN1_CON || tag != ASN1_SEQ)
1134                 return 0;
1135 
1136         while (!asn1_eoc_decode(&ctx, eoc)) {
1137                 unsigned int i;
1138 
1139                 if (!snmp_object_decode(&ctx, &obj)) {
1140                         if (obj) {
1141                                 kfree(obj->id);
1142                                 kfree(obj);
1143                         }
1144                         return 0;
1145                 }
1146 
1147                 if (debug > 1) {
1148                         pr_debug("bsalg: object: ");
1149                         for (i = 0; i < obj->id_len; i++) {
1150                                 if (i > 0)
1151                                         pr_cont(".");
1152                                 pr_cont("%lu", obj->id[i]);
1153                         }
1154                         pr_cont(": type=%u\n", obj->type);
1155 
1156                 }
1157 
1158                 if (obj->type == SNMP_IPADDR)
1159                         mangle_address(ctx.begin, ctx.pointer - 4, map, check);
1160 
1161                 kfree(obj->id);
1162                 kfree(obj);
1163         }
1164 
1165         if (!asn1_eoc_decode(&ctx, eoc))
1166                 return 0;
1167 
1168         return 1;
1169 }
1170 
1171 /*****************************************************************************
1172  *
1173  * NAT routines.
1174  *
1175  *****************************************************************************/
1176 
1177 /*
1178  * SNMP translation routine.
1179  */
1180 static int snmp_translate(struct nf_conn *ct,
1181                           enum ip_conntrack_info ctinfo,
1182                           struct sk_buff *skb)
1183 {
1184         struct iphdr *iph = ip_hdr(skb);
1185         struct udphdr *udph = (struct udphdr *)((__be32 *)iph + iph->ihl);
1186         u_int16_t udplen = ntohs(udph->len);
1187         u_int16_t paylen = udplen - sizeof(struct udphdr);
1188         int dir = CTINFO2DIR(ctinfo);
1189         struct oct1_map map;
1190 
1191         /*
1192          * Determine mappping for application layer addresses based
1193          * on NAT manipulations for the packet.
1194          */
1195         if (dir == IP_CT_DIR_ORIGINAL) {
1196                 /* SNAT traps */
1197                 map.from = NOCT1(&ct->tuplehash[dir].tuple.src.u3.ip);
1198                 map.to = NOCT1(&ct->tuplehash[!dir].tuple.dst.u3.ip);
1199         } else {
1200                 /* DNAT replies */
1201                 map.from = NOCT1(&ct->tuplehash[!dir].tuple.src.u3.ip);
1202                 map.to = NOCT1(&ct->tuplehash[dir].tuple.dst.u3.ip);
1203         }
1204 
1205         if (map.from == map.to)
1206                 return NF_ACCEPT;
1207 
1208         if (!snmp_parse_mangle((unsigned char *)udph + sizeof(struct udphdr),
1209                                paylen, &map, &udph->check)) {
1210                 net_warn_ratelimited("bsalg: parser failed\n");
1211                 return NF_DROP;
1212         }
1213         return NF_ACCEPT;
1214 }
1215 
1216 /* We don't actually set up expectations, just adjust internal IP
1217  * addresses if this is being NATted */
1218 static int help(struct sk_buff *skb, unsigned int protoff,
1219                 struct nf_conn *ct,
1220                 enum ip_conntrack_info ctinfo)
1221 {
1222         int dir = CTINFO2DIR(ctinfo);
1223         unsigned int ret;
1224         const struct iphdr *iph = ip_hdr(skb);
1225         const struct udphdr *udph = (struct udphdr *)((__be32 *)iph + iph->ihl);
1226 
1227         /* SNMP replies and originating SNMP traps get mangled */
1228         if (udph->source == htons(SNMP_PORT) && dir != IP_CT_DIR_REPLY)
1229                 return NF_ACCEPT;
1230         if (udph->dest == htons(SNMP_TRAP_PORT) && dir != IP_CT_DIR_ORIGINAL)
1231                 return NF_ACCEPT;
1232 
1233         /* No NAT? */
1234         if (!(ct->status & IPS_NAT_MASK))
1235                 return NF_ACCEPT;
1236 
1237         /*
1238          * Make sure the packet length is ok.  So far, we were only guaranteed
1239          * to have a valid length IP header plus 8 bytes, which means we have
1240          * enough room for a UDP header.  Just verify the UDP length field so we
1241          * can mess around with the payload.
1242          */
1243         if (ntohs(udph->len) != skb->len - (iph->ihl << 2)) {
1244                 net_warn_ratelimited("SNMP: dropping malformed packet src=%pI4 dst=%pI4\n",
1245                                      &iph->saddr, &iph->daddr);
1246                  return NF_DROP;
1247         }
1248 
1249         if (!skb_make_writable(skb, skb->len))
1250                 return NF_DROP;
1251 
1252         spin_lock_bh(&snmp_lock);
1253         ret = snmp_translate(ct, ctinfo, skb);
1254         spin_unlock_bh(&snmp_lock);
1255         return ret;
1256 }
1257 
1258 static const struct nf_conntrack_expect_policy snmp_exp_policy = {
1259         .max_expected   = 0,
1260         .timeout        = 180,
1261 };
1262 
1263 static struct nf_conntrack_helper snmp_helper __read_mostly = {
1264         .me                     = THIS_MODULE,
1265         .help                   = help,
1266         .expect_policy          = &snmp_exp_policy,
1267         .name                   = "snmp",
1268         .tuple.src.l3num        = AF_INET,
1269         .tuple.src.u.udp.port   = cpu_to_be16(SNMP_PORT),
1270         .tuple.dst.protonum     = IPPROTO_UDP,
1271 };
1272 
1273 static struct nf_conntrack_helper snmp_trap_helper __read_mostly = {
1274         .me                     = THIS_MODULE,
1275         .help                   = help,
1276         .expect_policy          = &snmp_exp_policy,
1277         .name                   = "snmp_trap",
1278         .tuple.src.l3num        = AF_INET,
1279         .tuple.src.u.udp.port   = cpu_to_be16(SNMP_TRAP_PORT),
1280         .tuple.dst.protonum     = IPPROTO_UDP,
1281 };
1282 
1283 /*****************************************************************************
1284  *
1285  * Module stuff.
1286  *
1287  *****************************************************************************/
1288 
1289 static int __init nf_nat_snmp_basic_init(void)
1290 {
1291         int ret = 0;
1292 
1293         BUG_ON(nf_nat_snmp_hook != NULL);
1294         RCU_INIT_POINTER(nf_nat_snmp_hook, help);
1295 
1296         ret = nf_conntrack_helper_register(&snmp_trap_helper);
1297         if (ret < 0) {
1298                 nf_conntrack_helper_unregister(&snmp_helper);
1299                 return ret;
1300         }
1301         return ret;
1302 }
1303 
1304 static void __exit nf_nat_snmp_basic_fini(void)
1305 {
1306         RCU_INIT_POINTER(nf_nat_snmp_hook, NULL);
1307         nf_conntrack_helper_unregister(&snmp_trap_helper);
1308 }
1309 
1310 module_init(nf_nat_snmp_basic_init);
1311 module_exit(nf_nat_snmp_basic_fini);
1312 
1313 module_param(debug, int, 0600);
1314 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp