@@ -50,20 +50,21 @@ static int icmp_pkt_to_tuple(const struct sk_buff *skb,
50
50
return 1 ;
51
51
}
52
52
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
+
53
65
static int icmp_invert_tuple (struct nf_conntrack_tuple * tuple ,
54
66
const struct nf_conntrack_tuple * orig )
55
67
{
56
- /* Add 1; spaces filled with 0. */
57
- static u_int8_t invmap []
58
- = { [ICMP_ECHO ] = ICMP_ECHOREPLY + 1 ,
59
- [ICMP_ECHOREPLY ] = ICMP_ECHO + 1 ,
60
- [ICMP_TIMESTAMP ] = ICMP_TIMESTAMPREPLY + 1 ,
61
- [ICMP_TIMESTAMPREPLY ] = ICMP_TIMESTAMP + 1 ,
62
- [ICMP_INFO_REQUEST ] = ICMP_INFO_REPLY + 1 ,
63
- [ICMP_INFO_REPLY ] = ICMP_INFO_REQUEST + 1 ,
64
- [ICMP_ADDRESS ] = ICMP_ADDRESSREPLY + 1 ,
65
- [ICMP_ADDRESSREPLY ] = ICMP_ADDRESS + 1 };
66
-
67
68
if (orig -> dst .u .icmp .type >= sizeof (invmap )
68
69
|| !invmap [orig -> dst .u .icmp .type ])
69
70
return 0 ;
@@ -120,11 +121,12 @@ static int icmp_packet(struct nf_conn *ct,
120
121
static int icmp_new (struct nf_conn * conntrack ,
121
122
const struct sk_buff * skb , unsigned int dataoff )
122
123
{
123
- static u_int8_t valid_new []
124
- = { [ICMP_ECHO ] = 1 ,
125
- [ICMP_TIMESTAMP ] = 1 ,
126
- [ICMP_INFO_REQUEST ] = 1 ,
127
- [ICMP_ADDRESS ] = 1 };
124
+ static const u_int8_t valid_new [] = {
125
+ [ICMP_ECHO ] = 1 ,
126
+ [ICMP_TIMESTAMP ] = 1 ,
127
+ [ICMP_INFO_REQUEST ] = 1 ,
128
+ [ICMP_ADDRESS ] = 1
129
+ };
128
130
129
131
if (conntrack -> tuplehash [0 ].tuple .dst .u .icmp .type >= sizeof (valid_new )
130
132
|| !valid_new [conntrack -> tuplehash [0 ].tuple .dst .u .icmp .type ]) {
@@ -168,7 +170,7 @@ icmp_error_message(struct sk_buff *skb,
168
170
return - NF_ACCEPT ;
169
171
}
170
172
171
- innerproto = nf_ct_find_proto (PF_INET , inside -> ip .protocol );
173
+ innerproto = __nf_ct_proto_find (PF_INET , inside -> ip .protocol );
172
174
dataoff = skb -> nh .iph -> ihl * 4 + sizeof (inside -> icmp );
173
175
/* Are they talking about one of our connections? */
174
176
if (!nf_ct_get_tuple (skb , dataoff , dataoff + inside -> ip .ihl * 4 , PF_INET ,
@@ -281,6 +283,60 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff,
281
283
return icmp_error_message (skb , ctinfo , hooknum );
282
284
}
283
285
286
+ #if defined(CONFIG_NF_CT_NETLINK ) || \
287
+ defined(CONFIG_NF_CT_NETLINK_MODULE )
288
+
289
+ #include <linux/netfilter/nfnetlink.h>
290
+ #include <linux/netfilter/nfnetlink_conntrack.h>
291
+
292
+ static int icmp_tuple_to_nfattr (struct sk_buff * skb ,
293
+ const struct nf_conntrack_tuple * t )
294
+ {
295
+ NFA_PUT (skb , CTA_PROTO_ICMP_ID , sizeof (u_int16_t ),
296
+ & t -> src .u .icmp .id );
297
+ NFA_PUT (skb , CTA_PROTO_ICMP_TYPE , sizeof (u_int8_t ),
298
+ & t -> dst .u .icmp .type );
299
+ NFA_PUT (skb , CTA_PROTO_ICMP_CODE , sizeof (u_int8_t ),
300
+ & t -> dst .u .icmp .code );
301
+
302
+ return 0 ;
303
+
304
+ nfattr_failure :
305
+ return -1 ;
306
+ }
307
+
308
+ static const size_t cta_min_proto [CTA_PROTO_MAX ] = {
309
+ [CTA_PROTO_ICMP_TYPE - 1 ] = sizeof (u_int8_t ),
310
+ [CTA_PROTO_ICMP_CODE - 1 ] = sizeof (u_int8_t ),
311
+ [CTA_PROTO_ICMP_ID - 1 ] = sizeof (u_int16_t )
312
+ };
313
+
314
+ static int icmp_nfattr_to_tuple (struct nfattr * tb [],
315
+ struct nf_conntrack_tuple * tuple )
316
+ {
317
+ if (!tb [CTA_PROTO_ICMP_TYPE - 1 ]
318
+ || !tb [CTA_PROTO_ICMP_CODE - 1 ]
319
+ || !tb [CTA_PROTO_ICMP_ID - 1 ])
320
+ return - EINVAL ;
321
+
322
+ if (nfattr_bad_size (tb , CTA_PROTO_MAX , cta_min_proto ))
323
+ return - EINVAL ;
324
+
325
+ tuple -> dst .u .icmp .type =
326
+ * (u_int8_t * )NFA_DATA (tb [CTA_PROTO_ICMP_TYPE - 1 ]);
327
+ tuple -> dst .u .icmp .code =
328
+ * (u_int8_t * )NFA_DATA (tb [CTA_PROTO_ICMP_CODE - 1 ]);
329
+ tuple -> src .u .icmp .id =
330
+ * (u_int16_t * )NFA_DATA (tb [CTA_PROTO_ICMP_ID - 1 ]);
331
+
332
+ if (tuple -> dst .u .icmp .type >= sizeof (invmap )
333
+ || !invmap [tuple -> dst .u .icmp .type ])
334
+ return - EINVAL ;
335
+
336
+ return 0 ;
337
+ }
338
+ #endif
339
+
284
340
struct nf_conntrack_protocol nf_conntrack_protocol_icmp =
285
341
{
286
342
.list = { NULL , NULL },
@@ -295,7 +351,12 @@ struct nf_conntrack_protocol nf_conntrack_protocol_icmp =
295
351
.new = icmp_new ,
296
352
.error = icmp_error ,
297
353
.destroy = NULL ,
298
- .me = NULL
354
+ .me = NULL ,
355
+ #if defined(CONFIG_NF_CT_NETLINK ) || \
356
+ defined (CONFIG_NF_CT_NETLINK_MODULE )
357
+ .tuple_to_nfattr = icmp_tuple_to_nfattr ,
358
+ .nfattr_to_tuple = icmp_nfattr_to_tuple ,
359
+ #endif
299
360
};
300
361
301
362
EXPORT_SYMBOL (nf_conntrack_protocol_icmp );
0 commit comments