- 论坛徽章:
- 13
|
*【wireshark默认关闭了IP checksum validation 】
现在很多网卡都能计算IP校验和了,所以IP协议栈就把校验值位段留空,等网卡发包时由它去填。
这样一来,wireshark干脆在后来的版本默认关闭了IP校验和的检测,它没办法检测,因为人家的校验和直到从网卡出去时,才被添上。
但debug时,最好还是打开wireshark这个功能,让它帮忙算算,因为IP checksum错误的后果还是很严重的,我昨天就是,papaya内核发出的ICMP ECHO REPLY,能被网线另一端的wireshark抓到,但ping程序就是收不到。
× echo reply 非常简单,把收到的echo包的type改成0 ,完璧归赵就行了。 另外就是从icmp层和ip层下去时,分别写入新的crc16的校验码。
* 【tcp的三次握手】
它希望小刚和小红都确认对方能听到自己。
【小刚说: 你听得到吗?】
(这句话传到小红的话筒里)
【小红说:我听得到,那你听得到我吗?】
(这句话传到小刚的话筒里) --注意,此时小刚知道对方能听到自己了。
【小刚说:我听得到你】
(这句话传到小红的话筒里) --此时,小红也知道对方能听到自己了。
【他们现在可以放心的聊天了】
我觉得TCP的三次握手,第一次是询问,第二次是(回答+询问),第三次是回答。
TCP协议的制定者应该希望从A --> B的传输顺利,从B --> A的传输也顺利。
什么叫“A --> B的传输顺利”,就是说:host A的网卡的发送功能得是好的;从A-->B一路上的路由得是好的;host B的网卡的接受功能得是好的。当然,A,B上运行的OS内核的TCP协议栈更要是好的。
反过来一样。
确认之后,就建立了一个所谓的"TCP连接"。如果不出意外,host A和host B通过这条连接发的包就能平安的抵达对方的协议栈了。
所谓意外,就是突然拔网线,路由器被雷击了,对方家里停电了等等。
* ethernet header,网卡物理帧的校验用的是CRC32,剩余的IP,UDP等等,用的都是16位校验。我这么长时间都以为物理帧用的也是16位校验的。
* 【crc16】
校验和算法是这样的,假如有0x4000,0x5000,0x6000,0x7000这4个数,我们算它的校验和。
第一步: 0x4000 + 0x5000 + 0x6000 + 0x7000 = 0x16000
我们用的是16位校验,所以超出的位,我们把它再累加到低16位上。
第二步: 0x6000 + 0x1 = 0x6001
校验和就是0x6001,如果第二步的结果仍旧溢出,我们再把溢出的位再加到低16位上,一直到结果在16位以内为止。
上面说的只是原理,具体操作时,最后还要取反,那只是一个数学的小技巧。参见wiki:
en.wikipedia.org/wiki/IPv4_header_checksum
顺便贴上papaya里的实现:
/* crc16 for big endian memory area*/
u16 crc16_compute_be(void *area, int len){
u16 *_area = area;
u32 sum = 0;
for(int i = 0; i < len/2; i++){
u16 field = ntohs(_area[i]);
sum += field;
}
struct{ u16 ax, carry; } *eax = (void *)∑
while(eax->carry){
sum = eax->ax + eax->carry;
}
return ~sum;
}
* 把变量当函数用的话,gcc不会报错。
----------main.c-----------
void main() { abc(); }
-------------------------
----------a.c-------------
int abc;
------------------------
gcc -o t t.c a.c -Wall
只有一句警告。
warning: implicit declaration of function ‘abc’
所以编译时还是把-Wno-implicit-function-declaration去掉为好。
* 机器加电后,RAM并不保证清零。
我开始是知道,但不知道“不清零”的程度这么大。一些bug,在虚拟机上测不出来,一到机器上就出来了,多出于此。
参见:forum.osdev.org/viewtopic.php?f=1&t=30477
* RFC里说,ip的identification字段是每个ip报文在生存时间内的唯一标识符。
但一些高速设备很快就会wrap。就典型的分片大小计算,16位的identification会把传输速度限制在6.7M。
所以后来有了更新,这个bit似乎已经遗弃了。
参见:crnetpackets.com/2015/08/29/a-short-story-about-the-ip-id-field/
|
|