基于WinPcap的NAT路由设计与实现
2013-01-29洪进栋焦凤先
洪进栋,焦凤先,魏 榕
(1.西安电子科技大学电子工程学院,陕西西安 710126;2.西安电子科技大学通信工程学院,陕西西安 710126;3.西安电子科技大学微电子学院,陕西西安 710126)
随着网络技术的发展,各种网络终端越来越多;使用NAT技术接入Internet的小型局域网在家庭、实验室等场合的应用更加普及。然而,无论是Windows自带的Internet共享(NAT)功能,还是传统小型路由器,一般都不具备流量监控、网络监管、数据过滤功能,无法满足网络安全的需求。
要在Windows自带NAT的基础上加入上述功能,由于该模块工作于内核模式下,需要通过加入Windows内核模块实现,开发难度较高。为解决这一问题,本文提出了一种工作于Windows用户模式的NAT路由器,并使用WinPcap实现了该方案。该路由预留了过滤层接口,能够快速加入流量监控、网络监管、数据过滤的功能。
1 原理介绍
1.1 NAT路由原理
NAT(Network Address Translation,网络地址转换)是一种将实现局域网内每个节点的私有IP地址转换成一个统一的公有IP地址和相应的反向转换的技术,从而实现多个网络终端共用一个公有IP地址接入互联网。
NAT路由器的核心功能是在内网发送网络数据包时,将内部私有IP地址翻译成外部合法公有IP地址;在接收到外网数据包时,将外部IP地址翻译回内部对应的私有IP地址。同时,有部分数据包仅在外部网络进行通信,或者在内部网络进行通信,不需要在内部和外部网络之间相互转发,因而这部分数据包不需要进行地址转换。
NAT的实现机制是将某一对私有IP地址、端口和公有IP地址的某个端口建立映射关系,并将这两个端口的数据包经过替换IP、端口等处理之后相互转发。
NAT技术解决了IP地址紧缺的问题,实现公有和私有IP地址之间的映射,而且能使内部和外部的网络隔离,提供一定程度的网络安全保障。因而,NAT技术在中小型局域网广泛应用,使得多个终端共用一个公有IP地址上网。
在典型的小型局域网中,NAT路由器通常分为2组端口,一组称为WAN口,配置公有IP接入互联网;另一组端口称为LAN口,配置私有IP接入局域网。NAT路由完成者2组端口之间的数据转发工作。
1.2 WinPcap工作原理
WinPcap是一个用于捕获、处理网络数据包析的开源库,应用于 Windows平台[1]。
在Windows平台下,大多数网络应用程序通过诸如Sockets等操作系统元件来访问网络。该方法的优点是简单,且类似于文件读写,因为操作系统已经妥善处理了底层具体实现细节。然而,实现NAT路由需要直接发送和接收网络中的原始数据包,即没有被操作系统利用网络协议处理过的数据包[2]。本项目通过WinPcap来实现访问网络原始数据包。
图1 WinPcap结构图
WinPcap就是一个能为Win32应用程序提供访问网络原始数据包的开源库,主要提供了以下功能:(1)捕获原始数据包,包括发往本机和其他终端的数据包。(2)根据用户指定的规则过滤数据包,然后再将剩余数据包发到给应用程序。(3)使用网络适配器将原始数据包发送到网络中。(4)收集并统计网络流量信息。
WinPcap借助安装在Win32内核中的网络设备驱动程序,以及几个动态链接库dll实现了上述功能;并且,WinPcap将这些功能都规范成统一的编程接口,使得访问网络原始数据包变得较容易,并能在不同的Windows操作系统上使用[3]。
2 基于WinPcap的NAT路由的实现
在以上原理的基础上,就可用WinPcap实现NAT路由功能。本项目使用一台配置两个网卡的Windows平台;其中一个网卡作为外网网卡,配置公有IP地址接入互联网,另一个网卡作为内网网卡,配置私有IP接入局域网;所开发的NAT路由软件就是需要完成这个两个网卡之间数据包的转发以及对应的NAT协议处理,如图2所示。
图2 基于WinPcap的NAT路由工作流程
2.1 数据包捕获及预处理
数据包捕获是指使用WinPcap从外网网卡和内网网卡获得网络原始数据包,预处理则完成部分数据包的筛选工作。
㉔陈国青等:《工商管理学科“十三五”发展战略与优先资助领域研究报告》,科学出版社2016年版,第101页。
首先,获得已连接的网络适配器(即网卡)列表。WinPcap提供了pcap_findalldevs_ex()函数来实现此功能:这个函数返回一个 pcap_if结构的链表,每个pcap_if结构都包含了一个适配器的详细信息。pcap_if结构数据域name和description表示一个适配器名称和一个描述。获取网络适配器列表后,就可利用pcap_open()函数打开网络适配器[2]。
然后,从列表中选择外网网络适配器和内网网络适配器,并使用pcap_open()函数打开它们。当适配器被打开,捕获工作就可以用pcap_loop()进行。这个函数有一个回调参数packet_handler,指向一个可以处理所接收数据包的函数。这个函数会在收到每个新的数据包时被WinPcap所调用,并向该函数提供一个指向pcap_pkthdr和 pkt_data结构指针。pcap_pkthdr结构一般有一些诸如时间戳、数据包长度的信息;pkt_data结构则包含了网络中的实际数据。
在回调函数中,我们对捕获的数据包进行预处理:筛选了TCP、UDP、ARP数据包存放到缓冲池,对于其他协议的数据包,直接丢弃。需要注意,将从内网网卡和外网网卡捕获的数据包分别存储到单独的缓冲池。
2.2 缓冲池设计
为提高程序处理数据包的效率,利用Queue(队列)这种数据结构实现一个缓冲池。
程序使用的缓冲池设计如下:缓冲池由2个工作Thread(线程)和一个Queue组成,一个线程负责把数据包放到Queue里面,而另一个Thread就依次取出这些数据包并进行处理。
Queue的一个经典实现是使用一个循环数组,如一个大小为size的数组,这个循环数组可以被想象成首尾相连的一个环。同时,使用first指针指向Queue中最早存入的数据的位置,next指向下一个可以放新数据的位置[4]。
当添加一个新数据到到Queue时,该数据被存到next的位置,同时需要更新next:next=(next+1)%size;
当first==next的时候,Queue为空;
当(next+1)%size==first时,Queue为满。
注意,为了区分Queue为空和为满的情况,实际上Queue里面最多能放size-1个数据。
在本项目中,Queue会同时被2个线程访问,需要考虑在多线程的情况下Queue如何正常工作,因而,采取了以下措施:首先,Queue是线程安全,使用Windows API提供的互斥体Mutex来确保同时只有一个Thread在访问Queue;其次,要防止Queue为空的取出数据操作,或者Queue为满的时候的数据存入操作。在多线程访问遇到这种情况时,一般希望执行操作的线程可以等待直到该操作可以进行下去。通过wait和notify方法使Thread在上述两种操作进行时等待(block),直到访问Queue另一个进程存入或取出数据。
在本项目中,由接收网络数据包的线程将网络数据包放到Queue里,由处理数据包并转发的线程负责取出数据包;并且,为两个网络适配器分别实例化了一个互相的独立的Queue。
2.3 协议分析及数据包处理
WinPcap接收到的网络原始数据包只包含帧头和载荷部分。NAT路由的核心工作是转发IP层的TCP和UDP数据包[5]。因而,协议分析则是将接收到的类型为TCP和UDP数据包分解为对应的9个部分并进行分析,即目的MAC、源MAC、帧类型、目的IP、目的端口、源IP、源端口、IP校验和以及数据。
在对数据包记性协议分析后,可以针对特定的数据包进行过滤,可完成流量统计、网络行为控制等功能。在本项目中,预留了过滤层接口,用于进一步扩展功能。
对于数据包的NAT转换处理,需要对内网发送的数据包和外网接收的数据包做不同的处理;在数据处理之前,初始化化了一个空路由表,路由表单条记录的格式为:内网IP、端口、MAC地址、外网端口。
对于内网发送的数据包,完成NAT转换的数据处理如下:(1)根据数据包的源IP、端口,在路由表查找内网IP、端口都相同的记录,如果存在相应的记录,则获取其外网端口;否则,选用一个未占用的外网端口,新建一条路由记录;(2)将数据包的源端口替换成上一步获取的端口,同时将源IP、源MAC替换成外网网卡的IP、MAC地址,目的MAC地址替换成外网下一跳的MAC地址。(3)重新计算IP校验和。
对于接收到的外网数据包,完成NAT转换的数据处理过程如下:(1)根据数据包的目的端口,在路由表查找外网端口相同的记录,如果存在,则获取内网IP、端口、MAC地址;否则,丢弃该数据包。(2)将数据包的目的IP、端口、目的MAC地址替换成上一步获取到的内网IP、端口、MAC地址,同时将源MAC替换成本机内网网卡的MAC地址。(3)重新计算IP校验和。
数据包处理完成后,该数据包就可以被转发了。
2.4 数据包转发
在一个网卡上捕获的数据包,按照NAT协议,经过内外网地址转换、端口转换后,需要在另一个网卡上发送。WinPcap的Pcap_sendpacket()函数提供了一个简单而又直接的方法来发送一个数据包;同时,由于对于发送数据包,WinPcap内部已经有缓冲机制,本项目中不需要缓冲发送队列。
3 实验结果
测试环境:Windows Server 2003服务器一台,服务器配置两块百兆网卡,其中一块网卡接入Internet,另一块网卡接交换机设备,与若干台客户机连接形成内网。
Windows Server 2003服务器运行上述NAT路由器,为内网电脑提供Internet接入共享;手动为内网设备分配私有IP。测试软件采用通用路由测试软件IxChariot测试。
测试结果:在功能测试方面,在内网的客户机均能通过服务器的网络共享正常上网,说明路由器功能正常。
同时测试本方案的NAT路由和Fast FW300R小型家用路由器,结果如表1所示。
表1 测试结果对比
在实际使用中,内网访问互联网的速度最高可达65 Mbit·s-1,能满足一般小型局域网的要求。
4 结束语
设计了一种工作于Windows用户模式的NAT路由器,并使用WinPcap实现了这种方案;经测试,该路由器功能正常,性能能够达到中档路由器的水平,预留的过滤层可以满足功能扩展的需求。
[1] 胡晓元,史浩山.WinPcap包截获系统的分析及其应用[J].软件技术与数据库,2005(2):96 -99.
[2] 于雷.WinPcap在网络监听管理中的应用研究[J].电脑知识与技术,2012,8(7):59 -62.
[3] 李延会,岳彩祥,徐金艳,等.基于Winpcap的数据包捕获和协议分析系统的设计与实现[J].中国科技信息,2009(10):89-92.
[4] 王丽珍.数据仓库与数据挖掘原理及应用[M].北京:科学出版社,2005.
[5] 李小玲,周金治.网络地址转换技术在计算机网络上的应用[J].山东科技大学学报:自然科学版,2004(2):168 -172.