1、 解析IP数据包程序设计与实现解析IP数据包程序设计与实现学生姓名:梁帅 指导老师:谢晓巍摘 要 现如今,计算机网络已经彻彻底底地改变了人们的生活。大量的数据都是经过计算机网络传输的,而TCP/IP协议是计算机网络中最重要的协议之一。计算机网络中绝大多数数据都是以IP数据包的形式发送和接受的。所以IP数据包的捕获是很多计算机安全技术的基础。本课程设计实现了可以捕获流经本地网卡的IP数据包并将其头部信息解析输出的程序。关键词 TCP/IP;IP数据包;计算机网络;捕获Design and implementation of IP data packetStudent name: LIANG Sh
2、uai Advisor:XIE Xiao-weiAbstract Nowadays, computer network has completely changed peoples life. A large amount of data is transmitted through computer networks, and the TCP/IP protocol is one of the most important protocols in computer networks. Most of the data in the computer network are sent and
3、 received in the form of IP data packets. So IP packet capture is the basis of many computer security technology. This course is designed to capture the IP data packet that flows through the local network card and the program to parse the output of its head.Key words TCP/IP;IP data packet;Computer n
4、etwork;Capture1引言1.1课程设计的目的本课程设计的目的就是设计一个解析IP数据包的程序,并根据这个程序,说明IP数据包的结构及IP协议的相关问题,从而对IP层的工作原理有更好的理解和认识。1.2课程设计的意义计算机之间进行通信时,交互的所有信息都封装在数据包中。因此,通过采集网络数据并对其进行相应的分析,可以清楚地了解到进行通信的计算机的通信目的。首先,分析采集到的数据包,可以确定网络是否受到攻击入侵;其次,也可以使用采集到的数据包来分析网络应用程序可能出现的问题的原因;此外,通过网络数据采集和统计可以清楚的了解整个网络在各个时段内的网络负载情况,从而判断网络使用得是否合理。除
5、了以上谈到的几个方面以外,数据包采集分析还有其他很多用途.在研究IPv4网络的同时,我们还对IPv6协议进行了初步的研究并通过对数据报的分析,了解了在不同网络环境下IPv6数据包的封装格式以及在网络中的传输路径。目前,在同一子网范围内,可以通过邻居计算机发现协议自动配置主机的本地一链路IPv6地址,并获取子网内其他主机的通信地址,通过该地址可以实现子网内的主机间纯IPv6环境下的通信。但由于现在整个因特网并不支持IM协议,因此IPv6数据包要在网间传输,必须通过基于双协议栈的IPv4隧道(Tunnel)技术,将EM数据报封装在IPv4包头中,并通过指定的支持IM协议的路由在Internet中传
6、送到目的地,再由目的主机进行数据报解析。获取IPv6数据报中的信息。1.3设计平台笔记本,windows7 64bit操作系统,Microsoft Visual C+6.0,C语言。2设计原理2.1 IP数据包格式说明IP数据包格式包含了标头固定部分,标头可变部分和数据区三部分。IP数据报标头部分固定为20个字节,其中包含了12个参数域,各参数域隐含着网间协议的传输机制。IP具体的标头格式如图1所示。 各参数域的具体含义如下: 1) 版本号:长度4位,表示所使用的IP协议的版本。IPv4版本号字段值为4;IPV6 版本号字段号的值为6. 2) 标头长:长度4位,定义了一个以4B为一个单位的IP
7、包的报头长度 3) 服务类型:共8位,高3位组成优先级子域,随后4位组成服务类型子域。 4) 数据报总长度:总长度为2B(即6位)。定义了以字节为单位的数据报的总长度。 5) 重装标识:长度16位,用于识别IP数据报的编号,让目的主机判断新来的数据属 于哪个分组。 6) 分片标识:共3位,最高位为0;DF禁止分片标识。DF=0,可以分片;DF=1,不能 分片。MF:分片标识。MF=0,表示接的是最后一个分片;MF=1,不是最后一个分片。 7) 片偏移值:共13位,说明分片在整个数据报中的相对位置。 8) 生存周期:8位,用来设置数据数据报在整个网络传输过程中的寿命。常以一个数 据报可以经过的最
8、多的路由器跳步数来控制。 9) 协议类型:共8位,表示该IP数据报的高层协议类型。 10) 标头校验和:共16位,用于存放检查报头错误的校验码。 11) 源、宿主机地址:共32位,分别表示发送和接受数据报的源主机和宿主机的IP地 址。 12) 选项数据域:0-40B,用于控制和测试。 IP数据包的格式为表2-11:表2-1 数据包格式4位版本4位首部长度8位服务类型TOS16位总长度16位标识3位标志13位片偏移8位生存时间TTL8位协议16位首部检验和32位源IP地址32位目的IP地址2.2 IP数据包的定义typedef struct _IP_HEADER /定义IP头 union BYT
9、E Version; /版本(前4位) BYTE HdrLen; /报头标长(后4位),IP头长度 ; BYTE ServiceType; /服务类型 WORD TotalLen; /数据报总长 WORD ID; /标识 union WORD Flags; /标识(前3位) WORD FragOff; /分段偏移(后13位) ; BYTE TimeToLive; /生存周期 BYTE Protocol; /协议 WORD HdrChksum; /头校验和 DWORD SrcAddr; /源地址 DWORD DstAddr; /目地地址BYTE Options; /选项 IP_HEADER;2.
10、3套接字的使用本程序使用套接字socket编程,将网卡设为能够接受流经网卡的所有类型的数据包。首先,初始化套接字,然后监听数据包,解析数据包。 SOCKET sock=socket(AF_INET,SOCK_RAW,IPPROTO_IP)用来创建套接字,其参数为通信发生的区字段和套接字的类型。 WSAIoctl(sock , IO_RCVALL ,&dwBufferInLen , sizeof(dwBufferInLen)函数用来把网卡设置为混杂模式。 recv(sock,buffer,65535,0)函数用来接收经过的IP包,其参数分别是套接字描述符,缓冲区的地址,缓冲区的大小2。3设计步骤
11、3.1程序流程图此次课程设计的程序流程图如图3-1开始构造程序运行文件,生成输出文件创建并初始化原始套接字设置网卡混杂模式监听网卡捕获和解析IP数据报输出解析信息,并存入文档NO是否达到需要次数结束 YES图3-1程序流程图3.2主要程序分析使用原始套接字 要进行IP层数据包的接收和发送,应使用原始套接字。创建原始套接字的代码如下: SOCKET sock; sock=WSASoccket(AF_INET,SOCK_RAW,IPPROTO_IP,NULL,0, WSA_FLAG_OVERLAPPED); 在WSASoccket函数中,第一个参数指定通信发生的区字段,AF_INET是针对Inte
12、rnet的,允许在远程主机之间通信。第二个参数是套接字的类型,在AF_INET地址族下,有SOCK_STREAM、SOCK_DGRAM、SOCK_RAW三种套接字类型。在这里,设置为SOCK_RAW,表示声明的是一个原始套接字类型。第三个参数依赖于第二个参数,用于指定套接字所有的特定协议,这里使用IP协议。第四个参数为WSAPROTOCOL_INFO位,该位可以置空。第五个参数保留,永远置0。第六个参数是标志位,WSA_FLAG_OVERLAPPED表明可以使用发送接收超时设置3。 创建原始套接字后,IP头就会包含在接收的数据中。然后,可以设置IP头操作选项,调用setsockopt函数。其中
13、flag设置为true,并设定IP_HDRINCL选项,表明用户可以亲自对IP头进行处理。 BOOL flag=true; setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(CHAR*)&flag,sizeof(flag); 之后,使用如下代码完成对socket的初始化工作: /*获取主机名*/ char hostName128; gethostname(hostName,100); /*获取本地IP地址*/ hostent * pHostIP; pHostIP = gethostbyname(hostName); /*填充SOCKADDR_IN结构的内容*/ so
14、ckaddr_in addr_in; addr_in.sin_addr = *(in_addr *)pHostIP-h_addr_list0; addr_in.sin_family = AF_INET; addr_in.sin_port = htons(6000); /*绑定socket*/ bind(sock,(PSOCKADDR)&addr_in,sizeof(addr_in); 填写sockaddr_in的内容时,其地址值应填写为本机IP地址,本机IP地址可以通过gethostbyname()函数获取;端口号可以随便填写,但不能与系统冲突;协议族应填为AF_INET。使用htons()函数可以将无符号短整型的主机数据转换为网络字节顺序的数据。最后使用bind()函数将socket绑定到本机网卡上。 绑定网卡后,需要用WSAIoctl()函数把网卡设置为混杂模式,使网卡能够接收所有网络数据,其关键代码如下: #def
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1