IP数据报首部中:::>那种检查和算法对?还是我的方法不对?

oicqkill 2005-03-17 10:38:16
IP数据报首部中:::>那种检查和算法对?还是我的方法不对?

我用Sniffer抓了IP包输出来, 输出信息见最后, 在输出的过程中为他的校验和作验算, 可是却发现无论如何和他以前的不一样,到底为什么?

// 检查和的计算
// size = 字节数
USHORT checksum(USHORT *buffer, int size)
{
unsigned long cksum = 0;
while(size > 1)
{
cksum += *buffer++;
size -= sizeof(USHORT);
}

// 如果还剩一个字节, 就需要补0
if(size)
cksum += *(UCHAR*)buffer;

cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >> 16);
return (USHORT)(~cksum);
}
/*
书上的如下: nWords 是字数
*/
short cksum( unsigned short *buf, int nWords )
{
unsigned short sum = 0;
for(; nWords > 0; nWords-- )
sum += *buf++;
sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);
return sum;
}

// 验算部分的代码
// 书上说只算IP头,我试了也不对, 为什么>>>>?
/*

unsigned short usOldCkSum = pIpheader->checksum;
pIpheader->checksum = 0;
char szTmpBuf[1000] = {0};
memcpy( szTmpBuf, buf, sizeof(IP_HEADER) );
pIpheader->checksum = checksum( (USHORT *)szTmpBuf, sizeof(IP_HEADER) );
*/

unsigned short usOldCkSum = pIpheader->checksum; // 验算校验和
pIpheader->checksum = 0;
char szTmpBuf[1000] = {0};
memcpy( szTmpBuf, buf, sizeof(IP_HEADER) + sizeof(TCP_HEADER) );
memset( szTmpBuf + sizeof(IP_HEADER) + sizeof(TCP_HEADER), 0, 4 );
pIpheader->checksum = checksum( (USHORT *)szTmpBuf, sizeof(IP_HEADER) + sizeof(TCP_HEADER) + 4 ); // ntohs
//////////////////////////*/
g_szPkBuf.Format("%sip.checksum = %i [ 16比特。检查和。为他验算:%i ]\n", g_szPkBuf, usOldCkSum, pIpheader->checksum );


-===========-IP数据包输出开始-===========-
IP包成员名 值 比特数 描述
ip.h_verlen = 69 [ 8比特。4比特IP版本号: 4; 4比特32比特为单位的首部长度: 5 双字或 20 字节 ]
ip.tos = 0 [ 8比特。服务类型。3比特(0普通 - 7网络控制): 0; 1比特低时延: 0; 1比特高吞吐量: 0; 1比特高可靠性: 0) = 0; 2比特未使用:4356116 ]
ip.total_len = 10241 [ 16比特。数据保总长度: 296。IP首部 + 数据部的字节数, 最大为65535 ]
ip.ident = 50121 [ 16比特。标识符: 51651 ]
ip.frag_and_flags = 0 [ 16比特。3比特的标志位:0;13比特的8位组为单位分片偏移量:0 ]
ip.ttl = 64 [ 8比特。生存时间, 单位为秒。]
ip.proto = 6 [ 8比特。协议类型:TCP ]
ip.checksum = 11560 [ 16比特。检查和。为他验算:8966 ]
ip.sourceIP = 704882880 [ 32比特。源IP地址:192.168.3.42 ]
ip.destIP = 1694738624 [ 32比特。源IP地址:192.168.3.101 ]
-===========-IP数据包输出结束-===========-

-===========-TCP 数据包输出开始-===========-
tcp.th_sport = 57614 [ 16比特的源端口:3809 ]
tcp.th_dport = 20480 [ 16比特的目的端口:80 ]
tcp.th_seq = 100376498i [ 32比特的序号: 45727 ]
tcp.th_ack = 833755834i [ 32比特的确认序号: 47642 ]
tcp.th_lenres = 80 [ 10比特首部长度,4为32比特为单位的首部长度: 5 双字或20字节,6比特保留: 0 ]
tcp.th_flag = 24 [ 6比特标志位。从左到右:URG(0)紧急指针字段可用;ACK(0)确认字段可用;PSH(0)本报文段请求急迫;RST(1)连接复位;SYN(1)序号同步;FIN(0)发送方字节流结束 ]
tcp.th_win = 54303 [ 窗口大小: 8148 给出发送方能够接受的报文缓冲区大小 ]
tcp.th_sum = 64136 [ 校验和: 包括TCP首部( 含伪首部)在内的全部数据完整性的校验; 验算校验和:64629 ]
tcp.th_urp = 0 [ 紧急数据偏移量 ]

GET / HTTP/1.1

Accept: */*

Accept-Language: zh-cn

Accept-Encoding: gzip, deflate

User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)

Host: 192.168.3.101

Connection: Keep-Alive

Cookie: ASPSESSIONIDCATQCCAD=LKLNNAJCKPDEDPCLFKNOGJDO




-===========-TCP 数据包输出结束-===========-
...全文
153 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
cxc014 2005-03-22
  • 打赏
  • 举报
回复
mark
oicqkill 2005-03-22
  • 打赏
  • 举报
回复
书:
加若干的0使得TCP首部长度是16位比特的倍数
校验和计算包括(先设置为0再计算): 伪首部 + TCP首部 + 数据
= 各个16位单元的二进制反码求和, 再将和的二进制反码作为校验和
不把填充的0和伪首部的长度计算道报文的长度中去,也不传输他们


-===========-IP数据包输出开始-===========-
IP包成员名 值 比特数 描述
ip.h_verlen = 69 [ 8比特。4比特IP版本号: 4; 4比特32比特为单位的首部长度: 5 双字或 20 字节 ]
ip.tos = 0 [ 8比特。服务类型。3比特(0普通 - 7网络控制): 0; 1比特低时延: 0; 1比特高吞吐量: 0; 1比特高可靠性: 0) = 0; 2比特未使用:4356132 ]
ip.total_len = 18176 [ 16比特。数据保总长度: 71。IP首部 + 数据部的字节数, 最大为65535 ]
ip.ident = 22860 [ 16比特。标识符: 19545 ]
ip.frag_and_flags = 0 [ 16比特。3比特的标志位:0;13比特的8位组为单位分片偏移量:0 ]
ip.ttl = 64 [ 8比特。生存时间, 单位为秒。]
ip.proto = 17 [ 8比特。协议类型:UDP ]
ip.checksum = 20474 [ 16比特。检查和。为他验算:43084 ]
ip.sourceIP = -720592118 [ 32比特。源IP地址:10.163.12.213 ]
ip.destIP = 840061962 [ 32比特。源IP地址:10.84.18.50 ]
-===========-IP数据包输出结束-===========-

-===========-UDP 数据包输出开始-===========-
udp.uh_sport = 40452 [ 16比特源端口 ]
udp.uh_dport = 13568 [ 16比特目的端口 ]
udp.uh_len = 13056 [ 16比特长度 ]
udp.uh_sum = 65203 [ 16比特校验和,验证校验和:16616 ]

0Xfffffff3
0Xffffffa1
0X1
0X0
0X0
0X1
0X0
0X0
0X0
0X0
0X0
0X0
0X2
0X39
0X33
0X2
0X31
0X32
0X3
0X31
0X36
0X33
0X2
0X31
0X30
0X7
0X69
0X6e
0X2d
0X61
0X64
0X64
0X72
0X4
0X61
0X72
0X70
0X61
0X0
0X0
0Xc
0X0
0X1-===========-UDP 数据包输出结束-===========-

-===========-IP数据包输出开始-===========-
IP包成员名 值 比特数 描述
ip.h_verlen = 69 [ 8比特。4比特IP版本号: 4; 4比特32比特为单位的首部长度: 5 双字或 20 字节 ]
ip.tos = 0 [ 8比特。服务类型。3比特(0普通 - 7网络控制): 0; 1比特低时延: 0; 1比特高吞吐量: 0; 1比特高可靠性: 0) = 0; 2比特未使用:4356132 ]
ip.total_len = 37888 [ 16比特。数据保总长度: 148。IP首部 + 数据部的字节数, 最大为65535 ]
ip.ident = 9562 [ 16比特。标识符: 23077 ]
ip.frag_and_flags = 64 [ 16比特。3比特的标志位:0;13比特的8位组为单位分片偏移量:64 ]
ip.ttl = 249 [ 8比特。生存时间, 单位为秒。]
ip.proto = 17 [ 8比特。协议类型:UDP ]
ip.checksum = 13811 [ 16比特。检查和。为他验算:52259 ]
ip.sourceIP = 840061962 [ 32比特。源IP地址:10.84.18.50 ]
ip.destIP = -720592118 [ 32比特。源IP地址:10.163.12.213 ]
-===========-IP数据包输出结束-===========-

-===========-UDP 数据包输出开始-===========-
udp.uh_sport = 13568 [ 16比特源端口 ]
udp.uh_dport = 40452 [ 16比特目的端口 ]
udp.uh_len = 32768 [ 16比特长度 ]
udp.uh_sum = 61268 [ 16比特校验和,验证校验和:32393 ]

0Xfffffff3
0Xffffffa1
0Xffffff81
0Xffffff83
0X0
0X1
0X0
0X0
0X0
0X1
0X0
0X0
0X2
0X39
0X33
0X2
0X31
0X32
0X3
0X31
0X36
0X33
0X2
0X31
0X30
0X7
0X69
0X6e
0X2d
0X61
0X64
0X64
0X72
0X4
0X61
0X72
0X70
0X61
0X0
0X0
0Xc
0X0
0X1
0Xffffffc0
0X16
0X0
0X6
0X0
0X1
0X0
0X0
0X2a
0X30
0X0
0X41
0X8
0X70
0X72
0X69
0X73
0X6f
0X6e
0X65
0X72
0X4
0X69
0X61
0X6e
0X61
0X3
0X6f
0X72
0X67
0X0
0Xa
0X68
0X6f
0X73
0X74
0X6d
0X61
0X73
0X74
0X65
0X72
0Xc
0X72
0X6f
0X6f
0X74
0X2d
0X73
0X65
0X72
0X76
0X65
0X72
0X73
0Xffffffc0
0X45
0X77
0X54
0Xffffffb7
0Xffffffe0
0X0
0X0
0X7
0X8
0X0
0X0
0X3
0Xffffff84
0X0
0X9
0X3a
0Xffffff80
0X0
0X9
0X3a
0Xffffff80-===========-UDP 数据包输出结束-===========-
smartcomplier 2005-03-17
  • 打赏
  • 举报
回复
我也作过这个,不过我不明白checksum()是怎么校验的.

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧