⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 beet-interfamily-2.6.22.6.patch

📁 HIP:Host Identity Protocol
💻 PATCH
📖 第 1 页 / 共 3 页
字号:
+		unsigned  char * optptr = opt->__data+opt->rr-sizeof(struct  iphdr);+		optptr[2] -= 4;+		memset(&optptr[optptr[2]-1], 0, 4);+	}+	if (opt->ts) {+		unsigned  char * optptr = opt->__data+opt->ts-sizeof(struct  iphdr);+		if (opt->ts_needtime) {+			optptr[2] -= 4;+			memset(&optptr[optptr[2]-1], 0, 4);+			if ((optptr[3]&0xF) == IPOPT_TS_PRESPEC)+				optptr[2] -= 4;+		}+		if (opt->ts_needaddr) {+			optptr[2] -= 4;+			memset(&optptr[optptr[2]-1], 0, 4);+		}+	}+}++static struct ip_options *ip_options_get_alloc(const int optlen)+{+	struct ip_options *opt = kmalloc(sizeof(*opt) + ((optlen + 3) & ~3),+					 GFP_KERNEL);+	if (opt)+		memset(opt, 0, sizeof(*opt));+	return opt;+}++static int ip_options_get_finish(struct ip_options **optp,+				 struct ip_options *opt, int optlen)+{+	while (optlen & 3)+		opt->__data[optlen++] = IPOPT_END;+	opt->optlen = optlen;+	opt->is_data = 1;+	if (optlen && ip_options_compile(opt, NULL)) {+		kfree(opt);+		return -EINVAL;+	}+	kfree(*optp);+	*optp = opt;+	return 0;+}++int ip_options_get_from_user(struct ip_options **optp, unsigned char __user *data, int optlen)+{+	struct ip_options *opt = ip_options_get_alloc(optlen);++	if (!opt)+		return -ENOMEM;+	if (optlen && copy_from_user(opt->__data, data, optlen)) {+		kfree(opt);+		return -EFAULT;+	}+	return ip_options_get_finish(optp, opt, optlen);+}++int ip_options_get(struct ip_options **optp, unsigned char *data, int optlen)+{+	struct ip_options *opt = ip_options_get_alloc(optlen);++	if (!opt)+		return -ENOMEM;+	if (optlen)+		memcpy(opt->__data, data, optlen);+	return ip_options_get_finish(optp, opt, optlen);+}++void ip_forward_options(struct sk_buff *skb)+{+	struct   ip_options * opt	= &(IPCB(skb)->opt);+	unsigned char * optptr;+	struct rtable *rt = (struct rtable*)skb->dst;+	unsigned char *raw = skb_network_header(skb);++	if (opt->rr_needaddr) {+		optptr = (unsigned char *)raw + opt->rr;+		ip_rt_get_source(&optptr[optptr[2]-5], rt);+		opt->is_changed = 1;+	}+	if (opt->srr_is_hit) {+		int srrptr, srrspace;++		optptr = raw + opt->srr;++		for ( srrptr=optptr[2], srrspace = optptr[1];+		     srrptr <= srrspace;+		     srrptr += 4+		     ) {+			if (srrptr + 3 > srrspace)+				break;+			if (memcmp(&rt->rt_dst, &optptr[srrptr-1], 4) == 0)+				break;+		}+		if (srrptr + 3 <= srrspace) {+			opt->is_changed = 1;+			ip_rt_get_source(&optptr[srrptr-1], rt);+			ip_hdr(skb)->daddr = rt->rt_dst;+			optptr[2] = srrptr+4;+		} else if (net_ratelimit())+			printk(KERN_CRIT "ip_forward(): Argh! Destination lost!\n");+		if (opt->ts_needaddr) {+			optptr = raw + opt->ts;+			ip_rt_get_source(&optptr[optptr[2]-9], rt);+			opt->is_changed = 1;+		}+	}+	if (opt->is_changed) {+		opt->is_changed = 0;+		ip_send_check(ip_hdr(skb));+	}+}++int ip_options_rcv_srr(struct sk_buff *skb)+{+	struct ip_options *opt = &(IPCB(skb)->opt);+	int srrspace, srrptr;+	__be32 nexthop;+	struct iphdr *iph = ip_hdr(skb);+	unsigned char *optptr = skb_network_header(skb) + opt->srr;+	struct rtable *rt = (struct rtable*)skb->dst;+	struct rtable *rt2;+	int err;++	if (!opt->srr)+		return 0;++	if (skb->pkt_type != PACKET_HOST)+		return -EINVAL;+	if (rt->rt_type == RTN_UNICAST) {+		if (!opt->is_strictroute)+			return 0;+		icmp_send(skb, ICMP_PARAMETERPROB, 0, htonl(16<<24));+		return -EINVAL;+	}+	if (rt->rt_type != RTN_LOCAL)+		return -EINVAL;++	for (srrptr=optptr[2], srrspace = optptr[1]; srrptr <= srrspace; srrptr += 4) {+		if (srrptr + 3 > srrspace) {+			icmp_send(skb, ICMP_PARAMETERPROB, 0, htonl((opt->srr+2)<<24));+			return -EINVAL;+		}+		memcpy(&nexthop, &optptr[srrptr-1], 4);++		rt = (struct rtable*)skb->dst;+		skb->dst = NULL;+		err = ip_route_input(skb, nexthop, iph->saddr, iph->tos, skb->dev);+		rt2 = (struct rtable*)skb->dst;+		if (err || (rt2->rt_type != RTN_UNICAST && rt2->rt_type != RTN_LOCAL)) {+			ip_rt_put(rt2);+			skb->dst = &rt->u.dst;+			return -EINVAL;+		}+		ip_rt_put(rt);+		if (rt2->rt_type != RTN_LOCAL)+			break;+		/* Superfast 8) loopback forward */+		memcpy(&iph->daddr, &optptr[srrptr-1], 4);+		opt->is_changed = 1;+	}+	if (srrptr <= srrspace) {+		opt->srr_is_hit = 1;+		opt->is_changed = 1;+	}+	return 0;+}diff -urN linux-2.6.22.6/net/ipv4/xfrm4_input.c linux-2.6.22.6-beet/net/ipv4/xfrm4_input.c--- linux-2.6.22.6/net/ipv4/xfrm4_input.c	2007-08-31 09:21:01.000000000 +0300+++ linux-2.6.22.6-beet/net/ipv4/xfrm4_input.c	2007-09-11 22:38:08.000000000 +0300@@ -108,7 +108,9 @@ 		if (x->mode->input(x, skb)) 			goto drop; -		if (x->props.mode == XFRM_MODE_TUNNEL) {+		if (x->props.mode == XFRM_MODE_TUNNEL ||+		    (x->props.mode == XFRM_MODE_BEET &&+		     x->sel.family != AF_INET)) { 			decaps = 1; 			break; 		}diff -urN linux-2.6.22.6/net/ipv4/xfrm4_input.c.orig linux-2.6.22.6-beet/net/ipv4/xfrm4_input.c.orig--- linux-2.6.22.6/net/ipv4/xfrm4_input.c.orig	1970-01-01 02:00:00.000000000 +0200+++ linux-2.6.22.6-beet/net/ipv4/xfrm4_input.c.orig	2007-08-31 09:21:01.000000000 +0300@@ -0,0 +1,169 @@+/*+ * xfrm4_input.c+ *+ * Changes:+ *	YOSHIFUJI Hideaki @USAGI+ *		Split up af-specific portion+ *	Derek Atkins <derek@ihtfp.com>+ *		Add Encapsulation support+ *+ */++#include <linux/module.h>+#include <linux/string.h>+#include <linux/netfilter.h>+#include <linux/netfilter_ipv4.h>+#include <net/ip.h>+#include <net/xfrm.h>++int xfrm4_rcv(struct sk_buff *skb)+{+	return xfrm4_rcv_encap(skb, 0);+}++EXPORT_SYMBOL(xfrm4_rcv);++static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)+{+	switch (nexthdr) {+	case IPPROTO_IPIP:+	case IPPROTO_IPV6:+		*spi = ip_hdr(skb)->saddr;+		*seq = 0;+		return 0;+	}++	return xfrm_parse_spi(skb, nexthdr, spi, seq);+}++#ifdef CONFIG_NETFILTER+static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb)+{+	if (skb->dst == NULL) {+		const struct iphdr *iph = ip_hdr(skb);++		if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos,+				   skb->dev))+			goto drop;+	}+	return dst_input(skb);+drop:+	kfree_skb(skb);+	return NET_RX_DROP;+}+#endif++int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)+{+	__be32 spi, seq;+	struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH];+	struct xfrm_state *x;+	int xfrm_nr = 0;+	int decaps = 0;+	int err = xfrm4_parse_spi(skb, ip_hdr(skb)->protocol, &spi, &seq);++	if (err != 0)+		goto drop;++	do {+		const struct iphdr *iph = ip_hdr(skb);++		if (xfrm_nr == XFRM_MAX_DEPTH)+			goto drop;++		x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi,+				iph->protocol != IPPROTO_IPV6 ? iph->protocol : IPPROTO_IPIP, AF_INET);+		if (x == NULL)+			goto drop;++		spin_lock(&x->lock);+		if (unlikely(x->km.state != XFRM_STATE_VALID))+			goto drop_unlock;++		if ((x->encap ? x->encap->encap_type : 0) != encap_type)+			goto drop_unlock;++		if (x->props.replay_window && xfrm_replay_check(x, seq))+			goto drop_unlock;++		if (xfrm_state_check_expire(x))+			goto drop_unlock;++		if (x->type->input(x, skb))+			goto drop_unlock;++		/* only the first xfrm gets the encap type */+		encap_type = 0;++		if (x->props.replay_window)+			xfrm_replay_advance(x, seq);++		x->curlft.bytes += skb->len;+		x->curlft.packets++;++		spin_unlock(&x->lock);++		xfrm_vec[xfrm_nr++] = x;++		if (x->mode->input(x, skb))+			goto drop;++		if (x->props.mode == XFRM_MODE_TUNNEL) {+			decaps = 1;+			break;+		}++		err = xfrm_parse_spi(skb, ip_hdr(skb)->protocol, &spi, &seq);+		if (err < 0)+			goto drop;+	} while (!err);++	/* Allocate new secpath or COW existing one. */++	if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1) {+		struct sec_path *sp;+		sp = secpath_dup(skb->sp);+		if (!sp)+			goto drop;+		if (skb->sp)+			secpath_put(skb->sp);+		skb->sp = sp;+	}+	if (xfrm_nr + skb->sp->len > XFRM_MAX_DEPTH)+		goto drop;++	memcpy(skb->sp->xvec + skb->sp->len, xfrm_vec,+	       xfrm_nr * sizeof(xfrm_vec[0]));+	skb->sp->len += xfrm_nr;++	nf_reset(skb);++	if (decaps) {+		dst_release(skb->dst);+		skb->dst = NULL;+		netif_rx(skb);+		return 0;+	} else {+#ifdef CONFIG_NETFILTER+		__skb_push(skb, skb->data - skb_network_header(skb));+		ip_hdr(skb)->tot_len = htons(skb->len);+		ip_send_check(ip_hdr(skb));++		NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL,+			xfrm4_rcv_encap_finish);+		return 0;+#else+		return -ip_hdr(skb)->protocol;+#endif+	}++drop_unlock:+	spin_unlock(&x->lock);+	xfrm_state_put(x);+drop:+	while (--xfrm_nr >= 0)+		xfrm_state_put(xfrm_vec[xfrm_nr]);++	kfree_skb(skb);+	return 0;+}diff -urN linux-2.6.22.6/net/ipv4/xfrm4_mode_beet.c linux-2.6.22.6-beet/net/ipv4/xfrm4_mode_beet.c--- linux-2.6.22.6/net/ipv4/xfrm4_mode_beet.c	2007-08-31 09:21:01.000000000 +0300+++ linux-2.6.22.6-beet/net/ipv4/xfrm4_mode_beet.c	2007-09-11 22:38:08.000000000 +0300@@ -6,6 +6,7 @@  *                    Herbert Xu     <herbert@gondor.apana.org.au>  *                    Abhinav Pathak <abhinav.pathak@hiit.fi>  *                    Jeff Ahrenholz <ahrenholz@gmail.com>+ *                    Joakim Koskela <jookos@gmail.com>  */  #include <linux/init.h>@@ -16,6 +17,7 @@ #include <net/dst.h> #include <net/ip.h> #include <net/xfrm.h>+#include <net/inet_ecn.h>  /* Add encapsulation header.  *@@ -24,92 +26,177 @@  *      tot_len  *      check  *- * On exit, skb->h will be set to the start of the payload to be processed- * by x->type->output and skb->nh will be set to the top IP header.+ * On exit, skb->transport_header will be set to the start of the+ * payload to be processed by x->type->output and skb->network_header+ * will be set to the top IP header.  */ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb) {-	struct iphdr *iph, *top_iph;-	int hdrlen, optlen;--	iph = ip_hdr(skb);-	skb->transport_header = skb->network_header;--	hdrlen = 0;-	optlen = iph->ihl * 4 - sizeof(*iph);-	if (unlikely(optlen))-		hdrlen += IPV4_BEET_PHMAXLEN - (optlen & 4);--	skb_push(skb, x->props.header_len - IPV4_BEET_PHMAXLEN + hdrlen);-	skb_reset_network_header(skb);-	top_iph = ip_hdr(skb);-	skb->transport_header += sizeof(*iph) - hdrlen;--	memmove(top_iph, iph, sizeof(*iph));-	if (unlikely(optlen)) {-		struct ip_beet_phdr *ph;--		BUG_ON(optlen < 0);--		ph = (struct ip_beet_phdr *)skb_transport_header(skb);-		ph->padlen = 4 - (optlen & 4);-		ph->hdrlen = optlen / 8;-		ph->nexthdr = top_iph->protocol;-		if (ph->padlen)-			memset(ph + 1, IPOPT_NOP, ph->padlen);--		top_iph->protocol = IPPROTO_BEETPH;-		top_iph->ihl = sizeof(struct iphdr) / 4;+	struct dst_entry *dst = skb->dst;+	struct iphdr *iphv4, *top_iphv4;+	int hdrlen;++	if (ip_hdr(skb)->version == 4) {+		int optlen;++		/* 4-4 */+		iphv4 = ip_hdr(skb);+		skb->transport_header = skb->network_header;++		hdrlen = 0;+		optlen = iphv4->ihl * 4 - sizeof(*iphv4);+		if (unlikely(optlen))+			hdrlen += IPV4_BEET_PHMAXLEN - (optlen & 4);++		skb_push(skb, x->props.header_len - IPV4_BEET_PHMAXLEN + hdrlen);+		skb_reset_network_header(skb);+		top_iphv4 = ip_hdr(skb);+		skb->transport_header += sizeof(*iphv4) - hdrlen;++		memmove(top_iphv4, iphv4, sizeof(*iphv4));+		if (unlikely(optlen)) {+			struct ip_beet_phdr *ph;++			BUG_ON(optlen < 0);++			ph = (struct ip_beet_phdr *)skb_transport_header(skb);+			ph->padlen = 4 - (optlen & 4);+			ph->hdrlen = optlen / 8;+			ph->nexthdr = iphv4->protocol;+			if (ph->padlen)+				memset(ph + 1, IPOPT_NOP, ph->padlen);++			top_iphv4->protocol = IPPROTO_BEETPH;+			top_iphv4->ihl = 5;+		}++		top_iphv4->saddr = x->props.saddr.a4;+		top_iphv4->daddr = x->id.daddr.a4;+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)+	} else if (ip_hdr(skb)->version == 6) {+		int delta = sizeof(struct ipv6hdr) - sizeof(struct iphdr);+		u8 protocol = ipv6_hdr(skb)->nexthdr;++		skb_set_transport_header(skb, sizeof(struct ipv6hdr));++		/* Inner = 6, Outer = 4 : changing the external IP hdr+		 * to the outer addresses+		 */+		hdrlen = x->props.header_len;++		skb_pull(skb, delta);+		skb_push(skb, hdrlen);++		skb_reset_network_header(skb);+		top_iphv4 = ip_hdr(skb);+		top_iphv4->ihl = 5;+		top_iphv4->version = 4;+		top_iphv4->id = 0;+		top_iphv4->frag_off = htons(IP_DF);+		top_iphv4->ttl = dst_metric(dst->child, RTAX_HOPLIMIT);+		top_iphv4->protocol = protocol;++		top_iphv4->saddr = x->props.saddr.a4;+		top_iphv4->daddr = x->id.daddr.a4;+		IPCB(skb)->flags = 0;+#endif 	} -	top_iph->saddr = x->props.saddr.a4;-	top_iph->daddr = x->id.daddr.a4;-+	skb->protocol = htons(ETH_P_IP);+	memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); 	return 0; }  static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb) { 	struct iphdr *iph = ip_hdr(skb);+	int hops = iph->ttl; 	int phlen = 0; 	int optlen = 0;-	u8 ph_nexthdr = 0;+	__u8 protocol = 0; 	int err = -EINVAL; -	if (unlikely(iph->protocol == IPPROTO_BEETPH)) {-		struct ip_beet_phdr *ph;+	protocol = iph->protocol;+	if (x->sel.family == AF_INET) {+		if (unlikely(protocol == IPPROTO_BEETPH)) {+			struct ip_beet_phdr *ph;++			if (!pskb_may_pull(skb, sizeof(*ph)))+				goto out;++			ph = (struct ip_beet_phdr *)(ipip_hdr(skb) + 1);++			phlen = sizeof(*ph) + ph->padlen;+			optlen = ph->hdrlen * 8 + (IPV4_BEET_PHMAXLEN - phlen);+			if (optlen < 0 || optlen & 3 || optlen > 250)+				goto out;++			if (!pskb_may_pull(skb, phlen + optlen))+				goto out;++			protocol = ph->nexthdr;+		}++		skb_push(skb, sizeof(*iph) - phlen);+		skb_reset_network_header(skb);+		memmove(skb_network_header(skb), iph, sizeof(*iph));++		iph = ip_hdr(skb);+		iph->ihl = (sizeof(*iph) + optlen) / 4;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -