struct rtable

int ip_rt_ioctl(unsigned int cmd, void *arg),这个函数会根据传入的cmd是SIOCADDRT,还是SIOCDELRT,来决定是创建一个路由表项,还是删除一个路由表项。

对于创建路由表项,系统着会再调用rt_new来继续工作

rt_new函数会对我们传入的参数进行判断,看是否符合创建路由表项的条件。

首先,函数先从传入的rt.rt_dev来判断要创建路由表项的设备是否存在,如果不存在则退出,因为创建一个路由表项,其实就是要对路由表项结构体的各个成员进行赋值的,其结构体如下

struct rtable

{

       struct rtable           *rt_next;/*指向下一个rtable表项 */

       unsigned long        rt_dst;/*目的IP地址*/

       unsigned long        rt_mask;/*子网掩码*/

       unsigned long        rt_gateway;/*网关地址 */

       unsigned char         rt_flags;/*标志位*/

       unsigned char         rt_metric;/*度量值(代价值*/

       short                     rt_refcnt;/*使用计数*/

       unsigned long        rt_use;/*被使用标志 */

       unsigned short        rt_mss;/*MSS值*/

       unsigned long        rt_window;/*窗口大小 */

       struct device          *rt_dev;/*与该路由项绑定的接口*/

};

其中关键的字段包括rt_dst,rt_mask,rt_gateway,rt_flags,rt_dev。

rt_dev即是跟路由器相连的本地网卡了,我们要发送IP包,如果目的IP不是在本地子网内,就需要把数据通过路由器转发出去了,如果找不到本地接口设备,则表明要发送数据的媒介都没有了,那如何发送,因此,也不需要创建路由表项了。

接着对从用户端传入的参数进行整理,主要是对rt_flags,rt_dst,rt_mask,rt_gateway这几个参数进行整理,接着就调用ip_rt_add函数,创建一个路由表项,填充各成员,并把表项插入到由rt_base管理的指针。

 

当IP协议要发送一个数据包时,会判断是否找到了目标地址所对应MAC,如果没有找到,则会根据数据包的localroute属性,来判断数据包是要发往本地子网的,还是发往外网的,从而决定是调用ip_rt_local函数,还是调用ip_rt_route,要发往外网,则需要把数据发送到网关,由网关转发,此时就要用到路由器了。由于我们设置的默认网关的目的地址是0.0.0.0,因此,任何一个往外网发送的数据包,经过路由表项目的地址跟目的地址异或后,再跟本地子网相与,都得到0值,因此,发往外网的数据包,如果没有找到其他路由时,最终都会从默认网关发出,ip_rt_local函数返回的设备是本地设备,但是其中包含了网关的IP地址(默认网关是被排列在rt_base指针链表的最后一项)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值