加入收藏 | 设为首页 | 会员中心 | 我要投稿 三明站长网 (https://www.0598zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

Linux内核分析 - 网络[十四]:IP选项

发布时间:2016-09-28 22:37:56 所属栏目:Linux 来源:站长网
导读:副标题#e# 内核版本:2.6.34 在发送报文时,可以调用函数setsockopt()来设置相应的选项,本文主要分析IP选项的生成,发送以及 接收所执行的流程,选取了LSRR为例子进行说明,主要分为选项的生成、选项的转发、选项的接收三部分。 先看一个源站路 由选项的例

从LSRR选项中取出下一跳地址,记录到nexthop中,并查询路由表从saddr到nexthop的路由项,记录 到skb中。如果没有这样的路由项,则返回错误;如果有这样的路由项且不是本机(如果下一跳是本机,则表示报文到达目的主机 了),则break跳出循环;如果下一跳就是本机,则拷贝下一跳地址到iph->daddr中。

需要注意的是这里重新查找了一次路 由表(ip_route_input)。而我们知道,在IP层会查找路由表(ip_rcv_finish函数中),它决定报文是否该被接收还是该被转发。 而这里重查一次路由表也是源站选项的意义所在,IP报头中的目的地址并不是最终地址,它只决定路径中的一站,真正的目的地 由选项中的值决定,因此需要根据选项中的值作为目的地址再查找一次,以便决定接下来的动作,用查找到的路由项rt2作为报 文skb的路由项。

for (srrptr=optptr[2], srrspace = optptr[1]; srrptr <= srrspace; srrptr += 4) {     
 memcpy(&nexthop, &optptr[srrptr-1], 4);     
         
 rt = skb_rtable(skb);     
 skb_dst_set(skb, NULL);     
 err = ip_route_input(skb, nexthop, iph->saddr, iph->tos, skb->dev);     
 rt2 = skb_rtable(skb);     
 if (err || (rt2->rt_type != RTN_UNICAST && rt2->rt_type != RTN_LOCAL)) {     
  ip_rt_put(rt2);     
  skb_dst_set(skb, &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;     
}

(编辑:三明站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读