private static IEnumerable <MIB_TCP6ROW_OWNER_PID> EnumTcpConnectionsV6() { int dwSize = sizeof(int) + Marshal.SizeOf(typeof(MIB_TCP6ROW_OWNER_PID)) * 100; IntPtr hTcpTable; { hTcpTable = Marshal.AllocHGlobal(dwSize); int ret = GetExtendedTcpTable(hTcpTable, ref dwSize, true, AF_INET6, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_CONNECTIONS, 0); if (ret != NO_ERROR) { // retry for new dwSize. Marshal.FreeHGlobal(hTcpTable); hTcpTable = Marshal.AllocHGlobal(dwSize); ret = GetExtendedTcpTable(hTcpTable, ref dwSize, true, AF_INET6, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_CONNECTIONS, 0); if (ret != NO_ERROR) { Marshal.FreeHGlobal(hTcpTable); throw new Exception("GetExtendedTcpTable return: " + ret); } } } { MIB_TCP6ROW_OWNER_PID item = new MIB_TCP6ROW_OWNER_PID(); int dwNumEntries = Marshal.ReadInt32(hTcpTable); IntPtr pItem = new IntPtr(hTcpTable.ToInt64() + sizeof(int)); for (int i = 0; i < dwNumEntries; ++i) { Marshal.PtrToStructure(pItem, item); pItem = new IntPtr(pItem.ToInt64() + Marshal.SizeOf(typeof(MIB_TCP6ROW_OWNER_PID))); yield return(item); } Marshal.FreeHGlobal(hTcpTable); } }
public static List <TcpConnectionInfo> GetTcpConnections(IPVersion ipVersion, Dictionary <int, Process> processesByPid = null) { int bufferSize = 0; List <TcpConnectionInfo> tcpTableRecords = new List <TcpConnectionInfo>(); int ulAf = AF_INET; if (ipVersion == IPVersion.IPv6) { ulAf = AF_INET6; } // Getting the initial size of TCP table. uint result = Iphlpapi.GetExtendedTcpTable(IntPtr.Zero, ref bufferSize, true, ulAf, TcpTableClass.TCP_TABLE_OWNER_PID_ALL); // Allocating memory as an IntPtr with the bufferSize. IntPtr tcpTableRecordsPtr = Marshal.AllocHGlobal(bufferSize); try { // The IntPtr from last call, tcpTableRecoresPtr must be used in the subsequent // call and passed as the first parameter. result = Iphlpapi.GetExtendedTcpTable(tcpTableRecordsPtr, ref bufferSize, true, ulAf, TcpTableClass.TCP_TABLE_OWNER_PID_ALL); // If not zero, the call failed. if (result != 0) { return(new List <TcpConnectionInfo>()); } // Marshals data fron an unmanaged block of memory to the // newly allocated managed object 'tcpRecordsTable' of type // 'MIB_TCPTABLE_OWNER_PID' to get number of entries of TCP // table structure. // Determine if IPv4 or IPv6. if (ipVersion == IPVersion.IPv4) { MIB_TCPTABLE_OWNER_PID tcpRecordsTable = (MIB_TCPTABLE_OWNER_PID)Marshal.PtrToStructure(tcpTableRecordsPtr, typeof(MIB_TCPTABLE_OWNER_PID)); IntPtr tableRowPtr = (IntPtr)((long)tcpTableRecordsPtr + Marshal.SizeOf(tcpRecordsTable.dwNumEntries)); // Read and parse the TCP records from the table and store them in list // 'TcpConnection' structure type objects. for (int row = 0; row < tcpRecordsTable.dwNumEntries; row++) { MIB_TCPROW_OWNER_PID tcpRow = (MIB_TCPROW_OWNER_PID)Marshal.PtrToStructure(tableRowPtr, typeof(MIB_TCPROW_OWNER_PID)); // Add row to list of TcpConnetions. tcpTableRecords.Add(new TcpConnectionInfo( Protocol.TCP, new IPAddress(tcpRow.localAddr), new IPAddress(tcpRow.remoteAddr), BitConverter.ToUInt16(new byte[2] { tcpRow.localPort[1], tcpRow.localPort[0] }, 0), BitConverter.ToUInt16(new byte[2] { tcpRow.remotePort[1], tcpRow.remotePort[0] }, 0), tcpRow.owningPid, tcpRow.state, GetProcessNameByPid(tcpRow.owningPid, processesByPid))); tableRowPtr = (IntPtr)((long)tableRowPtr + Marshal.SizeOf(tcpRow)); } } else if (ipVersion == IPVersion.IPv6) { MIB_TCP6TABLE_OWNER_PID tcpRecordsTable = (MIB_TCP6TABLE_OWNER_PID)Marshal.PtrToStructure(tcpTableRecordsPtr, typeof(MIB_TCP6TABLE_OWNER_PID)); IntPtr tableRowPtr = (IntPtr)((long)tcpTableRecordsPtr + Marshal.SizeOf(tcpRecordsTable.dwNumEntries)); // Read and parse the TCP records from the table and store them in list // 'TcpConnection' structure type objects. for (int row = 0; row < tcpRecordsTable.dwNumEntries; row++) { MIB_TCP6ROW_OWNER_PID tcpRow = (MIB_TCP6ROW_OWNER_PID)Marshal.PtrToStructure(tableRowPtr, typeof(MIB_TCP6ROW_OWNER_PID)); tcpTableRecords.Add(new TcpConnectionInfo( Protocol.TCP, new IPAddress(tcpRow.localAddr, tcpRow.localScopeId), new IPAddress(tcpRow.remoteAddr, tcpRow.remoteScopeId), BitConverter.ToUInt16(new byte[2] { tcpRow.localPort[1], tcpRow.localPort[0] }, 0), BitConverter.ToUInt16(new byte[2] { tcpRow.remotePort[1], tcpRow.remotePort[0] }, 0), tcpRow.owningPid, tcpRow.state, GetProcessNameByPid(tcpRow.owningPid, processesByPid))); tableRowPtr = (IntPtr)((long)tableRowPtr + Marshal.SizeOf(tcpRow)); } } } catch (OutOfMemoryException outOfMemoryException) { throw outOfMemoryException; } catch (Exception exception) { throw exception; } finally { Marshal.FreeHGlobal(tcpTableRecordsPtr); } return(tcpTableRecords != null?tcpTableRecords.Distinct().ToList() : new List <TcpConnectionInfo>()); }