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 unsafe HashSet <string> BuildCache() { var size = 1024; lock (sync) { while (true) { var buffer = resizeableBuffer.Get(ref size, false); fixed(byte *b = buffer) { var result = IPHlpApi.GetAdaptersAddresses( AddressFamily.AF_UNSPEC, GetAdaptersAddressesFlags.GAA_FLAG_INCLUDE_WINS_INFO | GetAdaptersAddressesFlags.GAA_FLAG_INCLUDE_GATEWAYS | GetAdaptersAddressesFlags.GAA_FLAG_INCLUDE_ALL_INTERFACES, IntPtr.Zero, b, ref size); if (result == (int)ErrorCodes.ERROR_BUFFER_OVERFLOW) { continue; } if (result == (int)ErrorCodes.ERROR_NO_DATA) { return(new HashSet <string>(StringComparer.OrdinalIgnoreCase)); } if (result != (int)ErrorCodes.ERROR_SUCCESS) { Win32ExceptionUtility.Throw(result); } var upInterfaces = new HashSet <string>(StringComparer.OrdinalIgnoreCase); for (var ptr = (IP_ADAPTER_ADDRESSES *)b; ptr != null; ptr = ptr->Next) { UnsafeHelper.CheckBounds(b, size, ptr, sizeof(IP_ADAPTER_ADDRESSES)); if (ptr->OperStatus == OperationalStatus.Up && ptr->IfType != NetworkInterfaceType.Loopback) { upInterfaces.Add(GetAdapterIdentity(new string(ptr->Description))); } } return(upInterfaces); } } } }
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); } } } }