using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.NetworkInformation; using System.Runtime.InteropServices; namespace AlmToolkit { #region Managed IP Helper API public class TcpTable : IEnumerable { #region Private Fields private IEnumerable tcpRows; #endregion #region Constructors public TcpTable(IEnumerable tcpRows) { this.tcpRows = tcpRows; } #endregion #region Public Properties public IEnumerable Rows { get { return this.tcpRows; } } #endregion #region IEnumerable Members public IEnumerator GetEnumerator() { return this.tcpRows.GetEnumerator(); } #endregion #region IEnumerable Members IEnumerator IEnumerable.GetEnumerator() { return this.tcpRows.GetEnumerator(); } #endregion } public class TcpRow { #region Private Fields private IPEndPoint localEndPoint; private IPEndPoint remoteEndPoint; private TcpState state; private int processId; #endregion #region Constructors public TcpRow(IpHelper.TcpRow tcpRow) { this.state = tcpRow.state; this.processId = tcpRow.owningPid; int localPort = (tcpRow.localPort1 << 8) + (tcpRow.localPort2) + (tcpRow.localPort3 << 24) + (tcpRow.localPort4 << 16); long localAddress = tcpRow.localAddr; this.localEndPoint = new IPEndPoint(localAddress, localPort); int remotePort = (tcpRow.remotePort1 << 8) + (tcpRow.remotePort2) + (tcpRow.remotePort3 << 24) + (tcpRow.remotePort4 << 16); long remoteAddress = tcpRow.remoteAddr; this.remoteEndPoint = new IPEndPoint(remoteAddress, remotePort); } #endregion #region Public Properties public IPEndPoint LocalEndPoint { get { return this.localEndPoint; } } public IPEndPoint RemoteEndPoint { get { return this.remoteEndPoint; } } public TcpState State { get { return this.state; } } public int ProcessId { get { return this.processId; } } #endregion } public static class ManagedIpHelper { #region Public Methods public static TcpTable GetExtendedTcpTable(bool sorted) { List tcpRows = new List(); IntPtr tcpTable = IntPtr.Zero; int tcpTableLength = 0; if (IpHelper.GetExtendedTcpTable(tcpTable, ref tcpTableLength, sorted, IpHelper.AfInet, IpHelper.TcpTableType.OwnerPidAll, 0) != 0) { try { tcpTable = Marshal.AllocHGlobal(tcpTableLength); if (IpHelper.GetExtendedTcpTable(tcpTable, ref tcpTableLength, true, IpHelper.AfInet, IpHelper.TcpTableType.OwnerPidAll, 0) == 0) { IpHelper.TcpTable table = (IpHelper.TcpTable)Marshal.PtrToStructure(tcpTable, typeof(IpHelper.TcpTable)); IntPtr rowPtr = (IntPtr)((long)tcpTable + Marshal.SizeOf(table.length)); for (int i = 0; i < table.length; ++i) { tcpRows.Add(new TcpRow((IpHelper.TcpRow)Marshal.PtrToStructure(rowPtr, typeof(IpHelper.TcpRow)))); rowPtr = (IntPtr)((long)rowPtr + Marshal.SizeOf(typeof(IpHelper.TcpRow))); } } } finally { if (tcpTable != IntPtr.Zero) { Marshal.FreeHGlobal(tcpTable); } } } return new TcpTable(tcpRows); } public static Dictionary GetExtendedTcpDictionary() { Dictionary tcpRows = new Dictionary(); IntPtr tcpTable = IntPtr.Zero; int tcpTableLength = 0; if (IpHelper.GetExtendedTcpTable(tcpTable, ref tcpTableLength, false, IpHelper.AfInet, IpHelper.TcpTableType.OwnerPidAll, 0) != 0) { try { tcpTable = Marshal.AllocHGlobal(tcpTableLength); if (IpHelper.GetExtendedTcpTable(tcpTable, ref tcpTableLength, true, IpHelper.AfInet, IpHelper.TcpTableType.OwnerPidAll, 0) == 0) { IpHelper.TcpTable table = (IpHelper.TcpTable)Marshal.PtrToStructure(tcpTable, typeof(IpHelper.TcpTable)); IntPtr rowPtr = (IntPtr)((long)tcpTable + Marshal.SizeOf(table.length)); for (int i = 0; i < table.length; ++i) { TcpRow row = new TcpRow((IpHelper.TcpRow)Marshal.PtrToStructure(rowPtr, typeof(IpHelper.TcpRow))); // HACK: only add first row that is in a Listening state if (row.State == TcpState.Listen) { if (!tcpRows.Keys.Contains(row.ProcessId)) tcpRows.Add(row.ProcessId, row); } rowPtr = (IntPtr)((long)rowPtr + Marshal.SizeOf(typeof(IpHelper.TcpRow))); } } } finally { if (tcpTable != IntPtr.Zero) { Marshal.FreeHGlobal(tcpTable); } } } return tcpRows; } #endregion } #endregion #region P/Invoke IP Helper API /// /// /// public static class IpHelper { #region Public Fields public const string DllName = "iphlpapi.dll"; public const int AfInet = 2; #endregion #region Public Methods /// /// /// [DllImport(IpHelper.DllName, SetLastError = true)] public static extern uint GetExtendedTcpTable(IntPtr tcpTable, ref int tcpTableLength, bool sort, int ipVersion, TcpTableType tcpTableType, int reserved); #endregion #region Public Enums /// /// /// public enum TcpTableType { BasicListener, BasicConnections, BasicAll, OwnerPidListener, OwnerPidConnections, OwnerPidAll, OwnerModuleListener, OwnerModuleConnections, OwnerModuleAll, } #endregion #region Public Structs /// /// /// [StructLayout(LayoutKind.Sequential)] public struct TcpTable { public uint length; public TcpRow row; } /// /// /// [StructLayout(LayoutKind.Sequential)] public struct TcpRow { public TcpState state; public uint localAddr; public byte localPort1; public byte localPort2; public byte localPort3; public byte localPort4; public uint remoteAddr; public byte remotePort1; public byte remotePort2; public byte remotePort3; public byte remotePort4; public int owningPid; } #endregion #endregion } }