UDP校验和计算

一、UDP概述

UDP是User Datagram Protocol的简称,中文名是用户数据报协议,是OSI(Open System Interconnection,开放式系统互联)参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,UDP在IP报文的协议号是17。

与所熟知的TCP(传输控制协议)协议一样,UDP协议直接位于IP(网际协议)协议的顶层。根据OSI(开放系统互连)参考模型,UDP和TCP都属于传输层协议。UDP协议的主要作用是将网络数据流量压缩成数据包的形式。一个典型的数据包就是一个二进制数据的传输单位。每一个数据包的前8个字节用来包含报头信息,剩余字节则用来包含具体的传输数据。

使用UDP协议包括:TFTPSNMP、NFS、DNS、BOOTP

UDP使用底层的互联网协议来传送报文,同IP一样提供不可靠的无连接数据包传输服务。它不提供报文到达确认、排序、及流量控制等功能。

二、UDP数据报

用户数据报UDP有两个字段:数据字段和首部字段。首部字段很简单,只有8个字节,有四个字段组成,每个字段的长度都是两字节。各段意义如下:

  1. 源端口:源端口号。在需要对方回信时选用。不需要时可用全0。
  2. 目的端口:目的端口号。这在终点交付报文时必须要使用到。
  3. 长度:UDP用户数据报的长度,其最小值是8(仅首部)。
  4. 校验和:检测UDP用户数据报在传输中是否有错。有错就丢弃。

三、UDP校验和计算

UDP计算校验和的方法和IP数据报首部校验和的方法相似。不同的是:IP数据报校验和只校验IP数据报的首部,但UDP的校验和是把首部和数据部分一起都检验。

UDP的校验和需要计算UDP首部加数据荷载部分,但也需要加上UDP伪首部。这个伪首部指,源地址、目的地址、UDP数据长度、协议类型(0x11),协议类型就一个字节,但需要补一个字节的0x0,构成12个字节。伪首部+UDP首部+数据一起计算校验和。

UDP检验和的计算方法是:

  1. 按每16位求和得出一个32位的数;
  2. 如果这个32位的数,高16位不为0,则高16位加低16位再得到一个32位的数;
  3. 重复第2步直到高16位为0,将低16位取反,得到校验和。

四、UDP校验和计算的C语言实现及抓包验证

用wireshark抓包并过滤出UDP数据报,分析如下:

  • 源IP地址:10.170.59.191(0x0aaa 0x3bbf)
  • 目的IP地址:210.14.150.13(0xd20e 0x960d)
  • 源端口:53539(0xd123)
  • 目的端口:10050(0x2742)
  • UDP长度:28(0x001c)
  • 校验和:0x285c

将12字节的伪首部、8字节的UDP首部(校验和置0)及20字节的数据放在一起,用C语言编程计算校验和,程序运行截图如下:

从程序运行结果来看,计算出来的校验和与抓包得到的校验和是一致的。

#include<stdio.h>
unsigned short checksum(unsigned short *buf,int nword)
{
unsigned long sum;
for(sum=0;nword>0;nword--)
{
sum += *buf++;
sum = (sum>>16) + (sum&0xffff);
}
return ~sum;
}
void main()
{  
	unsigned short buffer[20]={0x0aaa,0x3bbf,0xd20e,0x960d,0x0011,0x001c,0xd123,0x2742,0x001c,0x0000,0x6c41,0x5661,0x0000,0x0e00,0xf8b6,0xd401,0x9313,0x0000,0x0000,0x0000};
	int n=20;  
	unsigned short re_checksum;     
	re_checksum=checksum(buffer,n);
	printf("%x\t",re_checksum); 
	if(re_checksum==0x285c) 
		printf("校验和正确!\n"); 
	else          
		printf("校验和不正确!\n");
} 

猜你喜欢

转载自blog.csdn.net/stone_Yu/article/details/81611067