aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_icmp.c43
1 files changed, 24 insertions, 19 deletions
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
index 19cc55055584..30fc21d6165a 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
@@ -47,20 +47,21 @@ static int icmp_pkt_to_tuple(const struct sk_buff *skb,
47 return 1; 47 return 1;
48} 48}
49 49
50/* Add 1; spaces filled with 0. */
51static const u_int8_t invmap[] = {
52 [ICMP_ECHO] = ICMP_ECHOREPLY + 1,
53 [ICMP_ECHOREPLY] = ICMP_ECHO + 1,
54 [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1,
55 [ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1,
56 [ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1,
57 [ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1,
58 [ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1,
59 [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1
60};
61
50static int icmp_invert_tuple(struct ip_conntrack_tuple *tuple, 62static int icmp_invert_tuple(struct ip_conntrack_tuple *tuple,
51 const struct ip_conntrack_tuple *orig) 63 const struct ip_conntrack_tuple *orig)
52{ 64{
53 /* Add 1; spaces filled with 0. */
54 static const u_int8_t invmap[]
55 = { [ICMP_ECHO] = ICMP_ECHOREPLY + 1,
56 [ICMP_ECHOREPLY] = ICMP_ECHO + 1,
57 [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1,
58 [ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1,
59 [ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1,
60 [ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1,
61 [ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1,
62 [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1};
63
64 if (orig->dst.u.icmp.type >= sizeof(invmap) 65 if (orig->dst.u.icmp.type >= sizeof(invmap)
65 || !invmap[orig->dst.u.icmp.type]) 66 || !invmap[orig->dst.u.icmp.type])
66 return 0; 67 return 0;
@@ -110,17 +111,17 @@ static int icmp_packet(struct ip_conntrack *ct,
110 return NF_ACCEPT; 111 return NF_ACCEPT;
111} 112}
112 113
113static const u_int8_t valid_new[] = {
114 [ICMP_ECHO] = 1,
115 [ICMP_TIMESTAMP] = 1,
116 [ICMP_INFO_REQUEST] = 1,
117 [ICMP_ADDRESS] = 1
118};
119
120/* Called when a new connection for this protocol found. */ 114/* Called when a new connection for this protocol found. */
121static int icmp_new(struct ip_conntrack *conntrack, 115static int icmp_new(struct ip_conntrack *conntrack,
122 const struct sk_buff *skb) 116 const struct sk_buff *skb)
123{ 117{
118 static const u_int8_t valid_new[] = {
119 [ICMP_ECHO] = 1,
120 [ICMP_TIMESTAMP] = 1,
121 [ICMP_INFO_REQUEST] = 1,
122 [ICMP_ADDRESS] = 1
123 };
124
124 if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new) 125 if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new)
125 || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) { 126 || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) {
126 /* Can't create a new ICMP `conn' with this. */ 127 /* Can't create a new ICMP `conn' with this. */
@@ -291,7 +292,7 @@ static int icmp_nfattr_to_tuple(struct nfattr *tb[],
291 if (!tb[CTA_PROTO_ICMP_TYPE-1] 292 if (!tb[CTA_PROTO_ICMP_TYPE-1]
292 || !tb[CTA_PROTO_ICMP_CODE-1] 293 || !tb[CTA_PROTO_ICMP_CODE-1]
293 || !tb[CTA_PROTO_ICMP_ID-1]) 294 || !tb[CTA_PROTO_ICMP_ID-1])
294 return -1; 295 return -EINVAL;
295 296
296 tuple->dst.u.icmp.type = 297 tuple->dst.u.icmp.type =
297 *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_TYPE-1]); 298 *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_TYPE-1]);
@@ -300,6 +301,10 @@ static int icmp_nfattr_to_tuple(struct nfattr *tb[],
300 tuple->src.u.icmp.id = 301 tuple->src.u.icmp.id =
301 *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]); 302 *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]);
302 303
304 if (tuple->dst.u.icmp.type >= sizeof(invmap)
305 || !invmap[tuple->dst.u.icmp.type])
306 return -EINVAL;
307
303 return 0; 308 return 0;
304} 309}
305#endif 310#endif