📄 nf_conntrack_l3proto_ipv4.c
字号:
/* (C) 1999-2001 Paul `Rusty' Russell * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp> * - move L3 protocol dependent part to this file. * 23 Mar 2004: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp> * - add get_features() to support various size of conntrack * structures. * * Derived from net/ipv4/netfilter/ip_conntrack_standalone.c */#include <linux/config.h>#include <linux/types.h>#include <linux/ip.h>#include <linux/netfilter.h>#include <linux/module.h>#include <linux/skbuff.h>#include <linux/icmp.h>#include <linux/sysctl.h>#include <net/route.h>#include <net/ip.h>#include <linux/netfilter_ipv4.h>#include <net/netfilter/nf_conntrack.h>#include <net/netfilter/nf_conntrack_helper.h>#include <net/netfilter/nf_conntrack_protocol.h>#include <net/netfilter/nf_conntrack_l3proto.h>#include <net/netfilter/nf_conntrack_core.h>#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>#if 0#define DEBUGP printk#else#define DEBUGP(format, args...)#endifDECLARE_PER_CPU(struct nf_conntrack_stat, nf_conntrack_stat);static int ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, struct nf_conntrack_tuple *tuple){ u_int32_t _addrs[2], *ap; ap = skb_header_pointer(skb, nhoff + offsetof(struct iphdr, saddr), sizeof(u_int32_t) * 2, _addrs); if (ap == NULL) return 0; tuple->src.u3.ip = ap[0]; tuple->dst.u3.ip = ap[1]; return 1;}static int ipv4_invert_tuple(struct nf_conntrack_tuple *tuple, const struct nf_conntrack_tuple *orig){ tuple->src.u3.ip = orig->dst.u3.ip; tuple->dst.u3.ip = orig->src.u3.ip; return 1;}static int ipv4_print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple){ return seq_printf(s, "src=%u.%u.%u.%u dst=%u.%u.%u.%u ", NIPQUAD(tuple->src.u3.ip), NIPQUAD(tuple->dst.u3.ip));}static int ipv4_print_conntrack(struct seq_file *s, const struct nf_conn *conntrack){ return 0;}/* Returns new sk_buff, or NULL */static struct sk_buff *nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user){ skb_orphan(skb); local_bh_disable(); skb = ip_defrag(skb, user); local_bh_enable(); if (skb) ip_send_check(skb->nh.iph); return skb;}static intipv4_prepare(struct sk_buff **pskb, unsigned int hooknum, unsigned int *dataoff, u_int8_t *protonum){ /* Never happen */ if ((*pskb)->nh.iph->frag_off & htons(IP_OFFSET)) { if (net_ratelimit()) { printk(KERN_ERR "ipv4_prepare: Frag of proto %u (hook=%u)\n", (*pskb)->nh.iph->protocol, hooknum); } return -NF_DROP; } *dataoff = (*pskb)->nh.raw - (*pskb)->data + (*pskb)->nh.iph->ihl*4; *protonum = (*pskb)->nh.iph->protocol; return NF_ACCEPT;}int nat_module_is_loaded = 0;static u_int32_t ipv4_get_features(const struct nf_conntrack_tuple *tuple){ if (nat_module_is_loaded) return NF_CT_F_NAT; return NF_CT_F_BASIC;}static unsigned int ipv4_confirm(unsigned int hooknum, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)){ /* We've seen it coming out the other side: confirm it */ return nf_conntrack_confirm(pskb);}static unsigned int ipv4_conntrack_help(unsigned int hooknum, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)){ struct nf_conn *ct; enum ip_conntrack_info ctinfo; /* This is where we call the helper: as the packet goes out. */ ct = nf_ct_get(*pskb, &ctinfo); if (ct && ct->helper) { unsigned int ret; ret = ct->helper->help(pskb, (*pskb)->nh.raw - (*pskb)->data + (*pskb)->nh.iph->ihl*4, ct, ctinfo); if (ret != NF_ACCEPT) return ret; } return NF_ACCEPT;}static unsigned int ipv4_conntrack_defrag(unsigned int hooknum, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)){#if !defined(CONFIG_IP_NF_NAT) && !defined(CONFIG_IP_NF_NAT_MODULE) /* Previously seen (loopback)? Ignore. Do this before fragment check. */ if ((*pskb)->nfct) return NF_ACCEPT;#endif /* Gather fragments. */ if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) { *pskb = nf_ct_ipv4_gather_frags(*pskb, hooknum == NF_IP_PRE_ROUTING ? IP_DEFRAG_CONNTRACK_IN : IP_DEFRAG_CONNTRACK_OUT); if (!*pskb) return NF_STOLEN; } return NF_ACCEPT;}static unsigned int ipv4_conntrack_in(unsigned int hooknum, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)){ return nf_conntrack_in(PF_INET, hooknum, pskb);}static unsigned int ipv4_conntrack_local(unsigned int hooknum, struct sk_buff **pskb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)){ /* root is playing with raw sockets. */ if ((*pskb)->len < sizeof(struct iphdr) || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) { if (net_ratelimit()) printk("ipt_hook: happy cracking.\n"); return NF_ACCEPT; } return nf_conntrack_in(PF_INET, hooknum, pskb);}/* Connection tracking may drop packets, but never alters them, so make it the first hook. */static struct nf_hook_ops ipv4_conntrack_defrag_ops = { .hook = ipv4_conntrack_defrag, .owner = THIS_MODULE, .pf = PF_INET, .hooknum = NF_IP_PRE_ROUTING, .priority = NF_IP_PRI_CONNTRACK_DEFRAG,};static struct nf_hook_ops ipv4_conntrack_in_ops = { .hook = ipv4_conntrack_in, .owner = THIS_MODULE, .pf = PF_INET, .hooknum = NF_IP_PRE_ROUTING, .priority = NF_IP_PRI_CONNTRACK,};static struct nf_hook_ops ipv4_conntrack_defrag_local_out_ops = { .hook = ipv4_conntrack_defrag, .owner = THIS_MODULE, .pf = PF_INET, .hooknum = NF_IP_LOCAL_OUT, .priority = NF_IP_PRI_CONNTRACK_DEFRAG,};static struct nf_hook_ops ipv4_conntrack_local_out_ops = { .hook = ipv4_conntrack_local, .owner = THIS_MODULE, .pf = PF_INET, .hooknum = NF_IP_LOCAL_OUT, .priority = NF_IP_PRI_CONNTRACK,};/* helpers */static struct nf_hook_ops ipv4_conntrack_helper_out_ops = { .hook = ipv4_conntrack_help, .owner = THIS_MODULE, .pf = PF_INET, .hooknum = NF_IP_POST_ROUTING, .priority = NF_IP_PRI_CONNTRACK_HELPER,};static struct nf_hook_ops ipv4_conntrack_helper_in_ops = { .hook = ipv4_conntrack_help, .owner = THIS_MODULE, .pf = PF_INET, .hooknum = NF_IP_LOCAL_IN, .priority = NF_IP_PRI_CONNTRACK_HELPER,};/* Refragmenter; last chance. */static struct nf_hook_ops ipv4_conntrack_out_ops = { .hook = ipv4_confirm, .owner = THIS_MODULE, .pf = PF_INET, .hooknum = NF_IP_POST_ROUTING, .priority = NF_IP_PRI_CONNTRACK_CONFIRM,};static struct nf_hook_ops ipv4_conntrack_local_in_ops = { .hook = ipv4_confirm, .owner = THIS_MODULE, .pf = PF_INET, .hooknum = NF_IP_LOCAL_IN, .priority = NF_IP_PRI_CONNTRACK_CONFIRM,};#ifdef CONFIG_SYSCTL/* From nf_conntrack_proto_icmp.c */extern unsigned int nf_ct_icmp_timeout;static struct ctl_table_header *nf_ct_ipv4_sysctl_header;static ctl_table nf_ct_sysctl_table[] = { { .ctl_name = NET_NF_CONNTRACK_ICMP_TIMEOUT, .procname = "nf_conntrack_icmp_timeout", .data = &nf_ct_icmp_timeout, .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, }, { .ctl_name = 0 }};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -