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