9 #include <linux/types.h>
11 #include <linux/netfilter.h>
13 #include <linux/icmp.h>
17 #include <linux/netfilter_ipv4.h>
28 return &net->ct.nf_ct_proto.icmp;
31 static bool icmp_pkt_to_tuple(
const struct sk_buff *
skb,
unsigned int dataoff,
37 hp = skb_header_pointer(skb, dataoff,
sizeof(_hdr), &_hdr);
41 tuple->
dst.u.icmp.type = hp->type;
42 tuple->
src.u.icmp.id = hp->un.echo.id;
43 tuple->
dst.u.icmp.code = hp->code;
63 if (orig->
dst.u.icmp.type >=
sizeof(invmap) ||
64 !invmap[orig->
dst.u.icmp.type])
67 tuple->
src.u.icmp.id = orig->
src.u.icmp.id;
68 tuple->
dst.u.icmp.type = invmap[orig->
dst.u.icmp.type] - 1;
69 tuple->
dst.u.icmp.code = orig->
dst.u.icmp.code;
74 static int icmp_print_tuple(
struct seq_file *
s,
78 tuple->
dst.u.icmp.type,
79 tuple->
dst.u.icmp.code,
83 static unsigned int *icmp_get_timeouts(
struct net *
net)
85 return &icmp_pernet(net)->timeout;
89 static int icmp_packet(
struct nf_conn *
ct,
95 unsigned int *timeout)
100 nf_ct_refresh_acct(ct, ctinfo, skb, *timeout);
107 unsigned int dataoff,
unsigned int *timeouts)
109 static const u_int8_t valid_new[] = {
116 if (ct->
tuplehash[0].tuple.dst.u.icmp.type >=
sizeof(valid_new) ||
117 !valid_new[ct->
tuplehash[0].tuple.dst.u.icmp.type]) {
119 pr_debug(
"icmp: can't create new conn with type %u\n",
121 nf_ct_dump_tuple_ip(&ct->
tuplehash[0].tuple);
142 skb_network_offset(skb) + ip_hdrlen(skb)
145 pr_debug(
"icmp_error_message: failed to get tuple\n");
155 &nf_conntrack_l3proto_ipv4, innerproto)) {
156 pr_debug(
"icmp_error_message: no match\n");
164 pr_debug(
"icmp_error_message: no match\n");
172 skb->nfct = &nf_ct_tuplehash_to_ctrack(h)->ct_general;
179 icmp_error(
struct net *net,
struct nf_conn *tmpl,
180 struct sk_buff *skb,
unsigned int dataoff,
187 icmph = skb_header_pointer(skb, ip_hdrlen(skb),
sizeof(_ih), &_ih);
191 "nf_ct_icmp: short packet ");
200 "nf_ct_icmp: bad HW ICMP checksum ");
213 "nf_ct_icmp: invalid ICMP type ");
225 return icmp_error_message(net, tmpl, skb, ctinfo, hooknum);
228 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
230 #include <linux/netfilter/nfnetlink.h>
233 static int icmp_tuple_to_nlattr(
struct sk_buff *skb,
239 goto nla_put_failure;
252 static int icmp_nlattr_to_tuple(
struct nlattr *
tb[],
262 tuple->
src.u.icmp.id = nla_get_be16(tb[CTA_PROTO_ICMP_ID]);
264 if (tuple->
dst.u.icmp.type >=
sizeof(invmap) ||
265 !invmap[tuple->
dst.u.icmp.type])
271 static int icmp_nlattr_tuple_size(
void)
277 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
279 #include <linux/netfilter/nfnetlink.h>
282 static int icmp_timeout_nlattr_to_obj(
struct nlattr *tb[],
283 struct net *net,
void *
data)
290 ntohl(nla_get_be32(tb[CTA_TIMEOUT_ICMP_TIMEOUT])) *
HZ;
299 icmp_timeout_obj_to_nlattr(
struct sk_buff *skb,
const void *data)
301 const unsigned int *timeout =
data;
303 if (nla_put_be32(skb, CTA_TIMEOUT_ICMP_TIMEOUT,
htonl(*timeout /
HZ)))
304 goto nla_put_failure;
318 static struct ctl_table icmp_sysctl_table[] = {
320 .
procname =
"nf_conntrack_icmp_timeout",
321 .maxlen =
sizeof(
unsigned int),
327 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
328 static struct ctl_table icmp_compat_sysctl_table[] = {
330 .
procname =
"ip_conntrack_icmp_timeout",
331 .maxlen =
sizeof(
unsigned int),
344 pn->ctl_table =
kmemdup(icmp_sysctl_table,
345 sizeof(icmp_sysctl_table),
350 pn->ctl_table[0].data = &in->
timeout;
355 static int icmp_kmemdup_compat_sysctl_table(
struct nf_proto_net *pn,
359 #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
360 pn->ctl_compat_table =
kmemdup(icmp_compat_sysctl_table,
361 sizeof(icmp_compat_sysctl_table),
363 if (!pn->ctl_compat_table)
366 pn->ctl_compat_table[0].data = &in->
timeout;
378 in->
timeout = nf_ct_icmp_timeout;
380 ret = icmp_kmemdup_compat_sysctl_table(pn, in);
384 ret = icmp_kmemdup_sysctl_table(pn, in);
386 nf_ct_kfree_compat_sysctl_table(pn);
391 static struct nf_proto_net *icmp_get_net_proto(
struct net *net)
393 return &net->ct.nf_ct_proto.icmp.pn;
401 .pkt_to_tuple = icmp_pkt_to_tuple,
402 .invert_tuple = icmp_invert_tuple,
403 .print_tuple = icmp_print_tuple,
404 .packet = icmp_packet,
405 .get_timeouts = icmp_get_timeouts,
410 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
411 .tuple_to_nlattr = icmp_tuple_to_nlattr,
412 .nlattr_tuple_size = icmp_nlattr_tuple_size,
413 .nlattr_to_tuple = icmp_nlattr_to_tuple,
414 .nla_policy = icmp_nla_policy,
416 #if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
418 .nlattr_to_obj = icmp_timeout_nlattr_to_obj,
419 .obj_to_nlattr = icmp_timeout_obj_to_nlattr,
421 .obj_size =
sizeof(
unsigned int),