TCP/IP 协议驱动 (tcpip.sys) 分析

TCP/IP 协议驱动 (tcpip.sys) 分析

目录

  1. 概述
  2. 框架结构
  3. 核心数据结构
  4. 核心模块分析
  5. 工作流程图
  6. 数据流图
  7. 初始化序列
  8. 关键函数分析
  9. 构建配置

1. 概述

tcpip.sys 是 ReactOS 的网络协议驱动程序,实现了完整的 TCP/IP 协议栈。它位于 NT 执行体中的 Io 管理器NDIS 库 之间,为上层用户态应用程序(通过 Winsock)和下层 NDIS 微型端口驱动提供通信服务。

1.1 设计思想

ReactOS 的 TCP/IP 协议栈采用双栈架构

  • ReactOS 原生 IP 协议栈 (ip/ 目录):自己实现的 IPv4 网络层(IP、ARP、ICMP、路由转发)和传输层(TCP、UDP、Raw IP)
  • lwIP 协议栈 (lwip/ 目录):集成了 lwIP 2.x 第三方轻量级 TCP/IP 协议栈,通过 ip/lwip_glue/ 粘合层接入

其中 TCP/IP 协议栈的核心(TCP 传输层)直接从 Linux 内核 2.4.20 移植而来 ,完整保留了 Linux 内核的 struct sk_buffstruct sockstruct tcp_opt 等核心数据结构和 TCP 状态机逻辑。

1.2 双栈架构的设计原因

ReactOS 采用双栈架构而非单一栈,主要基于以下历史和技术考量:

1. 复用经过验证的 TCP 实现

TCP 协议的状态机极其复杂(11 个状态、状态转换、拥塞控制、RTT 估算、重传计时器等),从零实现不仅工作量大,而且容易引入难以发现的时序 bug。Linux 内核 2.4.20 的 TCP 实现已经过大量生产环境验证,将其移植到 ReactOS 可以快速获得一个健壮的 TCP 层,这是项目早期的务实选择。

2. 原生 IP 栈为 Windows TDI 框架而写

虽然 TCP 层移植自 Linux,但整个协议栈的运行环境是 Windows 内核(通过 TDI 接口与上层通信、通过 NDIS 接口与网卡驱动通信)。因此 IP 网络层(分片重组、路由转发)、ARP、ICMP、数据链路层(NDIS 协议驱动回调)等都是为 ReactOS 原生编写的,以无缝适配 Windows 驱动模型。Linux 的 net_deviceneigh 等数据结构不能直接在 NDIS 环境下工作。

3. lwIP 补充协议覆盖面

lwIP 是一个轻量级、独立于操作系统的 TCP/IP 协议栈实现,提供了原生 IP 栈未覆盖或实现不完善的协议特性:

  • IPv6 支持:原生栈主要面向 IPv4,lwIP 提供了完整的 IPv6 协议簇
  • DHCP 客户端:自动获取 IP 地址配置
  • DNS 解析:域名解析功能
  • PPP/PPPoE:拨号网络支持
  • TLS 上层:基于 altcp 的传输层安全抽象

将这些协议在原生栈中逐一实现需要大量开发工作,而 lwIP 以成熟的第三方库形式提供了开箱即用的方案。

4. 实际使用方式

在当前的 ReactOS 代码中,两个栈并非完全独立运行。通过 ip/lwip_glue/ 粘合层,部分协议功能可以借助 lwIP 实现的同时仍通过 TDI 暴露给上层应用。这种设计允许逐步将更多的协议处理从原生栈迁移到 lwIP,或者在特定场景下选择更合适的栈来处理特定类型的网络流量。

注:虽然工程结构上同时包含了两个 IP 栈的实现,但当前 ReactOS 系统实际运行时主要使用的是 ReactOS 原生 IP 协议栈,lwIP 栈处于可用但并非默认激活的状态。这种并存结构为未来的协议栈演进提供了灵活性。

1.3 架构总览

复制代码
用户态 (Winsock)
    |  TDI (Transport Driver Interface) → DeviceIoControl
    v
+------------------------------------------+
|  tcpip.sys                                |
|                                           |
|  +--------+  +--------+  +------------+  |
|  | TCP 设备|  | UDP 设备|  | RawIP 设备 |  |
|  +--------+  +--------+  +------------+  |
|                                           |
|  TDI 分发层 (dispatch.c)                   |
|    TDI_CONNECT/TDI_SEND/TDI_RECEIVE/...   |
|                                           |
|  +----------+  +----------+  +----------+ |
|  | TCP 模块  |  | UDP 模块  |  | RawIP 模块| |
|  | (Linux    |  +----------+  +----------+ |
|  |  2.4.20   |  +----------+  +----------+ |
|  | 移植)     |  | ICMP 模块 |  | Datagram | |
|  +----------+  +----------+  +----------+ |
|                                           |
|  IP 网络层 (ip.c / receive.c / transmit.c) |
|    协议表分发、分片重组、路由转发            |
|                                           |
|  ARP / 邻居缓存 / 路由表                    |
|                                           |
|  数据链路层 - LAN (datalink/lan.c)         |
|    NDIS 协议驱动接口                        |
+------------------------------------------+
    |  NdisSend / NdisRequest / ...
    v
+------------------------------------------+
|  NDIS 库 (ndis.sys)                       |
+------------------------------------------+
    |  MiniportXxx
    v
+------------------------------------------+
|  微型端口驱动 (e1000.sys, etc.)            |
+------------------------------------------+

2. 框架结构

2.1 模块组织

tcpip.sys 的源码位于 d:\reactos\drivers\network\tcpip\,组织结构如下:

2.1.1 驱动顶层 (tcpip/)
源文件 功能
main.c 驱动入口点 DriverEntry,创建设备对象,初始化各子系统
dispatch.c TDI IRP 分发处理(TDI_SEND/RECEIVE/CONNECT/LISTEN 等)
fileobjs.c 地址文件、连接端点、控制通道的文件对象管理
info.c TDI 信息查询/设置(InfoTdiQueryInformationEx
ainfo.c 地址信息查询
cinfo.c 连接信息查询
iinfo.c 接口信息查询
tinfo.c TCP 信息查询
ninfo.c NetBIOS 信息查询
buffer.c NDIS 数据包/缓冲区封装
lock.c 锁/同步操作封装
wait.c 等待/同步操作封装
proto.c 协议号提取工具
2.1.2 IP 网络层 (ip/network/)
源文件 功能
ip.c IP 模块初始化、接口管理、协议表注册/分发
receive.c IP 数据报接收、分片重组(RFC 815 算法)
transmit.c IP 数据报发送、分片处理
interface.c IP 接口管理(注册/注销/查找)
address.c IP 地址管理(IPv4/IPv6)
router.c 路由表管理(创建/查找/删除路由)
route.c 路由缓存和转发决策
arp.c ARP 协议(发送/接收/缓存管理)
neighbor.c 邻居缓存(NCE - Neighbor Cache Entry)
icmp.c ICMP 协议(回显请求/响应、错误报告)
checksum.c IP/TCP/UDP 校验和计算(含 x86 汇编优化)
loopback.c 回环接口适配器
ports.c TCP/UDP 端口分配管理
routines.c 辅助工具函数
2.1.3 传输层 (ip/transport/)
源文件 功能
tcp/tcp.c TCP 核心:连接管理、发送/接收窗口、重传计时器
tcp/accept.c TCP 监听/接受连接
tcp/event.c TCP 事件处理
tcp/if.c TCP 接口绑定/交互
udp/udp.c UDP 数据报发送/接收
rawip/rawip.c Raw IP 数据报发送/接收
datagram/datagram.c 数据报通用基础设施(请求队列、完成回调)
2.1.4 数据链路层 (datalink/)
源文件 功能
lan.c NDIS 协议注册、适配器绑定/解绑、ProtocolXxx 回调、数据包收发
2.1.5 lwIP 粘合层 (ip/lwip_glue/)
源文件 功能
ip.c lwIP IP 接口适配
memory.c lwIP 内存分配适配
sys_arch.c lwIP 系统层适配(线程/信号量/邮箱)
tcp.c lwIP TCP 适配
2.1.6 辅助模块
源文件 功能
chew/workqueue.c 工作队列(Chew - 异步任务调度)

2.2 TDI 接口

tcpip.sys 通过 TDI (Transport Driver Interface) 向上层提供网络服务。TDI 定义了传输层驱动的标准接口,包括:

TDI 设备对象 (创建于 DriverEntry):

  • \Device\Tcp --- TCP 设备,提供面向连接的流服务
  • \Device\Udp --- UDP 设备,提供无连接的数据报服务
  • \Device\Ip --- IP 设备,提供原始 IP 服务
  • \Device\RawIp --- Raw IP 设备,支持自定义协议号的原始套接字

TDI IRP Minor Function (定义在 dispatch.c):

Minor Function 处理函数 用途
TDI_CONNECT DispTdiConnect TCP 连接请求
TDI_LISTEN DispTdiListen TCP 监听请求
TDI_ACCEPT DispTdiAccept TCP 接受连接
TDI_DISCONNECT DispTdiDisconnect TCP 断开连接
TDI_SEND DispTdiSend TCP 数据发送
TDI_RECEIVE DispTdiReceive TCP 数据接收
TDI_SEND_DATAGRAM DispTdiSendDatagram UDP 数据报发送
TDI_RECEIVE_DATAGRAM DispTdiReceiveDatagram UDP 数据报接收
TDI_ASSOCIATE_ADDRESS DispTdiAssociateAddress 关联地址和连接
TDI_DISASSOCIATE_ADDRESS DispTdiDisassociateAddress 解除地址关联
TDI_SET_EVENT_HANDLER DispTdiSetEventHandler 设置事件回调
TDI_QUERY_INFORMATION DispTdiQueryInformation 查询连接/地址信息
TDI_SET_INFORMATION DispTdiSetInformation 设置信息

TDI 事件类型 (通过 TDI_SET_EVENT_HANDLER 注册):

事件 用途
TDI_EVENT_CONNECT 有新的连接到达
TDI_EVENT_DISCONNECT 连接断开
TDI_EVENT_RECEIVE 有数据可接收
TDI_EVENT_RECEIVE_DATAGRAM 有数据报可接收
TDI_EVENT_RECEIVE_EXPEDITED 有紧急数据可接收
TDI_EVENT_CHAINED_RECEIVE 链式接收
TDI_EVENT_CHAINED_RECEIVE_DATAGRAM 链式数据报接收
TDI_EVENT_ERROR 错误通知

2.3 文件对象类型

tcpip.sys 定义了三种文件对象类型:

文件对象类型 FsContext2 值 用途
地址文件 TDI_TRANSPORT_ADDRESS_FILE 绑定 IP 地址和端口(UDP/TCP 监听)
连接文件 TDI_CONNECTION_FILE TCP 连接端点(面向连接通信)
控制通道 TDI_CONTROL_CHANNEL_FILE 控制操作(信息查询/设置)

3. 核心数据结构

3.1 IP 数据包 (IP_PACKET)

定义在 ip.h(file:///d:/reactos/drivers/network/tcpip/include/ip.h#L77-L91):

c 复制代码
typedef struct _IP_PACKET {
    OBJECT_FREE_ROUTINE Free;           // 释放资源的函数
    UCHAR Type;                         // IP 地址类型 (IPv4/IPv6)
    UCHAR Flags;                        // 标记位
    BOOLEAN MappedHeader;               // Header 是否来自 MDL 映射
    BOOLEAN ReturnPacket;               // 是否需调用 NdisReturnPackets
    PVOID Header;                       // IP 头指针
    UINT HeaderSize;                    // IP 头大小
    PVOID Data;                         // 当前数据指针
    UINT TotalSize;                     // 数据包总大小
    UINT Position;                      // 当前逻辑偏移
    PNDIS_PACKET NdisPacket;            // 底层 NDIS 数据包
    IP_ADDRESS SrcAddr;                 // 源地址
    IP_ADDRESS DstAddr;                 // 目的地址
} IP_PACKET, *PIP_PACKET;

3.2 IP 接口 (IP_INTERFACE)

c 复制代码
typedef struct _IP_INTERFACE {
    LIST_ENTRY ListEntry;         // 链表入口
    KSPIN_LOCK Lock;              // 自旋锁
    PVOID Context;                // 下层 (LAN) 上下文
    UINT  HeaderSize;             // 链路层头大小 (如以太网 = 14)
    UINT  MinFrameSize;           // 最小帧大小
    UINT  MTU;                    // 最大传输单元
    UINT  Speed;                  // 链路速度
    UINT  Metric;                 // 接口跃点数
    IP_ADDRESS Unicast;           // 单播地址
    IP_ADDRESS PointToPoint;      // 点对点地址
    IP_ADDRESS Netmask;           // 子网掩码
    IP_ADDRESS Broadcast;         // 广播地址
    UNICODE_STRING Name;          // 适配器名称 (GUID)
    UNICODE_STRING Description;   // 适配器描述
    PUCHAR Address;               // 物理地址
    UINT  AddressLength;          // 物理地址长度
    UINT  Index;                  // 适配器索引
    LL_TRANSMIT_ROUTINE Transmit; // 链路层发送函数
    PVOID TCPContext;             // TCP 上下文
    SEND_RECV_STATS Stats;        // 收发统计
} IP_INTERFACE, *PIP_INTERFACE;

3.3 地址文件 (ADDRESS_FILE)

定义在 titypes.h(file:///d:/reactos/drivers/network/tcpip/include/titypes.h#L112-L120):

c 复制代码
typedef struct _ADDRESS_FILE {
    LIST_ENTRY ListEntry;
    LONG RefCount;
    OBJECT_FREE_ROUTINE Free;
    ERESOURCE Resource;                // 线程资源锁
    IP_ADDRESS Address;               // 本地 IP 地址
    USHORT Family;                    // 地址族
    USHORT Protocol;                  // 协议号
    USHORT Port;                      // 网络端口 (网络字节序)
    DATAGRAM_SEND_ROUTINE Send;       // 数据报发送函数
    PCONNECTION_ENDPOINT Connection;  // 关联的连接端点
    PCONNECTION_ENDPOINT Listener;    // TCP 监听器
    // ... 各种事件处理器和注册标记
} ADDRESS_FILE, *PADDRESS_FILE;

3.4 连接端点 (CONNECTION_ENDPOINT)

这是 TCP 的核心数据结构,包含 Linux 内核 struct tcp_opt 的完整移植:

复制代码
CONNECTION_ENDPOINT
├── 对象管理: RefCount, Free, Resource (ERESOURCE)
├── TCP 状态: State (LISTEN/SYN_SENT/ESTABLISHED/...)
├── 地址绑定: AddressFile, LocalAddress, RemoteAddress, LocalPort, RemotePort
├── TCP 选项/状态 (Linux struct tcp_opt 移植):
│   ├── 发送窗口: snd_una, snd_nxt, snd_wnd, snd_wl1/snd_wl2
│   ├── 接收窗口: rcv_nxt, rcv_wnd, rcv_wup
│   ├── 拥塞控制: ssthresh, cwnd
│   ├── RTT 估算: srtt, mdev, rto
│   └── 计时器管理: retransmit_timer, persist_timer, keepalive_timer, 2MSL_timer
├── 缓冲区队列:
│   ├── SendQueue/RecvQueue (PTDI_BUCKET)
│   ├── SendDataQueue (sk_buff 链表)
│   └── FastSendDataQueue
└── IRP 管理: RequestList, ConnectRequest, DisconnectRequest, SendRequest, ReceiveRequest

3.5 链路层适配器 (LAN_ADAPTER)

定义在 lan.h(file:///d:/reactos/drivers/network/tcpip/include/lan.h):

c 复制代码
typedef struct _LAN_ADAPTER {
    LIST_ENTRY ListEntry;          // 适配器链表入口
    KSPIN_LOCK Lock;               // 自旋锁
    NDIS_HANDLE NdisHandle;        // NDIS 打开句柄
    NDIS_STATUS NdisStatus;        // 异步操作状态
    KEVENT Event;                  // 同步事件
    PIP_INTERFACE Context;         // IP 接口指针
    // 硬件信息
    UCHAR HWAddress[IEEE_802_ADDR_LENGTH]; // MAC 地址
    UINT HWAddressLength;
    NDIS_MEDIUM Media;             // 介质类型
    UINT HeaderSize;               // 链路层头大小
    UINT MinFrameSize;             // 最小帧大小
    UINT MTU;                      // MTU 大小
    UINT MaxSendPackets;           // 最大发送包数
    UINT MaxPacketSize;            // 最大包大小
    UINT Speed;                    // 链路速度
    UINT PacketFilter;             // 数据包过滤器
    UINT MacOptions;               // MAC 选项
    LAN_STATE State;               // 状态机
    BOOLEAN CompletingReset;       // 是否完成重置
    LAN_STATE OldState;            // 重置前状态
} LAN_ADAPTER, *PLAN_ADAPTER;

3.6 全局链表体系

复制代码
                  全局地址文件列表 (AddressFileListHead)
                  ├── ADDRESS_FILE (TCP:80) ←→ ADDRESS_FILE (UDP:53)
                  ├── ...
                  
                  全局连接端点列表 (ConnectionEndpointListHead)
                  ├── CONNECTION_ENDPOINT (TCP ESTABLISHED)
                  ├── CONNECTION_ENDPOINT (TCP LISTEN)
                  ├── ...
                  
                  全局接口列表 (InterfaceListHead)
                  ├── IP_INTERFACE (e1000) ←→ IP_INTERFACE (loopback)
                  ├── ...
                  
                  包上下文链表 (PACKET_CONTEXT → DLComplete 回调链)
                  
                  重装列表 (ReassemblyListHead) --- IP 分片重组
                  ├── IPDATAGRAM_REASSEMBLY → HoleList + FragmentList
                  
                  协议表 (ProtocolTable[256]) --- 按协议号分发 IP 数据
                  ├── [IPPROTO_TCP=6] → TCPReceive
                  ├── [IPPROTO_UDP=17] → UDPReceive
                  ├── [IPPROTO_ICMP=1] → ICMPReceive
                  └── [IPPROTO_RAW=0] → RawIPReceive

4. 核心模块分析

4.1 驱动入口与初始化 (main.c)

DriverEntry 函数执行以下初始化步骤:

  1. 初始化 DPC 和计时器IPTimeoutDpc 用于 IP 超时处理(ARP 缓存过期、路由缓存清理等),每 IP_TIMEOUT (1000ms) 触发一次
  2. 创建 4 个设备对象\Device\Ip\Device\RawIp\Device\Udp\Device\Tcp
  3. 初始化工作队列ChewInit 创建异步工作队列
  4. 分配 NDIS 资源:500+1500 个数据包池、2000 个缓冲区描述符
  5. 初始化全局列表:地址文件列表、连接端点列表、接口列表
  6. 启动各子系统
    • IPStartup --- IP 网络层(初始化协议表、接口列表、重装列表、ARP 缓存)
    • RawIPStartup --- Raw IP 传输层
    • UDPStartup --- UDP 传输层
    • TCPStartup --- TCP 传输层
    • ICMPStartup --- ICMP 协议
  7. 初始化安全描述符
  8. 注册 IRP 分发函数IRP_MJ_CREATE/CLOSETiDispatchOpenCloseIRP_MJ_INTERNAL_DEVICE_CONTROLTiDispatchInternalIRP_MJ_DEVICE_CONTROLTiDispatch
  9. 创建回环适配器LoopRegisterAdapter
  10. 注册 NDIS 协议LANRegisterProtocol --- 通过 NDIS 绑定到所有微型端口

4.2 IRP 分发 (dispatch.c)

IRP 完成函数 IRPFinish:

  • 如果状态不是 STATUS_PENDING,取消 IRP 的取消例程并完成请求(增加网络优先级 IO_NETWORK_INCREMENT

内部 IOCTL 分发 TiDispatchInternal:

处理所有 TDI Minor Function,包括:

  • TDI_CONNECTDispTdiConnectTCPConnect (异步,通过 TCP_COMPLETION_ROUTINE 回调)
  • TDI_SENDDispTdiSendTCPSendData
  • TDI_RECEIVEDispTdiReceiveTCPReceiveData
  • TDI_SEND_DATAGRAMDispTdiSendDatagramUDP/RawIPSend 函数
  • TDI_RECEIVE_DATAGRAMDispTdiReceiveDatagramDGReceiveDatagram
  • TDI_LISTENDispTdiListenTCPListen + TCPAccept
  • TDI_SET_EVENT_HANDLERDispTdiSetEventHandler → 设置各类事件回调

设备 IOCTL 分发 TiDispatch:

  • IOCTL_TCP_QUERY_INFORMATION_EX --- TDI 扩展信息查询
  • IOCTL_TCP_SET_INFORMATION_EX --- TDI 扩展信息设置
  • IOCTL_SET_IP_ADDRESS --- 设置 IP 地址
  • IOCTL_DELETE_IP_ADDRESS --- 删除 IP 地址
  • IOCTL_QUERY_IP_HW_ADDRESS --- 查询硬件地址(通过 ARP)
  • IOCTL_ICMP_ECHO_REQUEST --- ICMP ping 请求

4.3 IP 网络层

4.3.1 IP 接收 (receive.c)

IPReceive 函数处理从链路层传入的 IP 数据报:

  1. 验证 IP 头(版本、校验和、总长度)
  2. 检查是否是本机地址(单播/广播/多播)
  3. 分片处理 (RFC 815 算法):通过 ReassemblyListHead 管理正在进行重装的 IP 数据报
    • 每个分片创建一个 IP_FRAGMENT 结构
    • 重组使用 IPDATAGRAM_REASSEMBLY + IPDATAGRAM_HOLE 描述空洞
    • 当所有片段到达后,组装完整数据报
  4. 调用 IPDispatchProtocolProtocol 字段分发给 TCP/UDP/ICMP 处理函数
4.3.2 IP 发送 (transmit.c)

IPTransmitPacket 处理 IP 数据报发送:

  1. 路由查找:通过 RouteGetRouteToDestination 查找目标路由
  2. MTU 分片 :如果数据报超过出接口 MTU,创建 IPFRAGMENT_CONTEXT 进行分片
    • 每片包含 IP 头 + 数据片段
    • 设置正确的 Fragment Offset 和 MF 标志
    • 重新计算校验和
  3. 通过 NBQueuePacket 将数据包放入邻居缓存发送队列
4.3.3 IP 协议表

IP 层维护一个 ProtocolTable[256] 的函数指针表,按协议号索引:

c 复制代码
IP_PROTOCOL_HANDLER ProtocolTable[IP_PROTOCOL_TABLE_SIZE];

// 注册
IPRegisterProtocol(IPPROTO_TCP, TCPReceive);
IPRegisterProtocol(IPPROTO_UDP, UDPReceive);
IPRegisterProtocol(IPPROTO_ICMP, ICMPReceive);

// 调用
ProtocolTable[IPHeader->Protocol](Interface, IPPacket);
4.3.4 IP 接口管理 (interface.c)
  • IPRegisterInterface --- 将新接口加入全局 InterfaceListHead
  • IPUnregisterInterface --- 从全局列表移除接口
  • AddrLocateInterface --- 根据 IP 地址查找对应的接口
  • IPCreateInterface --- 从 LLIP_BIND_INFO 创建接口
4.3.5 路由管理 (router.c / route.c)
  • RouterCreateRoute --- 添加路由(目标、掩码、下一跳、接口)
  • RouterRemoveRoute / RouterRemoveRoutesForInterface --- 删除路由
  • RouteGetRouteToDestination --- 查找最佳匹配路由
  • IPAddInterfaceRoute / IPRemoveInterfaceRoute --- 接口直连路由管理

4.4 传输层

4.4.1 TCP 模块 (tcp.c / accept.c / event.c / if.c)

TCP 实现直接从 Linux 内核 2.4.20 移植(见 tcpcore.h(file:///d:/reactos/drivers/network/tcpip/include/tcpcore.h) 注释),保留了:

  • 完整 TCP 状态机:CLOSED → LISTEN → SYN_SENT → SYN_RECEIVED → ESTABLISHED → FIN_WAIT_1/2 → CLOSE_WAIT → CLOSING → LAST_ACK → TIME_WAIT
  • 拥塞控制:慢启动、拥塞避免、快速重传、快速恢复
  • RTT 估算:SRTT、RTTVAR、RTO 计算
  • 滑动窗口:发送窗口、接收窗口、窗口通告
  • 计时器管理:重传计时器、坚持计时器、保活计时器、2MSL 计时器

关键函数:

函数 位置 功能
TCPSocket tcp.c(file:///d:/reactos/drivers/network/tcpip/ip/transport/tcp/tcp.c) 创建 TCP socket(初始化 Linux tcp_opt)
TCPConnect tcp.c(file:///d:/reactos/drivers/network/tcpip/ip/transport/tcp/tcp.c) 发起 TCP 连接(发送 SYN)
TCPListen accept.c(file:///d:/reactos/drivers/network/tcpip/ip/transport/tcp/accept.c) 进入监听状态
TCPAccept accept.c(file:///d:/reactos/drivers/network/tcpip/ip/transport/tcp/accept.c) 接受进入的连接
TCPReceiveData tcp.c(file:///d:/reactos/drivers/network/tcpip/ip/transport/tcp/tcp.c) 接收 TCP 数据
TCPSendData tcp.c(file:///d:/reactos/drivers/network/tcpip/ip/transport/tcp/tcp.c) 发送 TCP 数据
TCPDisconnect tcp.c(file:///d:/reactos/drivers/network/tcpip/ip/transport/tcp/tcp.c) 断开连接(发送 FIN/RST)
HandleSignalledConnection tcp.c(file:///d:/reactos/drivers/network/tcpip/ip/transport/tcp/tcp.c) TCP 事件处理(数据到达/状态变更)
4.4.2 UDP 模块 (udp.c)

UDP 实现相对简单:

  • UDPSend --- 构造 UDP 数据报并通过 IP 层发送
  • UDPReceive --- 接收 IP 层传来的 UDP 数据报,查找对应的地址文件进行分发
  • UDPStartup / UDPShutdown --- 初始化/清理
  • 端口管理通过 TCPAllocatePort / TCPFreePort 与 TCP 共享端口空间
4.4.3 Raw IP 模块 (rawip.c)
  • RawIPSend --- 构造并发送原始 IP 数据报
  • RawIPReceive --- 接收原始 IP 数据报
  • 支持自定义协议号的协议(通过文件对象名称中的数字指定)
4.4.4 ICMP 模块 (icmp.c)
  • ICMPReceive --- 处理 ICMP 回显请求(返回回显应答)和错误报告
  • ICMPTransmit --- 发送 ICMP 错误报告(如目的不可达)
  • ICMPEchoRequest --- 处理 ping 请求

4.5 数据链路层 (lan.c)

LAN 层是 tcpip.sys 与 NDIS 的直接接口,实现了 NDIS 协议驱动所需的所有回调:

4.5.1 NDIS 协议注册 (LANRegisterProtocol)

填充 NDIS_PROTOCOL_CHARACTERISTICS 并调用 NdisRegisterProtocol

c 复制代码
ProtChars.OpenAdapterCompleteHandler  = ProtocolOpenAdapterComplete;
ProtChars.CloseAdapterCompleteHandler = ProtocolCloseAdapterComplete;
ProtChars.ResetCompleteHandler        = ProtocolResetComplete;
ProtChars.RequestCompleteHandler      = ProtocolRequestComplete;
ProtChars.SendCompleteHandler         = ProtocolSendComplete;
ProtChars.TransferDataCompleteHandler = ProtocolTransferDataComplete;
ProtChars.ReceivePacketHandler        = ProtocolReceivePacket;
ProtChars.ReceiveHandler              = ProtocolReceive;
ProtChars.ReceiveCompleteHandler      = ProtocolReceiveComplete;
ProtChars.StatusHandler               = ProtocolStatus;
ProtChars.StatusCompleteHandler       = ProtocolStatusComplete;
ProtChars.BindAdapterHandler          = ProtocolBindAdapter;
ProtChars.PnPEventHandler             = ProtocolPnPEvent;
ProtChars.UnbindAdapterHandler        = ProtocolUnbindAdapter;
4.5.2 适配器注册 (LANRegisterAdapter)
  1. 分配 LAN_ADAPTER 结构
  2. 调用 NdisOpenAdapter 打开 NDIS 适配器
  3. 查询硬件地址、MTU、最大发送包数等
  4. 构建 LLIP_BIND_INFO 并调用 IPCreateInterface
  5. 读取注册表 IP 配置(IP 地址、掩码、网关)
  6. 设置数据包过滤器以接收广播/单播/多播
  7. 更新 TCP 接口信息
4.5.3 数据包接收

LAN 层支持两种 NDIS 接收模式:

  1. 传统接收 (ProtocolReceive):

    • 来自 NDIS MiniIndicateData → 调用 NdisTransferData 复制完整数据帧
    • 完成后调用 LanReceiveWorker 在工作队列中处理
  2. 数据包接收 (ProtocolReceivePacket):

    • 来自 NDIS MiniIndicateReceivePacket
    • 直接提交到工作队列,不复制数据
    • 返回 1 表示持有包引用(可通过 NdisReturnPackets 归还)

两种模式最终都在 LanReceiveWorker 中汇合:

  1. 解析以太网类型(ETYPE_IPv4 / ETYPE_IPv6 / ETYPE_ARP
  2. 初始化 IP_PACKET 结构
  3. 调用 IPReceive(IP 数据报)或 ARPReceive(ARP 请求)
4.5.4 数据包发送 (LANTransmit)
  1. 将数据拷贝到带以太网头的 NDIS 数据包
  2. 填充以太网头(目的 MAC、源 MAC、协议类型)
  3. 对大包设置 TcpLargeSendPacketInfo(LSO 卸载指示)
  4. 调用 NdisSend 发送
  5. 如果不是 NDIS_STATUS_PENDING,立即调用 ProtocolSendComplete
4.5.5 状态变化处理 (ProtocolStatus)

处理网络状态变化事件:

  • NDIS_STATUS_MEDIA_CONNECT → 设置 LAN_STATE_STARTED,重新配置接口
  • NDIS_STATUS_MEDIA_DISCONNECT → 设置 LAN_STATE_STOPPED,清除 IP 配置
  • NDIS_STATUS_RESET_START / NDIS_STATUS_RESET_END → 适配器重置状态管理

4.6 工作队列 (chew/workqueue.c)

Chew 工作队列提供异步任务调度:

  • ChewInit --- 创建工作线程
  • ChewCreate --- 提交工作任务
  • 用于接收处理、重配置等异步操作

4.7 ARP 和邻居缓存

ARP 模块 (arp.c) 和邻居缓存 (neighbor.c) 共同实现链路层地址解析:

  • ARP 发送 (ARPTransmit) --- 发送 ARP 请求/应答
  • ARP 接收 (ARPReceive) --- 处理 ARP 应答,更新 NCE
  • 邻居查找 (NBLocateNeighbor) --- 查找 IP 对应的链路层地址
  • 邻居缓存条目 (NCE) --- LRU 缓存,支持 NUD_INCOMPLETE / NUD_REACHABLE / NUD_STALE / NUD_DELAY / NUD_PROBE 等状态
  • 发送队列 (NBQueuePacket) --- 当 NCE 状态为 INCOMPLETE 时,数据包先排队等待 ARP 完成

5. 工作流程图

5.1 驱动初始化流程

#mermaid-svg-mxvGN5EWFO4zDpwB{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-mxvGN5EWFO4zDpwB .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-mxvGN5EWFO4zDpwB .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-mxvGN5EWFO4zDpwB .error-icon{fill:#552222;}#mermaid-svg-mxvGN5EWFO4zDpwB .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-mxvGN5EWFO4zDpwB .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-mxvGN5EWFO4zDpwB .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-mxvGN5EWFO4zDpwB .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-mxvGN5EWFO4zDpwB .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-mxvGN5EWFO4zDpwB .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-mxvGN5EWFO4zDpwB .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-mxvGN5EWFO4zDpwB .marker{fill:#333333;stroke:#333333;}#mermaid-svg-mxvGN5EWFO4zDpwB .marker.cross{stroke:#333333;}#mermaid-svg-mxvGN5EWFO4zDpwB svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-mxvGN5EWFO4zDpwB p{margin:0;}#mermaid-svg-mxvGN5EWFO4zDpwB .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-mxvGN5EWFO4zDpwB .cluster-label text{fill:#333;}#mermaid-svg-mxvGN5EWFO4zDpwB .cluster-label span{color:#333;}#mermaid-svg-mxvGN5EWFO4zDpwB .cluster-label span p{background-color:transparent;}#mermaid-svg-mxvGN5EWFO4zDpwB .label text,#mermaid-svg-mxvGN5EWFO4zDpwB span{fill:#333;color:#333;}#mermaid-svg-mxvGN5EWFO4zDpwB .node rect,#mermaid-svg-mxvGN5EWFO4zDpwB .node circle,#mermaid-svg-mxvGN5EWFO4zDpwB .node ellipse,#mermaid-svg-mxvGN5EWFO4zDpwB .node polygon,#mermaid-svg-mxvGN5EWFO4zDpwB .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-mxvGN5EWFO4zDpwB .rough-node .label text,#mermaid-svg-mxvGN5EWFO4zDpwB .node .label text,#mermaid-svg-mxvGN5EWFO4zDpwB .image-shape .label,#mermaid-svg-mxvGN5EWFO4zDpwB .icon-shape .label{text-anchor:middle;}#mermaid-svg-mxvGN5EWFO4zDpwB .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-mxvGN5EWFO4zDpwB .rough-node .label,#mermaid-svg-mxvGN5EWFO4zDpwB .node .label,#mermaid-svg-mxvGN5EWFO4zDpwB .image-shape .label,#mermaid-svg-mxvGN5EWFO4zDpwB .icon-shape .label{text-align:center;}#mermaid-svg-mxvGN5EWFO4zDpwB .node.clickable{cursor:pointer;}#mermaid-svg-mxvGN5EWFO4zDpwB .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-mxvGN5EWFO4zDpwB .arrowheadPath{fill:#333333;}#mermaid-svg-mxvGN5EWFO4zDpwB .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-mxvGN5EWFO4zDpwB .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-mxvGN5EWFO4zDpwB .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mxvGN5EWFO4zDpwB .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-mxvGN5EWFO4zDpwB .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mxvGN5EWFO4zDpwB .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-mxvGN5EWFO4zDpwB .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-mxvGN5EWFO4zDpwB .cluster text{fill:#333;}#mermaid-svg-mxvGN5EWFO4zDpwB .cluster span{color:#333;}#mermaid-svg-mxvGN5EWFO4zDpwB div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-mxvGN5EWFO4zDpwB .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-mxvGN5EWFO4zDpwB rect.text{fill:none;stroke-width:0;}#mermaid-svg-mxvGN5EWFO4zDpwB .icon-shape,#mermaid-svg-mxvGN5EWFO4zDpwB .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mxvGN5EWFO4zDpwB .icon-shape p,#mermaid-svg-mxvGN5EWFO4zDpwB .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-mxvGN5EWFO4zDpwB .icon-shape .label rect,#mermaid-svg-mxvGN5EWFO4zDpwB .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mxvGN5EWFO4zDpwB .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-mxvGN5EWFO4zDpwB .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-mxvGN5EWFO4zDpwB :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} NDIS 协议绑定
DriverEntry
初始化 DPC 和计时器
创建 4 个设备对象: IP/RawIP/UDP/TCP
ChewInit 创建工作队列
分配 NDIS 数据包池和缓冲区池
初始化全局列表
IPStartup - 网络层
RawIPStartup - 传输层
UDPStartup - 传输层
TCPStartup - 传输层
ICMPStartup - ICMP
初始化安全描述符
注册 IRP 分发表
LoopRegisterAdapter 创建回环
LANRegisterProtocol 注册 NDIS
NDIS 调用 ProtocolBindAdapter
NDIS 枚举所有微型端口
ProtocolBindAdapter → LANRegisterAdapter
NdisOpenAdapter 打开适配器
查询硬件信息
读取注册表 IP 配置
IPCreateInterface 创建接口
IPRegisterInterface 注册接口
设置数据包过滤器
启动周期计时器
系统就绪

5.2 TCP 连接建立流程 (TDI_CONNECT)

#mermaid-svg-oy8TaCzMJXYQVfyG{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-oy8TaCzMJXYQVfyG .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-oy8TaCzMJXYQVfyG .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-oy8TaCzMJXYQVfyG .error-icon{fill:#552222;}#mermaid-svg-oy8TaCzMJXYQVfyG .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-oy8TaCzMJXYQVfyG .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-oy8TaCzMJXYQVfyG .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-oy8TaCzMJXYQVfyG .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-oy8TaCzMJXYQVfyG .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-oy8TaCzMJXYQVfyG .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-oy8TaCzMJXYQVfyG .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-oy8TaCzMJXYQVfyG .marker{fill:#333333;stroke:#333333;}#mermaid-svg-oy8TaCzMJXYQVfyG .marker.cross{stroke:#333333;}#mermaid-svg-oy8TaCzMJXYQVfyG svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-oy8TaCzMJXYQVfyG p{margin:0;}#mermaid-svg-oy8TaCzMJXYQVfyG .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-oy8TaCzMJXYQVfyG .cluster-label text{fill:#333;}#mermaid-svg-oy8TaCzMJXYQVfyG .cluster-label span{color:#333;}#mermaid-svg-oy8TaCzMJXYQVfyG .cluster-label span p{background-color:transparent;}#mermaid-svg-oy8TaCzMJXYQVfyG .label text,#mermaid-svg-oy8TaCzMJXYQVfyG span{fill:#333;color:#333;}#mermaid-svg-oy8TaCzMJXYQVfyG .node rect,#mermaid-svg-oy8TaCzMJXYQVfyG .node circle,#mermaid-svg-oy8TaCzMJXYQVfyG .node ellipse,#mermaid-svg-oy8TaCzMJXYQVfyG .node polygon,#mermaid-svg-oy8TaCzMJXYQVfyG .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-oy8TaCzMJXYQVfyG .rough-node .label text,#mermaid-svg-oy8TaCzMJXYQVfyG .node .label text,#mermaid-svg-oy8TaCzMJXYQVfyG .image-shape .label,#mermaid-svg-oy8TaCzMJXYQVfyG .icon-shape .label{text-anchor:middle;}#mermaid-svg-oy8TaCzMJXYQVfyG .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-oy8TaCzMJXYQVfyG .rough-node .label,#mermaid-svg-oy8TaCzMJXYQVfyG .node .label,#mermaid-svg-oy8TaCzMJXYQVfyG .image-shape .label,#mermaid-svg-oy8TaCzMJXYQVfyG .icon-shape .label{text-align:center;}#mermaid-svg-oy8TaCzMJXYQVfyG .node.clickable{cursor:pointer;}#mermaid-svg-oy8TaCzMJXYQVfyG .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-oy8TaCzMJXYQVfyG .arrowheadPath{fill:#333333;}#mermaid-svg-oy8TaCzMJXYQVfyG .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-oy8TaCzMJXYQVfyG .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-oy8TaCzMJXYQVfyG .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-oy8TaCzMJXYQVfyG .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-oy8TaCzMJXYQVfyG .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-oy8TaCzMJXYQVfyG .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-oy8TaCzMJXYQVfyG .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-oy8TaCzMJXYQVfyG .cluster text{fill:#333;}#mermaid-svg-oy8TaCzMJXYQVfyG .cluster span{color:#333;}#mermaid-svg-oy8TaCzMJXYQVfyG div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-oy8TaCzMJXYQVfyG .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-oy8TaCzMJXYQVfyG rect.text{fill:none;stroke-width:0;}#mermaid-svg-oy8TaCzMJXYQVfyG .icon-shape,#mermaid-svg-oy8TaCzMJXYQVfyG .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-oy8TaCzMJXYQVfyG .icon-shape p,#mermaid-svg-oy8TaCzMJXYQVfyG .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-oy8TaCzMJXYQVfyG .icon-shape .label rect,#mermaid-svg-oy8TaCzMJXYQVfyG .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-oy8TaCzMJXYQVfyG .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-oy8TaCzMJXYQVfyG .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-oy8TaCzMJXYQVfyG :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 未初始化
收到 SYN+ACK
超时
应用程序调用 connect
Winsock → TDI_CONNECT IRP
TiDispatchInternal → DispTdiConnect
IoMarkIrpPending
DispPrepareIrpForCancel 设置取消例程
TCPConnect
连接端点状态?
AllocateLocalPort 分配本地端口
调用 IPTransmitPacket 发送 SYN
等待 SYN+ACK
发送 ACK → ESTABLISHED
连接失败
DispDataRequestComplete 完成 IRP
应用程序连接成功

5.3 TCP 数据发送流程

渲染错误: Mermaid 渲染失败: Parse error on line 10: ... --> JTCP 构建 TCP 段 (sk_buff) J --> -----------------------^ Expecting 'SQE', 'DOUBLECIRCLEEND', 'PE', '-)', 'STADIUMEND', 'SUBROUTINEEND', 'PIPE', 'CYLINDEREND', 'DIAMOND_STOP', 'TAGEND', 'TRAPEND', 'INVTRAPEND', 'UNICODE_TEXT', 'TEXT', 'TAGSTART', got 'PS'

5.4 数据接收流程

#mermaid-svg-H7lVUbspiimfd7ok{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-H7lVUbspiimfd7ok .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-H7lVUbspiimfd7ok .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-H7lVUbspiimfd7ok .error-icon{fill:#552222;}#mermaid-svg-H7lVUbspiimfd7ok .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-H7lVUbspiimfd7ok .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-H7lVUbspiimfd7ok .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-H7lVUbspiimfd7ok .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-H7lVUbspiimfd7ok .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-H7lVUbspiimfd7ok .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-H7lVUbspiimfd7ok .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-H7lVUbspiimfd7ok .marker{fill:#333333;stroke:#333333;}#mermaid-svg-H7lVUbspiimfd7ok .marker.cross{stroke:#333333;}#mermaid-svg-H7lVUbspiimfd7ok svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-H7lVUbspiimfd7ok p{margin:0;}#mermaid-svg-H7lVUbspiimfd7ok .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-H7lVUbspiimfd7ok .cluster-label text{fill:#333;}#mermaid-svg-H7lVUbspiimfd7ok .cluster-label span{color:#333;}#mermaid-svg-H7lVUbspiimfd7ok .cluster-label span p{background-color:transparent;}#mermaid-svg-H7lVUbspiimfd7ok .label text,#mermaid-svg-H7lVUbspiimfd7ok span{fill:#333;color:#333;}#mermaid-svg-H7lVUbspiimfd7ok .node rect,#mermaid-svg-H7lVUbspiimfd7ok .node circle,#mermaid-svg-H7lVUbspiimfd7ok .node ellipse,#mermaid-svg-H7lVUbspiimfd7ok .node polygon,#mermaid-svg-H7lVUbspiimfd7ok .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-H7lVUbspiimfd7ok .rough-node .label text,#mermaid-svg-H7lVUbspiimfd7ok .node .label text,#mermaid-svg-H7lVUbspiimfd7ok .image-shape .label,#mermaid-svg-H7lVUbspiimfd7ok .icon-shape .label{text-anchor:middle;}#mermaid-svg-H7lVUbspiimfd7ok .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-H7lVUbspiimfd7ok .rough-node .label,#mermaid-svg-H7lVUbspiimfd7ok .node .label,#mermaid-svg-H7lVUbspiimfd7ok .image-shape .label,#mermaid-svg-H7lVUbspiimfd7ok .icon-shape .label{text-align:center;}#mermaid-svg-H7lVUbspiimfd7ok .node.clickable{cursor:pointer;}#mermaid-svg-H7lVUbspiimfd7ok .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-H7lVUbspiimfd7ok .arrowheadPath{fill:#333333;}#mermaid-svg-H7lVUbspiimfd7ok .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-H7lVUbspiimfd7ok .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-H7lVUbspiimfd7ok .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-H7lVUbspiimfd7ok .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-H7lVUbspiimfd7ok .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-H7lVUbspiimfd7ok .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-H7lVUbspiimfd7ok .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-H7lVUbspiimfd7ok .cluster text{fill:#333;}#mermaid-svg-H7lVUbspiimfd7ok .cluster span{color:#333;}#mermaid-svg-H7lVUbspiimfd7ok div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-H7lVUbspiimfd7ok .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-H7lVUbspiimfd7ok rect.text{fill:none;stroke-width:0;}#mermaid-svg-H7lVUbspiimfd7ok .icon-shape,#mermaid-svg-H7lVUbspiimfd7ok .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-H7lVUbspiimfd7ok .icon-shape p,#mermaid-svg-H7lVUbspiimfd7ok .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-H7lVUbspiimfd7ok .icon-shape .label rect,#mermaid-svg-H7lVUbspiimfd7ok .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-H7lVUbspiimfd7ok .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-H7lVUbspiimfd7ok .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-H7lVUbspiimfd7ok :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 传输层
IP 网络层
LAN/链路层
硬件/NDIS
传统 Receive
Packet Receive
ETYPE_IPv4
ETYPE_ARP
ETYPE_IPv6




TCP
UDP
ICMP




网卡收到数据帧
NDIS 中断/DPC
接收方式?
ProtocolReceive
ProtocolReceivePacket
NdisTransferData
ProtocolTransferDataComplete
LanReceiveWorker 工作队列
以太网类型?
IPReceive
ARPReceive
IPReceive
验证 IPv4 头
需分片重组?
ReassemblyListHead 管理
等待所有分片
组装完整数据报
目标为本机?
路由器: IPTransmitPacket 转发
IPDispatchProtocol 按协议分发
下一层协议?
TCPReceive
UDPReceive
ICMPReceive
查找连接端点
数据入 TCP 接收队列
HandleSignalledConnection
有等待的 TDI_RECEIVE IRP?
拷贝数据到用户缓冲区
触发 TDI_EVENT_RECEIVE
查找地址文件/端口
有等待的 DG IRP?
复制数据到用户缓冲区
触发 TDI_EVENT_RECEIVE_DATAGRAM
DispDataRequestComplete 完成 IRP

5.5 IP 分片重组流程 (RFC 815)

#mermaid-svg-ojTZUDBAMhyBEreq{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ojTZUDBAMhyBEreq .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ojTZUDBAMhyBEreq .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ojTZUDBAMhyBEreq .error-icon{fill:#552222;}#mermaid-svg-ojTZUDBAMhyBEreq .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ojTZUDBAMhyBEreq .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ojTZUDBAMhyBEreq .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ojTZUDBAMhyBEreq .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ojTZUDBAMhyBEreq .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ojTZUDBAMhyBEreq .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ojTZUDBAMhyBEreq .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ojTZUDBAMhyBEreq .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ojTZUDBAMhyBEreq .marker.cross{stroke:#333333;}#mermaid-svg-ojTZUDBAMhyBEreq svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ojTZUDBAMhyBEreq p{margin:0;}#mermaid-svg-ojTZUDBAMhyBEreq .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ojTZUDBAMhyBEreq .cluster-label text{fill:#333;}#mermaid-svg-ojTZUDBAMhyBEreq .cluster-label span{color:#333;}#mermaid-svg-ojTZUDBAMhyBEreq .cluster-label span p{background-color:transparent;}#mermaid-svg-ojTZUDBAMhyBEreq .label text,#mermaid-svg-ojTZUDBAMhyBEreq span{fill:#333;color:#333;}#mermaid-svg-ojTZUDBAMhyBEreq .node rect,#mermaid-svg-ojTZUDBAMhyBEreq .node circle,#mermaid-svg-ojTZUDBAMhyBEreq .node ellipse,#mermaid-svg-ojTZUDBAMhyBEreq .node polygon,#mermaid-svg-ojTZUDBAMhyBEreq .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ojTZUDBAMhyBEreq .rough-node .label text,#mermaid-svg-ojTZUDBAMhyBEreq .node .label text,#mermaid-svg-ojTZUDBAMhyBEreq .image-shape .label,#mermaid-svg-ojTZUDBAMhyBEreq .icon-shape .label{text-anchor:middle;}#mermaid-svg-ojTZUDBAMhyBEreq .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ojTZUDBAMhyBEreq .rough-node .label,#mermaid-svg-ojTZUDBAMhyBEreq .node .label,#mermaid-svg-ojTZUDBAMhyBEreq .image-shape .label,#mermaid-svg-ojTZUDBAMhyBEreq .icon-shape .label{text-align:center;}#mermaid-svg-ojTZUDBAMhyBEreq .node.clickable{cursor:pointer;}#mermaid-svg-ojTZUDBAMhyBEreq .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ojTZUDBAMhyBEreq .arrowheadPath{fill:#333333;}#mermaid-svg-ojTZUDBAMhyBEreq .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ojTZUDBAMhyBEreq .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ojTZUDBAMhyBEreq .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ojTZUDBAMhyBEreq .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ojTZUDBAMhyBEreq .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ojTZUDBAMhyBEreq .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ojTZUDBAMhyBEreq .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ojTZUDBAMhyBEreq .cluster text{fill:#333;}#mermaid-svg-ojTZUDBAMhyBEreq .cluster span{color:#333;}#mermaid-svg-ojTZUDBAMhyBEreq div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ojTZUDBAMhyBEreq .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ojTZUDBAMhyBEreq rect.text{fill:none;stroke-width:0;}#mermaid-svg-ojTZUDBAMhyBEreq .icon-shape,#mermaid-svg-ojTZUDBAMhyBEreq .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ojTZUDBAMhyBEreq .icon-shape p,#mermaid-svg-ojTZUDBAMhyBEreq .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ojTZUDBAMhyBEreq .icon-shape .label rect,#mermaid-svg-ojTZUDBAMhyBEreq .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ojTZUDBAMhyBEreq .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ojTZUDBAMhyBEreq .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ojTZUDBAMhyBEreq :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 没有





收到 IP 分片
检查 Identification, Src, Dst
已有重装结构?
创建 IPDATAGRAM_REASSEMBLY
找到对应的 IPDR
创建初始 Hole: first=0, last=Max
将分片加入 FragmentList
分片覆盖空洞?
分裂/缩小 Hole
丢弃重叠分片
Hole 列表为空?
组装完成
继续等待更多分片
按顺序拼接各分片数据
释放 IPDR
IPDispatchProtocol


6. 数据流图

6.1 发送数据流

复制代码
应用程序 (Socket)
    |
    | send()
    v
Winsock 子系统 (afd.sys)
    |
    | TDI_SEND (IRP_MJ_INTERNAL_DEVICE_CONTROL)
    v
tcpip.sys ──── TiDispatchInternal
    |                   |
    |            DispTdiSend
    |                   |
    |            TCPSendData
    |                   |
    |        ┌──────────┴──────────┐
    |        | TCP 连接型           | UDP 数据报型
    |   TCP 分段/窗口管理      UDP 数据报构造
    |   ┌────┴────┐              ┌─┴─┐
    |   | sk_buff |              |   |
    |   | 队列管理 |              |   |
    |   └────┬────┘              └─┬─┘
    |        └────────┬───────────┘
    |                 |
    |         IPTransmitPacket
    |                 |
    |        ┌────────┴────────┐
    |        | 路由查找         |
    |        | RouteGetRoute   |
    |        └────────┬────────┘
    |                 |
    |        ┌────────┴────────┐
    |        | MTU 分片?       |
    |        | (IPFragment)    |
    |        └────────┬────────┘
    |                 |
    |        ┌────────┴────────┐
    |        | 邻居缓存         |
    |        | NBQueuePacket   |
    |        └────────┬────────┘
    |                 |
    |        ┌────────┴────────┐
    |        | ARP 解析?       |
    |        | (如有必要)       |
    |        └────────┬────────┘
    |                 |
    |           LANTransmit
    |                 |
    |         封以太网头 + NdisSend
    v
NDIS 库 (ndis.sys)
    |
    | MiniportSend
    v
网卡驱动 → 硬件发送

6.2 接收数据流

复制代码
网卡硬件
    |
    | 中断 → ISR → DPC
    v
NDIS 库 (ndis.sys)
    |
    | MiniIndicateReceive / MiniIndicateReceivePacket
    v
tcpip.sys ──── LAN 层
    |              |
    |     ProtocolReceivePacket/ProtocolReceive
    |              |
    |      LanReceiveWorker (工作队列)
    |              |
    |     ┌────────┴────────┐
    |     | 解析以太网类型   |
    |     └────────┬────────┘
    |              |
    |     ┌────────┴────────┐
    |     | IPReceive /     |
    |     | ARPReceive      |
    |     └────────┬────────┘
    |              |
    |     ┌────────┴────────┐
    |     | IP 头校验       |
    |     | 分片重组        |
    |     | IPDispatch     |
    |     └────────┬────────┘
    |              |
    |     ┌────────┴────────┐
    |     | 协议号分发       |
    |     └────────┬────────┘
    |              |
    |     ┌───────┴───────┐
    |     |               |
    |  TCPReceive    UDPReceive
    |     |               |
    |  ┌──┴──┐       ┌───┴───┐
    |  |查找  |       |查找   |
    |  |连接  |       |端口   |
    |  |端点  |       |文件   |
    |  └──┬──┘       └───┬───┘
    |     |               |
    |  ┌──┴──┐       ┌───┴───┐
    |  |数据  |       |触发   |
    |  |入队  |       |TDI_   |
    |  |通知  |       |EVENT  |
    |  |IRP   |       |或完成 |
    |  └──┬──┘       │IRP    |
    |     |          └───┬───┘
    |  ┌──┴──┐           |
    |  |完成 IRP 或      |
    |  |触发事件         |
    |  └──┬──┘           |
    |     └──────┬───────┘
    |            |
    |     DispDataRequestComplete
    |            |
    v       IoCompleteRequest
    |
应用程序 (通过事件或 IRP 完成收到数据)

6.3 TDI 事件模型

复制代码
用户态应用程序
    |
    | 1. CreateFile("\Device\Tcp")
    | 2. TDI_SET_EVENT_HANDLER (注册事件回调)
    | 3. TDI_CONNECT / TDI_LISTEN
    v
tcpip.sys
    |
    ├── DispTdiSetEventHandler
    |       └── 注册到 ADDRESS_FILE
    |           ├── ConnectHandler
    |           ├── ReceiveHandler
    |           ├── DisconnectHandler
    |           ├── ReceiveDatagramHandler
    |           └── ErrorHandler
    |
    ├── 数据到达时
    |       └── 如果己注册对应事件处理器
    |           └── 调用 TDI 事件回调 → 通知上层
    |
    └── 无对应事件处理器时
            └── 挂起 IRP → DispPrepareIrpForCancel
                → 等待 DispDataRequestComplete 完成

7. 初始化序列

7.1 完整的系统-网络初始化序列

复制代码
Phase 1: NDIS + TCPIP 内核模块加载
====================================
1. 系统加载 ndis.sys → DriverEntry 初始化全局列表
2. 系统加载 tcpip.sys → DriverEntry 执行:

Phase 2: TCP/IP 内部初始化
===========================
3. tcpip.sys DriverEntry:
   a. KeInitializeDpc(&IPTimeoutDpc, IPTimeoutDpcFn) --- 周期超时 DPC
   b. KeInitializeTimer(&IPTimer) --- 每秒触发
   c. IoCreateDevice 创建:
      - \Device\Ip (FILE_DEVICE_NETWORK)
      - \Device\RawIp (FILE_DEVICE_NETWORK)
      - \Device\Udp (FILE_DEVICE_NETWORK)
      - \Device\Tcp (FILE_DEVICE_NETWORK)
   d. ChewInit --- 初始化工作队列
   e. 分配 NDIS 包池 (500+1500) 和缓冲区池 (2000)
   f. 初始化全局列表:
      - AddressFileListHead
      - ConnectionEndpointListHead
      - InterfaceListHead

Phase 3: 协议子系统启动
=======================
4. IPStartup:
   a. 清空 ProtocolTable[256] 协议表
   b. 初始化 ReassemblyListHead (分片重组)
   c. 初始化 IPDRList / IPFragmentList / IPHoleList (内存后备列表)
   d. 初始化 NetTableListHead (网络表)

5. RawIPStartup / UDPStartup / TCPStartup / ICMPStartup:
   a. 初始化各自的资源
   b. 注册到 IP 层: IPRegisterProtocol(IPPROTO_xxx, Handler)
   c. TCP 额外: 初始化连接端点列表、端口分配管理

6. 注册 IRP 分发:
   IRP_MJ_CREATE → TiDispatchOpenClose
   IRP_MJ_CLOSE → TiDispatchOpenClose
   IRP_MJ_INTERNAL_DEVICE_CONTROL → TiDispatchInternal
   IRP_MJ_DEVICE_CONTROL → TiDispatch

Phase 4: 回环适配器 + NDIS 注册
===============================
7. LoopRegisterAdapter --- 创建回环接口 (127.0.0.1/8)
   a. IPCreateInterface 创建
   b. IPRegisterInterface 注册到 InterfaceListHead

8. LANRegisterProtocol --- 注册到 NDIS:
   a. 填充 NDIS_PROTOCOL_CHARACTERISTICS (14+ 个回调函数)
   b. NdisRegisterProtocol → NDIS 调用 ProtocolBindAdapter

Phase 5: NDIS 绑定微型端口
===========================
9. NDIS 枚举所有微型端口:
   a. 对 e1000/rtl8139 等每个适配器:
      - ProtocolBindAdapter → LANRegisterAdapter
      - NdisOpenAdapter 打开适配器
      - 查询 MAC 地址、MTU、介质类型
      - ReadIpConfiguration 从注册表读 IP 地址/掩码/网关
      - IPCreateInterface 创建 IP 接口
      - IPRegisterInterface 注册到全局列表
      - 设置以太网数据包过滤器
      - 发送 MEDIA_CONNECT 状态事件
   b. TCPUpdateInterfaceIPInformation/LinkStatus 更新 TCP 信息

Phase 6: 系统就绪
=================
10. 启动周期计时器 (IP_TIMEOUT = 1000ms) 
11. 网络栈就绪,等待用户态请求

8. 关键函数分析

8.1 驱动入口和分发

函数 位置 功能
DriverEntry main.c(file:///d:/reactos/drivers/network/tcpip/tcpip/main.c#L835-L1030) 创建设备、初始化子系统、注册 NDIS 协议
TiUnload main.c(file:///d:/reactos/drivers/network/tcpip/tcpip/main.c#L770-L833) 驱动卸载,按逆序释放所有资源
TiDispatchInternal dispatch.c(file:///d:/reactos/drivers/network/tcpip/tcpip/dispatch.c#L377-L477) TDI IRP 分发主入口,24 种 Minor Function 处理
TiDispatch dispatch.c(file:///d:/reactos/drivers/network/tcpip/tcpip/dispatch.c#L491-L561) Device IOCTL 分发(TDI 扩展查询、IP 设置、ICMP 等)
TiCreateFileObject main.c(file:///d:/reactos/drivers/network/tcpip/tcpip/main.c#L113-L275) 创建地址文件/连接端点/控制通道文件对象

8.2 TDI 调度函数

函数 位置 功能
DispTdiConnect dispatch.c(file:///d:/reactos/drivers/network/tcpip/tcpip/dispatch.c#L382-L443) TCP 连接,调用 TCPConnect
DispTdiListen dispatch.c(file:///d:/reactos/drivers/network/tcpip/tcpip/dispatch.c#L550-L659) TCP 监听,创建 Listener + TCPListen + TCPAccept
DispTdiSend dispatch.c(file:///d:/reactos/drivers/network/tcpip/tcpip/dispatch.c#L945-L1015) TCP 发送,调用 TCPSendData
DispTdiReceive dispatch.c(file:///d:/reactos/drivers/network/tcpip/tcpip/dispatch.c#L802-L867) TCP 接收,调用 TCPReceiveData
DispTdiSendDatagram dispatch.c(file:///d:/reactos/drivers/network/tcpip/tcpip/dispatch.c#L1018-L1100) UDP 数据报发送
DispTdiReceiveDatagram dispatch.c(file:///d:/reactos/drivers/network/tcpip/tcpip/dispatch.c#L870-L942) UDP 数据报接收
DispTdiSetEventHandler dispatch.c(file:///d:/reactos/drivers/network/tcpip/tcpip/dispatch.c#L1103-L1263) 注册 TDI 事件回调
DispTdiAssociateAddress dispatch.c(file:///d:/reactos/drivers/network/tcpip/tcpip/dispatch.c#L270-L379) 将连接端点与地址文件关联
IRPFinish dispatch.c(file:///d:/reactos/drivers/network/tcpip/tcpip/dispatch.c#L26-L39) IRP 完成包装(增加网络优先级)

8.3 网络层函数

函数 位置 功能
IPReceive receive.c(file:///d:/reactos/drivers/network/tcpip/ip/network/receive.c) IP 数据报接收入口,负责分片重组和协议分发
IPTransmitPacket transmit.c(file:///d:/reactos/drivers/network/tcpip/ip/network/transmit.c) IP 数据报发送入口,负责路由/分片/邻居队列
IPSendFragment transmit.c(file:///d:/reactos/drivers/network/tcpip/ip/network/transmit.c#L41-L60) 发送 IP 分片到邻居缓存队列
IPDispatchProtocol ip.c(file:///d:/reactos/drivers/network/tcpip/ip/network/ip.c) 按 IP 协议号分发给传输层处理函数
IPRegisterProtocol ip.c(file:///d:/reactos/drivers/network/tcpip/ip/network/ip.c) 注册传输层协议处理函数
IPCreateInterface interface.c(file:///d:/reactos/drivers/network/tcpip/ip/network/interface.c) LLIP_BIND_INFO 创建 IP 接口
IPRegisterInterface interface.c(file:///d:/reactos/drivers/network/tcpip/ip/network/interface.c) 注册 IP 接口
RouteGetRouteToDestination route.c(file:///d:/reactos/drivers/network/tcpip/ip/network/route.c) 路由查找

8.4 传输层函数

函数 位置 功能
TCPSocket tcp.c(file:///d:/reactos/drivers/network/tcpip/ip/transport/tcp/tcp.c) 创建 TCP socket(初始化 Linux tcp_opt)
TCPConnect tcp.c(file:///d:/reactos/drivers/network/tcpip/ip/transport/tcp/tcp.c) 发起 TCP 连接
TCPListen accept.c(file:///d:/reactos/drivers/network/tcpip/ip/transport/tcp/accept.c) TCP 监听
TCPAccept accept.c(file:///d:/reactos/drivers/network/tcpip/ip/transport/tcp/accept.c) TCP 接受连接
TCPSendData tcp.c(file:///d:/reactos/drivers/network/tcpip/ip/transport/tcp/tcp.c) TCP 数据发送
TCPReceiveData tcp.c(file:///d:/reactos/drivers/network/tcpip/ip/transport/tcp/tcp.c) TCP 数据接收
TCPDisconnect tcp.c(file:///d:/reactos/drivers/network/tcpip/ip/transport/tcp/tcp.c) TCP 断开连接
HandleSignalledConnection tcp.c(file:///d:/reactos/drivers/network/tcpip/ip/transport/tcp/tcp.c) TCP 事件驱动处理
UDPSend udp.c(file:///d:/reactos/drivers/network/tcpip/ip/transport/udp/udp.c) UDP 数据报发送
UDPReceive udp.c(file:///d:/reactos/drivers/network/tcpip/ip/transport/udp/udp.c) UDP 数据报接收

8.5 LAN/链路层函数

函数 位置 功能
LANRegisterProtocol lan.c(file:///d:/reactos/drivers/network/tcpip/datalink/lan.c#L1673-L1728) 注册 NDIS 协议驱动
LANRegisterAdapter lan.c(file:///d:/reactos/drivers/network/tcpip/datalink/lan.c#L1452-L1578) 打开 NDIS 适配器并绑定到 IP
LANTransmit lan.c(file:///d:/reactos/drivers/network/tcpip/datalink/lan.c#L963-L1091) 链路层发送(加以太网头 + NdisSend)
LanReceiveWorker lan.c(file:///d:/reactos/drivers/network/tcpip/datalink/lan.c#L307-L386) 接收工作线程,按以太网类型分发
ProtocolReceive lan.c(file:///d:/reactos/drivers/network/tcpip/datalink/lan.c#L462-L554) 传统 NDIS 接收回调
ProtocolReceivePacket lan.c(file:///d:/reactos/drivers/network/tcpip/datalink/lan.c#L442-L460) NDIS 数据包接收回调
ProtocolSendComplete lan.c(file:///d:/reactos/drivers/network/tcpip/datalink/lan.c#L292-L305) 发送完成回调(释放 NDIS 数据包)
ProtocolStatus lan.c(file:///d:/reactos/drivers/network/tcpip/datalink/lan.c#L824-L900) NDIS 状态变化回调(连接/断开/重置)
ReadIpConfiguration lan.c(file:///d:/reactos/drivers/network/tcpip/datalink/lan.c#L568-L731) 从注册表读取 IP 配置

8.6 辅助函数

函数 位置 功能
AllocatePacketWithBuffer buffer.c(file:///d:/reactos/drivers/network/tcpip/tcpip/buffer.c) 分配 NDIS 包 + 关联 MDL 缓冲区
FreeNdisPacket buffer.c(file:///d:/reactos/drivers/network/tcpip/tcpip/buffer.c) 释放 NDIS 包
ChewCreate workqueue.c(file:///d:/reactos/drivers/network/tcpip/chew/workqueue.c) 创建工作项
DispDataRequestComplete dispatch.c(file:///d:/reactos/drivers/network/tcpip/tcpip/dispatch.c#L87-L116) 数据请求完成通用回调

9. 构建配置

9.1 CMakeLists.txt

cmake 复制代码
add_definitions(
    -DNDIS40
    -D_NTDRIVER_)

add_library(tcpip MODULE
    chew/workqueue.c
    datalink/lan.c
    tcpip/ainfo.c
    tcpip/buffer.c
    tcpip/cinfo.c
    tcpip/dispatch.c
    tcpip/fileobjs.c
    tcpip/icmp.c
    tcpip/iinfo.c
    tcpip/info.c
    tcpip/lock.c
    tcpip/main.c
    tcpip/ninfo.c
    tcpip/proto.c
    tcpip/tinfo.c
    tcpip/wait.c
    ...)

target_link_libraries(tcpip ip ${PSEH_LIB})
set_module_type(tcpip kernelmodedriver)
add_importlibs(tcpip ndis ntoskrnl hal)

9.2 输出

编译结果为 reactos/system32/drivers/tcpip.sys,链接 ip 库(ip/CMakeLists.txt 编译的子库)、ndisntoskrnlhal

9.3 依赖关系

复制代码
tcpip.sys
  ├── ip 库 (ReactOS IP 协议栈)
  │   ├── network/ (IP/ARP/ICMP/路由/邻居)
  │   ├── transport/ (TCP/UDP/RawIP)
  │   └── lwip_glue/ (lwIP 粘合)
  ├── ndis (NDIS 接口)
  ├── ntoskrnl (内核 API)
  └── hal (硬件抽象层)

附录 A:NDIS 协议驱动特性

c 复制代码
// tcpip.sys 注册到 NDIS 的协议特性 (lan.c)
ProtChars.MajorNdisVersion               = NDIS_VERSION_MAJOR;  // 4
ProtChars.MinorNdisVersion               = NDIS_VERSION_MINOR;  // 0
ProtChars.OpenAdapterCompleteHandler     = ProtocolOpenAdapterComplete;
ProtChars.CloseAdapterCompleteHandler    = ProtocolCloseAdapterComplete;
ProtChars.ResetCompleteHandler           = ProtocolResetComplete;
ProtChars.RequestCompleteHandler         = ProtocolRequestComplete;
ProtChars.SendCompleteHandler            = ProtocolSendComplete;
ProtChars.TransferDataCompleteHandler    = ProtocolTransferDataComplete;
ProtChars.ReceivePacketHandler           = ProtocolReceivePacket;  // NDIS 5.0
ProtChars.ReceiveHandler                 = ProtocolReceive;
ProtChars.ReceiveCompleteHandler         = ProtocolReceiveComplete;
ProtChars.StatusHandler                  = ProtocolStatus;
ProtChars.StatusCompleteHandler          = ProtocolStatusComplete;
ProtChars.BindAdapterHandler             = ProtocolBindAdapter;
ProtChars.PnPEventHandler                = ProtocolPnPEvent;
ProtChars.UnbindAdapterHandler           = ProtocolUnbindAdapter;

附录 B:关键头文件索引

头文件 路径 说明
tcpip.h include/tcpip.h(file:///d:/reactos/drivers/network/tcpip/include/tcpip.h) 主头文件,全局变量、字节序宏
titypes.h include/titypes.h(file:///d:/reactos/drivers/network/tcpip/include/titypes.h) 核心类型:ADDRESS_FILE、引用计数、锁
ticonsts.h include/ticonsts.h(file:///d:/reactos/drivers/network/tcpip/include/ticonsts.h) 常量定义
ip.h include/ip.h(file:///d:/reactos/drivers/network/tcpip/include/ip.h) IP 层:IP_PACKET、IP_INTERFACE、LLIP_BIND_INFO
tcp.h include/tcp.h(file:///d:/reactos/drivers/network/tcpip/include/tcp.h) TCP 层:TCPv4_HEADER、TCP_COMPLETION_ROUTINE
tcpcore.h include/tcpcore.h(file:///d:/reactos/drivers/network/tcpip/include/tcpcore.h) Linux 内核移植:sk_buff、tcp_opt、sock 等
lan.h include/lan.h(file:///d:/reactos/drivers/network/tcpip/include/lan.h) 数据链路层:LAN_ADAPTER
arp.h include/arp.h(file:///d:/reactos/drivers/network/tcpip/include/arp.h) ARP 协议
route.h include/route.h(file:///d:/reactos/drivers/network/tcpip/include/route.h) 路由表
neighbor.h include/neighbor.h(file:///d:/reactos/drivers/network/tcpip/include/neighbor.h) 邻居缓存 (NCE)
receive.h include/receive.h(file:///d:/reactos/drivers/network/tcpip/include/receive.h) IP 接收
transmit.h include/transmit.h(file:///d:/reactos/drivers/network/tcpip/include/transmit.h) IP 发送
interface.h include/interface.h(file:///d:/reactos/drivers/network/tcpip/include/interface.h) 接口管理
udp.h include/udp.h(file:///d:/reactos/drivers/network/tcpip/include/udp.h) UDP
icmp.h include/icmp.h(file:///d:/reactos/drivers/network/tcpip/include/icmp.h) ICMP
rawip.h include/rawip.h(file:///d:/reactos/drivers/network/tcpip/include/rawip.h) Raw IP
dispatch.h include/dispatch.h(file:///d:/reactos/drivers/network/tcpip/include/dispatch.h) TDI 分发函数声明
fileobjs.h include/fileobjs.h(file:///d:/reactos/drivers/network/tcpip/include/fileobjs.h) 文件对象管理
info.h include/info.h(file:///d:/reactos/drivers/network/tcpip/include/info.h) TDI 信息查询
lock.h include/lock.h(file:///d:/reactos/drivers/network/tcpip/include/lock.h) 锁操作
wait.h include/wait.h(file:///d:/reactos/drivers/network/tcpip/include/wait.h) 等待操作

附录 C:TCP 状态机

复制代码
                    +---------+
                    |  CLOSED |
                    +----+----+
                         |
                  主动打开 / 被动打开
                         |
                    +----v----+
                    |  LISTEN |
                    +----+----+
                         | 收到 SYN
                    +----v----+
                    | SYN_RCV |
                    +----+----+
                         | 发送 SYN+ACK
                         |
      主动打开           |  同时打开
    +----v----+        +----v----+
    | SYN_SENT+--------> SYN_RCV |
    +----+----+        +----+----+
         |                  |
         |   收到 SYN+ACK   |   收到 ACK
         +--------+--------+
                  |
           +------v------+
           | ESTABLISHED  |
           +------+------+
                  |
           +------+------+
           | 主动关闭/被动关闭 |
           +------+------+
                  |
           +------v------+
           | FIN_WAIT_1  |          +---------+
           +------+------+          |CLOSE_WAIT|
                  |                  +----+----+
           +------v------+               |
           | FIN_WAIT_2  |               | 关闭
           +------+------+          +----v----+
                  |                  |LAST_ACK |
           +------v------+          +----+----+
           |  TIME_WAIT  |               |
           +------+------+               |
                  |                      |
           +------v------+               |
           |   CLOSED    |<--------------+
           +-------------+

附录 D:参考文档

  • NDIS 驱动分析(file:///d:/reactos/doc/NDIS_驱动分析.md) --- NDIS 库详细分析
  • ddk/ndis.h(file:///d:/reactos/sdk/include/ddk/ndis.h) --- NDIS DDK 头文件
  • tdikrnl.h(file:///d:/reactos/sdk/include/ddk/tdikrnl.h) --- TDI 内核接口头文件
  • tcpcore.h(file:///d:/reactos/drivers/network/tcpip/include/tcpcore.h) --- Linux TCP 内核移植
  • lwIP 源码(file:///d:/reactos/drivers/network/tcpip/lwip/) --- lwIP 协议栈
  • RFC 793 --- Transmission Control Protocol
  • RFC 791 --- Internet Protocol
  • RFC 815 --- IP Datagram Reassembly Algorithms
  • RFC 826 --- Ethernet Address Resolution Protocol
相关推荐
便利店10241 小时前
快递选「挂号」还是「平邮」?传输层一次讲清
网络·网络协议·tcp/ip·传输层
夜雪一千2 小时前
UDP 协议简介
网络·网络协议·udp
神奇霸王龙3 小时前
GPT-Image-2 角色一致性屠榜:2026 五款图生图模型 IP 漫剧实测
人工智能·gpt·tcp/ip·ai·ai作画·prompt·音视频
想你依然心痛3 小时前
TCP/IP协议栈深度解析:从底层原理到高性能优化实践
网络协议·tcp/ip·性能优化
凉凉的知识库3 小时前
什么是 HTTP Keep-Alive?一文讲清连接复用机制
网络协议·http·面试
白狐_7984 小时前
【408计算机网络|第01章|408-CN-01】计算机网络概述与体系结构:性能指标、分层、OSI与TCP/IP
网络协议·tcp/ip·计算机网络
MrDJun4 小时前
长期稳定跑网页监控:TLS 指纹、代理选路与请求节流的工程实践
运维·爬虫·python·网络协议·网站监控
白狐_7984 小时前
【408计算机网络|第03章·上|408-CN-03A】数据链路层(上):组帧、差错控制与可靠传输
网络·网络协议·计算机网络
老赵的博客5 小时前
工控机之udp远程控制
网络·网络协议·udp