diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2006-11-20 21:06:59 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-12-03 00:27:17 -0500 |
commit | 5b14027bf2132c0631ea9f3be11ced89a5057220 (patch) | |
tree | a4d28e0ca2342b8f3c85f702f483a88496c85a3a | |
parent | 8e5200f54062b8af0ed1d186ea0f113854786d89 (diff) |
[NETFILTER]: ip_nat_snmp_basic annotations.
... and switch the damn checksum update to something saner
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ipv4/netfilter/ip_nat_snmp_basic.c | 85 |
1 files changed, 34 insertions, 51 deletions
diff --git a/net/ipv4/netfilter/ip_nat_snmp_basic.c b/net/ipv4/netfilter/ip_nat_snmp_basic.c index 168f45fa1898..c3d9f3b090c4 100644 --- a/net/ipv4/netfilter/ip_nat_snmp_basic.c +++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c | |||
@@ -64,7 +64,7 @@ MODULE_DESCRIPTION("Basic SNMP Application Layer Gateway"); | |||
64 | 64 | ||
65 | #define SNMP_PORT 161 | 65 | #define SNMP_PORT 161 |
66 | #define SNMP_TRAP_PORT 162 | 66 | #define SNMP_TRAP_PORT 162 |
67 | #define NOCT1(n) (u_int8_t )((n) & 0xff) | 67 | #define NOCT1(n) (*(u8 *)n) |
68 | 68 | ||
69 | static int debug; | 69 | static int debug; |
70 | static DEFINE_SPINLOCK(snmp_lock); | 70 | static DEFINE_SPINLOCK(snmp_lock); |
@@ -613,7 +613,7 @@ struct snmp_v1_trap | |||
613 | static inline void mangle_address(unsigned char *begin, | 613 | static inline void mangle_address(unsigned char *begin, |
614 | unsigned char *addr, | 614 | unsigned char *addr, |
615 | const struct oct1_map *map, | 615 | const struct oct1_map *map, |
616 | u_int16_t *check); | 616 | __sum16 *check); |
617 | struct snmp_cnv | 617 | struct snmp_cnv |
618 | { | 618 | { |
619 | unsigned int class; | 619 | unsigned int class; |
@@ -873,38 +873,24 @@ static unsigned char snmp_request_decode(struct asn1_ctx *ctx, | |||
873 | * Fast checksum update for possibly oddly-aligned UDP byte, from the | 873 | * Fast checksum update for possibly oddly-aligned UDP byte, from the |
874 | * code example in the draft. | 874 | * code example in the draft. |
875 | */ | 875 | */ |
876 | static void fast_csum(unsigned char *csum, | 876 | static void fast_csum(__sum16 *csum, |
877 | const unsigned char *optr, | 877 | const unsigned char *optr, |
878 | const unsigned char *nptr, | 878 | const unsigned char *nptr, |
879 | int odd) | 879 | int offset) |
880 | { | 880 | { |
881 | long x, old, new; | 881 | unsigned char s[4]; |
882 | 882 | ||
883 | x = csum[0] * 256 + csum[1]; | 883 | if (offset & 1) { |
884 | 884 | s[0] = s[2] = 0; | |
885 | x =~ x & 0xFFFF; | 885 | s[1] = ~*optr; |
886 | 886 | s[3] = *nptr; | |
887 | if (odd) old = optr[0] * 256; | 887 | } else { |
888 | else old = optr[0]; | 888 | s[1] = s[3] = 0; |
889 | 889 | s[0] = ~*optr; | |
890 | x -= old & 0xFFFF; | 890 | s[2] = *nptr; |
891 | if (x <= 0) { | ||
892 | x--; | ||
893 | x &= 0xFFFF; | ||
894 | } | ||
895 | |||
896 | if (odd) new = nptr[0] * 256; | ||
897 | else new = nptr[0]; | ||
898 | |||
899 | x += new & 0xFFFF; | ||
900 | if (x & 0x10000) { | ||
901 | x++; | ||
902 | x &= 0xFFFF; | ||
903 | } | 891 | } |
904 | 892 | ||
905 | x =~ x & 0xFFFF; | 893 | *csum = csum_fold(csum_partial(s, 4, ~csum_unfold(*csum))); |
906 | csum[0] = x / 256; | ||
907 | csum[1] = x & 0xFF; | ||
908 | } | 894 | } |
909 | 895 | ||
910 | /* | 896 | /* |
@@ -915,9 +901,9 @@ static void fast_csum(unsigned char *csum, | |||
915 | static inline void mangle_address(unsigned char *begin, | 901 | static inline void mangle_address(unsigned char *begin, |
916 | unsigned char *addr, | 902 | unsigned char *addr, |
917 | const struct oct1_map *map, | 903 | const struct oct1_map *map, |
918 | u_int16_t *check) | 904 | __sum16 *check) |
919 | { | 905 | { |
920 | if (map->from == NOCT1(*addr)) { | 906 | if (map->from == NOCT1(addr)) { |
921 | u_int32_t old; | 907 | u_int32_t old; |
922 | 908 | ||
923 | if (debug) | 909 | if (debug) |
@@ -927,11 +913,8 @@ static inline void mangle_address(unsigned char *begin, | |||
927 | 913 | ||
928 | /* Update UDP checksum if being used */ | 914 | /* Update UDP checksum if being used */ |
929 | if (*check) { | 915 | if (*check) { |
930 | unsigned char odd = !((addr - begin) % 2); | 916 | fast_csum(check, |
931 | 917 | &map->from, &map->to, addr - begin); | |
932 | fast_csum((unsigned char *)check, | ||
933 | &map->from, &map->to, odd); | ||
934 | |||
935 | } | 918 | } |
936 | 919 | ||
937 | if (debug) | 920 | if (debug) |
@@ -943,7 +926,7 @@ static inline void mangle_address(unsigned char *begin, | |||
943 | static unsigned char snmp_trap_decode(struct asn1_ctx *ctx, | 926 | static unsigned char snmp_trap_decode(struct asn1_ctx *ctx, |
944 | struct snmp_v1_trap *trap, | 927 | struct snmp_v1_trap *trap, |
945 | const struct oct1_map *map, | 928 | const struct oct1_map *map, |
946 | u_int16_t *check) | 929 | __sum16 *check) |
947 | { | 930 | { |
948 | unsigned int cls, con, tag, len; | 931 | unsigned int cls, con, tag, len; |
949 | unsigned char *end; | 932 | unsigned char *end; |
@@ -1037,7 +1020,7 @@ static void hex_dump(unsigned char *buf, size_t len) | |||
1037 | static int snmp_parse_mangle(unsigned char *msg, | 1020 | static int snmp_parse_mangle(unsigned char *msg, |
1038 | u_int16_t len, | 1021 | u_int16_t len, |
1039 | const struct oct1_map *map, | 1022 | const struct oct1_map *map, |
1040 | u_int16_t *check) | 1023 | __sum16 *check) |
1041 | { | 1024 | { |
1042 | unsigned char *eoc, *end; | 1025 | unsigned char *eoc, *end; |
1043 | unsigned int cls, con, tag, vers, pdutype; | 1026 | unsigned int cls, con, tag, vers, pdutype; |
@@ -1223,12 +1206,12 @@ static int snmp_translate(struct ip_conntrack *ct, | |||
1223 | */ | 1206 | */ |
1224 | if (dir == IP_CT_DIR_ORIGINAL) { | 1207 | if (dir == IP_CT_DIR_ORIGINAL) { |
1225 | /* SNAT traps */ | 1208 | /* SNAT traps */ |
1226 | map.from = NOCT1(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip); | 1209 | map.from = NOCT1(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip); |
1227 | map.to = NOCT1(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip); | 1210 | map.to = NOCT1(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip); |
1228 | } else { | 1211 | } else { |
1229 | /* DNAT replies */ | 1212 | /* DNAT replies */ |
1230 | map.from = NOCT1(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip); | 1213 | map.from = NOCT1(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip); |
1231 | map.to = NOCT1(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip); | 1214 | map.to = NOCT1(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip); |
1232 | } | 1215 | } |
1233 | 1216 | ||
1234 | if (map.from == map.to) | 1217 | if (map.from == map.to) |
@@ -1294,11 +1277,11 @@ static struct ip_conntrack_helper snmp_helper = { | |||
1294 | .help = help, | 1277 | .help = help, |
1295 | .name = "snmp", | 1278 | .name = "snmp", |
1296 | 1279 | ||
1297 | .tuple = { .src = { .u = { __constant_htons(SNMP_PORT) } }, | 1280 | .tuple = {.src = {.u = {.udp = {.port = __constant_htons(SNMP_PORT)}}}, |
1298 | .dst = { .protonum = IPPROTO_UDP }, | 1281 | .dst = {.protonum = IPPROTO_UDP}, |
1299 | }, | 1282 | }, |
1300 | .mask = { .src = { .u = { 0xFFFF } }, | 1283 | .mask = {.src = {.u = {0xFFFF}}, |
1301 | .dst = { .protonum = 0xFF }, | 1284 | .dst = {.protonum = 0xFF}, |
1302 | }, | 1285 | }, |
1303 | }; | 1286 | }; |
1304 | 1287 | ||
@@ -1309,11 +1292,11 @@ static struct ip_conntrack_helper snmp_trap_helper = { | |||
1309 | .help = help, | 1292 | .help = help, |
1310 | .name = "snmp_trap", | 1293 | .name = "snmp_trap", |
1311 | 1294 | ||
1312 | .tuple = { .src = { .u = { __constant_htons(SNMP_TRAP_PORT) } }, | 1295 | .tuple = {.src = {.u = {.udp = {.port = __constant_htons(SNMP_TRAP_PORT)}}}, |
1313 | .dst = { .protonum = IPPROTO_UDP }, | 1296 | .dst = {.protonum = IPPROTO_UDP}, |
1314 | }, | 1297 | }, |
1315 | .mask = { .src = { .u = { 0xFFFF } }, | 1298 | .mask = {.src = {.u = {0xFFFF}}, |
1316 | .dst = { .protonum = 0xFF }, | 1299 | .dst = {.protonum = 0xFF}, |
1317 | }, | 1300 | }, |
1318 | }; | 1301 | }; |
1319 | 1302 | ||