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;
                }
            }
        }
Example #3
0
    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);
                }
            }
        }
    }