加入收藏 | 设为首页 | 会员中心 | 我要投稿 PHP编程网 - 黄冈站长网 (http://www.0713zz.com/)- 数据应用、建站、人体识别、智能机器人、语音技术!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

Linux内核分析 - 网络[十一]:ICMP模块

发布时间:2016-10-16 06:06:59 所属栏目:Linux 来源:站长网
导读:副标题#e# 内核版本:2.6.34 ICMP模块比较简单,要注意的是icmp的速率限制策略,向IP层传输数据ip_append_data()和 ip_push_pending_frames()。 在net/ipv4/af_inet.c中的inet_init()注册icmp协议,从这里也可以看出,ICMP模块是绑 定在IP模块之上的。inet_

skb_reserve()保留skb头的hh_len大小,skb_put()扩展skb大小到fraglen,然后设置network_header和 transport_header指向skb的正确位置,data指向ICMP报头的位置,具体可以看下面的图示:

skb_reserve(skb, 

hh_len);     
……     
data = skb_put(skb, fraglen);     
skb_set_network_header(skb, exthdrlen);     
skb->transport_header = (skb->network_header + fragheaderlen);     
data += fragheaderlen;

Linux内核分析 - 网络[十一]:ICMP模块

copy是要拷贝的长度,为传输层报头后的内容大小。getfrag()函数实现数据的拷贝,在icmp模块中, getfrag()指向icmp_glue_bits()函数,它从[from] + offset处拷贝copy个字节到data + transhdrlen处。

copy = 

datalen - transhdrlen - fraggap;     
if (copy > 0 && getfrag(from, data + transhdrlen, offset, copy, fraggap, skb) < 0) {     
 err = -EFAULT;     
 kfree_skb(skb);     
 goto error;     
}

偏移offset加上已经拷贝的字节数copy,fraggap=0,length减去的就是IP报文内容长度,由于报文才56字节,一个 分片足够,所以length=0,然后把新生成的skb放入sk->sk_write_queue中,然后执行下次while循环。各参数值:copy=42, offset=42, length=0, 更新transhdrlen=0。

offset += copy;     
length -= datalen - fraggap;     
transhdrlen = 0;     
……     
__skb_queue_tail(&sk->sk_write_queue, skb);     
continue;

while循环判断条件是length > 0,因此跳出循环,完成了向IP层发送的数据生成,结果如下,注意, ICMP报头还是没有填写的:

Linux内核分析 - 网络[十一]:ICMP模块

example 2:600 Byte echo 报文[假设MTU=520]

(编辑:PHP编程网 - 黄冈站长网)

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

热点阅读