江西卫视节目预告网络数据包生成技术

摘 要:数据包是TCP/IP通信传输中的数据单位,了解数据包的生成原理,可以帮助我们更好的理解网络中的数据传送和更有效的分析一些网络问题。数据包的构成主要以TCP/IP模型中的各个协议为基础,包括tcp协议、udp协议、ip协议和icmp协议等。在windows下,原始套接字、winpcap、和libnet是生成和发送数据包常用的3种方法。本文主要讨论了在各个协议下数据包的结构以及上述3种方法生成数据包的基本原理。

关键词:rawsocket;winpca;libnet;tcp/ip协议族;数据包

中图分类号:TP3 文献标识码:A 文章编号:1009-0118(2012)-03-0-02

一、数据包结构分析

(一)IP数据包

1、IP协议

(1)是点对点协议,虽然IP数据报携带源IP和目的IP地址,但进行数据传输时的对等实体一定相邻设备(同一网络中)的对等实体。

(2)IP协议不保证传输的可靠性,不对数据进行差错校验和跟踪,可靠性有IP的上层TCP协议加以保证。

(3)IP协议提供无连接数据报服务,各个数据报独立传输,可能沿着不同路径到达目的地,也可能不按序到达目的地。

正因为IP协议采用尽力传输的思想,所以IP协议的效率非常高,实现也简单。IP层向下要面对各种不同的物理网络,向上却提供一个同一的数据传输服务。通过IP数据报实现了物理数据帧的同一,IP层达到了向上屏蔽底层差异的目的。IP协议位于网络层,是因特网的核心协议,除了ARP和RARP报文外,几乎所有的数据都要经过IP协议进行发送。由于IP协议在网络层中具有重要地位,人们又将TCP/IP协议的网络层称为IP层。

2、IP数据包结构

(1)版本(VER):4位,表示数据报的IP协议版本,当前的IP协议版本号为4,即IPv4;下一代网络协议IPv6,版本号为6。

(2)首部长度(HLEN):4位,表示以字长(4字节)为单位的数据报首部长度。

(3)服务类型(SERVICETYPE):8位,规定本数据报的处理方式。前三位是优先级,0-7,0表示最低,7最高(最重要),但目前的IPv4没有使用优先级。后4位是TOS,表示本数据报在传输过程中所希望得到的服务,D--最小延迟(minimizedelay);T--最大吞吐率(maximizethroughout);R--最高可靠性(maximizereliability);C--最低成本(minimizecost)。

数据报总长度:总长度定义了IP数据报的总长度。这是一个2个字节的字段,可以定义长达65536个字节。

(4)标识(IDENTIFICATION):16位每个IP数据报都有一个本地唯一的标识符,它由信源机赋予IP数据报。每次自动加1。

(5)标志(FLAGS):3位,表示该IP数据报是否允许分片以及是否最后一片。

(6)片偏移(FRAGMENTATIONOFFSET):表示本片数据在他所属原始数据报数据区的偏移量。

(7)生存时间(timetolive,TTL):8位,生存期字段定义了数据报在被丢弃钱可以传输的跳数,防止数据报在路由器之间反复的传输。

(8)协议(IPPROTOCOL):8位,指明被IP数据报封装的协议:ICMP=1,IGMP=2,TCP=6,EGP=8,UDP=17,OSPF=89。

(二)TCP数据包

1、TCP协议

TCP是一种面向连接的、可靠的传输层协议;TCP协议建立在不可靠的网络层IP协议之上,IP不能提供任何可靠性机制,TCP的可靠性完全由自己实现,它在网络层IP服务的基础上,向应用层提供面向连接、可靠的流传输。

2、TCP数据包结构

(1)源端口地址:源端口地址定义了源计算机上的应用程序。

(2)目的端口地址:源端口地址定义了目的计算机上的应用程序。

(3)序列号:来自应用程序的数据流可以分为两个或者更多的TCP段。序列号字段显示了数据在原始数据流中的位置。

(4)确认号:32位的确认号用来确认接收来自其他通信设备的数据。这个序号只有在控制字段中设置了ACK为以后才有效,它定义了下一个期望收到的字节序列号。

(5)保留:6位的字段预留给将来使用。

(6)控制位:6位的控制字段中的每位都有独特的功能。它即可定义段的用途,也可以用作其他字段的有效性检查。当URG位被设置时,它验证紧急指针的有效性。这个位和紧急指针一起指明了段中的数据是紧急的。当ACK位被设置时,它验证确认号字段的有效性。PSH为用来通知发送方需要更高的吞吐量。RST位用于在序列号出现混乱时重置连接。SYN位在以下三种类型的段中用于序列号同步:连接请求、

连接确认(ACK未被设置)以及验证确认(ACK未被设置)。FIN位在三种类型的段中用于连接终止:终止请求、终止验证(ACK未被设置)以及终止验证的确认(ACK未被设置)。

(7)窗口大小:窗口是一个16位的字段,它定义了滑动窗口的大小。

(8)校验和:校验和是一个16位的字段,用在差错检验中。

(9)紧急指针:这是报文头中的最后一个字段。只有在控制字段中的URG位被设置后才能有效。在这种情况下,发送方通知接收方段中的数据是紧急数据,这个指针定义了紧急数据的结尾和普通数据的开始。

选项和填充:TCP报文头中的其余部分定义了可选字段。它们用来给接收方传送附加的信息,或者用来对齐数据。

(三)UDP数据包

1、UDP协议特点

(1)UDP是一个无连接协议,传输数据之前源端和终端不建立连接当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、计算机的能力和传输带宽的限制;在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段。

(2)由于传输数据不建立连接,因此也就不需要维护连接状态,包括收发状态等,因此一台服务机可同时向多个客户机传输相同的消息。

(3)UDP信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包的额外开销很小。

(4)吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、源端和终端主机性能的限制。

(5)UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的链接状态表(这里面有许多参数)。

(6)UDP是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付给IP层。既不拆分,也不合并,而是保留这些报文的边界,因此,应用程序需要选择合适的报文大小。

2、UDP数据包结构

(1)源端口地址:源端口地址是创建报文的应用程序的地址。

(2)目的端口地址:目的端口地址是接收报文的应用程序的地址。

(3)总长度:总长度定义了用户数据报的总长度,以字节为单位。

(4)校验和:校验和是用在差错检测中的16位字段。

二、基于原始套接字、winpcap、libnet生成数据包原理

(一)原始套接字工作原理及规则

1、使用原始套接字时应该注意的问题

(1)对于UDP/TCP产生的IP数据包,内核不将它传递给任何原始套接字,而只是将这些数据交给对应的UDP/TCP数据处理句柄(所以,如果你想要通过原始套接字来访问TCP/UDP或者其它类型的数据,调用socket函数创建原始套接字第三个参数应该指定为htons(ETH_P_IP),也就是通过直接访问数据链路层来实现。

(2)对于ICMP和EGP等使用IP数据包承载数据但又在传输层之下的协议类型的IP数据包,内核不管是否已经有注册了的句柄来处理这些数据,都会将这些IP数据包复制一份传递给协议类型匹配的原始套接字。

(3)对于不能识别协议类型的数据包,内核进行必要的校验,然后会查看是否有类型匹配的原始套接字负责处理这些数据,如果有的话,就会将这些IP数据包复制一份传递给匹配的原始套接字,否则,内核将会丢弃这个IP数据包,并返回一个ICMP主机不可达的消息给源主机。

2、编程选项

(1)bind函数:调用bind函数后,发送数据包的源IP地址将是bind函数指定的地址。如是不调用bind,则内核将以发送接口的主IP地址填充IP头。如果使用setsockopt设置了IP_HDRINCL(headerincluding)选项,就必须手工填充每个要发送的数据包的源IP地址,否则,内核将自动创建IP首部。

(2)connetc函数:调用connect函数后,就可以使用write和send函数来发送数据包,而且内核将会用这个绑定的地址填充IP数据包的目的IP地址,否则的话,则应使用sendto或sendmsg函数来发送数据包,并且要在函数参数中指定对方的IP地址。

综合以上种种功能和特点,我们可以使用原始套接字来实现很多功能,比如最基本的数据包分析,主机嗅探等。其实也可以使用原始套接字作一个自定义的传输层协议。

(二)基于winpcap的原理

Winpcap是Win32平台下的数据包捕获和网络分析构架。它包含了一个核心级的包过滤器,低级的动态链接库(Packet.dl1)和一个高级并且系统独立的链接库(Wpcap.dl1)。

由于捕获系统要绕过系统的协议栈直接访问网络数据,这就需要在操作系统内核中,有一部分直接与网卡驱动交互。这一部分是系统相关的,在Winpcap的解决方案中是通过一个设备驱动――NPF(NetgroupPacketFilter)来实现的。NPF驱动提供了例如包捕获和发送的基本功能,也提供了更高级的可编程过滤系统和监视系统。捕获系统实现了用户级应用程序与内核间的接口:Packet.dll和Wpcap.Dll。

利用Winpcap的库函数可以将指定数据缓冲区中的数据发送出去。其中发送函数为“intpcap_sendpacket(pcap_t*P,u_char*buf,intsize)”,此函数用来发送一个原始数据包,即从链路层的数据开始发送。这也就意味着在流程的第一步构造发送缓冲区数据时,需要自顶向下构造应用层数据、传输层数据、网络层数据和链路层数据。从这里表现出Winpcap比socketAPI函数对数据包具有更深层次的控制能力,后者只能控制数据封装到网络层。Winpcap比socketAPI的功能强大得多。函数参数中的P是控制打开网卡的句柄,buf指向准备发送的数据帧,size表示发送的数据长度。

(三)基于libnet的原理

Libnet生成数据包的方法很具有模块化,一个协议类型就是一个协议块,要构造一个完整的网络数据包,只需要给出此数据包的各个协议块,然后libnet把他们组合在一起发送出去。

1、内存初始化:libnet_init(intinjection_type,char*device,char*err_buf)

injection_type表示构造的类型;

device表示网络接口;

err_buf表示存放出错的信息。

2、释放内存:libnet_destroy( )。参数为libnet构建的对象。

3、数据包构造:libnet_build( ),参数为对应的协议参数。

4、数据包发送:libnet_write_ipproto( ),ipproto表示网络协议,参数为libnet构建的对象。

参考文献:

[1]刘文涛.网络安全编程技术与实例[M].机械工业出版社,2008.

[2]殷肖川.网络编程与开发技术[M].西安交通大学出版社,2008.

[3]刘文涛.网络安全开发包详解[M].北京电子工业出版社,2005.