private static unsafe int EstimateBufferSize(AddressFamily addressFamily, TCP_TABLE_CLASS tableClass) { var size = 0; var status = IPHlpApi.GetExtendedTcpTable(null, ref size, false, addressFamily, tableClass, 0); if (status != (int)ErrorCodes.ERROR_INSUFFICIENT_BUFFER) { Win32ExceptionUtility.Throw(status); } return(size); }
private static unsafe void GetTcpTableWithPid(AddressFamily addressFamily, ResizeableBuffer resizeableBuffer) { var size = EstimateBufferSize(addressFamily, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL); var buffer = resizeableBuffer.Get(ref size); while (true) { fixed(byte *b = buffer) { var result = IPHlpApi.GetExtendedTcpTable(b, ref size, false, addressFamily, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL, 0); if (result == (int)ErrorCodes.ERROR_INSUFFICIENT_BUFFER) { buffer = resizeableBuffer.Get(ref size); continue; } if (result != 0) { Win32ExceptionUtility.Throw(result); } var itemSize = addressFamily == AddressFamily.AF_INET ? sizeof(MIB_TCPROW_OWNER_PID) : sizeof(MIB_TCP6ROW_OWNER_PID); var itemCount = *(int *)b; if (itemCount * itemSize + 4 > buffer.Length) { throw new InvalidOperationException($"Buffer overflow check failed. ItemCount: {itemCount}, ItemSize: {itemSize}, BufferSize: {buffer.Length}"); } return; } } }
public unsafe void GetExtendedTcpTableTest() { IntPtr tcpTablePtr = IntPtr.Zero; int tcpTableLength = 0; if (IPHlpApi.GetExtendedTcpTable(tcpTablePtr, ref tcpTableLength, bOrder: true, AddressFamily.InterNetwork, IPHlpApi.TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL, 0) == Win32ErrorCode.ERROR_INSUFFICIENT_BUFFER) { try { tcpTablePtr = Marshal.AllocHGlobal(tcpTableLength); if (IPHlpApi.GetExtendedTcpTable(tcpTablePtr, ref tcpTableLength, bOrder: true, AddressFamily.InterNetwork, IPHlpApi.TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL, 0) == Win32ErrorCode.ERROR_SUCCESS) { IPHlpApi.MIB_TCPTABLE_OWNER_PID *tcpTable = (IPHlpApi.MIB_TCPTABLE_OWNER_PID *)tcpTablePtr; var tableSize = sizeof(IPHlpApi.MIB_TCPTABLE_OWNER_PID); IPHlpApi.MIB_TCPROW_OWNER_PID *tcpRow = (IPHlpApi.MIB_TCPROW_OWNER_PID *)(tcpTablePtr + tableSize); for (int i = 0; i < tcpTable->dwNumEntries; ++i) { Assert.InRange(tcpRow->LocalPort, 0, 65535); Assert.True(Enum.IsDefined(typeof(TcpState), tcpRow->dwState)); tcpRow++; } } } finally { if (tcpTablePtr != IntPtr.Zero) { Marshal.FreeHGlobal(tcpTablePtr); } } } }