函数原型: void ip_forward(struct mbuf *m, int srcrt)
参数说明: m指向所要转发的ip分组, srcrt标识该函数是否是由于分组中标识了源路由选项而被调用的
当ip 分组到达的系统不是分组的最终目的地址时, ip_input将调用ip_forward(m, 0)函数转发分组;或者如果在选项处理时发现选项标识了源路由,并且分组还没到达最终目的地时,则选项处理函数会调用ip_forward(m, 1)转发分组.下面讨论一下ip_forward()函数的具体处理过程:
(1)判断分组是否适合被转发.以下分组不能被转发:1.链路层广播的分组;2.环回分组;3.全0;4.E类;5.D类(D类地址应该由多播函数ip_mforward()来处理,而不是由ip_forward()处理).
通过判断m所指向的mbuf的首部中M_BCAST标志是否被设定,判断该分组是否为链路层广播分组;
通过调用in_canforward(ip->dest)来判断2345类情况
(2)检查ip分组的ttl是否为1,如果为1,则停止转发,并调用icmp_error()向源地址发送icmp超时报文
(3) 查看"转发高速路由缓存"ipforward_rt, 如果高速缓存为空,或者高速缓存所存储的路由表项所标识的目的地址不是分组所要到达的目的地址,则清空高速缓存,将分组的目的地址存放在高速缓存中,调用 rtalloc(&ipforward_rt)函数查找路由表,为当前分组的目的地址(key)寻找一个新路由,并通过新路由定位下一跳的目的地址.
高速路由缓存ipforward_rt的数据结构如下:
struct route
{
struct rtentry *ro_rt; //指向到目的地址ro_dst的路由项
struct sockaddr ro_dst;
}
(4)在启动发送前,ip_forward有两件事情必须完成:一是备份ip分组的前64个字节以备发送icmp出错报文;二是判断是否系统是否需要发送icmp重定向报文.系统是否发送icmp重定向报文的规则较为复杂.另外说明.
(5)调用ip_output()函数发送分组,如果发送成功,ip_output返回0,否则,返回差错值error.
(6)根据ip_output()的返回值判断是否需要发送icmp差错报告报文.
参数说明: m指向所要转发的ip分组, srcrt标识该函数是否是由于分组中标识了源路由选项而被调用的
当ip 分组到达的系统不是分组的最终目的地址时, ip_input将调用ip_forward(m, 0)函数转发分组;或者如果在选项处理时发现选项标识了源路由,并且分组还没到达最终目的地时,则选项处理函数会调用ip_forward(m, 1)转发分组.下面讨论一下ip_forward()函数的具体处理过程:
(1)判断分组是否适合被转发.以下分组不能被转发:1.链路层广播的分组;2.环回分组;3.全0;4.E类;5.D类(D类地址应该由多播函数ip_mforward()来处理,而不是由ip_forward()处理).
通过判断m所指向的mbuf的首部中M_BCAST标志是否被设定,判断该分组是否为链路层广播分组;
通过调用in_canforward(ip->dest)来判断2345类情况
(2)检查ip分组的ttl是否为1,如果为1,则停止转发,并调用icmp_error()向源地址发送icmp超时报文
(3) 查看"转发高速路由缓存"ipforward_rt, 如果高速缓存为空,或者高速缓存所存储的路由表项所标识的目的地址不是分组所要到达的目的地址,则清空高速缓存,将分组的目的地址存放在高速缓存中,调用 rtalloc(&ipforward_rt)函数查找路由表,为当前分组的目的地址(key)寻找一个新路由,并通过新路由定位下一跳的目的地址.
高速路由缓存ipforward_rt的数据结构如下:
struct route
{
struct rtentry *ro_rt; //指向到目的地址ro_dst的路由项
struct sockaddr ro_dst;
}
(4)在启动发送前,ip_forward有两件事情必须完成:一是备份ip分组的前64个字节以备发送icmp出错报文;二是判断是否系统是否需要发送icmp重定向报文.系统是否发送icmp重定向报文的规则较为复杂.另外说明.
(5)调用ip_output()函数发送分组,如果发送成功,ip_output返回0,否则,返回差错值error.
(6)根据ip_output()的返回值判断是否需要发送icmp差错报告报文.