2006-07-16 01:46:36 +08:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2004-06-22 06:37:04 +08:00
|
|
|
using System;
|
|
|
|
using System.IO;
|
|
|
|
using System.Collections;
|
|
|
|
using System.Runtime.InteropServices;
|
2004-09-18 05:05:59 +08:00
|
|
|
using System.Text;
|
2004-06-22 06:37:04 +08:00
|
|
|
|
|
|
|
namespace Hyperic.Sigar {
|
|
|
|
public class Sigar {
|
2004-09-18 07:58:22 +08:00
|
|
|
internal const int OK = 0;
|
|
|
|
internal const int SIGAR_START_ERROR = 20000;
|
|
|
|
internal const int SIGAR_ENOTIMPL = (SIGAR_START_ERROR + 1);
|
2004-06-22 06:37:04 +08:00
|
|
|
|
2004-09-18 06:20:02 +08:00
|
|
|
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;
|
|
|
|
|
2004-06-22 06:37:04 +08:00
|
|
|
internal const int FS_NAME_LEN = 64;
|
|
|
|
|
2004-09-21 06:44:05 +08:00
|
|
|
//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";
|
2004-06-22 06:37:04 +08:00
|
|
|
|
|
|
|
internal HandleRef sigar;
|
|
|
|
|
|
|
|
[DllImport(LIBSIGAR)]
|
2004-09-23 01:48:21 +08:00
|
|
|
private static extern int sigar_open(ref IntPtr sigar);
|
2004-06-22 06:37:04 +08:00
|
|
|
|
|
|
|
[DllImport(LIBSIGAR)]
|
|
|
|
private static extern int sigar_close(IntPtr sigar);
|
|
|
|
|
|
|
|
public Sigar() {
|
2004-09-23 01:48:21 +08:00
|
|
|
IntPtr handle = IntPtr.Zero;
|
|
|
|
sigar_open(ref handle);
|
2004-06-22 06:37:04 +08:00
|
|
|
this.sigar = new HandleRef(this, handle);
|
|
|
|
}
|
|
|
|
|
2004-09-18 06:40:47 +08:00
|
|
|
[DllImport(Sigar.LIBSIGAR)]
|
2004-09-23 00:51:49 +08:00
|
|
|
private static extern void
|
2005-12-07 01:08:14 +08:00
|
|
|
sigar_format_size(long size, StringBuilder buffer);
|
2004-09-18 06:40:47 +08:00
|
|
|
|
2005-12-07 01:08:14 +08:00
|
|
|
public static string FormatSize(long size) {
|
2004-09-23 00:51:49 +08:00
|
|
|
StringBuilder buffer = new StringBuilder(56);
|
|
|
|
sigar_format_size(size, buffer);
|
|
|
|
return buffer.ToString();
|
2004-09-18 06:40:47 +08:00
|
|
|
}
|
|
|
|
|
2004-06-22 06:37:04 +08:00
|
|
|
public Mem Mem() {
|
|
|
|
return Hyperic.Sigar.Mem.NativeGet(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Swap Swap() {
|
|
|
|
return Hyperic.Sigar.Swap.NativeGet(this);
|
|
|
|
}
|
|
|
|
|
2004-07-25 10:19:03 +08:00
|
|
|
public Cpu Cpu() {
|
|
|
|
return Hyperic.Sigar.Cpu.NativeGet(this);
|
|
|
|
}
|
|
|
|
|
2004-07-10 12:44:45 +08:00
|
|
|
public CpuInfo[] CpuInfoList() {
|
|
|
|
return Hyperic.Sigar.CpuInfoList.NativeGet(this);
|
2004-06-22 06:37:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public FileSystem[] FileSystemList() {
|
|
|
|
return Hyperic.Sigar.FileSystemList.NativeGet(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
public FileSystemUsage FileSystemUsage(string dirname) {
|
|
|
|
return Hyperic.Sigar.FileSystemUsage.NativeGet(this, dirname);
|
|
|
|
}
|
|
|
|
|
2004-09-18 02:00:16 +08:00
|
|
|
public String[] NetInterfaceList() {
|
|
|
|
return Hyperic.Sigar.NetInterfaceList.NativeGet(this);
|
|
|
|
}
|
|
|
|
|
2004-09-18 04:46:30 +08:00
|
|
|
public NetInterfaceConfig NetInterfaceConfig(string name) {
|
|
|
|
return Hyperic.Sigar.NetInterfaceConfig.NativeGet(this, name);
|
|
|
|
}
|
|
|
|
|
2004-09-18 06:16:14 +08:00
|
|
|
public NetInterfaceStat NetInterfaceStat(string name) {
|
|
|
|
return Hyperic.Sigar.NetInterfaceStat.NativeGet(this, name);
|
|
|
|
}
|
|
|
|
|
2004-06-22 06:37:04 +08:00
|
|
|
~Sigar() {
|
|
|
|
sigar_close(this.sigar.Handle);
|
|
|
|
}
|
|
|
|
|
|
|
|
internal static IntPtr incrementIntPtr(IntPtr ptr, int size) {
|
|
|
|
Int32 x = (Int32)ptr;
|
|
|
|
x += size;
|
|
|
|
return (IntPtr)x;
|
|
|
|
}
|
2004-09-18 07:58:22 +08:00
|
|
|
|
|
|
|
internal static SigarException FindException(Sigar sigar, int errno) {
|
|
|
|
switch (errno) {
|
|
|
|
case SIGAR_ENOTIMPL:
|
|
|
|
return new SigarNotImplementedException(sigar, errno);
|
|
|
|
default:
|
|
|
|
return new SigarException(sigar, errno);
|
|
|
|
}
|
|
|
|
}
|
2004-06-22 06:37:04 +08:00
|
|
|
}
|
|
|
|
|
2004-09-18 07:33:57 +08:00
|
|
|
public class SigarException : Exception {
|
|
|
|
Sigar sigar;
|
|
|
|
int errno;
|
|
|
|
|
2004-09-18 07:58:22 +08:00
|
|
|
public SigarException(Sigar sigar, int errno) : base() {
|
2004-09-18 07:33:57 +08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-09-18 07:58:22 +08:00
|
|
|
public class SigarNotImplementedException : SigarException {
|
|
|
|
public SigarNotImplementedException(Sigar sigar, int errno) :
|
|
|
|
base(sigar, errno) { }
|
|
|
|
}
|
|
|
|
|
2004-06-22 06:37:04 +08:00
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
|
|
public struct Mem {
|
2005-12-07 01:08:14 +08:00
|
|
|
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;
|
2004-06-22 06:37:04 +08:00
|
|
|
|
|
|
|
[DllImport(Sigar.LIBSIGAR)]
|
2004-09-18 07:03:17 +08:00
|
|
|
private static extern int
|
|
|
|
sigar_mem_get(IntPtr sigar, IntPtr mem);
|
2004-06-22 06:37:04 +08:00
|
|
|
|
|
|
|
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);
|
2004-09-18 07:58:22 +08:00
|
|
|
throw Sigar.FindException(sigar, status);
|
2004-06-22 06:37:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//memcpy(ptr, this, sizeof(this))
|
|
|
|
Mem mem = (Mem)Marshal.PtrToStructure(ptr, type);
|
|
|
|
Marshal.FreeHGlobal(ptr);
|
|
|
|
return mem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
|
|
public struct Swap {
|
2005-12-07 01:08:14 +08:00
|
|
|
public readonly long Total;
|
|
|
|
public readonly long Used;
|
|
|
|
public readonly long Free;
|
2004-06-22 06:37:04 +08:00
|
|
|
|
|
|
|
[DllImport(Sigar.LIBSIGAR)]
|
2004-09-18 07:03:17 +08:00
|
|
|
private static extern int
|
|
|
|
sigar_swap_get(IntPtr sigar, IntPtr swap);
|
2004-06-22 06:37:04 +08:00
|
|
|
|
|
|
|
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);
|
2004-09-18 07:58:22 +08:00
|
|
|
throw Sigar.FindException(sigar, status);
|
2004-06-22 06:37:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Swap swap = (Swap)Marshal.PtrToStructure(ptr, type);
|
|
|
|
Marshal.FreeHGlobal(ptr);
|
|
|
|
|
|
|
|
return swap;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-07-25 10:19:03 +08:00
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
|
|
public struct Cpu {
|
2005-12-07 01:08:14 +08:00
|
|
|
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;
|
2004-07-25 10:19:03 +08:00
|
|
|
|
|
|
|
[DllImport(Sigar.LIBSIGAR)]
|
2004-09-18 07:03:17 +08:00
|
|
|
private static extern int
|
|
|
|
sigar_cpu_get(IntPtr sigar, IntPtr cpu);
|
2004-07-25 10:19:03 +08:00
|
|
|
|
|
|
|
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);
|
2004-09-18 07:58:22 +08:00
|
|
|
throw Sigar.FindException(sigar, status);
|
2004-07-25 10:19:03 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Cpu cpu = (Cpu)Marshal.PtrToStructure(ptr, type);
|
|
|
|
Marshal.FreeHGlobal(ptr);
|
|
|
|
|
|
|
|
return cpu;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-06-22 06:37:04 +08:00
|
|
|
[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;
|
2005-12-07 01:08:14 +08:00
|
|
|
private readonly long CacheSize; //XXX not implemented
|
2004-06-22 06:37:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
2004-07-10 12:44:45 +08:00
|
|
|
internal struct CpuInfoList {
|
2004-06-22 06:37:04 +08:00
|
|
|
private readonly uint Number; //sizeof(unsigned long) == 4
|
|
|
|
private readonly uint size;
|
|
|
|
private readonly IntPtr data;
|
|
|
|
|
|
|
|
[DllImport(Sigar.LIBSIGAR)]
|
2004-09-18 07:03:17 +08:00
|
|
|
private static extern int
|
|
|
|
sigar_cpu_info_list_get(IntPtr sigar, IntPtr cpu_infos);
|
2004-06-22 06:37:04 +08:00
|
|
|
|
|
|
|
[DllImport(Sigar.LIBSIGAR)]
|
2004-09-18 07:03:17 +08:00
|
|
|
private static extern int
|
|
|
|
sigar_cpu_info_list_destroy(IntPtr sigar, IntPtr cpu_infos);
|
2004-06-22 06:37:04 +08:00
|
|
|
|
|
|
|
internal static CpuInfo[] NativeGet(Sigar sigar) {
|
2004-07-10 12:44:45 +08:00
|
|
|
Type type = typeof(CpuInfoList);
|
2004-06-22 06:37:04 +08:00
|
|
|
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(type));
|
|
|
|
|
2004-07-10 12:44:45 +08:00
|
|
|
int status = sigar_cpu_info_list_get(sigar.sigar.Handle, ptr);
|
2004-06-22 06:37:04 +08:00
|
|
|
|
|
|
|
if (status != Sigar.OK) {
|
|
|
|
Marshal.FreeHGlobal(ptr);
|
2004-09-18 07:58:22 +08:00
|
|
|
throw Sigar.FindException(sigar, status);
|
2004-06-22 06:37:04 +08:00
|
|
|
}
|
|
|
|
|
2004-07-10 12:44:45 +08:00
|
|
|
CpuInfoList infosPtr =
|
|
|
|
(CpuInfoList)Marshal.PtrToStructure(ptr, type);
|
2004-06-22 06:37:04 +08:00
|
|
|
|
|
|
|
CpuInfo[] infos = new CpuInfo[infosPtr.Number];
|
|
|
|
|
|
|
|
IntPtr eptr = infosPtr.data;
|
|
|
|
int size = Marshal.SizeOf(infos[0]);
|
|
|
|
|
|
|
|
for (int i=0; i<infosPtr.Number; i++) {
|
2004-09-18 07:03:17 +08:00
|
|
|
infos[i] =
|
|
|
|
(CpuInfo)Marshal.PtrToStructure(eptr, typeof(CpuInfo));
|
2004-06-22 06:37:04 +08:00
|
|
|
|
|
|
|
//eptr += sizeof(sigar_cpu_info_t);
|
|
|
|
eptr = Sigar.incrementIntPtr(eptr, size);
|
|
|
|
}
|
|
|
|
|
2004-07-10 12:44:45 +08:00
|
|
|
sigar_cpu_info_list_destroy(sigar.sigar.Handle, ptr);
|
2004-06-22 06:37:04 +08:00
|
|
|
|
|
|
|
Marshal.FreeHGlobal(ptr);
|
|
|
|
|
|
|
|
return infos;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
|
|
public struct FileSystem {
|
|
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=Sigar.FS_NAME_LEN)]
|
|
|
|
public readonly string DirName;
|
|
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=Sigar.FS_NAME_LEN)]
|
|
|
|
public readonly string DevName;
|
|
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=Sigar.FS_NAME_LEN)]
|
|
|
|
public readonly string TypeName;
|
|
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=Sigar.FS_NAME_LEN)]
|
|
|
|
public readonly string SysTypeName;
|
|
|
|
public readonly int Type;
|
|
|
|
public readonly uint Flags;
|
|
|
|
}
|
|
|
|
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
|
|
internal struct FileSystemList {
|
|
|
|
private readonly uint Number;
|
|
|
|
private readonly uint size;
|
|
|
|
private readonly IntPtr data;
|
|
|
|
|
|
|
|
[DllImport(Sigar.LIBSIGAR)]
|
2004-09-18 07:03:17 +08:00
|
|
|
private static extern int
|
|
|
|
sigar_file_system_list_get(IntPtr sigar, IntPtr fslist);
|
2004-06-22 06:37:04 +08:00
|
|
|
|
|
|
|
[DllImport(Sigar.LIBSIGAR)]
|
2004-09-18 07:03:17 +08:00
|
|
|
private static extern int
|
|
|
|
sigar_file_system_list_destroy(IntPtr sigar, IntPtr fslist);
|
2004-06-22 06:37:04 +08:00
|
|
|
|
|
|
|
internal static FileSystem[] NativeGet(Sigar sigar) {
|
|
|
|
Type type = typeof(FileSystemList);
|
|
|
|
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(type));
|
|
|
|
|
|
|
|
int status = sigar_file_system_list_get(sigar.sigar.Handle, ptr);
|
|
|
|
|
|
|
|
if (status != Sigar.OK) {
|
|
|
|
Marshal.FreeHGlobal(ptr);
|
2004-09-18 07:58:22 +08:00
|
|
|
throw Sigar.FindException(sigar, status);
|
2004-06-22 06:37:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
FileSystemList fsPtr =
|
|
|
|
(FileSystemList)Marshal.PtrToStructure(ptr, type);
|
|
|
|
|
|
|
|
FileSystem[] fs = new FileSystem[fsPtr.Number];
|
|
|
|
|
|
|
|
IntPtr fptr = fsPtr.data;
|
|
|
|
int size = Marshal.SizeOf(fs[0]);
|
|
|
|
|
|
|
|
for (int i=0; i<fsPtr.Number; i++) {
|
2004-09-18 07:03:17 +08:00
|
|
|
fs[i] =
|
|
|
|
(FileSystem)Marshal.PtrToStructure(fptr,
|
|
|
|
typeof(FileSystem));
|
2004-06-22 06:37:04 +08:00
|
|
|
|
|
|
|
//fptr += sizeof(sigar_fs_t);
|
|
|
|
fptr = Sigar.incrementIntPtr(fptr, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
sigar_file_system_list_destroy(sigar.sigar.Handle, ptr);
|
|
|
|
|
|
|
|
Marshal.FreeHGlobal(ptr);
|
|
|
|
|
|
|
|
return fs;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
|
|
public struct FileSystemUsage {
|
2005-12-07 01:08:14 +08:00
|
|
|
public readonly long Total;
|
|
|
|
public readonly long Free;
|
|
|
|
public readonly long Avail;
|
|
|
|
public readonly long Used;
|
|
|
|
private readonly long NA_Files; //XXX not implemented
|
|
|
|
private readonly long NA_FreeFiles;
|
|
|
|
private readonly long DiskReads;
|
|
|
|
private readonly long DiskWrites;
|
|
|
|
private readonly long DiskWriteBytes;
|
|
|
|
private readonly long DiskReadBytes;
|
|
|
|
private readonly long DiskQueue;
|
2004-06-22 06:37:04 +08:00
|
|
|
public readonly double UsePercent;
|
|
|
|
|
|
|
|
[DllImport(Sigar.LIBSIGAR)]
|
2004-09-18 07:03:17 +08:00
|
|
|
private static extern int
|
|
|
|
sigar_file_system_usage_get(IntPtr sigar, string dirname,
|
|
|
|
IntPtr fsusage);
|
2004-06-22 06:37:04 +08:00
|
|
|
|
2004-09-18 07:03:17 +08:00
|
|
|
internal static FileSystemUsage NativeGet(Sigar sigar,
|
|
|
|
string dirname) {
|
2004-06-22 06:37:04 +08:00
|
|
|
Type type = typeof(FileSystemUsage);
|
|
|
|
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(type));
|
|
|
|
|
|
|
|
int status = sigar_file_system_usage_get(sigar.sigar.Handle,
|
|
|
|
dirname, ptr);
|
|
|
|
|
|
|
|
if (status != Sigar.OK) {
|
|
|
|
Marshal.FreeHGlobal(ptr);
|
2004-09-18 07:58:22 +08:00
|
|
|
throw Sigar.FindException(sigar, status);
|
2004-06-22 06:37:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
FileSystemUsage fsusage =
|
|
|
|
(FileSystemUsage)Marshal.PtrToStructure(ptr, type);
|
|
|
|
|
|
|
|
Marshal.FreeHGlobal(ptr);
|
|
|
|
|
|
|
|
return fsusage;
|
|
|
|
}
|
|
|
|
}
|
2004-09-18 02:00:16 +08:00
|
|
|
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
|
|
internal struct NetInterfaceList {
|
|
|
|
private readonly uint number;
|
|
|
|
private readonly uint size;
|
|
|
|
private readonly IntPtr data;
|
|
|
|
|
|
|
|
[DllImport(Sigar.LIBSIGAR)]
|
2004-09-18 07:03:17 +08:00
|
|
|
private static extern int
|
|
|
|
sigar_net_interface_list_get(IntPtr sigar, IntPtr iflist);
|
2004-09-18 02:00:16 +08:00
|
|
|
|
|
|
|
[DllImport(Sigar.LIBSIGAR)]
|
2004-09-18 07:03:17 +08:00
|
|
|
private static extern int
|
|
|
|
sigar_net_interface_list_destroy(IntPtr sigar, IntPtr iflist);
|
2004-09-18 02:00:16 +08:00
|
|
|
|
|
|
|
internal static String[] NativeGet(Sigar sigar) {
|
|
|
|
Type type = typeof(NetInterfaceList);
|
|
|
|
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(type));
|
|
|
|
|
2004-09-18 07:03:17 +08:00
|
|
|
int status =
|
|
|
|
sigar_net_interface_list_get(sigar.sigar.Handle, ptr);
|
2004-09-18 02:00:16 +08:00
|
|
|
|
|
|
|
if (status != Sigar.OK) {
|
|
|
|
Marshal.FreeHGlobal(ptr);
|
2004-09-18 07:58:22 +08:00
|
|
|
throw Sigar.FindException(sigar, status);
|
2004-09-18 02:00:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
NetInterfaceList ifPtr =
|
|
|
|
(NetInterfaceList)Marshal.PtrToStructure(ptr, type);
|
|
|
|
|
|
|
|
String[] iflist = new String[ifPtr.number];
|
|
|
|
|
|
|
|
IntPtr iptr = ifPtr.data;
|
|
|
|
|
|
|
|
for (int i=0; i<ifPtr.number; i++) {
|
|
|
|
IntPtr str = Marshal.ReadIntPtr(iptr, i * IntPtr.Size);
|
|
|
|
iflist[i] = Marshal.PtrToStringAnsi(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
sigar_net_interface_list_destroy(sigar.sigar.Handle, ptr);
|
|
|
|
|
|
|
|
Marshal.FreeHGlobal(ptr);
|
|
|
|
|
|
|
|
return iflist;
|
|
|
|
}
|
|
|
|
}
|
2004-09-18 04:46:30 +08:00
|
|
|
|
2006-07-06 00:55:36 +08:00
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
|
|
internal struct NetAddress {
|
|
|
|
internal readonly uint family;
|
|
|
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst=4)]
|
|
|
|
internal readonly uint[] addr;
|
|
|
|
}
|
|
|
|
|
2004-09-18 04:46:30 +08:00
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
|
|
public struct NetInterfaceConfig {
|
|
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=16)]
|
|
|
|
public readonly string Name; //char[16]
|
|
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=64)]
|
2005-12-07 01:01:54 +08:00
|
|
|
public readonly string Type; //char[64]
|
2006-07-06 00:55:36 +08:00
|
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)]
|
|
|
|
public readonly string Description; //char[256]
|
2006-07-06 05:42:28 +08:00
|
|
|
private readonly NetAddress hwaddr;
|
2006-07-06 00:55:36 +08:00
|
|
|
private readonly NetAddress address;
|
|
|
|
private readonly NetAddress destination;
|
|
|
|
private readonly NetAddress broadcast;
|
|
|
|
private readonly NetAddress netmask;
|
2005-12-07 01:08:14 +08:00
|
|
|
public readonly long Flags;
|
|
|
|
public readonly long Mtu;
|
|
|
|
public readonly long Metric;
|
2004-09-18 04:46:30 +08:00
|
|
|
|
|
|
|
[DllImport(Sigar.LIBSIGAR)]
|
|
|
|
private static extern int
|
|
|
|
sigar_net_interface_config_get(IntPtr sigar, string name,
|
|
|
|
IntPtr ifconfig);
|
|
|
|
|
|
|
|
internal static NetInterfaceConfig NativeGet(Sigar sigar,
|
|
|
|
string name) {
|
|
|
|
Type type = typeof(NetInterfaceConfig);
|
|
|
|
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(type));
|
|
|
|
|
|
|
|
int status = sigar_net_interface_config_get(sigar.sigar.Handle,
|
|
|
|
name, ptr);
|
|
|
|
|
|
|
|
if (status != Sigar.OK) {
|
|
|
|
Marshal.FreeHGlobal(ptr);
|
2004-09-18 07:58:22 +08:00
|
|
|
throw Sigar.FindException(sigar, status);
|
2004-09-18 04:46:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
NetInterfaceConfig ifconfig =
|
|
|
|
(NetInterfaceConfig)Marshal.PtrToStructure(ptr, type);
|
|
|
|
|
|
|
|
Marshal.FreeHGlobal(ptr);
|
|
|
|
|
|
|
|
return ifconfig;
|
|
|
|
}
|
2004-09-18 05:05:59 +08:00
|
|
|
|
|
|
|
[DllImport(Sigar.LIBSIGAR)]
|
|
|
|
private static extern int
|
2006-07-06 00:55:36 +08:00
|
|
|
sigar_net_address_to_string(IntPtr sigar,
|
|
|
|
IntPtr address,
|
|
|
|
StringBuilder addr_str);
|
2004-09-18 05:05:59 +08:00
|
|
|
|
2006-07-06 00:55:36 +08:00
|
|
|
private string inet_ntoa(NetAddress address) {
|
|
|
|
//XXX seems a little stilly, we can't use &address
|
|
|
|
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(address));
|
2004-09-18 05:05:59 +08:00
|
|
|
StringBuilder buffer = new StringBuilder();
|
2006-07-06 00:55:36 +08:00
|
|
|
buffer.Capacity = 46;
|
|
|
|
Marshal.StructureToPtr(address, ptr, true);
|
|
|
|
sigar_net_address_to_string(IntPtr.Zero, ptr, buffer);
|
2004-09-18 05:05:59 +08:00
|
|
|
return buffer.ToString();
|
|
|
|
}
|
|
|
|
|
2006-07-06 05:42:28 +08:00
|
|
|
public string Hwaddr {
|
|
|
|
get {
|
|
|
|
return inet_ntoa(this.hwaddr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-09-18 05:05:59 +08:00
|
|
|
public string Address {
|
|
|
|
get {
|
|
|
|
return inet_ntoa(this.address);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public string Destination {
|
|
|
|
get {
|
|
|
|
return inet_ntoa(this.destination);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public string Broadcast {
|
|
|
|
get {
|
|
|
|
return inet_ntoa(this.broadcast);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public string Netmask {
|
|
|
|
get {
|
|
|
|
return inet_ntoa(this.netmask);
|
|
|
|
}
|
|
|
|
}
|
2004-09-18 06:32:45 +08:00
|
|
|
|
|
|
|
public String FlagsString() {
|
2005-12-07 01:08:14 +08:00
|
|
|
long flags = this.Flags;
|
2004-09-18 06:32:45 +08:00
|
|
|
String retval = "";
|
|
|
|
|
|
|
|
if (flags == 0)
|
|
|
|
retval += "[NO FLAGS] ";
|
|
|
|
if ((flags & Sigar.IFF_UP) > 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;
|
|
|
|
}
|
2004-09-18 04:46:30 +08:00
|
|
|
}
|
2004-09-18 06:16:14 +08:00
|
|
|
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
|
|
public struct NetInterfaceStat {
|
2005-12-07 01:08:14 +08:00
|
|
|
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;
|
2004-09-18 06:16:14 +08:00
|
|
|
|
|
|
|
[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);
|
2004-09-18 07:58:22 +08:00
|
|
|
throw Sigar.FindException(sigar, status);
|
2004-09-18 06:16:14 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
NetInterfaceStat ifstat =
|
|
|
|
(NetInterfaceStat)Marshal.PtrToStructure(ptr, type);
|
|
|
|
|
|
|
|
Marshal.FreeHGlobal(ptr);
|
|
|
|
|
|
|
|
return ifstat;
|
|
|
|
}
|
|
|
|
}
|
2004-06-22 06:37:04 +08:00
|
|
|
}
|