Beispiel #1
0
        internal SystemTcpConnectionInformation(Interop.IpHlpApi.MibTcpRow row)
        {
            _state = row.state;

            // Port is returned in Big-Endian - most significant bit on left.
            // Unfortunately, its done at the word level and not the DWORD level.
            int localPort  = row.localPort1 << 8 | row.localPort2;
            int remotePort = ((_state == TcpState.Listen) ? 0 : row.remotePort1 << 8 | row.remotePort2);

            _localEndPoint  = new IPEndPoint(row.localAddr, (int)localPort);
            _remoteEndPoint = new IPEndPoint(row.remoteAddr, (int)remotePort);
        }
Beispiel #2
0
        ///
        /// Gets the active TCP connections. Uses the native GetTcpTable API.
        private List <SystemTcpConnectionInformation> GetAllTcpConnections()
        {
            uint size   = 0;
            uint result = 0;
            SafeLocalAllocHandle buffer = null;
            List <SystemTcpConnectionInformation> tcpConnections = new List <SystemTcpConnectionInformation>();

            // Check if it supports IPv4 for IPv6 only modes.
            if (Socket.OSSupportsIPv4)
            {
                // Get the buffer size needed.
                result = Interop.IpHlpApi.GetTcpTable(SafeLocalAllocHandle.Zero, ref size, true);

                while (result == Interop.IpHlpApi.ERROR_INSUFFICIENT_BUFFER)
                {
                    // Allocate the buffer and get the TCP table.
                    using (buffer = SafeLocalAllocHandle.LocalAlloc((int)size))
                    {
                        result = Interop.IpHlpApi.GetTcpTable(buffer, ref size, true);

                        if (result == Interop.IpHlpApi.ERROR_SUCCESS)
                        {
                            // The table info just gives us the number of rows.
                            IntPtr newPtr = buffer.DangerousGetHandle();
                            Interop.IpHlpApi.MibTcpTable tcpTableInfo = Marshal.PtrToStructure <Interop.IpHlpApi.MibTcpTable>(newPtr);

                            if (tcpTableInfo.numberOfEntries > 0)
                            {
                                // Skip over the tableinfo to get the inline rows.
                                newPtr = (IntPtr)((long)newPtr + Marshal.SizeOf(tcpTableInfo.numberOfEntries));

                                for (int i = 0; i < tcpTableInfo.numberOfEntries; i++)
                                {
                                    Interop.IpHlpApi.MibTcpRow tcpRow = Marshal.PtrToStructure <Interop.IpHlpApi.MibTcpRow>(newPtr);
                                    tcpConnections.Add(new SystemTcpConnectionInformation(tcpRow));

                                    // Increment the pointer to the next row.
                                    newPtr = (IntPtr)((long)newPtr + Marshal.SizeOf(tcpRow));
                                }
                            }
                        }
                    }
                }

                // If we don't have any ipv4 interfaces detected, just continue.
                if (result != Interop.IpHlpApi.ERROR_SUCCESS && result != Interop.IpHlpApi.ERROR_NO_DATA)
                {
                    throw new NetworkInformationException((int)result);
                }
            }

            if (Socket.OSSupportsIPv6)
            {
                // Get the buffer size needed.
                size   = 0;
                result = Interop.IpHlpApi.GetExtendedTcpTable(SafeLocalAllocHandle.Zero, ref size, true,
                                                              (uint)AddressFamily.InterNetworkV6,
                                                              Interop.IpHlpApi.TcpTableClass.TcpTableOwnerPidAll, 0);

                while (result == Interop.IpHlpApi.ERROR_INSUFFICIENT_BUFFER)
                {
                    // Allocate the buffer and get the TCP table.
                    using (buffer = SafeLocalAllocHandle.LocalAlloc((int)size))
                    {
                        result = Interop.IpHlpApi.GetExtendedTcpTable(buffer, ref size, true,
                                                                      (uint)AddressFamily.InterNetworkV6,
                                                                      Interop.IpHlpApi.TcpTableClass.TcpTableOwnerPidAll, 0);
                        if (result == Interop.IpHlpApi.ERROR_SUCCESS)
                        {
                            // The table info just gives us the number of rows.
                            IntPtr newPtr = buffer.DangerousGetHandle();

                            Interop.IpHlpApi.MibTcp6TableOwnerPid tcpTable6OwnerPid = Marshal.PtrToStructure <Interop.IpHlpApi.MibTcp6TableOwnerPid>(newPtr);

                            if (tcpTable6OwnerPid.numberOfEntries > 0)
                            {
                                // Skip over the tableinfo to get the inline rows.
                                newPtr = (IntPtr)((long)newPtr + Marshal.SizeOf(tcpTable6OwnerPid.numberOfEntries));

                                for (int i = 0; i < tcpTable6OwnerPid.numberOfEntries; i++)
                                {
                                    Interop.IpHlpApi.MibTcp6RowOwnerPid tcp6RowOwnerPid = Marshal.PtrToStructure <Interop.IpHlpApi.MibTcp6RowOwnerPid>(newPtr);
                                    tcpConnections.Add(new SystemTcpConnectionInformation(tcp6RowOwnerPid));

                                    // We increment the pointer to the next row.
                                    newPtr = (IntPtr)((long)newPtr + Marshal.SizeOf(tcp6RowOwnerPid));
                                }
                            }
                        }
                    }
                }

                // If we don't have any ipv6 interfaces detected, just continue.
                if (result != Interop.IpHlpApi.ERROR_SUCCESS && result != Interop.IpHlpApi.ERROR_NO_DATA)
                {
                    throw new NetworkInformationException((int)result);
                }
            }

            return(tcpConnections);
        }