aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ip_options.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/ip_options.c')
-rw-r--r--net/ipv4/ip_options.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index f906a80d5a87..251346828cb4 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -40,7 +40,7 @@
40void ip_options_build(struct sk_buff * skb, struct ip_options * opt, 40void ip_options_build(struct sk_buff * skb, struct ip_options * opt,
41 __be32 daddr, struct rtable *rt, int is_frag) 41 __be32 daddr, struct rtable *rt, int is_frag)
42{ 42{
43 unsigned char * iph = skb->nh.raw; 43 unsigned char *iph = skb_network_header(skb);
44 44
45 memcpy(&(IPCB(skb)->opt), opt, sizeof(struct ip_options)); 45 memcpy(&(IPCB(skb)->opt), opt, sizeof(struct ip_options));
46 memcpy(iph+sizeof(struct iphdr), opt->__data, opt->optlen); 46 memcpy(iph+sizeof(struct iphdr), opt->__data, opt->optlen);
@@ -104,13 +104,13 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb)
104 return 0; 104 return 0;
105 } 105 }
106 106
107 sptr = skb->nh.raw; 107 sptr = skb_network_header(skb);
108 dptr = dopt->__data; 108 dptr = dopt->__data;
109 109
110 if (skb->dst) 110 if (skb->dst)
111 daddr = ((struct rtable*)skb->dst)->rt_spec_dst; 111 daddr = ((struct rtable*)skb->dst)->rt_spec_dst;
112 else 112 else
113 daddr = skb->nh.iph->daddr; 113 daddr = ip_hdr(skb)->daddr;
114 114
115 if (sopt->rr) { 115 if (sopt->rr) {
116 optlen = sptr[sopt->rr+1]; 116 optlen = sptr[sopt->rr+1];
@@ -180,7 +180,8 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb)
180 /* 180 /*
181 * RFC1812 requires to fix illegal source routes. 181 * RFC1812 requires to fix illegal source routes.
182 */ 182 */
183 if (memcmp(&skb->nh.iph->saddr, &start[soffset+3], 4) == 0) 183 if (memcmp(&ip_hdr(skb)->saddr,
184 &start[soffset + 3], 4) == 0)
184 doffset -= 4; 185 doffset -= 4;
185 } 186 }
186 if (doffset > 3) { 187 if (doffset > 3) {
@@ -217,7 +218,7 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb)
217 218
218void ip_options_fragment(struct sk_buff * skb) 219void ip_options_fragment(struct sk_buff * skb)
219{ 220{
220 unsigned char * optptr = skb->nh.raw + sizeof(struct iphdr); 221 unsigned char *optptr = skb_network_header(skb) + sizeof(struct iphdr);
221 struct ip_options * opt = &(IPCB(skb)->opt); 222 struct ip_options * opt = &(IPCB(skb)->opt);
222 int l = opt->optlen; 223 int l = opt->optlen;
223 int optlen; 224 int optlen;
@@ -264,12 +265,13 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb)
264 265
265 if (!opt) { 266 if (!opt) {
266 opt = &(IPCB(skb)->opt); 267 opt = &(IPCB(skb)->opt);
267 iph = skb->nh.raw; 268 iph = skb_network_header(skb);
268 opt->optlen = ((struct iphdr *)iph)->ihl*4 - sizeof(struct iphdr); 269 opt->optlen = ((struct iphdr *)iph)->ihl*4 - sizeof(struct iphdr);
269 optptr = iph + sizeof(struct iphdr); 270 optptr = iph + sizeof(struct iphdr);
270 opt->is_data = 0; 271 opt->is_data = 0;
271 } else { 272 } else {
272 optptr = opt->is_data ? opt->__data : (unsigned char*)&(skb->nh.iph[1]); 273 optptr = opt->is_data ? opt->__data :
274 (unsigned char *)&(ip_hdr(skb)[1]);
273 iph = optptr - sizeof(struct iphdr); 275 iph = optptr - sizeof(struct iphdr);
274 } 276 }
275 277
@@ -563,7 +565,7 @@ void ip_forward_options(struct sk_buff *skb)
563 struct ip_options * opt = &(IPCB(skb)->opt); 565 struct ip_options * opt = &(IPCB(skb)->opt);
564 unsigned char * optptr; 566 unsigned char * optptr;
565 struct rtable *rt = (struct rtable*)skb->dst; 567 struct rtable *rt = (struct rtable*)skb->dst;
566 unsigned char *raw = skb->nh.raw; 568 unsigned char *raw = skb_network_header(skb);
567 569
568 if (opt->rr_needaddr) { 570 if (opt->rr_needaddr) {
569 optptr = (unsigned char *)raw + opt->rr; 571 optptr = (unsigned char *)raw + opt->rr;
@@ -587,7 +589,7 @@ void ip_forward_options(struct sk_buff *skb)
587 if (srrptr + 3 <= srrspace) { 589 if (srrptr + 3 <= srrspace) {
588 opt->is_changed = 1; 590 opt->is_changed = 1;
589 ip_rt_get_source(&optptr[srrptr-1], rt); 591 ip_rt_get_source(&optptr[srrptr-1], rt);
590 skb->nh.iph->daddr = rt->rt_dst; 592 ip_hdr(skb)->daddr = rt->rt_dst;
591 optptr[2] = srrptr+4; 593 optptr[2] = srrptr+4;
592 } else if (net_ratelimit()) 594 } else if (net_ratelimit())
593 printk(KERN_CRIT "ip_forward(): Argh! Destination lost!\n"); 595 printk(KERN_CRIT "ip_forward(): Argh! Destination lost!\n");
@@ -599,7 +601,7 @@ void ip_forward_options(struct sk_buff *skb)
599 } 601 }
600 if (opt->is_changed) { 602 if (opt->is_changed) {
601 opt->is_changed = 0; 603 opt->is_changed = 0;
602 ip_send_check(skb->nh.iph); 604 ip_send_check(ip_hdr(skb));
603 } 605 }
604} 606}
605 607
@@ -608,8 +610,8 @@ int ip_options_rcv_srr(struct sk_buff *skb)
608 struct ip_options *opt = &(IPCB(skb)->opt); 610 struct ip_options *opt = &(IPCB(skb)->opt);
609 int srrspace, srrptr; 611 int srrspace, srrptr;
610 __be32 nexthop; 612 __be32 nexthop;
611 struct iphdr *iph = skb->nh.iph; 613 struct iphdr *iph = ip_hdr(skb);
612 unsigned char * optptr = skb->nh.raw + opt->srr; 614 unsigned char *optptr = skb_network_header(skb) + opt->srr;
613 struct rtable *rt = (struct rtable*)skb->dst; 615 struct rtable *rt = (struct rtable*)skb->dst;
614 struct rtable *rt2; 616 struct rtable *rt2;
615 int err; 617 int err;