- 论坛徽章:
- 0
|
though only for the case of syn flood,
maybe the first time of cookie implementation in netfilter,
since iam lazy and netfilter is nice.
- diff -upr linux-2.6.17.8/include/linux/netfilter/nf_conntrack_tcp.h msyn-linux-2.6.17.8/include/linux/netfilter/nf_conntrack_tcp.h
- --- linux-2.6.17.8/include/linux/netfilter/nf_conntrack_tcp.h 2006-08-07 12:18:54.000000000 +0800
- +++ msyn-linux-2.6.17.8/include/linux/netfilter/nf_conntrack_tcp.h 2007-04-09 15:06:47.000000000 +0800
- @@ -36,6 +36,7 @@ struct ip_ct_tcp_state {
- u_int8_t td_scale; /* window scale factor */
- u_int8_t loose; /* used when connection picked up from the middle */
- u_int8_t flags; /* per direction options */
- + u_int8_t dummy;
- };
-
- struct ip_ct_tcp
- @@ -49,6 +50,8 @@ struct ip_ct_tcp
- u_int32_t last_seq; /* Last sequence number seen in dir */
- u_int32_t last_ack; /* Last sequence number seen in opposite dir */
- u_int32_t last_end; /* Last seq + len */
- + u_int32_t aseq;
- + u_int32_t pseq;
- };
-
- #endif /* __KERNEL__ */
- diff -upr linux-2.6.17.8/include/linux/netfilter_ipv4/ip_conntrack.h msyn-linux-2.6.17.8/include/linux/netfilter_ipv4/ip_conntrack.h
- --- linux-2.6.17.8/include/linux/netfilter_ipv4/ip_conntrack.h 2006-08-07 12:18:54.000000000 +0800
- +++ msyn-linux-2.6.17.8/include/linux/netfilter_ipv4/ip_conntrack.h 2007-04-29 15:23:07.000000000 +0800
- @@ -81,6 +81,10 @@ struct ip_conntrack
-
- /* Have we seen traffic both ways yet? (bitset) */
- unsigned long status;
- +
- + unsigned long cookie;
- +#define IPCT_COOKIE 0x00001000 /* cookie ct */
- +#define IPCT_HOCONT 0x00000010 /* half-open-cnt ct */
-
- /* Timer function; drops refcnt when it goes off. */
- struct timer_list timeout;
- @@ -287,6 +291,10 @@ static inline int is_confirmed(struct ip
- return test_bit(IPS_CONFIRMED_BIT, &ct->status);
- }
-
- +extern int nr_ho;
- +//extern int cfg_nic_ok(struct sk_buff *);
- +extern int sysctl_nt_syn_cookie[4];
- +
- static inline int is_dying(struct ip_conntrack *ct)
- {
- return test_bit(IPS_DYING_BIT, &ct->status);
- diff -upr linux-2.6.17.8/include/linux/netfilter_ipv4/ip_conntrack_tuple.h msyn-linux-2.6.17.8/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
- --- linux-2.6.17.8/include/linux/netfilter_ipv4/ip_conntrack_tuple.h 2006-08-07 12:18:54.000000000 +0800
- +++ msyn-linux-2.6.17.8/include/linux/netfilter_ipv4/ip_conntrack_tuple.h 2007-04-09 15:09:11.000000000 +0800
- @@ -47,7 +47,7 @@ struct ip_conntrack_manip
- struct ip_conntrack_tuple
- {
- struct ip_conntrack_manip src;
- -
- +
- /* These are the parts of the tuple which are fixed. */
- struct {
- u_int32_t ip;
- diff -upr linux-2.6.17.8/include/linux/skbuff.h msyn-linux-2.6.17.8/include/linux/skbuff.h
- --- linux-2.6.17.8/include/linux/skbuff.h 2006-08-07 12:18:54.000000000 +0800
- +++ msyn-linux-2.6.17.8/include/linux/skbuff.h 2007-04-03 11:51:08.000000000 +0800
- @@ -89,6 +89,7 @@ struct net_device;
- struct nf_conntrack {
- atomic_t use;
- void (*destroy)(struct nf_conntrack *);
- + unsigned long dummy, cook2;
- };
-
- #ifdef CONFIG_BRIDGE_NETFILTER
- diff -upr linux-2.6.17.8/net/ipv4/netfilter/ip_conntrack_core.c msyn-linux-2.6.17.8/net/ipv4/netfilter/ip_conntrack_core.c
- --- linux-2.6.17.8/net/ipv4/netfilter/ip_conntrack_core.c 2006-08-07 12:18:54.000000000 +0800
- +++ msyn-linux-2.6.17.8/net/ipv4/netfilter/ip_conntrack_core.c 2007-04-29 15:23:38.000000000 +0800
- @@ -21,6 +21,7 @@
- #include <linux/types.h>
- #include <linux/icmp.h>
- #include <linux/ip.h>
- +#include <linux/tcp.h>
- #include <linux/netfilter.h>
- #include <linux/netfilter_ipv4.h>
- #include <linux/module.h>
- @@ -69,6 +70,8 @@ struct ip_conntrack_protocol *ip_ct_prot
- static LIST_HEAD(helpers);
- unsigned int ip_conntrack_htable_size = 0;
- int ip_conntrack_max;
- +int sysctl_nt_syn_cookie[4] = { 8192, 128, 0, 0 };
- +int nr_ho = 0;
- struct list_head *ip_conntrack_hash;
- static kmem_cache_t *ip_conntrack_cachep __read_mostly;
- static kmem_cache_t *ip_conntrack_expect_cachep __read_mostly;
- @@ -352,6 +355,13 @@ destroy_conntrack(struct nf_conntrack *n
- ip_conntrack_put(ct->master);
-
- DEBUGP("destroy_conntrack: returning ct=%p to slab\n", ct);
- + if (nfct->cook2) {
- + struct sk_buff * tmp =
- + (struct sk_buff *) nfct->cook2;
- + nfct->cook2 = 0;
- + atomic_dec(&(tmp->users));
- + kfree_skb(tmp);
- + }
- ip_conntrack_free(ct);
- }
-
- @@ -363,7 +373,13 @@ static void death_by_timeout(unsigned lo
- /* Inside lock so preempt is disabled on module removal path.
- * Otherwise we can get spurious warnings. */
- CONNTRACK_STAT_INC(delete_list);
- - clean_from_lists(ct);
- + clean_from_lists(ct);
- + if ((ct->cookie & IPCT_HOCONT)
- + && (ct->proto.tcp.state == TCP_CONNTRACK_SYN_SENT
- + || ct->proto.tcp.state == TCP_CONNTRACK_SYN_RECV))
- + --nr_ho;
- + if (nr_ho <0)
- + nr_ho = 0;
- write_unlock_bh(&ip_conntrack_lock);
- ip_conntrack_put(ct);
- }
- @@ -492,6 +508,9 @@ __ip_conntrack_confirm(struct sk_buff **
- set_bit(IPS_CONFIRMED_BIT, &ct->status);
- CONNTRACK_STAT_INC(insert);
- write_unlock_bh(&ip_conntrack_lock);
- + if ((ct->cookie & IPCT_HOCONT)
- + && ct->proto.tcp.state == TCP_CONNTRACK_SYN_SENT)
- + ++nr_ho;
- if (ct->helper)
- ip_conntrack_event_cache(IPCT_HELPER, *pskb);
- #ifdef CONFIG_IP_NF_NAT_NEEDED
- @@ -503,8 +522,7 @@ __ip_conntrack_confirm(struct sk_buff **
- IPCT_RELATED : IPCT_NEW, *pskb);
-
- return NF_ACCEPT;
- - }
- -
- + }
- CONNTRACK_STAT_INC(insert_failed);
- write_unlock_bh(&ip_conntrack_lock);
-
- @@ -745,7 +763,192 @@ init_conntrack(struct ip_conntrack_tuple
-
- return &conntrack->tuplehash[IP_CT_DIR_ORIGINAL];
- }
- +static struct sk_buff * make_new_syn(struct sk_buff *);
- +static void give_cookie_toc(struct sk_buff *);
- +static int skb_is_cookie_ok(struct sk_buff *);
- +static u32 make_cookie(struct sk_buff * , int);
- +static int skb_is_syn_ack(struct sk_buff * , int);
- +
- +static struct sk_buff * make_new_syn (struct sk_buff * skbo)
- +{
- + struct sk_buff * skb ;
- + struct tcphdr *th, *oth;
- + struct iphdr *iph, *oiph;
- + struct ethhdr *eth, *oeth;
- + unsigned int size = 20 + 28;
- +
- + size += (((skbo->nh.raw - skbo->mac.raw) +15) & ~15);
- + if ((skb = alloc_skb(size, GFP_ATOMIC)) == NULL)
- + return NULL;
- + skb_reserve(skb, size);
- +
- + oeth = (struct ethhdr *)skbo->mac.raw;
- + oiph = skbo->nh.iph;
- + oth = (void *)oiph + (oiph->ihl<<2) ;
- +
- + th = (struct tcphdr *) skb_push(skb, 28);
- + memset(th, 0, 28);
- +
- + th->source = oth->source;
- + th->dest = oth->dest;
- +
- + th->seq = htonl(ntohl(oth->seq) -1);
- +
- + th->syn = 1;
- + th->doff = 28 >> 2;
- + th->window = oth->window ;
- + *(__be32 *)(th + 1) = htonl((2 << 24) | (4 << 16) | 1460);
- + th->check = csum_tcpudp_magic(oiph->saddr, oiph->daddr,
- + skb->len, IPPROTO_TCP,
- + csum_partial((char *)th, skb->len, 0));
- +
- + skb->nh.iph = iph = (struct iphdr *)skb_push(skb, 20);
- + memset(iph, 0, 20);
- +
- + iph->version = 4;
- + iph->ihl = 5;
- + iph->ttl = oiph->ttl;
- + iph->tos = oiph->tos;
- + iph->protocol = oiph->protocol;
- + iph->id = oiph->id ;
- +
- + iph->daddr = oiph->daddr;
- + iph->saddr = oiph->saddr;
- +
- + iph->tot_len = htons(skb->len);
- + iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
- +
- + size = skbo->nh.raw - skbo->mac.raw;
- + eth = (struct ethhdr *)skb_push(skb, size);
- + skb_pull(skb, size);
- + skb->mac.raw = (void *)eth;
- + memcpy(skb->mac.raw, skbo->mac.raw, size);
- + skb->protocol = skbo->protocol;
- + skb->pkt_type = skbo->pkt_type;
- + skb->dev = skbo->dev;
- + return skb;
- +}
- +static void give_cookie_toc (struct sk_buff * skbo)
- +{
- + struct sk_buff * skb ;
- + struct tcphdr *th, *oth;
- + struct iphdr *iph, *oiph;
- + struct ethhdr *eth, *oeth;
- + unsigned int size = 20 + 28;
- +
- + size += (((skbo->nh.raw - skbo->mac.raw) +15) & ~15);
- + if ((skb = alloc_skb(size, GFP_ATOMIC)) == NULL)
- + return;
- + skb_reserve(skb, size);
- +
- + oeth = (struct ethhdr *) skbo->mac.raw;
- + oiph = skbo->nh.iph;
- + oth = (struct tcphdr *)((char *)oiph + (oiph->ihl<<2));
- +
- + skb->h.th = th = (struct tcphdr *) skb_push(skb, 28);
- + memset(th, 0, 28);
- +
- + th->source = oth->dest;
- + th->dest = oth->source;
- +
- + th->ack_seq = htonl(ntohl(oth->seq) + 1);
- + th->seq = htonl(make_cookie(skbo, 1));
- +
- + th->syn = th->ack = 1;
- + th->doff = 28 >> 2;
- +
- + th->window = htons(5840);
- + *(__be32 *)(th + 1) = htonl((2 << 24) | (4 << 16) | 1460);
- +
- + th->check = csum_tcpudp_magic(oiph->daddr, oiph->saddr,
- + skb->len, IPPROTO_TCP,
- + csum_partial((char *)th, skb->len, 0));
- +
- + skb->nh.iph = iph = (struct iphdr *)skb_push(skb, 20);
- + memset(iph, 0, 20);
- +
- + iph->daddr = oiph->saddr;
- + iph->saddr = oiph->daddr;
- +
- + iph->version = 4;
- + iph->ihl = 5;
- + iph->ttl = 64;
- + iph->tos = oiph->tos;
- + iph->protocol = oiph->protocol;
- + iph->id = oiph->id ;
- +
- + iph->tot_len = htons(skb->len);
- + iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
- +
- + size = skbo->nh.raw - skbo->mac.raw;
- + eth = (struct ethhdr *)skb_push(skb, size);
- + skb->mac.raw = (void *)eth;
- + memcpy(skb->mac.raw, skbo->mac.raw, size);
- + memcpy(eth->h_dest, oeth->h_source, ETH_ALEN);
- + memcpy(eth->h_source, oeth->h_dest, ETH_ALEN);
- +
- + skb->protocol = skbo->protocol;
- + skb->dev = (skbo->dev->priv_flags & IFF_EBRIDGE) ?
- + skbo->nf_bridge->physindev :
- + skbo->input_dev;
- + dev_queue_xmit(skb);
- +}
- +static int skb_is_syn_ack (struct sk_buff * skb, int syn)
- +{
- + struct iphdr * i = skb->nh.iph;
- + struct tcphdr * t =
- + (struct tcphdr *)((char *)i +(i->ihl<<2));
- +
- + if ((syn ? (t->syn == 1 && t->ack == 0) :
- + (t->syn == 0 && t->ack == 1))
- + && t->fin == 0 && t->rst == 0
- + && skb->len == 4*(i->ihl + t->doff))
- + return 1;
- + return 0;
- +}
- +static u32 make_cookie (struct sk_buff * skb, int is_syn)
- +{
- + /*
- + * code granted by other guys,
- + * though simple and effective,
- + * no need to appreciate.
- + *
- + * and linux has other nicee codes,
- + * isnt it?
- + *
- + *
- + *
- + *
- + *
- + */
- +}
- +static int skb_is_cookie_ok (struct sk_buff * skb)
- +{
- + struct iphdr * i = skb->nh.iph;
- + struct tcphdr * t =
- + (struct tcphdr *)((char *)i +(i->ihl<<2));
-
- + if (skb/*xxuglyx*/)
- + return 1;
- + return 0;
- +}
- +static int cfg_nic_ok(struct sk_buff * skb)
- +{
- + int j, k;
- +
- + k = sizeof(sysctl_nt_syn_cookie) / sizeof(int);
- + for (j = 2; j < k; j++) {
- + if (sysctl_nt_syn_cookie[j] > 0 &&
- + sysctl_nt_syn_cookie[j] == (
- +#ifdef CONFIG_BRIDGE_NETFILTER
- + skb->nf_bridge ?
- + skb->nf_bridge->physindev->ifindex :
- +#endif
- + skb->input_dev->ifindex))
- + return 1;
- + }
- + return 0;
- +}
- /* On success, returns conntrack ptr, sets skb->nfct and ctinfo */
- static inline struct ip_conntrack *
- resolve_normal_ct(struct sk_buff *skb,
- @@ -758,6 +961,9 @@ resolve_normal_ct(struct sk_buff *skb,
- struct ip_conntrack_tuple_hash *h;
- struct ip_conntrack *ct;
-
- + static unsigned long cnt_ho, tstamp = 0;
- + unsigned long now;
- +
- IP_NF_ASSERT((skb->nh.iph->frag_off & htons(IP_OFFSET)) == 0);
-
- if (!ip_ct_get_tuple(skb->nh.iph, skb, skb->nh.iph->ihl*4,
- @@ -767,6 +973,48 @@ resolve_normal_ct(struct sk_buff *skb,
- /* look for tuple match */
- h = ip_conntrack_find_get(&tuple, NULL);
- if (!h) {
- +#define cfg_anr sysctl_nt_syn_cookie[0]
- +#define cfg_snr sysctl_nt_syn_cookie[1]
- +
- + if (proto->proto == IPPROTO_TCP &&
- + hooknum == NF_IP_PRE_ROUTING &&
- + cfg_nic_ok(skb))
- + {
- + if (cfg_anr < 0 || cfg_snr < 0) {
- + mixi:
- + h = ERR_PTR(-601);
- + return (void *)h;
- + }
- + tuple.dst.dir = 0;
- + if (skb_is_syn_ack(skb, 1)) {
- + int buk = 0;
- +
- + now = jiffies ;
- + cnt_ho += (now - tstamp);
- + tstamp = now;
- + if (cnt_ho > HZ * cfg_snr)
- + cnt_ho = HZ * cfg_snr;
- + if (cnt_ho >= HZ) {
- + cnt_ho -= HZ ;
- + buk = 1;
- + }
- + if (nr_ho < cfg_anr && buk) {
- + tuple.dst.dir = 4;
- + goto nook;
- + }
- + h = ERR_PTR(-600);
- + return (void *)h;
- + } else if (skb_is_syn_ack(skb, 0) &&
- + skb_is_cookie_ok(skb)) {
- + tuple.dst.dir = 12;
- + goto nook;
- + } else
- + goto mixi;
- + }
- +#undef cfg_anr
- +#undef cfg_snr
- +
- + nook:
- h = init_conntrack(&tuple, proto, skb);
- if (!h)
- return NULL;
- @@ -801,7 +1049,24 @@ resolve_normal_ct(struct sk_buff *skb,
- skb->nfctinfo = *ctinfo;
- return ct;
- }
- -
- +static void rechk_skb(struct tcphdr * th,
- + enum ip_conntrack_dir dir,
- + u_int32_t aseq, u_int32_t pseq)
- +{
- + u32 diffs[2];
- +
- + if (!dir) {
- + diffs[0] = ~(th->ack_seq);
- + th->ack_seq = diffs[1] =
- + htonl(ntohl(th->ack_seq) - pseq+aseq) ;
- + } else {
- + diffs[0] = ~(th->seq);
- + th->seq = diffs[1] =
- + htonl(ntohl(th->seq) - aseq+pseq) ;
- + }
- + th->check = csum_fold(csum_partial((char *)diffs,
- + sizeof(diffs), th->check^0xFFFF));
- +}
- /* Netfilter hook itself. */
- unsigned int ip_conntrack_in(unsigned int hooknum,
- struct sk_buff **pskb,
- @@ -815,6 +1080,16 @@ unsigned int ip_conntrack_in(unsigned in
- int set_reply = 0;
- int ret;
-
- + u_int8_t old_state = 0;
- + enum ip_conntrack_dir dir;
- + struct iphdr *iph;
- + struct tcphdr *th;
- + unsigned int index;
- +
- + int ala = 0;
- + int cry, br;
- + struct sk_buff *new_skb;
- +
- /* Previously seen (loopback or untracked)? Ignore. */
- if ((*pskb)->nfct) {
- CONNTRACK_STAT_INC(ignore);
- @@ -856,21 +1131,103 @@ unsigned int ip_conntrack_in(unsigned in
- CONNTRACK_STAT_INC(invalid);
- return -ret;
- }
- -
- - if (!(ct = resolve_normal_ct(*pskb, proto,&set_reply,hooknum,&ctinfo))) {
- + if (!(ct = resolve_normal_ct(*pskb, proto,
- + &set_reply, hooknum, &ctinfo))) {
- /* Not valid part of a connection */
- CONNTRACK_STAT_INC(invalid);
- return NF_ACCEPT;
- }
- -
- if (IS_ERR(ct)) {
- /* Too stressed to deal. */
- CONNTRACK_STAT_INC(drop);
- + if (PTR_ERR(ct) == -600) {
- + give_cookie_toc(*pskb);
- + }
- return NF_DROP;
- }
- -
- IP_NF_ASSERT((*pskb)->nfct);
-
- +#define COOK_TCP_SYN_SET 0
- +#define COOK_TCP_SYNACK_SET 1
- +#define COOK_TCP_FIN_SET 2
- +#define COOK_TCP_ACK_SET 3
- +#define COOK_TCP_RST_SET 4
- +#define COOK_TCP_NONE_SET 5
- +#define COOK_TCP_CONNTRACK_NONE 0
- +#define COOK_TCP_CONNTRACK_SYN_SENT 1
- +
- + dir = CTINFO2DIR(ctinfo);
- + cry = (proto->proto == IPPROTO_TCP
- + && (ct->cookie & IPCT_COOKIE)) ? 111 : 0;
- + br = (in && (in->priv_flags & IFF_EBRIDGE)) ? 11 : 0;
- + old_state = ct->proto.tcp.state;
- +
- + if (cry) {
- + iph = (*pskb)->nh.iph;
- + th = (struct tcphdr *)(iph->ihl*4 + (char *)iph);
- + if (th->rst) {
- + index = COOK_TCP_RST_SET;
- + /* why not smilee? */
- + } else if (th->syn)
- + index = th->ack ?
- + COOK_TCP_SYNACK_SET :
- + COOK_TCP_SYN_SET;
- + else if (th->fin)
- + index = COOK_TCP_FIN_SET;
- + else if (th->ack)
- + index = COOK_TCP_ACK_SET;
- + else
- + index = COOK_TCP_NONE_SET;
- + //old_state = ct->proto.tcp.state;
- + ala = 4+3;
- +
- + if (hooknum == NF_IP_LOCAL_OUT &&
- + dir && !in && out) {
- + if (index == COOK_TCP_SYNACK_SET &&
- + old_state == COOK_TCP_CONNTRACK_SYN_SENT)
- + ala = 3;
- + }
- + if (hooknum == NF_IP_PRE_ROUTING &&
- + dir && !out && in &&
- + !cfg_nic_ok(*pskb)) {
- + if (index == COOK_TCP_SYNACK_SET &&
- + old_state == COOK_TCP_CONNTRACK_SYN_SENT)
- + ala = 2;
- + }
- + if (hooknum == NF_IP_PRE_ROUTING &&
- + !dir && !out && in &&
- + cfg_nic_ok(*pskb)) {
- + if (index == COOK_TCP_ACK_SET &&
- + old_state == COOK_TCP_CONNTRACK_NONE)
- + ala = 1;
- + }
- + }
- + if (cry && ala == 1) {
- + new_skb = make_new_syn(*pskb);
- + if (!new_skb)
- + return NF_DROP;
- +
- + ct->ct_general.cook2 = (unsigned long) *pskb;
- + atomic_inc(&((*pskb)->users));
- +
- + new_skb->nfct = (*pskb)->nfct;
- + (*pskb)->nfct = NULL;
- + new_skb->nfctinfo = (*pskb)->nfctinfo;
- + (*pskb)->nfctinfo = 0;
- + if (br && (*pskb)->nf_bridge) {
- + new_skb->nf_bridge = (*pskb)->nf_bridge;
- + nf_bridge_get((*pskb)->nf_bridge);
- + }
- + *pskb = new_skb;
- + } else if (cry && ala > 3 && !dir) {
- + if (!skb_make_writable(pskb, 20+(*pskb)->nh.iph->ihl*4))
- + return NF_DROP;
- + iph = (*pskb)->nh.iph;
- + th = (struct tcphdr *)((char *)iph + iph->ihl*4);
- + rechk_skb(th, dir,
- + ct->proto.tcp.aseq, ct->proto.tcp.pseq);
- + }
- +
- ret = proto->packet(ct, *pskb, ctinfo);
- if (ret < 0) {
- /* Invalid: inverse of the return code tells
- @@ -880,11 +1237,69 @@ unsigned int ip_conntrack_in(unsigned in
- CONNTRACK_STAT_INC(invalid);
- return -ret;
- }
- -
- if (set_reply && !test_and_set_bit(IPS_SEEN_REPLY_BIT, &ct->status))
- ip_conntrack_event_cache(IPCT_STATUS, *pskb);
-
- + if (ret == NF_ACCEPT && cry && dir
- + && (ala == 3 || ala == 2)) {
- + if (ala == 3 && ct->ct_general.cook2) {
- + new_skb = (struct sk_buff *)ct->ct_general.cook2;
- +
- + ct->ct_general.cook2 = 0;
- + atomic_dec(&(new_skb->users));
- + kfree_skb(new_skb);
- + return NF_DROP;
- + } else if (ala == 2 && ct->ct_general.cook2) {
- + int r;
- +
- + new_skb = (struct sk_buff *)ct->ct_general.cook2;
- + ct->ct_general.cook2 = 0;
- + atomic_dec(&(new_skb->users));
- + if (!skb_make_writable(&new_skb,
- + 20+new_skb->nh.iph->ihl*4)) {
- + kfree(new_skb);
- + return NF_DROP;
- + }
- + new_skb->nfct = (*pskb)->nfct;
- + (*pskb)->nfct = NULL;
- + new_skb->nfctinfo = (*pskb)->nfctinfo - IP_CT_DIR_REPLY;
- + (*pskb)->nfctinfo = 0;
- +
- + kfree_skb(*pskb);
- + *pskb = new_skb;
- + iph = (*pskb)->nh.iph;
- + th = (struct tcphdr *)((char *)iph + iph->ihl*4);
- +
- + rechk_skb(th, dir,
- + ct->proto.tcp.aseq, ct->proto.tcp.pseq);
- +
- + r = proto->packet(ct, *pskb, (*pskb)->nfctinfo);
- + if (r < 0) {
- + nf_conntrack_put((*pskb)->nfct);
- + (*pskb)->nfct = NULL;
- + CONNTRACK_STAT_INC(invalid);
- + return -r ;
- + }
- + return r;
- + }
- + }
- + if (ret == NF_ACCEPT && cry && ala > 3 && dir) {
- + if (!skb_make_writable(pskb, 20+(*pskb)->nh.iph->ihl*4))
- + return NF_DROP;
- + iph = (*pskb)->nh.iph;
- + th = (void *)iph + iph->ihl*4;
- + rechk_skb(th, dir,
- + ct->proto.tcp.aseq, ct->proto.tcp.pseq);
- + }
- return ret;
- +#undef COOK_TCP_SYN_SET
- +#undef COOK_TCP_SYNACK_SET
- +#undef COOK_TCP_FIN_SET
- +#undef COOK_TCP_ACK_SET
- +#undef COOK_TCP_RST_SET
- +#undef COOK_TCP_NONE_SET
- +#undef COOK_TCP_CONNTRACK_NONE
- +#undef COOK_TCP_CONNTRACK_SYN_SENT
- }
-
- int invert_tuplepr(struct ip_conntrack_tuple *inverse,
复制代码
[ 本帖最后由 sisi8408 于 2008-2-24 18:00 编辑 ] |
|