[经验]tcp udp完整数据包校验和通用计算

上传人:子 文档编号:43743922 上传时间:2018-06-07 格式:DOC 页数:9 大小:16.33KB
返回 下载 相关 举报
[经验]tcp udp完整数据包校验和通用计算_第1页
第1页 / 共9页
[经验]tcp udp完整数据包校验和通用计算_第2页
第2页 / 共9页
[经验]tcp udp完整数据包校验和通用计算_第3页
第3页 / 共9页
[经验]tcp udp完整数据包校验和通用计算_第4页
第4页 / 共9页
[经验]tcp udp完整数据包校验和通用计算_第5页
第5页 / 共9页
点击查看更多>>
资源描述

《[经验]tcp udp完整数据包校验和通用计算》由会员分享,可在线阅读,更多相关《[经验]tcp udp完整数据包校验和通用计算(9页珍藏版)》请在金锄头文库上搜索。

1、 经验经验TCPTCP UDPUDP 完整数据包校验和通用计算完整数据包校验和通用计算ICMP,IP,UDP,TCP 报头部分都有 checksum(检验和)字段。ICMP和 IP 报头校验和的计算都很简单,使用 RFC1071 中给出的方法即可完成(如下) 。/计算校验和USHORT checksum(USHORT *buffer,int size)unsigned long cksum=0;while(size1)cksum+=*buffer+;size-=sizeof(USHORT);if(size)cksum+=*(UCHAR *)buffer;/将 32 位数转换成 16while

2、(cksum16)cksum=(cksum16)+(cksum return (USHORT) (cksum);UDP/TCP 报头中的校验和的计算比较复杂的,要用到 UDP/TCP伪首部:先要填充伪首部各个字段,然后再将 UDP/TCP 报头以后(包括报头)的数据附加到伪首部的后面,再对位首部使用上述校验和计算,所得到的值才是 UDP/TCP 报头部分的校验和。位首部可以用如下的结构体表示:typedef structULONG sourceip; /源 IP 地址ULONG destip; /目的 IP 地址BYTE mbz; /置空(0)BYTE ptcl; /协议类型USHORT pl

3、en; /TCP/UDP 数据包的长度(即从 TCP/UDP 报头算起到数据包结束的长度 单位:字节)Psd_Header;这个过程是一个很繁琐的过程,计算过几次后再也忍受不了做这样重复的工作,于是写了一个通用的计算函数。这个函数使用起来我感觉非常方便:先封装好你的数据包(完整的,包括以太头) ,然后将数据包的首地址作为参数,调用该函数即可。函数将帮你完成 IP报头以及 UDP/TCP 报头部分校验和的计算。/-/ PacketCheckSum/ 计算数据包的校验和/ 参数:packet-待处理数据(将封装好的数据包的指针)/-void PacketCheckSum(unsigned char

4、 packet)Dlc_Header *pdlc_header=NULL; /以太头指针Ip_Header *pip_header=NULL; /IP 头指针unsigned short attachsize=0; /传输层协议头以及附加数据的总长度pdlc_header=(Dlc_Header *)packet;/判断 ethertype,如果不是 IP 包则不予处理if(ntohs(pdlc_header-ethertype)!=0x0800) return;pip_header=(Ip_Header *)(packet+14);/TCP 包if(0x06=pip_header-proto

5、)Tcp_Header *ptcp_header=NULL; /TCP 头指针Tcp_Psd_Header *ptcp_psd_header=NULL;ptcp_header=(Tcp_Header *)(packet+14+(pip_header-ver_len)attachsize=ntohs(pip_header-total_len)-(pip_header-ver_len)ptcp_psd_header=(Tcp_Psd_Header *)malloc(attachsize+sizeof(Tcp_Psd_Header);if(!ptcp_psd_header) return;memse

6、t(ptcp_psd_header,0,attachsize+sizeof(Tcp_Psd_Header);/填充伪 TCP 头ptcp_psd_header-destip=pip_header-destIP;ptcp_psd_header-sourceip=pip_header-sourceIP;ptcp_psd_header-mbz=0;ptcp_psd_header-ptcl=0x06;ptcp_psd_header-tcpl=htons(attachsize);/计算 TCP 校验和ptcp_header-chksum=0;memcpy(unsigned char *)ptcp_psd

7、_header+sizeof(Tcp_Psd_Header),(unsigned char *)ptcp_header,attachsize);ptcp_header-chksum=checksum(unsigned short *)ptcp_psd_header,attachsize+sizeof(Tcp_Psd_Header);/计算 ip 头的校验和pip_header-checksum=0;pip_header-checksum=checksum(unsigned short *)pip_header,20);return;/UDP 包if(0x11=pip_header-proto)

8、Udp_Header *pudp_header=NULL; /UDP 头指针Udp_Psd_Header *pudp_psd_header=NULL;pudp_header=(Udp_Header *)(packet+14+(pip_header-ver_len)attachsize=ntohs(pip_header-total_len)-(pip_header-ver_len)pudp_psd_header=(Udp_Psd_Header *)malloc(attachsize+sizeof(Udp_Psd_Header);if(!pudp_psd_header) return;memset

9、(pudp_psd_header,0,attachsize+sizeof(Udp_Psd_Header);/填充伪 UDP 头pudp_psd_header-destip=pip_header-destIP;pudp_psd_header-sourceip=pip_header-sourceIP;pudp_psd_header-mbz=0;pudp_psd_header-ptcl=0x11;pudp_psd_header-udpl=htons(attachsize);/计算 UDP 校验和pudp_header-chksum=0;memcpy(unsigned char *)pudp_psd_

10、header+sizeof(Udp_Psd_Header),(unsigned char *)pudp_header,attachsize);pudp_header-chksum=checksum(unsigned short *)pudp_psd_header,attachsize+sizeof(Udp_Psd_Header);/计算 ip 头的校验和pip_header-checksum=0;pip_header-checksum=checksum(unsigned short *)pip_header,20); return;return;需要几个头文件,以及库:#include #in

11、clude #include “packet.h“#pragma comment(lib,“ws2_32.lib“)最后附上我使用的数据包的结构体(比较多):/数据包结构体#pragma pack(1) /*物理帧头结构*/typedef struct BYTE desmac6; /目的 MAC 地址BYTE srcmac6; /源 MAC 地址USHORT ethertype; /帧类型Dlc_Header; /*Arp 帧结构*/typedef struct USHORT hw_type; /硬件类型 Ethernet:0x1USHORT prot_type; /上层协议类型 IP:0x0

12、800BYTE hw_addr_len; /硬件地址长度:6BYTE prot_addr_len; /协议地址(IP 地址)的长度:4USHORT flag; /1 表示请求,2 表示应答BYTE send_hw_addr6; /源 MAC 地址UINT send_prot_addr; /源 IP 地址BYTE targ_hw_addr6; /目的 MAC 地址UINT targ_prot_addr; /目的 IP 地址BYTE padding18; /填充数据 Arp_Frame;/*ARP 包=DLC 头+ARP 帧*/typedef struct Dlc_Header dlcheader

13、;/DLC 头Arp_Frame arpframe; /ARP 帧ARP_Packet;/*IP 报头结构*/typedef struct BYTE ver_len; /IP 包头部长度,单位:4 字节BYTE tos; /服务类型 TOSUSHORT total_len; /IP 包总长度 USHORT ident; /标识USHORT frag_and_flags; /标志位BYTE ttl; /生存时间BYTE proto; /协议USHORT checksum; /IP 首部校验和UINT sourceIP; /源 IP 地址(32 位)UINT destIP; /目的 IP 地址(3

14、2 位)Ip_Header;/*TCP 报头结构*/typedef struct USHORT srcport; / 源端口USHORT dstport; / 目的端口UINT seqnum; / 顺序号UINT acknum; / 确认号BYTE dataoff; / TCP 头长BYTE flags; / 标志(URG、ACK 等)USHORT window; / 窗口大小USHORT chksum; / 校验和USHORT urgptr; / 紧急指针Tcp_Header;/TCP 伪首部 用于进行 TCP 校验和的计算,保证 TCP 效验的有效性typedef structULONG sourceip; /源 IP 地址ULONG destip; /目的 IP 地址BYTE mbz; /置空(0)BYTE ptcl; /协议类型(IPPROTO_TCP)USHORT tcpl; /TCP 包的总长度(单位:字节)Tcp_Psd_Header;/*UDP 报头*/typedef struct USHORT srcport; / 源端口USHORT dstport; / 目的端口USHORT total_len; / 包括 UDP 报头及 UDP 数据的长度(单位:字节)USHORT ch

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 生活休闲 > 科普知识

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号