0004-如何计算IP报头的checksum
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
如何计算IP报头的checksum
written by whowin
如果你研究过TCP/IP协议,那么你肯定知道IP报头中的checksum字段,或许你还曾经为如何计算这个字段的值所困扰,本⽂我们将讨论checksum的概念,并详细介绍IP报头中的checksum是如何计算的。
1. checksum是什么?
简单地说,checksum就是从数据包中计算出来的⼀个值,⽤于检查数据包完整性;通过检查checksum来判断收到的数据是否有错误;
数据在⽹络上传输时,由于各种原因数据包有可能损坏,所以在接收端必须要有⼀种⽅法来判断数据是否已经损坏,为此,在报头中加⼊checksum字段;
在发送端要按照规定的算法计算checksum并将其设置为报头中的⼀个字段中;在接收端,要使⽤同样的算法重新计算checksum,并与收到的报头中的checksum进⾏交叉校验,以确定数据包是否正常。
2. IP报头中的checksum
IP报头的checksum仅⽤于验证IP报头是否正确,所以仅需在IP报头上计算即可,与IP报头后⾯数据⽆关,因为IP报头后⾯的数据(⽐如UDP、TCP、ICMP等)通常都有⾃⼰的checksum;
计算IP报头的checksum当然要了解IP协议的基本报头结构,下⾯是IP报头的基本格式:
图1:IP报头的基本格式
更好地理解IP报头各字段的含义,可以参考我的另⼀篇⽂章《Linux下如何在数据链路层接收原始数据包》或者参考IP Protocol Header Fundamentals Explained with Diagrams;
仅就算法⽽⾔,IP报头的checksum定义为:IP报头中所有16-bit字的反码之和;也就是说把IP报头按照16-bit 字分割,然后把它们逐⼀相加,要求相加的结果仍为16-bit字,如果出现溢出(结果超出16-bit字),则丢弃溢出并把结果加1,全部16-bit字相加完成的结果再求反码,其结果就是checksum;
上⾯的计算⽅法是在报⽂的发送端完成的;在接收端⾸先要将IP报头中的checksum字段清0,然后⽤与发送端相同的⽅法计算,得到的值与收到的IP报头中的checksum字段⽐较,如果⼀样,则表⽰IP报头完好,否则认为IP报头已经损坏;
实际在发送端的做法是:将IP报头按照16-bit字分割,然后把它们逐⼀相加(包括收到的checksum字段),其结果如果为全1(0XFFFF),则表⽰IP报头完好,否则认为IP报头已经损坏。
3. IP报头checksum实例
对于IP报头的checksum,我们现在已经有了⾜够的理论知识,下⾯我们⽤⼀个实例实际做⼀下计算;
假定下⾯使我们收到的IP报头(按16进制)
4500 003c 1c46 4000 4006 b1e6 ac10 0a63 ac10 0a0c
我们先来看看这些数字与IP报头中各个字段的对应关系(请参考图1)
'45'对应报头中的前两个字段,'4'对应Version字段,'5'对应Header Length字段,因为Header Length
的单位是4字节,所以报头的实际⻓度是5x4=20字节;
'00'对应报头中的Service Type字段,这个字段通常不使⽤,'00'表⽰普通正常服务;
'003c'对应报头中的Total Length字段,这个字段的含义是IP报⽂的总⻓度,所以这个IP数据报的⻓度为60字节;
'1c46'对应报头中的Identification字段,这个字段是IP报⽂的⼀个唯⼀标识符;
'4000'需要分成两部分,bit0-2对应报头中的Flags,bit3-15对应Fragment Offset字段;
‘4006’可分为‘40’和‘06’两个字节,第⼀个字节‘40’对应TTL字段,字节‘06’对应IP报头中的Protocol字
段,‘06’表⽰协议是TCP;
‘be16’对应报头中的checksum字段,这个值是在发送端设置的checksum;如前所述,在接收端计算
checksum时,该字段将设置为零;
'ac10 0a63'对应IP报头中的Source IP Address,也就是源IP地址,相当于IP地址:172.16.10.99
'ac10 0a0c'对应IP报头中的Destination IP Address,也就是⽬的IP地址,相当于IP地址:172.16.10.12现在我们已经搞清楚了这些数字与IP报头各个字段的对应关系,我们先把这些16进制的数字转换成⼆进制
4500 -> 0100 0101 0000 0000
003c -> 0000 0000 0011 1100
1c46 -> 0001 1100 0100 0110
4000 -> 0100 0000 0000 0000
4006 -> 0100 0000 0000 0110
0000 -> 0000 0000 0000 0000 // clear checksum field
ac10 -> 1010 1100 0001 0000
0a63 -> 0000 1010 0110 0011
ac10 -> 1010 1100 0001 0000
0a0c -> 0000 1010 0000 1100
我们把这些⼆进制数注意相加
4500 -> 0100 0101 0000 0000
003c -> 0000 0000 0011 1100
453C -> 0100 0101 0011 1100 // First result
453C -> 0100 0101 0011 1100 // First result plus next 16-bit word.
1c46 -> 0001 1100 0100 0110
6182 -> 0110 0001 1000 0010 // Second result.。