技能训练.docx
- 文档编号:26605204
- 上传时间:2023-06-20
- 格式:DOCX
- 页数:13
- 大小:233.54KB
技能训练.docx
《技能训练.docx》由会员分享,可在线阅读,更多相关《技能训练.docx(13页珍藏版)》请在冰豆网上搜索。
技能训练
技 能 训 练
题 目:
TCP包的捕获与解析
院 系:
计算机科学与技术学院网络工程系
班级:
学号:
姓 名:
同组成员:
指导教师:
成绩:
2014年09月12日
一.系统设计的目标
1.1理论学习
掌握IP数据包、TCP报文段的格式,以及学习Winsock编程的知识,和如何设计网卡相关知识。
掌握网络通信协议的基本工作原理;培养基本掌握网络编程的基本思路和方法;能提高对所学计算机网络理论知识的理解能力。
提高和挖掘对所学知识的实际应用能力和创新能力;提高的科技论文写作能力。
TCP数据包捕获与解析的设计。
设计任务:
掌握IP数据包的工作原理与报头设计的相关字段以及TCP报文段的格式以及相关字段;理解IP包的版本、头长度、服务类型、数据包总长度、数据包标识、分段标志、分段、偏移量、生存时间、上层协议类型、头校验合、源IP地址和目的IP地址等内容。
理解TCP报文段的源端口、目标端口、序号、确认序号、数据偏移、保存字段、紧急比特、确认比特、急迫比特、复位比特、同步比特、终止比特、窗口、通知窗口、拥塞窗口。
根据IP数据包的标准格式以及TCP报文段的标准格式,编写程序捕获IP数据包并进行解析,并将解析后各IP包的头部与数据字段,以确认是TCP包。
数据字段的值从IP首部即可获取。
为了获取网络中的IP数据包,可以采用VC++中的Winsock的数据库查询函数解决,捕获IP数据包并解析IP地址等内容。
1.2实践目标
编写程序,通过使用VC++中的WinSock实现捕获局域网内TCP数据报,并解析TCP包头。
实现该功能并掌握WinSock编程,完成技能训练报告的编写,提高对所学知识的实际应用能力和写作能力。
提高实践能力,提高编程能力,掌握原始套接字的使用。
二.系统原理
2.1IP数据包
TCP/IP协议定义了一个在因特网上传输的包,称为IP数据报(IPDatagram)。
由首部和数据两部分组成,其格式如图所示。
首部的前一部分是固定长度,共20字节。
在首部的固定部分的后面是一些可选字段,其长度是可变的。
首部中的源地址和目的地址都是IP协议地址。
IP首部的可变部分就是一个可选字段。
选项字段用来支持排错、测量以及安全等措施,内容很丰富。
此字段的长度可变,从1个字节到40个字节不等,取决于所选择的项目。
某些选项项目只需要1个字节,它只包括1个字节的选项代码。
但还有些选项需要多个字节,这些选项一个个拼接起来,中间不需要有分隔符,最后用全0的填充字段补齐成为4字节的整数倍。
增加首部的可变部分是为了增加IP数据报的功能,但这同时也使得IP数据报的首部长度成为可变的。
这就增加了每一个路由器处理数据报的开销。
实际上这些选项很少被使用。
新的IP版本IPv6就将IP数据报的首部长度做成固定的。
IP数据报的格式说明IP协议都具有什么功能。
其首部,版本目前广泛使用的版本号为4;首部长度站4bit;服务类型占8bit,总长度字段为2B,IP数据包的最大长度是65535B;标识占16bit,它是一个计数器,用来产生数据报的标识;标志占3bit,其中最低为为MF,MF=1时为后面“还有分片”,MF=0表示这是数据报片中的最后一个,DF=0时,表示允许分片;片偏移以8个字节为偏移单位;生存时间字段记为TTL,单位为秒;协议段占8bit,用于指出次数据是使用何种协议,典型的协议号有6:
TCP,17:
UDP,1:
ICMP。
图2-1IP数据包首部
2.2TCP数据包
TCP是一种面向连接(连接导向)的、可靠的、基于字节流的运输层(Transportlayer)通信协议,由IETF的RFC793说明(specified)。
在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能,UDP是同一层内另一个重要的传输协议。
在因特网协议族(Internetprotocolsuite)中,TCP层是位于IP层之上,应用层之下的中间层。
不同主机的应用层之间经常需要可靠的、像管道一样的连接,但是IP层不提供这样的流机制,而是提供不可靠的包交换。
TCP协议是面向字节的。
TCP将所要传送的报文看成是字节组成的数据流,并使每一个字节对应于一个序号。
在连接建立时,双方要商定初始序号。
TCP每次发送的报文段的首部中的序号字段数值表示该报文段中的数据部分的第一个字节的序号。
TCP的确认是对接收到的数据的最高序号表示确认。
应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,然后TCP把数据流分割成适当长度的报文段(通常受该计算机连接的网络的数据链路层的最大传送单元(MTU)的限制)。
之后TCP把结果包传给IP层,由它来通过网络将包传送给接收端实体的TCP层。
TCP为了保证不发生丢包,就给每个字节一个序号,同时序号也保证了传送到接收端实体的包的按序接收。
然后接收端实体对已成功收到的字节发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据(假设丢失了)将会被重传。
TCP用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。
图2-2TCP报文段首部
2.3WinSock编程
Winsock是Windows下的网络编程接口,它是由Unix下的BSDSocket发展而来,是一个与网络协议无关的编程接口。
WindowsSockets是在Windows环境下使用的一套网络编程规范,常常简称为WinSock。
在Winsock规范中把WinsockAPI函数集分为与BSDSocket(用在UNIX中)相兼容的基本函数、网络数据信息检索函数和Windows专用扩展函数三类。
WindowsSocket1规范的核心内容是符合BerkeleySocket风格的库函数,例如可以编写基于select模型的的socket跨平台库。
select模型可以很好地实现跨平台,但对具体操作系统平台而言,并非性能最佳的I/O模型。
为了使程序员能充分利用Windows消息驱动机制进行编程,又定义开发了一组针对Windows的扩展库函数,这就是WindowsSocket2规范。
Winsock2.x提供了基于Windows消息机制的WSAAsyncSelcet异步I/O网络事件通知模型,除此之外WinSock2.x还提供了基于事件通知的异步I/O网络事件通知的WSAEventSelect模型和高效的重叠I/O模型。
具体平台实现了各自高效的网络I/O管理模型,例如Windoze的IOCP模型、Linux的epoll模型,它们用来实现大规模高并发的通信应用程序。
Winsock在常见的Windows平台上有两个主要的版本,即Winsock1和Winsock2。
编写与Winsock1兼容的程序你需要引用头文件WINSOCK.H,如果编写使用Winsock2的程序,则需要引用WINSOCK2.H。
此外还有一个MSWSOCK.H头文件,它是专门用来支持在Windows平台上高性能网络程序扩展功能的。
使用WINSOCK.H头文件时,同时需要库文件WSOCK32.LIB,使用WINSOCK2.H时,则需要WS2_32.LIB,如果使用MSWSOCK.H中的扩展API,则需要MSWSOCK.LIB。
正确引用了头文件,并链接了对应的库文件,你就构建起编写WINSOCK网络程序的环境了。
初始化Winsock,每个Winsock程序必须使用WSAStartup载入合适的Winsock动态链接库,如果载入失败,WSAStartup将返回SOCKET_ERROR,这个错误就是WSANOTINITIALISED,WSAStartup的定义如下:
IntWSAStartup(
WORDwVersionRequested,
LPWSADATAlpWSAData);
2.4网卡设置
在通常情况下,网络通信的套接字程序只能响应与自己硬件地址相匹配的或是以广播形式发出的数据帧,对于其他形式的数据帧比如已到达网络接口但却不是发给此地址的数据帧,网络接口在验证投递地址并非自身地址之后将不引起响应,也就是说应用程序无法收取与自己无关的的数据包。
所以我们要想实现截获流经网络设备的所有数据包,就要采取一点特别的手段了:
将网卡设置为混杂模式。
这样一来,该主机的网卡就可以捕获到所有流经其网卡的数据包和帧。
但是要注意一点,这种截获仅仅是数据包的一份拷贝,而不能对其进行截断,要想截断网络流量就要采用一些更底层的办法了,不在本文的讨论范围之内。
在以太网中,所有的通信都是广播的,也就是说通常在同一个网段的所有网络接口都可以访问在物理媒体上传输的所有数据,每一个网络接口都有一个唯一的硬件地址,就是网卡的MAC地址,在正常的情况下,一个网络接口应该只响应两种数据帧:
与自己硬件地址相匹配的数据帧;向所有计算机的广播数据帧,在实际系统中数据的收发是由网卡来完成,网卡接收到传来的数据,网卡内的程序接收数据帧的目的MAC地址,根据计算机上的网卡驱动程序设置的接收模式判断该不该接收,认为该接收就接收后产生中断信号通知CPU,认为不该接收就丢掉不管,不该接收的数据就被网卡截断了,计算机根本不知道,对于网卡来说一般有4种接收模式:
广播方式:
该模式下的网卡能够接收网络中的广播信息,组播方式:
该模式下的网卡能够接收组播数据。
直接方式:
该模式下只有目的网卡才能接收数据。
混杂模式:
该模式下的网卡能够接收一切通过它的数据,而不管该数据是否是传给它,要想实现对网络的数据进行分析,首先必须把网卡设置成混杂模式,只有这样才能让网卡接收一切所能接收的数据。
一般每一台的电脑上都会有两块网卡,在使用Winpcap时可以列举出电脑上的两块网卡的信息,并选择网卡获取数据包,但是其中的一块是不能获取数据包的。
由此可见,要想实现数据包捕获及分析系统,应该做三件事:
把网卡设置成混杂模式,捕获数据包,分析数据包。
四.系统实现
4.1理论介绍
系统的开发环境是VC++6.0,利用套接字来实现包捕获功能)在包捕获的具体实现之前,首先是设置网卡的模式)主要包括:
创建原始套接字;设置IP头操作选项,其中flag设置为ture,表示对IP头进行处理;填充SOCKADDR_IN结构;将原始套接字绑定到本地网卡;设置套接字模式;启动接收数据线程)根据不同的选择执行不同的程序,并把最后结果显示在对话框中,捕获和分析网络数据包系统主要实现的是网络数据包的捕获及分析的功能,它主要有两大功能模块:
第一个是包捕获功能模块,在这个模块中主要是利用套接字对网络层的数据进行抓包,然后把它存储在缓冲存储器中;第二个是包分析功能模块,在这个模块中根据协议的报文格式,把抓到的包进行解析,最后显示出协议的报头内容。
系统的功能基本达到了原定的设计目标,实现了数据包的捕获与初步的协议分析)
本程序使用套接字socket编程,将网卡设为能够接受流经网卡的所有类型的数据包。
首先,初始化套接字,然后监听数据包,解析数据包。
1.创建套接字
SOCKETsock=socket(AF_INET,SOCK_RAW,IPPROTO_IP)
用来创建套接字,其参数为通信发生的区字段和套接字的类型。
2.设置网卡为混杂模式
WSAIoctl(sock,IO_RCVALL,&Len,sizeof(dwBufferInLen)
用来把网卡设置为混杂模式。
3.接收IP数据包
recv(sock,buffer,65535,0)
用来接收经过的IP包,其参数分别是套接字描述符,缓冲区的地址,缓冲区的大小。
typedefstructIP_HEAD
{
}ip_head;用来定义IP头部数据。
4.获取本机IP地址
setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char*)用来获取本机IP
htons()函数将无符号短整型转换为网络字节顺序的数据。
4.2源程序
本程序在Windows环境下利用C++语言编写。
#include
#include
#include
#pragmacomment(lib,"ws2_32.lib")
#defineSIO_RCVALL_WSAIOW(IOC_VENDOR,1)//IPv4包头结构体typedefstructip_header{unsignedcharver_ihl;//Version(4bits)+Internetheaderlength(4bits)unsignedchartos;//Typeofserviceunsignedshorttlen;//Totallengthunsignedshortidentification;//Identificationunsignedshortflags_fo;//Flags(3bits)+Fragmentoffset(13bits)unsignedcharttl;//Timetoliveunsignedcharproto;//Protocolunsignedshortcrc;//Headerchecksumu_charip_src[4];//Sourceaddressu_charip_dst[4];//Destinationaddress}IPHEADER,*PIPHEADER;//IPv4包头结构体//TCP包头结构体typedefstructtcp_header{WORDSourPort;//源端口号 WORDDestPort;//目的端口号DWORDSeqNo;//序号DWORDAckNo;//确认序号BYTEHLen;//首部长度(保留位)BYTEFlag;//标识(保留位)WORDWindow;//窗口大小WORDChkSum;//校验和WORDUrgPtr;//紧急指针}TCPHEADER,*PTCPHEADER;//全局变量SOCKETm_Socket;//函数声明voidInitWinsock2();//初始化Winsock2voidBindSocket();//绑定套接字voidRecieveTCP();//捕获TCP数据报intmain(intargc,char*argv[]){printf("============================\n");printf("捕获TCP数据报,并解析TCP包头\n");
printf("============================\n\n");InitWinsock2();BindSocket();RecieveTCP();closesocket(m_Socket);WSACleanup();return0;}//初始化WinSock2voidInitWinsock2(){WSADATAwsaData;WORDversion;intret;version=MAKEWORD(2,2);ret=WSAStartup(version,&wsaData);if(ret!
=0){printf("Failedtoloadwinsock2library.\n");return;}}//对网络进行监听voidBindSocket(){SOCKET_ADDRESS_LIST*slist=NULL;charbuffer[2048];DWORDdwBytesRet;SOCKADDR_INm_SockAddr;DWORDdwVal=1;//建立套接字m_Socket=WSASocket(AF_INET,SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED);if(m_Socket==INVALID_SOCKET)return;//绑定套接字if(WSAIoctl(m_Socket,SIO_ADDRESS_LIST_QUERY,NULL,0,&buffer,2048,&dwBytesRet,NULL,NULL)==SOCKET_ERROR)return;slist=(SOCKET_ADDRESS_LIST*)buffer;if(slist->iAddressCount<=0)return;m_SockAddr.sin_addr.s_addr=((SOCKADDR_IN*)slist->Address[0].lpSockaddr)->sin_addr.s_addr;m_SockAddr.sin_family=AF_INET;m_SockAddr.sin_port=htons(0);if(:
:
bind(m_Socket,(SOCKADDR*)&m_SockAddr,sizeof(m_SockAddr))==SOCKET_ERROR)return;if(WSAIoctl(m_Socket,SIO_RCVALL,&dwVal,sizeof(dwVal),NULL,0,&dwBytesRet,NULL,NULL)==SOCKET_ERROR)return;}voidRecieveTCP(){DWORDdwFlags;DWORDdwBytesRead;WSABUFwbuf;charbuff1[0x1500];wbuf.len=0x1500;wbuf.buf=buff1;unsignedchar*buf;PIPHEADERip_header;PTCPHEADERtcp_header;while
(1){dwFlags=0;WSARecv(m_Socket,&wbuf,1,&dwBytesRead,&dwFlags,NULL,NULL);//捕获数据报WSABUF*pBuf=(WSABUF*)&wbuf;buf=(UCHAR*)GlobalAlloc(GPTR,pBuf->len);buf=(unsignedchar*)pBuf->buf;ip_header=(PIPHEADER)buf;tcp_header=(PTCPHEADER)(buf+sizeof(IPHEADER));if(ip_header->proto==6){//IPv4包头中Proto字段值为6表示上层数据包为TCPprintf("源端口:
%d",ntohs(tcp_header->SourPort));//源端口号printf("目的端口:
%d",ntohs(tcp_header->DestPort));//目的端口号printf("序号:
%ld",ntohl(tcp_header->SeqNo));//序号printf("确认序号:
%ld",ntohl(tcp_header->AckNo));//确认序号printf("头长度:
%d\n",tcp_header->HLen>>4);//头长度printf("保留位:
%d",(tcp_header->HLen&15)+(tcp_header->Flag>>6));//保留位printf("码源比特:
%d",tcp_header->Flag&63);//码源比特printf("窗口大小:
%d",ntohs(tcp_header->Window));//窗口大小printf("TCP校验和:
%d",ntohs(tcp_header->ChkSum));//TCP校验和printf("紧急指针:
%d\n",ntohs(tcp_header->UrgPtr));//紧急指针printf("====================\n");}}
}
4.3运行结果
图4-1单次捕获TCP数据包
图4-2循环捕获TCP数据包(守护进程)
五.总结
5.1提出问题
在用捕获数据包时,没有选择我的IP进行数据包捕获的按钮,导致一直没有捕获到任何的数据包。
但除了设置IP,仍旧无法捕获到数据包,后来通过查询资料获知,网卡要设置成混杂模式才可以接收所有的数据包,将网卡设置成混杂模式之后,程序才捕获到了数据包。
5.2解决问题
后来查阅资料时,发现了这一个错误,因为没有选择针对那个IP进行捕获,根本没有源IP,当然没有数据包,这使我的设计刚开始就频频出错。
并将网卡设置成混杂模式,改正后立即可以捕获数据包。
六.心得体会
经过两周的课程设计,刚开始时还认为两周时间还是很长,有足够的时间完成这个设计,想不到一眨眼间,两周的时间就这样匆匆过去了。
现在感觉到时间过得真快,从一开始对抓包没有任何基础的,现在已能对数据包进行简单的分析,以及怎么样设置这个软件的参数。
在用VisualC++编程的这一步中,实在花了不少时间,这个是在我这个设计中最难的一步,虽然在网上能找到相关程序,但所找到的那些程序都基本上有一两处错误,而对于我这个只有一点VisualC++基础的来说无疑是一个天大的麻烦。
但是,经过这两周的努力,还是能改正了这些错误,而且在同学的帮助下,终于把这个程序给做出来了。
经过这一次的设计,这对以后的工作需要提供了很大的帮助。
七.致谢
感谢在这次课程设计中帮助过我的同学,还有在设计过程中给老师带来了诸多麻烦,很感谢您这么细心的为我讲导。
我想,否则这次课程我不可能按时完成。
其中许多不足,还请老师给与批平、指正。
八.参考文献
[1]梁亚声等.计算机网络安全教程.第2版.北京:
机械工业出版社,2008
[2]刘文涛.网络安全编程技术与实例.北京:
机械工业出版社2008
[3]谢希仁.计算机网络.北京:
电子工业出版社,2008.1
[4]薛辉.网络数据获取方法浅析.网络安全技术.2007
[5]秦根建.网络数据包截获机制研究.兵工自动化,2003,22(6):
2-3.
[6]刘文涛.网络安全开发包详解.电子工业出版社,2005:
88-103.
[7]谢希仁.计算机网络.电子工业出版社,2003:
34-40.
[8]BehrouzAForouzan,SophiaChungFegan.TCP/IP协议族.
谢希仁,译.北京:
清华大学出版社,2006:
24-29.
[9]郑明雄,李辉,蒋朝根.基于NDIS中间层的包截获及分析处理.现代计算机,2004,20(3):
65-66.
[10]董玉格,金海.攻击与防护网络安全技术.人民邮电出版社,2002:
23-27.
[11]谭思亮.监听与隐藏网络侦听与数据保护.人民邮电出版社,2002:
8-10.
[12]刘锋,陶然.网络对抗.北京:
国防工业出版社,2003:
34-36.
[13]DouglasEComer.计算机网络与Internet—网络应用,2002:
67-69.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 技能 训练
![提示](https://static.bdocx.com/images/bang_tan.gif)