/* * Copyright (C) [2004, 2005, 2006], Hyperic, Inc. * This file is part of SIGAR. * * SIGAR is free software; you can redistribute it and/or modify * it under the terms version 2 of the GNU General Public License as * published by the Free Software Foundation. This program is distributed * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. */ 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; //cp sigar-x86-winnt.dll sigar.dll //ln -s libsigar-x86-linux.so libsigar.so //XXX can we determine the real name at runtime? internal const string LIBSIGAR = "sigar"; internal HandleRef sigar; [DllImport(LIBSIGAR)] private static extern int sigar_open(ref IntPtr sigar); [DllImport(LIBSIGAR)] private static extern int sigar_close(IntPtr sigar); public Sigar() { IntPtr handle = IntPtr.Zero; sigar_open(ref handle); this.sigar = new HandleRef(this, handle); } [DllImport(Sigar.LIBSIGAR)] private static extern void sigar_format_size(long size, StringBuilder buffer); public static string FormatSize(long size) { StringBuilder buffer = new StringBuilder(56); sigar_format_size(size, buffer); return buffer.ToString(); } 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 long Ram; public readonly long Total; public readonly long Used; public readonly long Free; public readonly long Shared; public readonly long ActualFree; public readonly long ActualUsed; [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 long Total; public readonly long Used; public readonly long 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 long User; public readonly long Sys; private readonly long NA_Nice; public readonly long Idle; private readonly long NA_Wait; public readonly long 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 long 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 long RxPackets; public readonly long RxBytes; public readonly long RxErrors; public readonly long RxDropped; public readonly long RxOverruns; public readonly long RxFrame; public readonly long TxPackets; public readonly long TxBytes; public readonly long TxErrors; public readonly long TxDropped; public readonly long TxOverruns; public readonly long TxCollisions; public readonly long 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; } } }