diff --git a/WindivertDotnet/WinDivertAddress.cs b/WindivertDotnet/WinDivertAddress.cs index 5aee4ca..94dc28e 100644 --- a/WindivertDotnet/WinDivertAddress.cs +++ b/WindivertDotnet/WinDivertAddress.cs @@ -9,7 +9,7 @@ namespace WindivertDotnet /// 表示WinDivert地址信息 /// [DebuggerDisplay("Flags = {Flags}")] - public unsafe class WinDivertAddress : SafeHandleZeroOrMinusOneIsInvalid + public unsafe class WinDivertAddress : SafeHandleZeroOrMinusOneIsInvalid, ICloneable { [DebuggerBrowsable(DebuggerBrowsableState.Never)] private AddressStruct* Pointer => (AddressStruct*)this.handle.ToPointer(); @@ -131,6 +131,11 @@ public WinDivertAddress Clone() return addr; } + object ICloneable.Clone() + { + return this.Clone(); + } + [StructLayout(LayoutKind.Explicit)] private struct AddressStruct { diff --git a/WindivertDotnet/WinDivertPacket.cs b/WindivertDotnet/WinDivertPacket.cs index 44b09f0..68dd897 100644 --- a/WindivertDotnet/WinDivertPacket.cs +++ b/WindivertDotnet/WinDivertPacket.cs @@ -15,7 +15,7 @@ namespace WindivertDotnet /// 表示WinDivert的数据包 /// [DebuggerDisplay("Length = {Length}, Capacity = {Capacity}")] - public class WinDivertPacket : SafeHandleZeroOrMinusOneIsInvalid, IEquatable + public class WinDivertPacket : SafeHandleZeroOrMinusOneIsInvalid, IEquatable, ICloneable { /// /// MTU的最大长度 @@ -202,9 +202,9 @@ private unsafe bool TryParseIPAddress( if (this.length > 1) { var ptr = this.handle.ToPointer(); - var version = Unsafe.Read(ptr) >> 4; + var version = (IPVersion)(Unsafe.Read(ptr) >> 4); - if (version == 4 && this.length >= sizeof(IPV4Header)) + if (version == IPVersion.V4 && this.length >= sizeof(IPV4Header)) { var header = (IPV4Header*)ptr; srcAddr = header->SrcAddr; @@ -212,7 +212,7 @@ private unsafe bool TryParseIPAddress( return true; } - if (version == 6 && this.length >= sizeof(IPV6Header)) + if (version == IPVersion.V6 && this.length >= sizeof(IPV6Header)) { var header = (IPV6Header*)ptr; srcAddr = header->SrcAddr; @@ -318,6 +318,127 @@ public unsafe WinDivertParseResult GetParseResult() }; } + /// + /// 克隆 + /// + /// + public WinDivertPacket Clone() + { + var target = new WinDivertPacket(this.Capacity); + this.CopyTo(target); + return target; + } + + object ICloneable.Clone() + { + return this.Clone(); + } + + /// + /// 复制数据到指定目标 + /// + /// + /// + public void CopyTo(WinDivertPacket target) + { + target.GetWriter().Write(this.Span); + } + + /// + /// 翻转Src和Dst地址和端口 + /// + /// + [SupportedOSPlatform("windows")] + public unsafe bool ReverseEndPoint() + { + var result = this.GetParseResult(); + if (result.IPV4Header != null) + { + var src = result.IPV4Header->SrcAddr; + result.IPV4Header->SrcAddr = result.IPV4Header->DstAddr; + result.IPV4Header->DstAddr = src; + } + else if (result.IPV6Header != null) + { + var src = result.IPV6Header->SrcAddr; + result.IPV6Header->SrcAddr = result.IPV6Header->DstAddr; + result.IPV6Header->DstAddr = src; + } + else + { + return false; + } + + if (result.TcpHeader != null) + { + var src = result.TcpHeader->SrcPort; + result.TcpHeader->SrcPort = result.TcpHeader->DstPort; + result.TcpHeader->DstPort = src; + } + + if (result.UdpHeader != null) + { + var src = result.UdpHeader->SrcPort; + result.UdpHeader->SrcPort = result.UdpHeader->DstPort; + result.UdpHeader->DstPort = src; + } + + return true; + } + + /// + /// 应用当前的Length值到IP头和Udp头 + /// 返回影响到Header数 + /// + /// + public unsafe int ApplyLengthToHeaders() + { + if (this.length < sizeof(IPV4Header)) + { + return 0; + } + + var count = 0; + var ptr = (byte*)this.handle.ToPointer(); + var version = (IPVersion)(Unsafe.Read(ptr) >> 4); + + ProtocolType protocol; + int ipHeaderLength; + + if (version == IPVersion.V4) + { + var header = (IPV4Header*)ptr; + header->Length = (ushort)this.length; + protocol = header->Protocol; + ipHeaderLength = header->HdrLength * 4; + count += 1; + } + else if (version == IPVersion.V6 && this.length >= sizeof(IPV6Header)) + { + var header = (IPV6Header*)ptr; + header->Length = (ushort)(this.length - sizeof(IPV6Header)); + protocol = header->NextHdr; + ipHeaderLength = sizeof(IPV6Header); + count += 1; + } + else + { + return count; + } + + if (protocol == ProtocolType.Udp && + this.length >= ipHeaderLength + sizeof(UdpHeader)) + { + var header = (UdpHeader*)(ptr + ipHeaderLength); + header->Length = (ushort)(this.length - ipHeaderLength); + count += 1; + } + + return count; + } + + + /// /// 是否相等 /// diff --git a/WindivertDotnet/WinDivertPacketExtensions.cs b/WindivertDotnet/WinDivertPacketExtensions.cs deleted file mode 100644 index 80fcbf7..0000000 --- a/WindivertDotnet/WinDivertPacketExtensions.cs +++ /dev/null @@ -1,132 +0,0 @@ -using System; -using System.Net.Sockets; -using System.Runtime.CompilerServices; -using System.Runtime.Versioning; - -namespace WindivertDotnet -{ - /// - /// WinDivertPacket扩展 - /// - public static class WinDivertPacketExtensions - { - /// - /// 克隆自制 - /// - /// - /// - /// - public static WinDivertPacket Clone(this WinDivertPacket packet) - { - var dstPacket = new WinDivertPacket(packet.Capacity); - packet.CopyTo(dstPacket); - return dstPacket; - } - - /// - /// 复制数据到dstPacket - /// - /// - /// - /// - public static void CopyTo(this WinDivertPacket packet, WinDivertPacket dstPacket) - { - dstPacket.GetWriter().Write(packet.Span); - } - - /// - /// 应用当前的Length值到IP头和Udp头 - /// 返回影响到Header数 - /// - /// - /// - public unsafe static int ApplyLengthToHeaders(this WinDivertPacket packet) - { - if (packet.Length < sizeof(IPV4Header)) - { - return 0; - } - - var count = 0; - var ptr = (byte*)packet.DangerousGetHandle().ToPointer(); - var version = Unsafe.Read(ptr) >> 4; - - ProtocolType protocol; - int ipHeaderLength; - - if (version == 4) - { - var header = (IPV4Header*)ptr; - header->Length = (ushort)packet.Length; - protocol = header->Protocol; - ipHeaderLength = header->HdrLength * 4; - count += 1; - } - else if (version == 6 && packet.Length >= sizeof(IPV6Header)) - { - var header = (IPV6Header*)ptr; - header->Length = (ushort)(packet.Length - sizeof(IPV6Header)); - protocol = header->NextHdr; - ipHeaderLength = sizeof(IPV6Header); - count += 1; - } - else - { - return count; - } - - if (protocol == ProtocolType.Udp && - packet.Length >= ipHeaderLength + sizeof(UdpHeader)) - { - var header = (UdpHeader*)(ptr + ipHeaderLength); - header->Length = (ushort)(packet.Length - ipHeaderLength); - count += 1; - } - - return count; - } - - /// - /// 翻转Src和Dst地址和端口 - /// - /// - /// - [SupportedOSPlatform("windows")] - public unsafe static bool ReverseEndPoint(this WinDivertPacket packet) - { - var result = packet.GetParseResult(); - if (result.IPV4Header != null) - { - var src = result.IPV4Header->SrcAddr; - result.IPV4Header->SrcAddr = result.IPV4Header->DstAddr; - result.IPV4Header->DstAddr = src; - } - else if (result.IPV6Header != null) - { - var src = result.IPV6Header->SrcAddr; - result.IPV6Header->SrcAddr = result.IPV6Header->DstAddr; - result.IPV6Header->DstAddr = src; - } - else - { - return false; - } - - if (result.TcpHeader != null) - { - var src = result.TcpHeader->SrcPort; - result.TcpHeader->SrcPort = result.TcpHeader->DstPort; - result.TcpHeader->DstPort = src; - } - - if (result.UdpHeader != null) - { - var src = result.UdpHeader->SrcPort; - result.UdpHeader->SrcPort = result.UdpHeader->DstPort; - result.UdpHeader->DstPort = src; - } - - return true; - } - } -}