[netfilter-cvslog] r3475 - in trunk/nfsim/core: . ipv4
rusty at netfilter.org
rusty at netfilter.org
Mon Dec 20 14:38:35 CET 2004
Author: rusty at netfilter.org
Date: 2004-12-20 14:38:35 +0100 (Mon, 20 Dec 2004)
New Revision: 3475
Modified:
trunk/nfsim/core/core.c
trunk/nfsim/core/ipv4/ipv4.c
Log:
Fragment handling.
Modified: trunk/nfsim/core/core.c
===================================================================
--- trunk/nfsim/core/core.c 2004-12-20 06:46:58 UTC (rev 3474)
+++ trunk/nfsim/core/core.c 2004-12-20 13:38:35 UTC (rev 3475)
@@ -143,9 +143,14 @@
talloc_free(hookname);
ret = ops->hook(hooknum, skb, in, out, okfn);
- nfsim_log(LOG_HOOK, "hook:%s %s %s%s",
- nf_hooknames[PF_INET][hooknum], ops->owner->name,
- nf_retval(ret), describe_packet(*skb));
+ if (ret == NF_STOLEN)
+ nfsim_log(LOG_HOOK, "hook:%s %s %s",
+ nf_hooknames[PF_INET][hooknum], ops->owner->name,
+ nf_retval(ret));
+ else
+ nfsim_log(LOG_HOOK, "hook:%s %s %s%s",
+ nf_hooknames[PF_INET][hooknum], ops->owner->name,
+ nf_retval(ret), describe_packet(*skb));
return ret;
}
Modified: trunk/nfsim/core/ipv4/ipv4.c
===================================================================
--- trunk/nfsim/core/ipv4/ipv4.c 2004-12-20 06:46:58 UTC (rev 3474)
+++ trunk/nfsim/core/ipv4/ipv4.c 2004-12-20 13:38:35 UTC (rev 3475)
@@ -467,12 +467,87 @@
return 0;
}
-struct sk_buff *ip_defrag(struct sk_buff *skb)
+struct fraglist
{
- log_packet(skb, "ip_defrag");
+ struct list_head list;
+ struct sk_buff *frags[20];
+};
+static LIST_HEAD(fraglist);
+
+static struct sk_buff *gather_frag(struct fraglist *f, struct sk_buff *skb)
+{
+ unsigned int i, len, off, max = 0;
+ bool old, ended = false;
+ char filled[70000] = { 0 };
+ char data[70000];
+
+ for (i = 0; i < ARRAY_SIZE(f->frags); i++) {
+ if (!f->frags[i]) {
+ if (!skb)
+ break;
+ f->frags[i] = skb;
+ talloc_steal(f, skb);
+ skb = NULL;
+ }
+
+ off = (ntohs(f->frags[i]->nh.iph->frag_off) & IP_OFFSET)*8;
+ len = ntohs(f->frags[i]->nh.iph->tot_len)
+ - f->frags[i]->nh.iph->ihl * 4;
+ if (len + off > max)
+ max = len + off;
+
+ memset(filled + off, 1, len);
+ memcpy(data + off, (void *)f->frags[i]->nh.iph
+ + f->frags[i]->nh.iph->ihl * 4,
+ len);
+ if (!(ntohs(f->frags[i]->nh.iph->frag_off) & IP_MF))
+ ended = true;
+ }
+ if (skb)
+ barf("Can't handle %i frags!\n", i);
+
+ /* Not a complete packet? */
+ if (!ended || memchr(filled, 0, max) != NULL)
+ return NULL;
+
+ /* Copy header and data. */
+ old = suppress_failtest;
+ suppress_failtest = true;
+ skb = skb_copy_expand(f->frags[0], 0, max, GFP_KERNEL);
+ suppress_failtest = old;
+
+ skb->nh.iph = (void *)skb->data;
+ memcpy(skb->nh.iph, f->frags[0]->nh.iph, f->frags[0]->nh.iph->ihl*4);
+ memcpy((void *)skb->nh.iph + f->frags[0]->nh.iph->ihl*4, data, len);
+
+ /* Except we're not a fragment, and we're longer. */
+ skb->nh.iph->frag_off = 0;
+ skb->nh.iph->tot_len = max + skb->nh.iph->ihl*4;
+
+ list_del(&f->list);
+ talloc_free(f);
return skb;
}
+struct sk_buff *ip_defrag(struct sk_buff *skb)
+{
+ struct fraglist *i;
+
+ list_for_each_entry(i, &fraglist, list) {
+ if (i->frags[0]->nh.iph->saddr != skb->nh.iph->saddr
+ || i->frags[0]->nh.iph->daddr != skb->nh.iph->daddr
+ || i->frags[0]->nh.iph->protocol!=skb->nh.iph->protocol)
+ continue;
+ return gather_frag(i, skb);
+ }
+ i = talloc(NULL, struct fraglist);
+ memset(i->frags, 0, sizeof(i->frags));
+ i->frags[0] = skb;
+ list_add(&i->list, &fraglist);
+ talloc_steal(i, skb);
+ return NULL;
+}
+
void ipfrag_flush(void)
{
}
More information about the netfilter-cvslog
mailing list