X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fipv4%2Fnetfilter%2Fip_nat_snmp_basic.c;fp=net%2Fipv4%2Fnetfilter%2Fip_nat_snmp_basic.c;h=c3d9f3b090c44851a279eb8ee7aa5a5c9b22464a;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=df57e7a117dbb4c46605e44dc349ca818e58171e;hpb=76828883507a47dae78837ab5dec5a5b4513c667;p=linux-2.6.git diff --git a/net/ipv4/netfilter/ip_nat_snmp_basic.c b/net/ipv4/netfilter/ip_nat_snmp_basic.c index df57e7a11..c3d9f3b09 100644 --- a/net/ipv4/netfilter/ip_nat_snmp_basic.c +++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c @@ -43,7 +43,6 @@ * 2000-08-06: Convert to new helper API (Harald Welte). * */ -#include #include #include #include @@ -65,7 +64,7 @@ MODULE_DESCRIPTION("Basic SNMP Application Layer Gateway"); #define SNMP_PORT 161 #define SNMP_TRAP_PORT 162 -#define NOCT1(n) (u_int8_t )((n) & 0xff) +#define NOCT1(n) (*(u8 *)n) static int debug; static DEFINE_SPINLOCK(snmp_lock); @@ -250,6 +249,7 @@ static unsigned char asn1_header_decode(struct asn1_ctx *ctx, if (!asn1_id_decode(ctx, cls, con, tag)) return 0; + def = len = 0; if (!asn1_length_decode(ctx, &def, &len)) return 0; @@ -613,7 +613,7 @@ struct snmp_v1_trap static inline void mangle_address(unsigned char *begin, unsigned char *addr, const struct oct1_map *map, - u_int16_t *check); + __sum16 *check); struct snmp_cnv { unsigned int class; @@ -669,7 +669,7 @@ static unsigned char snmp_object_decode(struct asn1_ctx *ctx, unsigned char *eoc, *end, *p; unsigned long *lp, *id; unsigned long ul; - long l; + long l; *obj = NULL; id = NULL; @@ -699,11 +699,13 @@ static unsigned char snmp_object_decode(struct asn1_ctx *ctx, return 0; } + type = 0; if (!snmp_tag_cls2syntax(tag, cls, &type)) { kfree(id); return 0; } + l = 0; switch (type) { case SNMP_INTEGER: len = sizeof(long); @@ -765,6 +767,7 @@ static unsigned char snmp_object_decode(struct asn1_ctx *ctx, len *= sizeof(unsigned long); *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC); if (*obj == NULL) { + kfree(lp); kfree(id); if (net_ratelimit()) printk("OOM in bsalg (%d)\n", __LINE__); @@ -870,38 +873,24 @@ static unsigned char snmp_request_decode(struct asn1_ctx *ctx, * Fast checksum update for possibly oddly-aligned UDP byte, from the * code example in the draft. */ -static void fast_csum(unsigned char *csum, +static void fast_csum(__sum16 *csum, const unsigned char *optr, const unsigned char *nptr, - int odd) + int offset) { - long x, old, new; - - x = csum[0] * 256 + csum[1]; - - x =~ x & 0xFFFF; - - if (odd) old = optr[0] * 256; - else old = optr[0]; - - x -= old & 0xFFFF; - if (x <= 0) { - x--; - x &= 0xFFFF; - } - - if (odd) new = nptr[0] * 256; - else new = nptr[0]; - - x += new & 0xFFFF; - if (x & 0x10000) { - x++; - x &= 0xFFFF; + unsigned char s[4]; + + if (offset & 1) { + s[0] = s[2] = 0; + s[1] = ~*optr; + s[3] = *nptr; + } else { + s[1] = s[3] = 0; + s[0] = ~*optr; + s[2] = *nptr; } - - x =~ x & 0xFFFF; - csum[0] = x / 256; - csum[1] = x & 0xFF; + + *csum = csum_fold(csum_partial(s, 4, ~csum_unfold(*csum))); } /* @@ -912,9 +901,9 @@ static void fast_csum(unsigned char *csum, static inline void mangle_address(unsigned char *begin, unsigned char *addr, const struct oct1_map *map, - u_int16_t *check) + __sum16 *check) { - if (map->from == NOCT1(*addr)) { + if (map->from == NOCT1(addr)) { u_int32_t old; if (debug) @@ -924,11 +913,8 @@ static inline void mangle_address(unsigned char *begin, /* Update UDP checksum if being used */ if (*check) { - unsigned char odd = !((addr - begin) % 2); - - fast_csum((unsigned char *)check, - &map->from, &map->to, odd); - + fast_csum(check, + &map->from, &map->to, addr - begin); } if (debug) @@ -940,7 +926,7 @@ static inline void mangle_address(unsigned char *begin, static unsigned char snmp_trap_decode(struct asn1_ctx *ctx, struct snmp_v1_trap *trap, const struct oct1_map *map, - u_int16_t *check) + __sum16 *check) { unsigned int cls, con, tag, len; unsigned char *end; @@ -1034,7 +1020,7 @@ static void hex_dump(unsigned char *buf, size_t len) static int snmp_parse_mangle(unsigned char *msg, u_int16_t len, const struct oct1_map *map, - u_int16_t *check) + __sum16 *check) { unsigned char *eoc, *end; unsigned int cls, con, tag, vers, pdutype; @@ -1208,7 +1194,7 @@ static int snmp_translate(struct ip_conntrack *ct, struct sk_buff **pskb) { struct iphdr *iph = (*pskb)->nh.iph; - struct udphdr *udph = (struct udphdr *)((u_int32_t *)iph + iph->ihl); + struct udphdr *udph = (struct udphdr *)((__be32 *)iph + iph->ihl); u_int16_t udplen = ntohs(udph->len); u_int16_t paylen = udplen - sizeof(struct udphdr); int dir = CTINFO2DIR(ctinfo); @@ -1220,12 +1206,12 @@ static int snmp_translate(struct ip_conntrack *ct, */ if (dir == IP_CT_DIR_ORIGINAL) { /* SNAT traps */ - map.from = NOCT1(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip); - map.to = NOCT1(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip); + map.from = NOCT1(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip); + map.to = NOCT1(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip); } else { /* DNAT replies */ - map.from = NOCT1(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip); - map.to = NOCT1(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip); + map.from = NOCT1(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip); + map.to = NOCT1(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip); } if (map.from == map.to) @@ -1252,9 +1238,9 @@ static int help(struct sk_buff **pskb, struct udphdr *udph = (struct udphdr *)((u_int32_t *)iph + iph->ihl); /* SNMP replies and originating SNMP traps get mangled */ - if (udph->source == ntohs(SNMP_PORT) && dir != IP_CT_DIR_REPLY) + if (udph->source == htons(SNMP_PORT) && dir != IP_CT_DIR_REPLY) return NF_ACCEPT; - if (udph->dest == ntohs(SNMP_TRAP_PORT) && dir != IP_CT_DIR_ORIGINAL) + if (udph->dest == htons(SNMP_TRAP_PORT) && dir != IP_CT_DIR_ORIGINAL) return NF_ACCEPT; /* No NAT? */ @@ -1291,11 +1277,11 @@ static struct ip_conntrack_helper snmp_helper = { .help = help, .name = "snmp", - .tuple = { .src = { .u = { __constant_htons(SNMP_PORT) } }, - .dst = { .protonum = IPPROTO_UDP }, + .tuple = {.src = {.u = {.udp = {.port = __constant_htons(SNMP_PORT)}}}, + .dst = {.protonum = IPPROTO_UDP}, }, - .mask = { .src = { .u = { 0xFFFF } }, - .dst = { .protonum = 0xFF }, + .mask = {.src = {.u = {0xFFFF}}, + .dst = {.protonum = 0xFF}, }, }; @@ -1306,11 +1292,11 @@ static struct ip_conntrack_helper snmp_trap_helper = { .help = help, .name = "snmp_trap", - .tuple = { .src = { .u = { __constant_htons(SNMP_TRAP_PORT) } }, - .dst = { .protonum = IPPROTO_UDP }, + .tuple = {.src = {.u = {.udp = {.port = __constant_htons(SNMP_TRAP_PORT)}}}, + .dst = {.protonum = IPPROTO_UDP}, }, - .mask = { .src = { .u = { 0xFFFF } }, - .dst = { .protonum = 0xFF }, + .mask = {.src = {.u = {0xFFFF}}, + .dst = {.protonum = 0xFF}, }, }; @@ -1320,7 +1306,7 @@ static struct ip_conntrack_helper snmp_trap_helper = { * *****************************************************************************/ -static int __init init(void) +static int __init ip_nat_snmp_basic_init(void) { int ret = 0; @@ -1335,13 +1321,13 @@ static int __init init(void) return ret; } -static void __exit fini(void) +static void __exit ip_nat_snmp_basic_fini(void) { ip_conntrack_helper_unregister(&snmp_helper); ip_conntrack_helper_unregister(&snmp_trap_helper); } -module_init(init); -module_exit(fini); +module_init(ip_nat_snmp_basic_init); +module_exit(ip_nat_snmp_basic_fini); -module_param(debug, bool, 0600); +module_param(debug, int, 0600);