# WindivertDotnet **Repository Path**: ouriping/WindivertDotnet ## Basic Information - **Project Name**: WindivertDotnet - **Description**: 备份 源来自:https://github.com/xljiulang/WindivertDotnet - **Primary Language**: C# - **License**: GPL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-10-18 - **Last Updated**: 2022-10-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # WindivertDotnet 面向对象的[WinDivertv2.2](https://github.com/basil00/Divert)的dotnet异步封装,轻松实现网络数据拦截与修改。 ### 1 nuget [WindivertDotnet](https://www.nuget.org/packages/WindivertDotnet) ``` ``` ### 2 功能介绍 * Filter对象支持Lambda构建filter language,脱离字符串的苦海; * 内存安全的WinDivert对象,基于IOCP的ValueTask异步发送与接收方法; * 内存安全的WinDivertPacket对象,提供获取包有效数据长度、解包、重构chucksums等; * WinDivertParseResult提供对解包的数据进行精细修改,修改后对WinDivertPacket直接生效; ### 3 Api表 #### 3.1 WinDivert | Api | 描述 | 原Api | | -------------------------------------------------------------------------------- | ------------------ | ----------------- | | WinDivert(Filter, WinDivertLayer, short , WinDivertFlag) | 构造器 | WinDivertOpen | | int Recv(WinDivertPacket, WinDivertAddress) | 同步阻塞读取数据包 | RecvEx | | int Recv(WinDivertPacket, WinDivertAddress, CancellationToken) | 同步阻塞读取数据包 | RecvEx | | `ValueTask` RecvAsync(WinDivertPacket, WinDivertAddress) | 异步IO读取数据包 | RecvEx | | `ValueTask` RecvAsync(WinDivertPacket, WinDivertAddress, CancellationToken) | 异步IO读取数据包 | RecvEx | | int Send(WinDivertPacket, WinDivertAddress) | 同步阻塞发送数据包 | SendEx | | int Send(WinDivertPacket, WinDivertAddress, CancellationToken) | 同步阻塞发送数据包 | SendEx | | `ValueTask` SendAsync(WinDivertPacket, WinDivertAddress) | 异步IO发送数据包 | SendEx | | `ValueTask` SendAsync(WinDivertPacket, WinDivertAddress, CancellationToken) | 异步IO发送数据包 | SendEx | | bool Shutdown(WinDivertShutdown) | 关闭 | WinDivertShutdown | | void Dispose() | 关闭并释放资源 | WinDivertClose | #### 3.2 Filter | Api | 描述 | 原Api | | --------------------------------------------- | ------------------------- | ---------------------------- | | static string Format(string, WinDivertLayer) | 格式化filter | WinDivertHelperFormatFilter | | static string Compile(string, WinDivertLayer) | 编译filter | WinDivertHelperCompileFilter | | static Filter True { get; } | 获取值为true的filter | 无 | | static Filter False { get; } | 获取值为false的filter | 无 | | Filter And(Expression>) | 使用and逻辑创建新的fitler | 无 | | Filter And(Filter) | 使用and逻辑创建新的fitler | 无 | | Filter Or(Expression>) | 使用or逻辑创建新的fitler | 无 | | Filter Or(Filter) | 使用or逻辑创建新的fitler | 无 | #### 3.3 WinDivertPacket | Api | 描述 | 原Api | | --------------------------------------------------- | --------------------------------------------------------------- | ---------------------------- | | int Capacity { get; } | 获取缓冲区容量 | 无 | | int Length { get; set;} | 获取或设置有效数据的长度 | 无 | | Span Span { get; } | 获取有效数据视图 | 无 | | void Clear() | 将有效数据清0 | 无 | | Span GetSpan(int, int) | 获取缓冲区的Span | 无 | | bool CalcChecksums(WinDivertAddress, ChecksumsFlag) | 重新计算和修改相关的Checksums | WinDivertHelperCalcChecksums | | bool CalcNetworkIfIdx(WinDivertAddress ) | 根据IP地址重新计算和修改addr的Network->IfIdx | 无 | | bool CalcOutboundFlag(WinDivertAddress) | 根据IP地址和addr.Network->IfIdx重新计算和修改addr的Outbound标记 | 无 | | bool CalcLoopbackFlag(WinDivertAddress) | 根据IP地址重新计算和修改addr的Loopback标记 | 无 | | bool DecrementTTL() | ttl减1 | WinDivertHelperDecrementTTL | | int GetHashCode() | 获取包的哈希 | WinDivertHelperHashPacket | | int GetHashCode(long) | 获取包的哈希 | WinDivertHelperHashPacket | | WinDivertParseResult GetParseResult() | 获取包的解析结果 | WinDivertHelperParsePacket | #### 3.4 WinDivertRouter | Api | 描述 | | ------------------------------------------ | ------------------ | | IPAddress DstAddress { get; } | 获取目标地址 | | IPAddress SrcAddress { get; } | 获取源地址 | | int InterfaceIndex { get; } | 获取网络接口索引 | | bool IsOutbound { get; } | 获取是否为出口方向 | | WinDivertRouter(IPAddress) | 构造器 | | WinDivertRouter(IPAddress, IPAddress) | 构造器 | | WinDivertRouter(IPAddress, IPAddress, int) | 构造器 | ### 4 如何使用 ``` var filter = Filter.True .And(f => f.Network.Loopback) .And(f => f.Tcp.DstPort == 443) .And(f => f.Tcp.Ack == true); using var divert = new WinDivert(filter, WinDivertLayer.Network); using var packet = new WinDivertPacket(); using var addr = new WinDivertAddress(); while(true) { // 读包 await divert.RecvAsync(packet, addr); // 解包 var result = packet.GetParseResult(); // 改包 result.TcpHeader->DstPort = 443; // 重算checksums packet.CalcChecksums(addr); // 修改后发出 await divert.SendAsync(packet, addr); }