用C++实现网络编程---抓取网络数据包的实现方法

论坛 期权论坛     
选择匿名的用户   2021-5-28 02:08   19   0
<p>做过网管或协议分析的人一般都熟悉sniffer这个工具,它可以捕捉流经本地网卡的所有数据包。抓取网络数据包进行分析有很多用处,如分析网络是否有网络病毒等异常数据,通信协议的分析(数据链路层协议、IP、UDP、TCP、甚至各种应用层协议),敏感数据的捕捉等。下面我们就来看看在windows下如何实现数据包的捕获。 </p>
<p>下面先对网络嗅探器的原理做简单介绍。</p>
<p><strong><font size="2">嗅探器设计原理</font></strong></p>
<p><font size="2">  嗅探器作为一种</font><font size="2">网络</font><font size="2">通讯程序,也是通过对网卡的编程来实现</font><font size="2">网络</font><font size="2">通讯的,对网卡的编程也是使用通常的</font><font size="2">套接字</font><font size="2">(socket)方式来进行。但是,通常的套接字程序只能响应与自己硬件地址相匹配的或是以广播形式发出的数据帧,对于其他形式的数据帧比如已到达</font><font size="2">网络</font><font size="2">接口但却不是发给此地址的数据帧,</font><font size="2">网络</font><font size="2">接口在验证投递地址并非自身地址之后将不引起响应,也就是说应用程序无法收取到达的数据包。而</font><font size="2">网络</font><font size="2">嗅探器的目的恰恰在于从网卡接收所有经过它的数据包,这些数据包即可以是发给它的也可以是发往别处的。显然,要达到此目的就不能再让网卡按通常的正常模式工作,而必须将其设置为混杂模式。</font> </p>
<p><font size="2">具体到编程实现上,这种对网卡混杂模式的设置是通过原始套接字(raw socket)来实现的,这也有别于通常经常使用的数据流套接字和数据报套接字。在创建了原始套接字后,需要通过setsockopt()函数来设置IP头操作选项,然后再通过bind()函数将原始套接字绑定到本地网卡。为了让原始套接字能接受所有的数据,还需要通过ioctlsocket()来进行设置,而且还可以指定是否亲自处理IP头。至此,实际就可以开始对</font><a class="wordstyle" href="http://www.kuziyuan.com/softdevp/25/" rel="noopener noreferrer" target="_blank"><font size="2">网络</font></a><font size="2">数据包进行嗅探了,对数据包的获取仍象流式套接字或数据报套接字那样通过recv()函数来完成。但是与其他两种套接字不同的是,原始套接字此时捕获到的数据包并不仅仅是单纯的数据信息,而是包含有 IP头、 TCP头等信息头的最原始的数据信息,这些信息保留了它在</font><a class="wordstyle" href="http://www.kuziyuan.com/softdevp/25/" rel="noopener noreferrer" target="_blank"><font size="2">网络</font></a><font size="2">传输时的原貌。通过对这些在低层传输的原始信息的分析可以得到有关</font><a class="wordstyle" href="http://www.kuziyuan.com/softdevp/25/" rel="noopener noreferrer" target="_blank"><font size="2">网络</font></a><font size="2">的一些信息。由于这些数据经过了</font><a class="wordstyle" href="http://www.kuziyuan.com/softdevp/25/" rel="noopener noreferrer" target="_blank"><font size="2">网络</font></a><font size="2">层和传输层的打包,因此需要根据其附加的帧头对数据包进行分析。下面先给出结构.数据包的总体结构:</font></p>
<p> </p>
<table border="1" cellpadding="0" cellspacing="0" width="43%"><tbody><tr align="center"><td colspan="3"><font size="2">数据包</font></td></tr><tr><td align="center" width="24%"><font size="2">IP头</font></td><td align="center" width="61%"><font size="2">TCP头(或其他信息头)</font></td><td align="center" width="15%"><font size="2">数据</font></td></tr></tbody></table>
<p></p>
<p><font size="2">  数据在从应用层到达传输层时,将添加TCP数据段头,或是UDP数据段头。其中UDP数据段头比较简单,由一个8字节的头和数据部分组成,具体格式如下:<br></font></p>
<p> </p>
<table border="1" cellpadding="0" cellspacing="0" width="55%"><tbody><tr><td><font size="2">16位</font></td><td><font size="2">16位</font></td></tr><tr><td><font size="2">源端口</font></td><td><font size="2">目的端口</font></td></tr><tr><td><font size="2">UDP长度</font></td><td><font size="2">UDP校验和</font></td></tr></tbody></table>
<p></p>
<p><font size="2">  而TCP数据头则比较复杂,以20个固定字节开始,在固定头后面还可以有一些长度不固定的可选项,下面给出TCP数据段头的格式组成:<br></font></p>
<p> </p>
<table border="1" cellpadding="0" cellspacing="0" width="69%"><tbody><tr><td align="center" colspan="8"><font size="2">16位 </font></td><td align="center" width="48%"><font size="2">16位</font></td></tr><tr><td align="center" colspan="8"><font size="2">源端口</font></td><td align="center" width="48%"><font size="2">目的端口</font></td></tr><tr align="center
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP