public bool Receive() { //Buffer pointer IntPtr bufferPtr = Marshal.AllocHGlobal(NativeConstants.WinDivertMaxBuffer); byte[] bufferArr = new byte[NativeConstants.WinDivertMaxBuffer]; //Adderss pointer WINDIVERT_ADDRESS pAddress = new WINDIVERT_ADDRESS(); IntPtr pAddressPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(WINDIVERT_ADDRESS))); Marshal.StructureToPtr(pAddress, pAddressPtr, true); //Read pointer IntPtr readPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(uint))); //Packet parsing IntPtr ipHdr = IntPtr.Zero; IntPtr ipv6Hdr = IntPtr.Zero; IntPtr icmpHdr = IntPtr.Zero; IntPtr icmpv6Hdr = IntPtr.Zero; IntPtr tcpHdr = IntPtr.Zero; IntPtr udpHdr = IntPtr.Zero; IntPtr ppData = IntPtr.Zero; IntPtr ppReadLen = IntPtr.Zero; try { //Invoke WinDivertRecv if (NativeMethods.WinDivertRecv(_divert_handle, bufferPtr, (uint)NativeConstants.WinDivertMaxBuffer, pAddressPtr, readPtr) == true) { //We received a packet pAddress = (WINDIVERT_ADDRESS)Marshal.PtrToStructure(pAddressPtr, typeof(WINDIVERT_ADDRESS)); //This line is used to copy buffer data to managed Byte[] //Marshal.Copy(bufferPtr, bufferArr, 0, bufferArr.Length); //Packet length uint readlen = (uint)Marshal.ReadInt32(readPtr); //Try to parse data ipHdr = IntPtr.Zero; //Marshal.AllocHGlobal(Marshal.SizeOf(typeof(WINDIVERT_IPHDR))); ipv6Hdr = IntPtr.Zero; //Marshal.AllocHGlobal(Marshal.SizeOf(typeof(WINDIVERT_IPV6HDR))); icmpHdr = IntPtr.Zero; //Marshal.AllocHGlobal(Marshal.SizeOf(typeof(WINDIVERT_ICMPHDR))); icmpv6Hdr = IntPtr.Zero; //Marshal.AllocHGlobal(Marshal.SizeOf(typeof(WINDIVERT_ICMPV6HDR))); tcpHdr = IntPtr.Zero; //Marshal.AllocHGlobal(Marshal.SizeOf(typeof(WINDIVERT_TCPHDR))); udpHdr = IntPtr.Zero; //Marshal.AllocHGlobal(Marshal.SizeOf(typeof(WINDIVERT_UDPHDR))); ppData = IntPtr.Zero; //Marshal.AllocHGlobal(NativeConstants.WinDivertMaxBuffer); ppReadLen = IntPtr.Zero; //Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int))); //But WinDivertHelperParsePacket always return FALSE //if (NativeMethods.WinDivertHelperParsePacket(bufferPtr, readlen, ref ipHdr, ref ipv6Hdr, ref icmpHdr, ref icmpv6Hdr, ref tcpHdr, ref udpHdr, ref ppData, ppReadLen) == true) //{ NativeMethods.WinDivertHelperParsePacket(bufferPtr, readlen, ref ipHdr, ref ipv6Hdr, ref icmpHdr, ref icmpv6Hdr, ref tcpHdr, ref udpHdr, ref ppData, ppReadLen); if (ipHdr != IntPtr.Zero) { Console.Write("IPV4 Src Address : "); WINDIVERT_IPHDR dvIP = (WINDIVERT_IPHDR)Marshal.PtrToStructure(ipHdr, typeof(WINDIVERT_IPHDR)); Console.WriteLine(dvIP.SrcAddr); } if (ipv6Hdr != IntPtr.Zero) { Console.Write("IPV6 Src Address : "); WINDIVERT_IPV6HDR dvIP = (WINDIVERT_IPV6HDR)Marshal.PtrToStructure(ipv6Hdr, typeof(WINDIVERT_IPV6HDR)); //Console.WriteLine(dvIP.SrcAddr); byte[] ipArr = new byte[4]; ipArr[0] = (byte)dvIP.SrcAddr[0]; ipArr[1] = (byte)dvIP.SrcAddr[1]; ipArr[2] = (byte)dvIP.SrcAddr[2]; ipArr[3] = (byte)dvIP.SrcAddr[3]; System.Net.IPAddress ipAd = new System.Net.IPAddress(ipArr); Console.WriteLine(ipAd.ToString()); } if (icmpHdr != IntPtr.Zero) { Console.Write("ICMP Body : "); WINDIVERT_ICMPHDR dvIP = (WINDIVERT_ICMPHDR)Marshal.PtrToStructure(ipv6Hdr, typeof(WINDIVERT_ICMPHDR)); Console.WriteLine(dvIP.Body); } //} //Write to console Console.WriteLine(String.Format(@"Direction : {0}, Idfx : {1}, Subidfx : {2}", pAddress.Direction, pAddress.IfIdx, pAddress.SubIfIdx)); return(true); } else { return(false); } } finally { //Release all resources Marshal.FreeHGlobal(pAddressPtr); Marshal.FreeHGlobal(bufferPtr); Marshal.FreeHGlobal(readPtr); } }
/// <summary> /// Sets the flow label value. /// </summary> /// <param name="hdr"> /// The ipv6 header. /// </param> /// <param name="val"> /// The value. /// </param> public static void WINDIVERT_IPV6HDR_SET_FLOWLABEL(WINDIVERT_IPV6HDR hdr, uint val) { //hdr.FlowLabel0 = (uint)(val >> 16); //hdr.FlowLabel1 = (ushort)val; }
/// <summary> /// Gets the flow label value. /// </summary> /// <param name="hdr"> /// The ipv6 header. /// </param> /// <returns> /// The flow label value. /// </returns> public static uint WINDIVERT_IPV6HDR_GET_FLOWLABEL(WINDIVERT_IPV6HDR hdr) { return((uint)((hdr.FlowLabel0 << 16) | hdr.FlowLabel1)); }
/// <summary> /// Sets the traffic class value. /// </summary> /// <param name="hdr"> /// The ipv6 header. /// </param> /// <param name="val"> /// The value. /// </param> public static void WINDIVERT_IPV6HDR_SET_TRAFFICCLASS(WINDIVERT_IPV6HDR hdr, byte val) { hdr.TrafficClass0 = (byte)((val) >> 4); hdr.TrafficClass1 = val; }
/// <summary> /// Gets the traffic class value. /// </summary> /// <param name="hdr"> /// The ipv6 header. /// </param> /// <returns> /// The traffic class value. /// </returns> public static uint WINDIVERT_IPV6HDR_GET_TRAFFICCLASS(WINDIVERT_IPV6HDR hdr) { return((byte)((hdr.TrafficClass0 << 4) | (byte)hdr.TrafficClass1)); }