⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ip_nat_snmp_basic.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * ip_nat_snmp_basic.c * * Basic SNMP Application Layer Gateway * * This IP NAT module is intended for use with SNMP network  * discovery and monitoring applications where target networks use  * conflicting private address realms. * * Static NAT is used to remap the networks from the view of the network  * management system at the IP layer, and this module remaps some application * layer addresses to match. * * The simplest form of ALG is performed, where only tagged IP addresses * are modified.  The module does not need to be MIB aware and only scans * messages at the ASN.1/BER level. * * Currently, only SNMPv1 and SNMPv2 are supported. * * More information on ALG and associated issues can be found in * RFC 2962 * * The ASB.1/BER parsing code is derived from the gxsnmp package by Gregory  * McLean & Jochen Friedrich, stripped down for use in the kernel. * * Copyright (c) 2000 RP Internet (www.rpi.net.au). * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA * * Author: James Morris <jmorris@intercode.com.au> * * Updates: * 2000-08-06: Convert to new helper API (Harald Welte). * */#include <linux/config.h>#include <linux/module.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/moduleparam.h>#include <linux/netfilter_ipv4.h>#include <linux/netfilter_ipv4/ip_nat.h>#include <linux/netfilter_ipv4/ip_conntrack_helper.h>#include <linux/netfilter_ipv4/ip_nat_helper.h>#include <linux/ip.h>#include <net/checksum.h>#include <net/udp.h>#include <asm/uaccess.h>MODULE_LICENSE("GPL");MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");MODULE_DESCRIPTION("Basic SNMP Application Layer Gateway");#define SNMP_PORT 161#define SNMP_TRAP_PORT 162#define NOCT1(n) (u_int8_t )((n) & 0xff)static int debug;static DEFINE_SPINLOCK(snmp_lock);/*  * Application layer address mapping mimics the NAT mapping, but  * only for the first octet in this case (a more flexible system * can be implemented if needed). */struct oct1_map{	u_int8_t from;	u_int8_t to;};                                  /***************************************************************************** * * Basic ASN.1 decoding routines (gxsnmp author Dirk Wisse) * *****************************************************************************//* Class */#define ASN1_UNI	0	/* Universal */#define ASN1_APL	1	/* Application */#define ASN1_CTX	2	/* Context */#define ASN1_PRV	3	/* Private *//* Tag */#define ASN1_EOC	0	/* End Of Contents */#define ASN1_BOL	1	/* Boolean */#define ASN1_INT	2	/* Integer */#define ASN1_BTS	3	/* Bit String */#define ASN1_OTS	4	/* Octet String */#define ASN1_NUL	5	/* Null */#define ASN1_OJI	6	/* Object Identifier  */#define ASN1_OJD	7	/* Object Description */#define ASN1_EXT	8	/* External */#define ASN1_SEQ	16	/* Sequence */#define ASN1_SET	17	/* Set */#define ASN1_NUMSTR	18	/* Numerical String */#define ASN1_PRNSTR	19	/* Printable String */#define ASN1_TEXSTR	20	/* Teletext String */#define ASN1_VIDSTR	21	/* Video String */#define ASN1_IA5STR	22	/* IA5 String */#define ASN1_UNITIM	23	/* Universal Time */#define ASN1_GENTIM	24	/* General Time */#define ASN1_GRASTR	25	/* Graphical String */#define ASN1_VISSTR	26	/* Visible String */#define ASN1_GENSTR	27	/* General String *//* Primitive / Constructed methods*/#define ASN1_PRI	0	/* Primitive */#define ASN1_CON	1	/* Constructed *//* * Error codes. */#define ASN1_ERR_NOERROR		0#define ASN1_ERR_DEC_EMPTY		2#define ASN1_ERR_DEC_EOC_MISMATCH	3#define ASN1_ERR_DEC_LENGTH_MISMATCH	4#define ASN1_ERR_DEC_BADVALUE		5/*  * ASN.1 context. */struct asn1_ctx{	int error;			/* Error condition */	unsigned char *pointer;		/* Octet just to be decoded */	unsigned char *begin;		/* First octet */	unsigned char *end;		/* Octet after last octet */};/* * Octet string (not null terminated) */struct asn1_octstr{	unsigned char *data;	unsigned int len;};	static void asn1_open(struct asn1_ctx *ctx,                      unsigned char *buf,                      unsigned int len){	ctx->begin = buf;	ctx->end = buf + len;	ctx->pointer = buf;	ctx->error = ASN1_ERR_NOERROR;}static unsigned char asn1_octet_decode(struct asn1_ctx *ctx, unsigned char *ch){	if (ctx->pointer >= ctx->end) {		ctx->error = ASN1_ERR_DEC_EMPTY;		return 0;	}	*ch = *(ctx->pointer)++;	return 1;}static unsigned char asn1_tag_decode(struct asn1_ctx *ctx, unsigned int *tag){	unsigned char ch;		*tag = 0;		do	{		if (!asn1_octet_decode(ctx, &ch))			return 0;		*tag <<= 7;		*tag |= ch & 0x7F;	} while ((ch & 0x80) == 0x80);	return 1;}static unsigned char asn1_id_decode(struct asn1_ctx *ctx,                                     unsigned int *cls,                                    unsigned int *con,                                    unsigned int *tag){	unsigned char ch;		if (!asn1_octet_decode(ctx, &ch))		return 0;			*cls = (ch & 0xC0) >> 6;	*con = (ch & 0x20) >> 5;	*tag = (ch & 0x1F);		if (*tag == 0x1F) {		if (!asn1_tag_decode(ctx, tag))			return 0;	}	return 1;}static unsigned char asn1_length_decode(struct asn1_ctx *ctx,                                        unsigned int *def,                                        unsigned int *len){	unsigned char ch, cnt;		if (!asn1_octet_decode(ctx, &ch))		return 0;			if (ch == 0x80)		*def = 0;	else {		*def = 1;				if (ch < 0x80)			*len = ch;		else {			cnt = (unsigned char) (ch & 0x7F);			*len = 0;						while (cnt > 0) {				if (!asn1_octet_decode(ctx, &ch))					return 0;				*len <<= 8;				*len |= ch;				cnt--;			}		}	}	return 1;}static unsigned char asn1_header_decode(struct asn1_ctx *ctx,                                        unsigned char **eoc,                                        unsigned int *cls,                                        unsigned int *con,                                        unsigned int *tag){	unsigned int def, len;		if (!asn1_id_decode(ctx, cls, con, tag))		return 0;			if (!asn1_length_decode(ctx, &def, &len))		return 0;			if (def)		*eoc = ctx->pointer + len;	else		*eoc = NULL;	return 1;}static unsigned char asn1_eoc_decode(struct asn1_ctx *ctx, unsigned char *eoc){	unsigned char ch;		if (eoc == 0) {		if (!asn1_octet_decode(ctx, &ch))			return 0;					if (ch != 0x00) {			ctx->error = ASN1_ERR_DEC_EOC_MISMATCH;			return 0;		}				if (!asn1_octet_decode(ctx, &ch))			return 0;					if (ch != 0x00) {			ctx->error = ASN1_ERR_DEC_EOC_MISMATCH;			return 0;		}		return 1;	} else {		if (ctx->pointer != eoc) {			ctx->error = ASN1_ERR_DEC_LENGTH_MISMATCH;			return 0;		}		return 1;	}}static unsigned char asn1_null_decode(struct asn1_ctx *ctx, unsigned char *eoc){	ctx->pointer = eoc;	return 1;}static unsigned char asn1_long_decode(struct asn1_ctx *ctx,                                      unsigned char *eoc,                                      long *integer){	unsigned char ch;	unsigned int  len;		if (!asn1_octet_decode(ctx, &ch))		return 0;			*integer = (signed char) ch;	len = 1;		while (ctx->pointer < eoc) {		if (++len > sizeof (long)) {			ctx->error = ASN1_ERR_DEC_BADVALUE;			return 0;		}				if (!asn1_octet_decode(ctx, &ch))			return 0;					*integer <<= 8;		*integer |= ch;	}	return 1;}static unsigned char asn1_uint_decode(struct asn1_ctx *ctx,                                      unsigned char *eoc,                                      unsigned int *integer){	unsigned char ch;	unsigned int  len;		if (!asn1_octet_decode(ctx, &ch))		return 0;			*integer = ch;	if (ch == 0) len = 0;	else len = 1;		while (ctx->pointer < eoc) {		if (++len > sizeof (unsigned int)) {			ctx->error = ASN1_ERR_DEC_BADVALUE;			return 0;		}				if (!asn1_octet_decode(ctx, &ch))			return 0;					*integer <<= 8;		*integer |= ch;	}	return 1;}static unsigned char asn1_ulong_decode(struct asn1_ctx *ctx,                                       unsigned char *eoc,                                       unsigned long *integer){	unsigned char ch;	unsigned int  len;		if (!asn1_octet_decode(ctx, &ch))		return 0;			*integer = ch;	if (ch == 0) len = 0;	else len = 1;		while (ctx->pointer < eoc) {		if (++len > sizeof (unsigned long)) {			ctx->error = ASN1_ERR_DEC_BADVALUE;			return 0;		}				if (!asn1_octet_decode(ctx, &ch))			return 0;					*integer <<= 8;		*integer |= ch;	}	return 1;}static unsigned char asn1_octets_decode(struct asn1_ctx *ctx,                                        unsigned char *eoc,                                        unsigned char **octets,                                        unsigned int *len){	unsigned char *ptr;		*len = 0;		*octets = kmalloc(eoc - ctx->pointer, GFP_ATOMIC);	if (*octets == NULL) {		if (net_ratelimit())			printk("OOM in bsalg (%d)\n", __LINE__);		return 0;	}		ptr = *octets;	while (ctx->pointer < eoc) {		if (!asn1_octet_decode(ctx, (unsigned char *)ptr++)) {			kfree(*octets);			*octets = NULL;			return 0;		}		(*len)++;	}	return 1;}static unsigned char asn1_subid_decode(struct asn1_ctx *ctx,                                       unsigned long *subid){	unsigned char ch;		*subid = 0;		do {		if (!asn1_octet_decode(ctx, &ch))			return 0;				*subid <<= 7;		*subid |= ch & 0x7F;	} while ((ch & 0x80) == 0x80);	return 1;}static unsigned char asn1_oid_decode(struct asn1_ctx *ctx,                                     unsigned char *eoc,                                     unsigned long **oid,                                     unsigned int *len){	unsigned long subid;	unsigned int  size;	unsigned long *optr;		size = eoc - ctx->pointer + 1;	*oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC);	if (*oid == NULL) {		if (net_ratelimit())			printk("OOM in bsalg (%d)\n", __LINE__);		return 0;	}		optr = *oid;		if (!asn1_subid_decode(ctx, &subid)) {		kfree(*oid);		*oid = NULL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -