转:http://blog.csdn.net/nerdx/article/details/12587459
-
-
-
-
-
-
-
-
-
-
1.1 int ip_forward(struct sk_buff *skb)
-
{
-
struct iphdr *iph;
-
struct rtable *rt;
-
struct ip_options * opt = &(IPCB(skb)->opt);
-
-
-
if (!xfrm4_policy_check(NULL, XFRM_POLICY_FWD, skb))
-
goto drop;
-
-
if (IPCB(skb)->opt.router_alert && ip_call_ra_chain(skb))
-
return NET_RX_SUCCESS;
-
-
if (skb->pkt_type != PACKET_HOST)
-
goto drop;
-
-
skb->ip_summed = CHECKSUM_NONE;
-
-
iph = skb->nh.iph;
-
-
if (iph->ttl <= 1)
-
goto too_many_hops;
-
-
if (!xfrm4_route_forward(skb))
-
goto drop;
-
-
iph = skb->nh.iph;
-
rt = (struct rtable*)skb->dst;
-
-
-
-
-
if (opt->is_strictroute && rt->rt_dst != rt->rt_gateway)
-
goto sr_failed;
-
-
if (skb_cow(skb, LL_RESERVED_SPACE(rt->u.dst.dev)+rt->u.dst.header_len))
-
goto drop;
-
iph = skb->nh.iph;
-
-
ip_decrease_ttl(iph);
-
-
if (rt->rt_flags&RTCF_DOREDIRECT && !opt->srr)
-
ip_rt_send_redirect(skb);
-
-
skb->priority = rt_tos2priority(iph->tos);
-
-
return NF_HOOK(PF_INET, NF_IP_FORWARD, skb, skb->dev, rt->u.dst.dev,
-
ip_forward_finish);
-
-
sr_failed:
-
-
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_SR_FAILED, 0);
-
goto drop;
-
-
too_many_hops:
-
icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0);
-
drop:
-
kfree_skb(skb);
-
return NET_RX_DROP;
-
}
-
-
-
-
-
1.2 static inline int ip_forward_finish(struct sk_buff *skb)
-
{
-
struct ip_options * opt = &(IPCB(skb)->opt);
-
-
IP_INC_STATS_BH(IPSTATS_MIB_OUTFORWDATAGRAMS);
-
-
if (unlikely(opt->optlen))
-
ip_forward_options(skb);
-
-
return dst_output(skb);
-
}
-
-
-
-
-
1.3 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->nh.raw;
-
-
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);
-
skb->nh.iph->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(skb->nh.iph);
-
}
-
}
-
阅读(393) | 评论(0) | 转发(0) |