转:http://blog.csdn.net/nerdx/article/details/12495445
-
-
-
-
-
-
-
-
-
-
-
-
1.1 int ip_options_rcv_srr(struct sk_buff *skb)
-
{
-
struct ip_options *opt = &(IPCB(skb)->opt);
-
int srrspace, srrptr;
-
u32 nexthop;
-
struct iphdr *iph = skb->nh.iph;
-
unsigned char * optptr = skb->nh.raw + 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;
-
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;
-
}
-
阅读(711) | 评论(0) | 转发(0) |