UDP中的伪首部是干什么用得到?

UDP首部校验和计算:
对于TCP和UDP的数据报,其头部也包含16位的校验和,校验算法与IPv4分组头完全一致,但参与校验的数据不同。
这时校验和不仅包含整个TCP/UDP数据报,还覆盖了一个虚头部(伪首部)。
校验和计算
u_int16_t in_cksum (u_int16_t * addr, int len)
{
int nleft = len;
u_int32_t sum = 0;
u_int16_t *w = addr;
u_int16_t answer = 0;
/*
* Our algorithm is simple, using a 32 bit accumulator (sum), we add
* sequential 16 bit words to it, and at the end, fold back all the
* carry bits from the top 16 bits into the lower 16 bits.
*/
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}
/* mop up an odd byte, if necessary */
if (nleft == 1) {
* (unsigned char *) (&answer) = * (unsigned char *) w;
sum += answer;
}
/* add back carry outs from top 16 bits to low 16 bits */
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* truncate to 16 bits */
return (answer);
}
==================不足偶数字节补0
45 00 00 2e----4表示ip版本号为ip第4版;5表示首部长度为5个32 bit字长,即为20字节;00 2e表示ip总长度为46字节,其中ip数据部分为26字节。
be 55 00 00----be 55表示标识符;00 00表示3 bit标志及13 bit片偏移量;
7a 11 51 ac----7a表示ttl值为122;11表示协议号为17的udp协议;51 ac表示16 bit首部检验和值;
de b7 7e e3----表示32 bit 源ip地址为222.183.126.227
c0 a8 12 7a----表示32 bit 目的ip地址为192.168.18.122
//不需要htons,详见rfc1071
picmp_hdr->icmp_chksum = checksum((unsigned short*)pSendBuf, sizeof (ICMPHeader) + nSendDataSize);
之后发送pSendBuf中的数据,长度为sizeof (ICMPHeader) + nSendDataSize;
char *pRecvBuf = new char[sizeof(ICMPHeader) + nSendDataSize];
当接收到数据报再对它进行校验和验证,假设接收到的icmp数据存在pRecvBuf中
ICMPHeader *picmp_hdr2 = (ICMPHeader*)pRecvBuf;
//注意:验证数据的时候,不需要转化为主机字节序列,
//因为校验和发送端是以网络字节序来计算的,接收到的字节序列已经是网络字节序
//根据接收到的校验和进行验证
//不需要ntohs,详见rfc1071
//picmp_hdr2->checksum = ntohs(picmp_hdr2->checksum);
- unsigned short check_sum(unsigned short *a, int len)
- {
- unsigned int sum = 0;
- while (len > 1) {
- sum += *a++;
- len -= 2;
- }
- if (len) {
- sum += *(unsigned char *)a;
- }
- while (sum >> 16) {
- sum = (sum >> 16) + (sum & 0xffff);
- }
- return (unsigned short)(~sum);
- }
==================检验和验证计算========================
首先,把检验和字段置为0。
45 00 00 2e
be 55 00 00
7a 11 00 00<----检验和置为0
de b7 7e e3
c0 a8 12 7a
其次,对整个首部中的每个16 bit进行二进制反码求和,
求和值为0x3_ae50,然后3+ae50=0xae53(这是根据源代码中算法 cksum = (cksum >> 16) + (cksum & 0xffff) 进行的 )
最后,ae53+51ac=ffff。因此判断ip首部在传输过程中没有发生任何差错。
本文详细介绍了UDP首部校验和的计算过程,包括参与校验的数据和伪首部的作用。通过实例展示了如何计算和验证校验和,确保数据在传输过程中的准确性。
2887

被折叠的 条评论
为什么被折叠?



