全部博文(436)
分类: LINUX
2010-10-29 18:01:29
ICMP协议重定向报文
0 7 8 15 16 31
Icmp_type ICMP_REDIRECT |
Icmp_code 0-3 |
Icmp_cksum |
Icmp_gwaddr 优选路由器的IP地址 | ||
Icmp_ip Ip首部(包括选项)和原始IP数据报中开始的至少8个字节 |
重定向报文类型列表
代码值 |
类型描述 |
|
代码值 |
类型描述 |
0 |
对网络重定向报文 |
|
2 |
对网络和服务类型重定向报文 |
1 |
对主机重定向报文 |
|
3 |
对主机和服务类型重定向报文 |
/* Handle ICMP_REDIRECT. */ //处理ICMP_REDIRECT 完成icmp重定向
static void
icmp_redirect(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev)//类型5
{
struct iphdr *iph;
unsigned long ip;//
iph = (struct iphdr *) (icmph + 1);// iph指向icmph+1
ip = iph->daddr;//ip指向目标ip地址
switch(icmph->code & 7) {
case ICMP_REDIR_NET://当网络重定向时
#ifdef not_a_good_idea
rt_add((RTF_DYNAMIC | RTF_MODIFIED | RTF_GATEWAY),
ip, 0, icmph->un.gateway, dev);
break;
#endif
case ICMP_REDIR_HOST://当主机重定向时
rt_add((RTF_DYNAMIC | RTF_MODIFIED | RTF_HOST | RTF_GATEWAY),
ip, 0, icmph->un.gateway, dev);
break;
case ICMP_REDIR_NETTOS://当网络和服务类型重定向时
case ICMP_REDIR_HOSTTOS://当主机和服务类型重定向时
printk("ICMP: cannot handle TOS redirects yet!\n");//输出icmp协议不能处理服务条款尚未重定向
break;
default:
DPRINTF((DBG_ICMP, "ICMP: Unreach: CODE=%d\n",
(icmph->code & 7)));//若不是上述情况 输出DBG_ICMP 输出icmp:不可达到 code的值
break;
}
skb->sk = NULL;
kfree_skb(skb, FREE_READ);
}
功能:处理重定向报文。
1.若入参的len小于IP头结构的大小,转入FLUSHIT(4)。
2.如果这是一个router(未设成DUMB)并且在运行路由协议(IPFORWARD),调用DETDEBUG(ICMP redirect ignored),转入FLUSHIT(4)。
3.判断ICMP的CODE(低位3个bit):
A.REDIR-NET:以RTF_DYNAMIC | RTF_MODIFIED | RTF_GATEWAY为参数,调用增加路由函数,转入B
B.REDIR-HOST:调用NETDEBUG,指明是重定向;调用路由重定向函数,转出到4
C.REDIR-NETTOS和REDIR-HOSTTOS;调用NETDEBUG,指明不能处理TOS重定向,转出到4
D.其它类型:转出到4
4.FLUSHIT:以FREE-READ为参,释放skb结构。
小节:当路由发生错误的时候,不应该接受该数据报的路由器会向信源主机发送一个ICMP重定向,重定向报文中包含了到达所期望目的地的正确路由器或网关地址,另外,IP头加上数据报中第一个8位组说明问题,返回信源主机,帮助主机诊断处理报文过程中出现的错误。