Windows系统内核网络堆栈实现简述

了解windows平台内部网络堆栈实现架构,对于我们开发 NDIS驱动,TDI驱动,WSK驱动,WFP驱动等网络驱动更有帮助。
因为windows并不是开源系统,不像linux那样可以从源代码中详细了解网络堆栈的实现流程,
所以只能从MSDN文档,WDK驱动开发包的实例代码,以及网络上零碎的资料来做个大致的了解。
我们从底层往上层一直到用户层了解win7的网络堆栈流程。
最底层的是NDIS驱动结构,这个是跟网卡相关的接口规范,NDIS接口规范是比较优秀的,
至少比linux在这方面做得好,因为想在linux中做个拦截链路层数据包的驱动,都找不到一个通用的接口代码。
NDIS又分为三层,最底层的是微端口驱动,是直接操作物理网卡的驱动,由她来管理物理网卡从物理网络上收发数据包,
第二层是NDIS中间驱动。他的功能比较神奇,既可以拦截数据包,又可以实现复合网卡等功能。
他朝下提供的是协议驱动接口,朝上提供的是微端口驱动接口,所以他是把最底层和最上层的结合到一块了。
NDIS最上一次是协议驱动。这一层的所有的协议驱动,都是平等级的,平等的获取来自各个网卡的各种数据包,
然后分析处理自己感兴趣的数据包。比如 tcpip.sys 就是windows里最著名的协议驱动。
NDIS的三层模式从最早的windows版本到最新版本,都是兼容的。
从WIN7以后,又出现了 NDIS Filter,这个是属于NDIS第2层,就是中间驱动那一层,
如果我们只是过滤数据包,按照原来的中间驱动做法,既要开发一个微端口又要开发一个协议驱动,非常麻烦,
所以NDIS Filter结合了两者,极大的简化了我们开发NDIS过滤驱动的复杂度。
NDIS 从上而下:
NDIS 协议驱动(实现各种协议驱动,分析处理自己感兴趣的数据包,比如tcpip.sys处理ip包)
|
NDIS 中间驱动( win7之后出现新的 NDIS Filter)
|
NDIS微端口驱动(物理网卡)

我们接着往上走,来到 tcpip.sys协议驱动里,tcpip.sys实现 IP包的处理,
按照TCPIP层次结构,他分层为 网络层(IP层)和传输层(TCP/UDP层),都在这个驱动里实现,
至于 对IP包的分析以及TCP的组合重传等算法本来就复杂,但是也是通用的,我们可以从开源系统里找到TCPIP堆栈的实现影子。
我们只说windows平台相关的,
在WINXP以及以前的版本里,tcpip.sys协议驱动只向上层提供了 TDI接口 ,简单说就是tcpip.sys协议驱动创建一些标准设备,
(\Device\Tcp 对应TCP协议, \Device\Udp 对应UDP协议, \Device\rawIp 对应原始包, )
然后提供一些标准的 IRP请求命令,当上层驱动打开这些设备,发送IRP标准请求,就可收发网络数据包。
对windows来说,就是把网络包的处理变成windows内核中标准 IRP请求。
我们再开发标准的设备过滤驱动程序,挂载到这些标准设备栈上,拦截IRP命令,就能实现网络数据包的拦截修改等功能,
这就是我们在TDI开发中经常做的事情,虽然思路简单,但是这些IRP命令被微软搞得蛮啰嗦的,所以做来也就比较臃肿和啰嗦了。
至于 WIN7以后,tcpip.sys协议驱动向上提供的接口就非常丰富了,我们后面再描述。
再往上走,是afd.sys驱动,他负责管理网络套接字,比如每个套接字内部缓冲管理,端口管理等等。
最后那就是我们的应用层的套接字接口,比如我们在应用程序里调用 socket( AF_INET,SOCK_STREAM,0) 函数, 进入到 内核,
调用 afd.sys驱动里的 AfdCreate(函数名不一定正确),打开 TDI接口 \Device\Tcp 设备,朝这设备发送 IRP_MJ_CREATE命令,
如果我们安装了TDI过滤驱动,就能在过滤驱动里抓取到这个命令,我们就可以拦截处理了。
从上而下:
socket(.. SOCK_STREAM)
|
AfdCreate ( afd.sys驱动)
|
NtCreateFile( 打开 \Device\Tcp设备,发送 MJ_CREATE创建命令
| --> (TDI filter 标准的设备过滤驱动 )
TDI ( tcpip.sys实现的TDI接口做具体的处理)

再回到 win7以后的版本来,win7 在tcpip.sys上向上提供的接口非常的丰富,而此时TDI接口只是为了兼容作为一个附加组件被实现。
他提供 WSK(WinSock Kernel),就是内核态的套接字,这是以前版本没有的,我们可以在内核态使用套接字就跟在应用层那样使用。
比如我们要实现一个极致高效的服务器,在内核态就完成网络数据的处理,使用WSK就是最好的选择。
这个概念,linux版本很早就应该有了,我估计windows是仿照 linux的思路。
他提供WFP(windows Filter Platform),主要是过滤使用的,他同 NDIS Filter不一样的,他们位置都不一样,
WFP只是在 tcpip.sys 的NDIS协议层驱动里,向上层驱动提供数据包时候,所做的是更高层的过滤,
NDIS Filter是 NDIS中间驱动位置,更为底层和彻底的包过滤。
WFP像极了 linux系统里 的netfilter, 估计也是仿照linux思路开发的,但是 netfilter更简单。
netfilter只工作在IP层,只能filter 住 IP层的数据包,
而WFP分得更加细致,他能 filter网络层(IP层)的包,也能filter传输层(TCP层)的包,还能filter 更上层的包。

最后看看 作为兼容 TDI 是如何被tcpip.sys加载的, 我们在 win7以后的版本,能找到 一个叫 tdx.sys 的驱动,
他就是为了兼容 TDI接口的驱动模块,
当我们 应用程序调用 socket ,进入到 afd.sys驱动,
AfdCreate函数会检查 /Tcp/Udp/Rawip/Tcp6/Udp6/Rawip6 等六个设备是不是有我们的TDI过滤设备驱动,
如果有的话,就进入到 WINXP那样的流程,
否则就直接进入到 tcpip.sys 驱动处理(估计这时就直接调用WSK接口)。

以上就是粗浅的理解,大致流程是没什么问题,可能有些细节地方会有差错,不吝指教!

posted @ 2022-11-04 15:16  信易达  阅读(696)  评论(0编辑  收藏  举报