private unsafe byte[] ConstructIP6Packet( byte ipversion, ushort trafficclass, uint flowlabel, ulong source_address1, ulong source_address2, ulong destination_address1, ulong destination_address2, byte[] data ) { int size = (data?.Length ?? 0); if (size % 8 != 0) { size += 8 - (size % 8); } byte[] ret = new byte[size + sizeof(IPv6Header)]; IPv6Header header = new IPv6Header(); ushort temp = Utility.htons((ushort)((ipversion << 4) + trafficclass)); header.version_ltc = (byte)(temp >> 8); header.htc_lfl = (byte)((temp & 0xff) + (flowlabel >> 8)); header.flow_label = (ushort)(flowlabel & 0xff); header.payload_length = Utility.htons((ushort)(size / 8)); header.next_header = 0; header.hop_limit = 60; header.source_address1 = Utility.htonq(source_address1); header.source_address2 = Utility.htonq(source_address2); header.dest_address1 = Utility.htonq(destination_address1); header.dest_address2 = Utility.htonq(destination_address2); // todo: what about custom headers? IntPtr ptr = IntPtr.Zero; try { ptr = Marshal.AllocHGlobal(sizeof(IPv6Header)); Marshal.StructureToPtr(header, ptr, true); Marshal.Copy(ptr, ret, 0, sizeof(IPv6Header)); } finally { if (ptr != IntPtr.Zero) { Marshal.FreeHGlobal(ptr); } } if ((data?.Length ?? 0) > 0) { Array.Copy(data, 0, ret, sizeof(IPv6Header), data.Length); } return(ret); }
async void SendTask() { while (true) { if (sendbuf.Count > 0) { var payload = sendbuf.Dequeue(); GREHeader outhead = new GREHeader { flags_ver = 0, protocol = payload.Type }; //TODO: callback to print packet now? maybe another task? switch (payload.Type) { case 0x86dd: var v6outHeader = IPv6Header.FromBytes(payload.Data, 0); Console.WriteLine($"Type: {v6outHeader.nextHeader} Payload: {v6outHeader.payloadLen} From: {v6outHeader.source} To: {v6outHeader.dest}"); break; case 0x0800: var v4outHeader = IPv4Header.FromBytes(payload.Data, 0); Console.WriteLine($"Type: {v4outHeader.protocol} Size: {v4outHeader.totalLen} From: {v4outHeader.source} To: {v4outHeader.dest}"); break; case 0x88B5: // code for private experimentation Console.WriteLine($"FCP"); break; default: Console.WriteLine($"GRE Invalid Type: 0x{payload.Type:x4} {payload.Data.Length} bytes"); break; } var packet = new List <ArraySegment <byte> > { new ArraySegment <byte>(outhead.ToBytes()), new ArraySegment <byte>(payload.Data) }; await Task.Factory.FromAsync( (callback, state) => gresock.BeginSend(packet, SocketFlags.None, callback, state) , gresock.EndSend, null); } else { //TODO: better way to wait for new packets? await Task.Delay(1); } } }
PackedFrame packet_to_circuit(byte[] buffer, int startAt, int size) { var frame = new List <VarInt>(); frame.Add(1); // firstsignal = 1 we start at the beginning of the map... frame.Add(((size + 3) / 4) + 2); // sigcount = enough signals to hold all the bytes plus two for feathernet header... frame.Add(0); // grey = broadcast / placeholder for feathernet dest frame.Add(1); // white = 1 to mark feathernet map int i; for (i = startAt; i < startAt + size; i += 4) { Int32 nextword = ((buffer[i] << 24) | (buffer[i + 1] << 16) | (buffer[i + 2] << 8) | (buffer[i + 3])); // clear tail bytes if last word... if ((startAt + size) - i < 4) { nextword = (Int32)(nextword & (0xffffffff << ((4 - ((startAt + size) - i)) * 8))); } frame.Add(nextword); } // add a world-id to be consistent with other clusterio traffic VarInt srcid = ID; var head = IPv6Header.FromBytes(buffer, startAt); var ipdest = head.dest; VarInt dstid, featherdst; if (ipdest.IsIPv6Multicast) { dstid = 0xffffffff; featherdst = 0; } else { var ipdestbytes = ipdest.GetAddressBytes(); dstid = ((ipdestbytes[8] << 24) | (ipdestbytes[9] << 16) | (ipdestbytes[10] << 8) | (ipdestbytes[11])); featherdst = ((ipdestbytes[12] << 24) | (ipdestbytes[13] << 16) | (ipdestbytes[14] << 8) | (ipdestbytes[15])); } frame[2] = featherdst; return(new PackedFrame(dstid, srcid, frame, Feathernet_0_16)); }
static void Main(string[] args) { Console.CancelKeyPress += delegate { _running = false; }; // open handle using (var handle = Diversion.WinDivertOpen("true", WinDivertLayer.Network, 100, 0)) { if (handle.IsInvalid) { Console.WriteLine("Unable to open handle. Error: " + Marshal.GetLastWin32Error()); return; } // prepare headers var ipHeader = new IPHeader(); var ipv6Header = new IPv6Header(); var icmpHeader = new ICMPHeader(); var icmpv6Header = new ICMPv6Header(); var tcpHeader = new TCPHeader(); var udpHeader = new UDPHeader(); var address = new Address(); byte[] buffer = new byte[65535]; uint receiveLength = 0; uint sendLength = 0; string processName; uint pid = 0; // loop while (_running) { pid = 0; } receiveLength = 0; sendLength = 0; fixed(byte *data = buffer) { Diversion.WinDivertHelperParsePacket(data, receiveLength, ipHeader, ipv6Header, icmpHeader, icmpv6Header, tcpHeader, udpHeader, null, null); } } }
void ReceivedBytes(byte[] rcvbuf) { // convert to signals and OnRecieve() switch (rcvbuf[0] >> 4) { case 4: var v4Header = IPv4Header.FromBytes(rcvbuf, 0); if (v4Header.protocol != 47) { break; // only GRE... this should be handled by socket, but just to be sure... } if (v4Header.headLen != 5) { break; // don't currently handle any options } var GRE4Header = GREHeader.FromBytes(rcvbuf, (v4Header.headLen * 4)); if (GRE4Header.flags_ver != 0) { break; // don't support any GRE flags, version is always 0 } // convert inner to json for clusterio and submit... for now we only have v6 inner switch (GRE4Header.protocol) { case 0x86dd: var v6inHeader = IPv6Header.FromBytes(rcvbuf, ((v4Header.headLen + 1) * 4)); Console.WriteLine($"Type: {v6inHeader.nextHeader} Payload: {v6inHeader.payloadLen} From: {v6inHeader.source} To: {v6inHeader.dest}"); if (v6inHeader.payloadLen + 40 <= ((Feathernet_0_16.Count - 2) * 4)) { if (v6inHeader.nextHeader == 44) { Console.WriteLine("Fragmented packet dropped"); } else { var circpacket = packet_to_circuit(rcvbuf, ((v4Header.headLen + 1) * 4), v6inHeader.totalLen).Unpack(); circpacket.origin = this; OnReceive?.Invoke(circpacket); } } else { Console.WriteLine("Too large"); } break; default: break; } break; case 6: var v6Header = IPv6Header.FromBytes(rcvbuf, 0); var GRE6Header = GREHeader.FromBytes(rcvbuf, 40); break; default: break; } }
/// <summary> /// Sets the flow label value. /// </summary> /// <param name="hdr"> /// The ipv6 header. /// </param> /// <param name="val"> /// The value. /// </param> public static void IPv6Header_SET_FLOWLABEL(IPv6Header hdr, uint val) { //hdr.FlowLabel0 = (uint)(val >> 16); //hdr.FlowLabel1 = (ushort)val; }
/// <summary> /// Sets the traffic class value. /// </summary> /// <param name="hdr"> /// The ipv6 header. /// </param> /// <param name="val"> /// The value. /// </param> public static void IPv6Header_SET_TRAFFICCLASS(IPv6Header hdr, byte val) { hdr.TrafficClass0 = (byte)(val >> 4); hdr.TrafficClass1 = val; }
/// <summary> /// Gets the flow label value. /// </summary> /// <param name="hdr"> /// The ipv6 header. /// </param> /// <returns> /// The flow label value. /// </returns> public static uint IPv6Header_GET_FLOWLABEL(IPv6Header hdr) { return((hdr.FlowLabel0 << 16) | hdr.FlowLabel1); }
/// <summary> /// Gets the traffic class value. /// </summary> /// <param name="hdr"> /// The ipv6 header. /// </param> /// <returns> /// The traffic class value. /// </returns> public static uint IPv6Header_GET_TRAFFICCLASS(IPv6Header hdr) { return((byte)((hdr.TrafficClass0 << 4) | (byte)hdr.TrafficClass1)); }
static void Main(string[] args) { // This is not really like the netdump example in the native WinDivert examples. Since we are // pulling the names of processes behind packet flows, we need to fully intercept/divert packets, // make the process query, then reinject. If we just sniff, the process will either be closed or // no longer bound to the local port the packet is associated with, and the process query will // be hit or miss (probably fail). So, by fully diverting rather than sniffing, we force // the process to hang open waiting for the packet while we check the process identity, then // hand the packet over untouched. // // Ideally you do not want to be querying the process on every single packet. Rather, you would // create a stucture that keeps track of a network flow, identify the process (protocol, whatever // else) one time, then only re-check when the flow has ended and a new flow has begun. This is // just for basic demonstration though, so we don't create and track any flows. // // Note also that the process identification is still not 100%. Many system processes run under // PID 4. I'm not satisfied with just getting SYSTEM for these processes, and I'd like to // ideally be able to identify exactly which processes they are. Still working on that. Console.WindowWidth = Console.LargestWindowWidth; bool running = true; Console.CancelKeyPress += delegate { running = false; }; Diversion diversion; string filter = "true"; try { diversion = Diversion.Open(filter, DivertLayer.Network, 100, 0); } catch(Exception e) { Console.WriteLine(e.Message); return; } if(!diversion.Handle.Valid) { Console.WriteLine("Failed to open divert handle with error {0}", System.Runtime.InteropServices.Marshal.GetLastWin32Error()); return; } IPHeader ipHeader = new IPHeader(); IPv6Header ipv6Header = new IPv6Header(); ICMPHeader icmpHeader = new ICMPHeader(); ICMPv6Header icmpv6Header = new ICMPv6Header(); TCPHeader tcpHeader = new TCPHeader(); UDPHeader udpHeader = new UDPHeader(); Address address = new Address(); byte[] buffer = new byte[65535]; uint receiveLength = 0; uint sendLength = 0; string processName; uint pid = 0; while (running) { pid = 0; receiveLength = 0; sendLength = 0; if (!diversion.Receive(buffer, address, ref receiveLength)) { Console.WriteLine("Failed to receive packet with error {0}", System.Runtime.InteropServices.Marshal.GetLastWin32Error()); continue; } diversion.ParsePacket(buffer, receiveLength, ipHeader, ipv6Header, icmpHeader, icmpv6Header, tcpHeader, udpHeader); if (ipHeader.Valid && tcpHeader.Valid) { Diversion.GetPacketProcess(address, tcpHeader, ipHeader, ref pid, out processName); if (processName.Equals("SYSTEM", StringComparison.OrdinalIgnoreCase)) { Console.WriteLine("ERROR {0} and PID is {1}", System.Runtime.InteropServices.Marshal.GetLastWin32Error(), pid); } Console.WriteLine( "{0} IPv4 TCP packet captured destined for {1}:{2} from {3}:{4} {5}.", address.Direction == DivertDirection.Inbound ? "Inbound" : "Outbound", ipHeader.DestinationAddress.ToString(), tcpHeader.DestinationPort.ToString(), ipHeader.SourceAddress.ToString(), tcpHeader.SourcePort.ToString(), address.Direction == DivertDirection.Inbound ? string.Format("to process {0}", processName) : string.Format("from process {0}", processName) ); Console.WriteLine(string.Format("ack: {0}, syn: {1}, len: {2}, seq: {3}", tcpHeader.Ack, tcpHeader.Syn, ipHeader.Length, tcpHeader.SequenceNumber)); } else if(ipHeader.Valid && udpHeader.Valid) { Diversion.GetPacketProcess(address, udpHeader, ipHeader, ref pid, out processName); if (processName.Equals("SYSTEM", StringComparison.OrdinalIgnoreCase)) { Console.WriteLine("ERROR {0} and PID is {1}", System.Runtime.InteropServices.Marshal.GetLastWin32Error(), pid); } Console.WriteLine( "{0} IPv4 UDP packet captured destined for {1}:{2} from {3}:{4} {5}.", address.Direction == DivertDirection.Inbound ? "Inbound" : "Outbound", ipHeader.DestinationAddress.ToString(), tcpHeader.DestinationPort.ToString(), ipHeader.SourceAddress.ToString(), tcpHeader.SourcePort.ToString(), address.Direction == DivertDirection.Inbound ? string.Format("to process {0}", processName) : string.Format("from process {0}", processName) ); } else if(ipv6Header.Valid && tcpHeader.Valid) { Diversion.GetPacketProcess(address, tcpHeader, ipv6Header, ref pid, out processName); if (processName.Equals("SYSTEM", StringComparison.OrdinalIgnoreCase)) { Console.WriteLine("ERROR {0} and PID is {1}", System.Runtime.InteropServices.Marshal.GetLastWin32Error(), pid); } Console.WriteLine( "{0} IPv6 TCP packet captured destined for {1}:{2} from {3}:{4} {5}.", address.Direction == DivertDirection.Inbound ? "Inbound" : "Outbound", ipHeader.DestinationAddress.ToString(), tcpHeader.DestinationPort.ToString(), ipHeader.SourceAddress.ToString(), tcpHeader.SourcePort.ToString(), address.Direction == DivertDirection.Inbound ? string.Format("to process {0}", processName) : string.Format("from process {0}", processName) ); Console.WriteLine(string.Format("ack: {0}, syn: {1}, len: {2}, seq: {3}", tcpHeader.Ack, tcpHeader.Syn, ipv6Header.Length, tcpHeader.SequenceNumber)); } else if (ipv6Header.Valid && udpHeader.Valid) { Diversion.GetPacketProcess(address, udpHeader, ipv6Header, ref pid, out processName); if (processName.Equals("SYSTEM", StringComparison.OrdinalIgnoreCase)) { Console.WriteLine("ERROR {0} and PID is {1}", System.Runtime.InteropServices.Marshal.GetLastWin32Error(), pid); } Console.WriteLine( "{0} IPv6 UDP packet captured destined for {1}:{2} from {3}:{4} {5}.", address.Direction == DivertDirection.Inbound ? "Inbound" : "Outbound", ipHeader.DestinationAddress.ToString(), tcpHeader.DestinationPort.ToString(), ipHeader.SourceAddress.ToString(), tcpHeader.SourcePort.ToString(), address.Direction == DivertDirection.Inbound ? string.Format("to process {0}", processName) : string.Format("from process {0}", processName) ); } if(address.Direction == DivertDirection.Outbound) { diversion.CalculateChecksums(buffer, receiveLength, 0); } diversion.SendAsync(buffer, receiveLength, address, ref sendLength); } diversion.Close(); }
public void ParseNetworkPacket(PacketRawInfo args) { IPHeader ipHeader = null; IPv6Header ipv6Header = null; EthernetHeader ethernetHeader = null; EthernetPacketType ethernetPackeType = EthernetPacketType.IpV4; PacketInfo packetInfo = new PacketInfo(); packetInfo.protocolE = PacketType.UNKNOWN; packetInfo.count = 1; if (args.linkLayer == LinkLayers.Ethernet) { ethernetHeader = new EthernetHeader(args.data, args.size); ethernetPackeType = ethernetHeader.EtherType; packetInfo.hardwareSource = ethernetHeader.SourceMac; packetInfo.harwareDestination = ethernetHeader.DestinationMac; packetInfo.protocol = ((Protocol)ethernetHeader.EtherType).ToString(); if (ethernetHeader.EtherType == EthernetPacketType.IpV4) { args.data = ethernetHeader.Payload; args.size = ethernetHeader.Payload.Length; } } else { packetInfo.protocol = Protocol.Iplt.ToString(); } switch (ethernetPackeType) { case EthernetPacketType.IpV4: ipHeader = new IPHeader(args.data, args.size); packetInfo.ipDestination = ipHeader.DestinationAddress.ToString(); packetInfo.ipSource = ipHeader.SourceAddress.ToString(); packetInfo.size = ipHeader.MessageLength; if (packetInfo.ipSource == incomingIP) { packetInfo.incoming = true; } Statistics.AddToIPPacketsStats(packetInfo.size, packetInfo.incoming); break; case EthernetPacketType.IpV6: ipv6Header = new IPv6Header(args.data, args.size); packetInfo.ipDestination = ipv6Header.DestinationAddress.ToString(); packetInfo.ipSource = ipv6Header.SourceAddress.ToString(); if (packetInfo.ipSource == incomingIP) { packetInfo.incoming = true; } Statistics.AddToIPPacketsStats(packetInfo.size, packetInfo.incoming); break; case EthernetPacketType.Arp: ARPHeader arpHeader = new ARPHeader(ethernetHeader.Payload, ethernetHeader.Payload.Length); packetInfo.ipDestination = arpHeader.TPA; packetInfo.ipSource = arpHeader.SPA; packetInfo.desription = arpHeader.Description; if (packetInfo.ipSource == incomingIP) { packetInfo.incoming = true; } packetInfo.size = arpHeader.Size; packetInfo.protocol = "ARP"; packetInfo.protocolE = PacketType.ARP; Statistics.AddToARPPacketsStats(packetInfo.size, packetInfo.incoming); break; case EthernetPacketType.WakeOnLan: break; default: packetInfo.desription = "неизвестный Ethernet протокол"; break; } if (ipHeader != null) { switch (ipHeader.ProtocolType) { case Protocol.Udp: NetworkShow.Network.Packets.UDPHeader udpheader = new UDPHeader(ipHeader.Data, ipHeader.Data.Length); packetInfo.portDestination = udpheader.DestinationPort; packetInfo.portSource = udpheader.SourcePort; packetInfo.size = udpheader.Length; packetInfo.protocol = "UDP"; packetInfo.protocolE = PacketType.UDP; packetInfo.active = "T"; Statistics.AddToUDPPacketsStats(packetInfo.size, packetInfo.incoming); break; case Protocol.Tcp: NetworkShow.Network.Packets.TCPHeader tcpheader = new TCPHeader(ipHeader.Data, ipHeader.Data.Length); packetInfo.portDestination = tcpheader.DestinationPort; packetInfo.portSource = tcpheader.SourcePort; packetInfo.size = tcpheader.MessageLength + tcpheader.HeaderLength; packetInfo.active = "T"; packetInfo.protocol = "TCP"; packetInfo.protocolE = PacketType.TCP; Statistics.AddToTCPPacketsStats(packetInfo.size, packetInfo.incoming); break; case Protocol.InternetControlMessageProtocol: NetworkShow.Network.Packets.ICMPHeader icmpheader = new ICMPHeader(ipHeader.Data, ipHeader.Data.Length); packetInfo.desription = icmpheader.Type.ToString(); packetInfo.size = icmpheader.Size; packetInfo.protocol = "ICMP"; packetInfo.protocolE = PacketType.ICMP; Statistics.AddToICMPPacketsStats(packetInfo.size, packetInfo.incoming); break; case Protocol.InternetGroupManagementProtocol: NetworkShow.Network.Packets.IGMPHeader igmpheader = new IGMPHeader(ipHeader.Data, ipHeader.Data.Length); packetInfo.desription = igmpheader.GroupAddress + " " + igmpheader.Type + " " + igmpheader.Version; packetInfo.size = igmpheader.Size; packetInfo.protocol = "IGMP"; packetInfo.protocolE = PacketType.IGMP; Statistics.AddToIGMPPacketsStats(packetInfo.size, packetInfo.incoming); break; default: packetInfo.desription = "неизвестный IP протокол"; packetInfo.protocol = ipHeader.ProtocolType.ToString(); packetInfo.protocolE = PacketType.UNKNOWN; packetInfo.size = ipHeader.MessageLength; break; } } //PacketsInfo.AddToQueue(packetInfo); int pos = -1; if ((packetInfo.protocol == "TCP") || (packetInfo.protocol == "UDP")) { //pos = FindConnection(packetInfo); pos = FindConnection(packetInfo); if (pos >= 0) { packetInfo = UpdateConnection(pos, packetInfo); UpdateInfoEvent(packetInfo.protocol); db.UpdateConnection(packetInfo.pos, packetInfo); } else { packetInfo.pos = db.SaveNewPacket(packetInfo); AddConnection(packetInfo); ChangeRowsCountEvent(packetInfo.protocolE, packetInfo.pos, packetInfo.portSource, packetInfo.portSource); } } else { int position = db.SaveNewPacket(packetInfo); ChangeRowsCountEvent(packetInfo.protocolE, position, packetInfo.portSource, packetInfo.portSource); } }
static void Main(string[] args) { // This is not really like the netdump example in the native WinDivert examples. Since we are // pulling the names of processes behind packet flows, we need to fully intercept/divert packets, // make the process query, then reinject. If we just sniff, the process will either be closed or // no longer bound to the local port the packet is associated with, and the process query will // be hit or miss (probably fail). So, by fully diverting rather than sniffing, we force // the process to hang open waiting for the packet while we check the process identity, then // hand the packet over untouched. // // Ideally you do not want to be querying the process on every single packet. Rather, you would // create a stucture that keeps track of a network flow, identify the process (protocol, whatever // else) one time, then only re-check when the flow has ended and a new flow has begun. This is // just for basic demonstration though, so we don't create and track any flows. // // Note also that the process identification is still not 100%. Many system processes run under // PID 4. I'm not satisfied with just getting SYSTEM for these processes, and I'd like to // ideally be able to identify exactly which processes they are. Still working on that. Console.WindowWidth = Console.LargestWindowWidth; bool running = true; Console.CancelKeyPress += delegate { running = false; }; Diversion diversion; string filter = "true"; try { diversion = Diversion.Open(filter, DivertLayer.Network, 100, 0); } catch (Exception e) { Console.WriteLine(e.Message); return; } if (!diversion.Handle.Valid) { Console.WriteLine("Failed to open divert handle with error {0}", System.Runtime.InteropServices.Marshal.GetLastWin32Error()); return; } IPHeader ipHeader = new IPHeader(); IPv6Header ipv6Header = new IPv6Header(); ICMPHeader icmpHeader = new ICMPHeader(); ICMPv6Header icmpv6Header = new ICMPv6Header(); TCPHeader tcpHeader = new TCPHeader(); UDPHeader udpHeader = new UDPHeader(); Address address = new Address(); byte[] buffer = new byte[65535]; uint receiveLength = 0; uint sendLength = 0; string processName; uint pid = 0; while (running) { pid = 0; receiveLength = 0; sendLength = 0; if (!diversion.Receive(buffer, address, ref receiveLength)) { Console.WriteLine("Failed to receive packet with error {0}", System.Runtime.InteropServices.Marshal.GetLastWin32Error()); continue; } diversion.ParsePacket(buffer, receiveLength, ipHeader, ipv6Header, icmpHeader, icmpv6Header, tcpHeader, udpHeader); if (ipHeader.Valid && tcpHeader.Valid) { Diversion.GetPacketProcess(address, tcpHeader, ipHeader, ref pid, out processName); if (processName.Equals("SYSTEM", StringComparison.OrdinalIgnoreCase)) { Console.WriteLine("ERROR {0} and PID is {1}", System.Runtime.InteropServices.Marshal.GetLastWin32Error(), pid); } Console.WriteLine( "{0} IPv4 TCP packet captured destined for {1}:{2} from {3}:{4} {5}.", address.Direction == DivertDirection.Inbound ? "Inbound" : "Outbound", ipHeader.DestinationAddress.ToString(), tcpHeader.DestinationPort.ToString(), ipHeader.SourceAddress.ToString(), tcpHeader.SourcePort.ToString(), address.Direction == DivertDirection.Inbound ? string.Format("to process {0}", processName) : string.Format("from process {0}", processName) ); Console.WriteLine(string.Format("ack: {0}, syn: {1}, len: {2}, seq: {3}", tcpHeader.Ack, tcpHeader.Syn, ipHeader.Length, tcpHeader.SequenceNumber)); } else if (ipHeader.Valid && udpHeader.Valid) { Diversion.GetPacketProcess(address, udpHeader, ipHeader, ref pid, out processName); if (processName.Equals("SYSTEM", StringComparison.OrdinalIgnoreCase)) { Console.WriteLine("ERROR {0} and PID is {1}", System.Runtime.InteropServices.Marshal.GetLastWin32Error(), pid); } Console.WriteLine( "{0} IPv4 UDP packet captured destined for {1}:{2} from {3}:{4} {5}.", address.Direction == DivertDirection.Inbound ? "Inbound" : "Outbound", ipHeader.DestinationAddress.ToString(), tcpHeader.DestinationPort.ToString(), ipHeader.SourceAddress.ToString(), tcpHeader.SourcePort.ToString(), address.Direction == DivertDirection.Inbound ? string.Format("to process {0}", processName) : string.Format("from process {0}", processName) ); } else if (ipv6Header.Valid && tcpHeader.Valid) { Diversion.GetPacketProcess(address, tcpHeader, ipv6Header, ref pid, out processName); if (processName.Equals("SYSTEM", StringComparison.OrdinalIgnoreCase)) { Console.WriteLine("ERROR {0} and PID is {1}", System.Runtime.InteropServices.Marshal.GetLastWin32Error(), pid); } Console.WriteLine( "{0} IPv6 TCP packet captured destined for {1}:{2} from {3}:{4} {5}.", address.Direction == DivertDirection.Inbound ? "Inbound" : "Outbound", ipHeader.DestinationAddress.ToString(), tcpHeader.DestinationPort.ToString(), ipHeader.SourceAddress.ToString(), tcpHeader.SourcePort.ToString(), address.Direction == DivertDirection.Inbound ? string.Format("to process {0}", processName) : string.Format("from process {0}", processName) ); Console.WriteLine(string.Format("ack: {0}, syn: {1}, len: {2}, seq: {3}", tcpHeader.Ack, tcpHeader.Syn, ipv6Header.Length, tcpHeader.SequenceNumber)); } else if (ipv6Header.Valid && udpHeader.Valid) { Diversion.GetPacketProcess(address, udpHeader, ipv6Header, ref pid, out processName); if (processName.Equals("SYSTEM", StringComparison.OrdinalIgnoreCase)) { Console.WriteLine("ERROR {0} and PID is {1}", System.Runtime.InteropServices.Marshal.GetLastWin32Error(), pid); } Console.WriteLine( "{0} IPv6 UDP packet captured destined for {1}:{2} from {3}:{4} {5}.", address.Direction == DivertDirection.Inbound ? "Inbound" : "Outbound", ipHeader.DestinationAddress.ToString(), tcpHeader.DestinationPort.ToString(), ipHeader.SourceAddress.ToString(), tcpHeader.SourcePort.ToString(), address.Direction == DivertDirection.Inbound ? string.Format("to process {0}", processName) : string.Format("from process {0}", processName) ); } if (address.Direction == DivertDirection.Outbound) { diversion.CalculateChecksums(buffer, receiveLength, 0); } diversion.SendAsync(buffer, receiveLength, address, ref sendLength); } diversion.Close(); }