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);
        }
Esempio n. 2
0
        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;
                }
            }
        }
Esempio n. 4
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);
                }
            }
        }
    }