patch-2.1.68 linux/net/ipv4/ip_options.c

Next file: linux/net/ipv4/ip_output.c
Previous file: linux/net/ipv4/ip_nat_dumb.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.67/linux/net/ipv4/ip_options.c linux/net/ipv4/ip_options.c
@@ -5,6 +5,8 @@
  *
  *		The options processing module for ip.c
  *
+ * Version:	$Id: ip_options.c,v 1.12 1997/10/10 22:41:08 davem Exp $
+ *
  * Authors:	A.N.Kuznetsov
  *		
  */
@@ -15,10 +17,10 @@
 #include <linux/ip.h>
 #include <linux/icmp.h>
 #include <linux/netdevice.h>
+#include <linux/rtnetlink.h>
 #include <net/sock.h>
 #include <net/ip.h>
 #include <net/icmp.h>
-#include <linux/net_alias.h>
 
 /* 
  * Write options to IP header, record destination address to
@@ -32,7 +34,7 @@
  */
 
 void ip_options_build(struct sk_buff * skb, struct ip_options * opt,
-			    u32 daddr, u32 saddr, int is_frag) 
+			    u32 daddr, struct rtable *rt, int is_frag) 
 {
 	unsigned char * iph = skb->nh.raw;
 
@@ -46,9 +48,9 @@
 
 	if (!is_frag) {
 		if (opt->rr_needaddr)
-			memcpy(iph+opt->rr+iph[opt->rr+2]-5, &saddr, 4);
+			ip_rt_get_source(iph+opt->rr+iph[opt->rr+2]-5, rt);
 		if (opt->ts_needaddr)
-			memcpy(iph+opt->ts+iph[opt->ts+2]-9, &saddr, 4);
+			ip_rt_get_source(iph+opt->ts+iph[opt->ts+2]-9, rt);
 		if (opt->ts_needtime) {
 			struct timeval tv;
 			__u32 midtime;
@@ -147,7 +149,7 @@
 			if (((struct timestamp*)(dptr+1))->flags == IPOPT_TS_PRESPEC) {
 				__u32 addr;
 				memcpy(&addr, sptr+soffset-9, 4);
-				if (__ip_chk_addr(addr) == 0) {
+				if (inet_addr_type(addr) == RTN_UNICAST) {
 					dopt->ts_needtime = 0;
 					dopt->ts_needaddr = 0;
 					soffset -= 8;
@@ -248,6 +250,7 @@
 	unsigned char * optptr;
 	int optlen;
 	unsigned char * pp_ptr = NULL;
+	struct rtable *rt = skb ? (struct rtable*)skb->dst : NULL;
 
 	if (!opt) {
 		opt = &(IPCB(skb)->opt);
@@ -328,7 +331,7 @@
 					goto error;
 				}
 				if (skb) {
-					memcpy(&optptr[optptr[2]-1], &skb->dev->pa_addr, 4);
+					memcpy(&optptr[optptr[2]-1], &rt->rt_spec_dst, 4);
 					opt->is_changed = 1;
 				}
 				optptr[2] += 4;
@@ -371,7 +374,7 @@
 					}
 					opt->ts = optptr - iph;
 					if (skb) {
-						memcpy(&optptr[ts->ptr-1], &skb->dev->pa_addr, 4);
+						memcpy(&optptr[ts->ptr-1], &rt->rt_spec_dst, 4);
 						timeptr = (__u32*)&optptr[ts->ptr+3];
 					}
 					opt->ts_needaddr = 1;
@@ -387,7 +390,7 @@
 					{
 						u32 addr;
 						memcpy(&addr, &optptr[ts->ptr-1], 4);
-						if (__ip_chk_addr(addr) == 0)
+						if (inet_addr_type(addr) == RTN_UNICAST)
 							break;
 						if (skb)
 							timeptr = (__u32*)&optptr[ts->ptr+3];
@@ -521,7 +524,7 @@
 
 	if (opt->rr_needaddr) {
 		optptr = (unsigned char *)raw + opt->rr;
-		memcpy(&optptr[optptr[2]-5], &rt->u.dst.dev->pa_addr, 4);
+		ip_rt_get_source(&optptr[optptr[2]-5], rt);
 		opt->is_changed = 1;
 	}
 	if (opt->srr_is_hit) {
@@ -540,20 +543,20 @@
 		}
 		if (srrptr + 3 <= srrspace) {
 			opt->is_changed = 1;
-			memcpy(&optptr[srrptr-1], &rt->u.dst.dev->pa_addr, 4);
+			ip_rt_get_source(&optptr[srrptr-1], rt);
 			skb->nh.iph->daddr = rt->rt_dst;
 			optptr[2] = srrptr+4;
 		} else
 			printk(KERN_CRIT "ip_forward(): Argh! Destination lost!\n");
 		if (opt->ts_needaddr) {
 			optptr = raw + opt->ts;
-			memcpy(&optptr[optptr[2]-9], &rt->u.dst.dev->pa_addr, 4);
+			ip_rt_get_source(&optptr[optptr[2]-9], rt);
 			opt->is_changed = 1;
 		}
-		if (opt->is_changed) {
-			opt->is_changed = 0;
-			ip_send_check(skb->nh.iph);
-		}
+	}
+	if (opt->is_changed) {
+		opt->is_changed = 0;
+		ip_send_check(skb->nh.iph);
 	}
 }
 
@@ -571,16 +574,16 @@
 	if (!opt->srr)
 		return 0;
 
-	if (rt->rt_flags&(RTF_BROADCAST|RTF_MULTICAST|RTF_NAT)
-	    || skb->pkt_type != PACKET_HOST)
+	if (skb->pkt_type != PACKET_HOST)
 		return -EINVAL;
-
-	if (!(rt->rt_flags & RTF_LOCAL)) {
+	if (rt->rt_type == RTN_UNICAST) {
 		if (!opt->is_strictroute)
 			return 0;
 		icmp_send(skb, ICMP_PARAMETERPROB, 0, 16);
 		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) {
@@ -591,16 +594,15 @@
 
 		rt = (struct rtable*)skb->dst;
 		skb->dst = NULL;
-		err = ip_route_input(skb, nexthop, iph->saddr, iph->tos,
-				     net_alias_main_dev(skb->dev));
+		err = ip_route_input(skb, nexthop, iph->saddr, iph->tos, skb->dev);
 		rt2 = (struct rtable*)skb->dst;
-		if (err || rt2->rt_flags&(RTF_BROADCAST|RTF_MULTICAST|RTF_NAT)) {
+		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_flags&RTF_LOCAL))
+		if (rt2->rt_type != RTN_LOCAL)
 			break;
 		/* Superfast 8) loopback forward */
 		memcpy(&iph->daddr, &optptr[srrptr-1], 4);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov