免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1950 | 回复: 8
打印 上一主题 下一主题

ICMP的校验和 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-11 12:27 |只看该作者 |倒序浏览
这个校验和在TCP/IP Illustrated的Volume I中有如下说法:
The checksum field covers the entire ICMP message. The algorithm used is the same as we described for the IP header checksum in Section 3.2. The ICMP checksum is required.


但我测试TAP时用户进程中虚拟出TAP所在网段的ARP和ICMP简单支持时发现写到TAP的ICMP Echo Reply中这个校验和可以是任意值,ping都能正确地收到响应报文。是Linux协议栈不处理这个校验和?


另外顺便问一个问题:这个校验和计算有没有标准的库函数?

论坛徽章:
0
2 [报告]
发表于 2009-04-11 15:16 |只看该作者
通过 write 直接发给 TAP 设备好像不经过协议栈了吧?只当做一个你自己构造的帧而已
而对端能否回应你的 request,就要看对端是否验证 checksum 了

论坛徽章:
0
3 [报告]
发表于 2009-04-11 20:37 |只看该作者
原帖由 platinum 于 2009-4-11 15:16 发表
通过 write 直接发给 TAP 设备好像不经过协议栈了吧?只当做一个你自己构造的帧而已
而对端能否回应你的 request,就要看对端是否验证 checksum 了


write写TAP当然经常协议栈了,否则我的ping怎么可能收到响应?ping是通过标准的协议栈来传数据的,如果没有过协议栈,数据也就不可能回给它了。
忘了我们有一个板子很容易直接处理以太网包,可以用它回一个校验和不对的,分别测试一下Windows和Linux看能否收到ping的响应。

论坛徽章:
0
4 [报告]
发表于 2009-04-11 21:09 |只看该作者
自己测试了一下,发现校验和不对时在Windows下虽然能抓到包,但ping返回超时,应该是协议栈进行了校验并把包丢掉了,而Linux下却没可以ping通。FreeBSD暂时没来得及测试。

看来应该是协议栈实现上的行为了,也不知道哪个算是标准的。

论坛徽章:
0
5 [报告]
发表于 2009-04-11 23:29 |只看该作者
原帖由 Cyberman.Wu 于 2009-4-11 20:37 发表


write写TAP当然经常协议栈了,否则我的ping怎么可能收到响应?ping是通过标准的协议栈来传数据的,如果没有过协议栈,数据也就不可能回给它了。
忘了我们有一个板子很容易直接处理以太网包,可以用它回一个 ...

我是说,出去的包不经过协议栈,只是构造一个 frame 然后发出去了而已,经过协议栈处理的是两边 C/S 的事情,和 TAP 设备无关,和 write 方法无关

论坛徽章:
0
6 [报告]
发表于 2009-04-11 23:57 |只看该作者
好像网卡有自动算检验和的功能。记不太清了

论坛徽章:
0
7 [报告]
发表于 2009-04-12 01:59 |只看该作者
原帖由 emmoblin 于 2009-4-11 23:57 发表
好像网卡有自动算检验和的功能。记不太清了

网卡有 GSO、TFO、UFO,但没有针对 ICMP 协议的 “IFO”

论坛徽章:
0
8 [报告]
发表于 2009-04-12 18:36 |只看该作者
原帖由 platinum 于 2009-4-11 23:29 发表

我是说,出去的包不经过协议栈,只是构造一个 frame 然后发出去了而已,经过协议栈处理的是两边 C/S 的事情,和 TAP 设备无关,和 write 方法无关


我确定的是数据包是经过协议栈的,这个还是能判断出来的。另外你看我前面写的帖子,从测试结果看Linux协议栈确实不校验ICMP,而Windows会。

论坛徽章:
0
9 [报告]
发表于 2009-04-12 22:15 |只看该作者

回复 #1 Cyberman.Wu 的帖子

好像是没有进行这个工作,相信IP了:
/*
*        Deal with incoming ICMP packets.
*/
int icmp_rcv(struct sk_buff *skb)
{
        struct icmphdr *icmph;
        struct rtable *rt = (struct rtable *)skb->dst;

        ICMP_INC_STATS_BH(ICMP_MIB_INMSGS);

        switch (skb->ip_summed) {
        case CHECKSUM_HW:
                if (!(u16)csum_fold(skb->csum))
                        break;
                NETDEBUG(if (net_ratelimit())
                                printk(KERN_DEBUG "icmp v4 hw csum failure\n"));
        case CHECKSUM_NONE:
                if ((u16)csum_fold(skb_checksum(skb, 0, skb->len, 0)))
                        goto error;
        default:;
        }
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP