using System; using System.IO; using System.Collections; using System.Runtime.InteropServices; using System.Text; namespace Hyperic.Sigar { public class Sigar { internal const int OK = 0; internal const int SIGAR_START_ERROR = 20000; internal const int SIGAR_ENOTIMPL = (SIGAR_START_ERROR + 1); public const String NULL_HWADDR = "00:00:00:00:00:00"; public const int IFF_UP = 0x1; public const int IFF_BROADCAST = 0x2; public const int IFF_DEBUG = 0x4; public const int IFF_LOOPBACK = 0x8; public const int IFF_POINTOPOINT = 0x10; public const int IFF_NOTRAILERS = 0x20; public const int IFF_RUNNING = 0x40; public const int IFF_NOARP = 0x80; public const int IFF_PROMISC = 0x100; public const int IFF_ALLMULTI = 0x200; public const int IFF_MULTICAST = 0x800; internal const int FS_NAME_LEN = 64; internal const string LIBSIGAR = "sigar-x86-winnt.dll"; internal HandleRef sigar; [DllImport(LIBSIGAR)] private static extern IntPtr sigar_new(); [DllImport(LIBSIGAR)] private static extern int sigar_close(IntPtr sigar); public Sigar() { IntPtr handle = sigar_new(); this.sigar = new HandleRef(this, handle); } [DllImport(Sigar.LIBSIGAR)] private static extern string sigar_format_size(ulong size, StringBuilder buffer); public static string FormatSize(ulong size) { StringBuilder buffer = new StringBuilder(); buffer.Capacity = 56; return sigar_format_size(size, buffer); } public Mem Mem() { return Hyperic.Sigar.Mem.NativeGet(this); } public Swap Swap() { return Hyperic.Sigar.Swap.NativeGet(this); } public Cpu Cpu() { return Hyperic.Sigar.Cpu.NativeGet(this); } public CpuInfo[] CpuInfoList() { return Hyperic.Sigar.CpuInfoList.NativeGet(this); } public FileSystem[] FileSystemList() { return Hyperic.Sigar.FileSystemList.NativeGet(this); } public FileSystemUsage FileSystemUsage(string dirname) { return Hyperic.Sigar.FileSystemUsage.NativeGet(this, dirname); } public String[] NetInterfaceList() { return Hyperic.Sigar.NetInterfaceList.NativeGet(this); } public NetInterfaceConfig NetInterfaceConfig(string name) { return Hyperic.Sigar.NetInterfaceConfig.NativeGet(this, name); } public NetInterfaceStat NetInterfaceStat(string name) { return Hyperic.Sigar.NetInterfaceStat.NativeGet(this, name); } ~Sigar() { sigar_close(this.sigar.Handle); } internal static IntPtr incrementIntPtr(IntPtr ptr, int size) { Int32 x = (Int32)ptr; x += size; return (IntPtr)x; } internal static SigarException FindException(Sigar sigar, int errno) { switch (errno) { case SIGAR_ENOTIMPL: return new SigarNotImplementedException(sigar, errno); default: return new SigarException(sigar, errno); } } } public class SigarException : Exception { Sigar sigar; int errno; public SigarException(Sigar sigar, int errno) : base() { this.sigar = sigar; this.errno = errno; } [DllImport(Sigar.LIBSIGAR)] private static extern string sigar_strerror(IntPtr sigar, int errno); public override string Message { get { return sigar_strerror(this.sigar.sigar.Handle, this.errno); } } } public class SigarNotImplementedException : SigarException { public SigarNotImplementedException(Sigar sigar, int errno) : base(sigar, errno) { } } [StructLayout(LayoutKind.Sequential)] public struct Mem { public readonly ulong Ram; public readonly ulong Total; public readonly ulong Used; public readonly ulong Free; public readonly ulong Shared; private readonly ulong NA_buffer; private readonly ulong NA_cached; [DllImport(Sigar.LIBSIGAR)] private static extern int sigar_mem_get(IntPtr sigar, IntPtr mem); internal static Mem NativeGet(Sigar sigar) { Type type = typeof(Mem); //sigar_mem_t *ptr = malloc(sizeof(*ptr)) IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(type)); int status = sigar_mem_get(sigar.sigar.Handle, ptr); if (status != Sigar.OK) { Marshal.FreeHGlobal(ptr); throw Sigar.FindException(sigar, status); } //memcpy(ptr, this, sizeof(this)) Mem mem = (Mem)Marshal.PtrToStructure(ptr, type); Marshal.FreeHGlobal(ptr); return mem; } } [StructLayout(LayoutKind.Sequential)] public struct Swap { public readonly ulong Total; public readonly ulong Used; public readonly ulong Free; [DllImport(Sigar.LIBSIGAR)] private static extern int sigar_swap_get(IntPtr sigar, IntPtr swap); internal static Swap NativeGet(Sigar sigar) { Type type = typeof(Swap); IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(type)); int status = sigar_swap_get(sigar.sigar.Handle, ptr); if (status != Sigar.OK) { Marshal.FreeHGlobal(ptr); throw Sigar.FindException(sigar, status); } Swap swap = (Swap)Marshal.PtrToStructure(ptr, type); Marshal.FreeHGlobal(ptr); return swap; } } [StructLayout(LayoutKind.Sequential)] public struct Cpu { public readonly ulong User; public readonly ulong Sys; private readonly ulong NA_Nice; public readonly ulong Idle; public readonly ulong Total; [DllImport(Sigar.LIBSIGAR)] private static extern int sigar_cpu_get(IntPtr sigar, IntPtr cpu); internal static Cpu NativeGet(Sigar sigar) { Type type = typeof(Cpu); IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(type)); int status = sigar_cpu_get(sigar.sigar.Handle, ptr); if (status != Sigar.OK) { Marshal.FreeHGlobal(ptr); throw Sigar.FindException(sigar, status); } Cpu cpu = (Cpu)Marshal.PtrToStructure(ptr, type); Marshal.FreeHGlobal(ptr); return cpu; } } [StructLayout(LayoutKind.Sequential)] public struct CpuInfo { [MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)] public readonly string Vendor; //char[128] [MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)] public readonly string Model; //char[128] public readonly int Mhz; private readonly ulong CacheSize; //XXX not implemented } [StructLayout(LayoutKind.Sequential)] internal struct CpuInfoList { private readonly uint Number; //sizeof(unsigned long) == 4 private readonly uint size; private readonly IntPtr data; [DllImport(Sigar.LIBSIGAR)] private static extern int sigar_cpu_info_list_get(IntPtr sigar, IntPtr cpu_infos); [DllImport(Sigar.LIBSIGAR)] private static extern int sigar_cpu_info_list_destroy(IntPtr sigar, IntPtr cpu_infos); internal static CpuInfo[] NativeGet(Sigar sigar) { Type type = typeof(CpuInfoList); IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(type)); int status = sigar_cpu_info_list_get(sigar.sigar.Handle, ptr); if (status != Sigar.OK) { Marshal.FreeHGlobal(ptr); throw Sigar.FindException(sigar, status); } CpuInfoList infosPtr = (CpuInfoList)Marshal.PtrToStructure(ptr, type); CpuInfo[] infos = new CpuInfo[infosPtr.Number]; IntPtr eptr = infosPtr.data; int size = Marshal.SizeOf(infos[0]); for (int i=0; i 0) retval += "UP "; if ((flags & Sigar.IFF_BROADCAST) > 0) retval += "BROADCAST "; if ((flags & Sigar.IFF_DEBUG) > 0) retval += "DEBUG "; if ((flags & Sigar.IFF_LOOPBACK) > 0) retval += "LOOPBACK "; if ((flags & Sigar.IFF_POINTOPOINT) > 0) retval += "POINTOPOINT "; if ((flags & Sigar.IFF_NOTRAILERS) > 0) retval += "NOTRAILERS "; if ((flags & Sigar.IFF_RUNNING) > 0) retval += "RUNNING "; if ((flags & Sigar.IFF_NOARP) > 0) retval += "NOARP "; if ((flags & Sigar.IFF_PROMISC) > 0) retval += "PROMISC "; if ((flags & Sigar.IFF_ALLMULTI) > 0) retval += "ALLMULTI "; if ((flags & Sigar.IFF_MULTICAST) > 0) retval += "MULTICAST "; return retval; } } [StructLayout(LayoutKind.Sequential)] public struct NetInterfaceStat { public readonly ulong RxPackets; public readonly ulong RxBytes; public readonly ulong RxErrors; public readonly ulong RxDropped; public readonly ulong RxOverruns; public readonly ulong RxFrame; public readonly ulong TxPackets; public readonly ulong TxBytes; public readonly ulong TxErrors; public readonly ulong TxDropped; public readonly ulong TxOverruns; public readonly ulong TxCollisions; public readonly ulong TxCarrier; [DllImport(Sigar.LIBSIGAR)] private static extern int sigar_net_interface_stat_get(IntPtr sigar, string name, IntPtr ifstat); internal static NetInterfaceStat NativeGet(Sigar sigar, string name) { Type type = typeof(NetInterfaceStat); IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(type)); int status = sigar_net_interface_stat_get(sigar.sigar.Handle, name, ptr); if (status != Sigar.OK) { Marshal.FreeHGlobal(ptr); throw Sigar.FindException(sigar, status); } NetInterfaceStat ifstat = (NetInterfaceStat)Marshal.PtrToStructure(ptr, type); Marshal.FreeHGlobal(ptr); return ifstat; } } }