[PATCH] Simple implementation of network interface properties for Mac OS X

View: New views
7 Messages — Rating Filter:   Alert me  

[PATCH] Simple implementation of network interface properties for Mac OS X

by Alexander Shulgin :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

In the current version System.Net.NetworkInformation.NetworkInterface
provides limited information about network interfaces on the system
(their names only).

The attached patch adds support for NetworkInterfaceType and
GetPhysicalAddress() on Mac OS.

The outline of the changes is as follows:

- Used the same trick with uname as in MWF XplatUI to detect if running
Mac OS.

- In several places I've added base classes like UnixNetworkInterface to
derive Linux- and MacOs- implementation classes from them.  Where
possible, common code moved to Unix- classes; in some places dummy
methods are used to return default "don't know" values (0, false, "").

- Added new file MacOsNetworkInterfaceMarshal to define MacOs-specific
(BSD) structs like sockaddr as they're slightly different from those
used in Linux.

Comments are welcome! :)

--
Cheers,
Alex

Index: System.dll.sources
===================================================================
--- System.dll.sources (revision 133967)
+++ System.dll.sources (working copy)
@@ -761,6 +761,7 @@
 System.Net.NetworkInformation/IPv4InterfaceStatistics.cs
 System.Net.NetworkInformation/IPv6InterfaceProperties.cs
 System.Net.NetworkInformation/LinuxNetworkInterfaceMarshal.cs
+System.Net.NetworkInformation/MacOsNetworkInterfaceMarshal.cs
 System.Net.NetworkInformation/MulticastIPAddressInformationCollection.cs
 System.Net.NetworkInformation/MulticastIPAddressInformation.cs
 System.Net.NetworkInformation/NetBiosNodeType.cs
Index: System.Net.NetworkInformation/IPv4InterfaceStatistics.cs
===================================================================
--- System.Net.NetworkInformation/IPv4InterfaceStatistics.cs (revision 133967)
+++ System.Net.NetworkInformation/IPv4InterfaceStatistics.cs (working copy)
@@ -201,8 +201,65 @@
  return Read ("statistics/tx_packets");
  }
  }
+ }
 
+ // dummy class
+ class MacOsIPv4InterfaceStatistics : IPv4InterfaceStatistics
+ {
+ MacOsNetworkInterface macos;
 
+ public MacOsIPv4InterfaceStatistics (MacOsNetworkInterface parent)
+ {
+ macos = parent;
+ }
+
+ public override long BytesReceived {
+ get { return 0; }
+ }
+
+ public override long BytesSent {
+ get { return 0; }
+ }
+
+ public override long IncomingPacketsDiscarded {
+ get { return 0; }
+ }
+
+ public override long IncomingPacketsWithErrors {
+ get { return 0; }
+ }
+
+ public override long IncomingUnknownProtocolPackets {
+ get { return 0; }
+ }
+
+ public override long NonUnicastPacketsReceived {
+ get { return 0; }
+ }
+
+ public override long NonUnicastPacketsSent {
+ get { return 0; }
+ }
+
+ public override long OutgoingPacketsDiscarded {
+ get { return 0; }
+ }
+
+ public override long OutgoingPacketsWithErrors {
+ get { return 0; }
+ }
+
+ public override long OutputQueueLength {
+ get { return 0; }
+ }
+
+ public override long UnicastPacketsReceived {
+ get { return 0; }
+ }
+
+ public override long UnicastPacketsSent {
+ get { return 0; }
+ }
  }
 
 }
Index: System.Net.NetworkInformation/IPv4InterfaceProperties.cs
===================================================================
--- System.Net.NetworkInformation/IPv4InterfaceProperties.cs (revision 133967)
+++ System.Net.NetworkInformation/IPv4InterfaceProperties.cs (working copy)
@@ -46,17 +46,17 @@
  public abstract bool UsesWins { get; }
  }
 
- sealed class LinuxIPv4InterfaceProperties : IPv4InterfaceProperties
+ abstract class UnixIPv4InterfaceProperties : IPv4InterfaceProperties
  {
- LinuxNetworkInterface iface;
+ protected UnixNetworkInterface iface;
 
- public LinuxIPv4InterfaceProperties (LinuxNetworkInterface iface)
+ public UnixIPv4InterfaceProperties (UnixNetworkInterface iface)
  {
  this.iface = iface;
  }
 
  public override int Index {
- get { return LinuxNetworkInterface.IfNameToIndex (iface.Name); }
+ get { return UnixNetworkInterface.IfNameToIndex (iface.Name); }
  }
 
  // TODO: how to discover that?
@@ -74,6 +74,18 @@
  get { return false; }
  }
 
+ public override bool UsesWins {
+ get { return false; }
+ }
+ }
+
+ sealed class LinuxIPv4InterfaceProperties : UnixIPv4InterfaceProperties
+ {
+ public LinuxIPv4InterfaceProperties (LinuxNetworkInterface iface)
+ : base (iface)
+ {
+ }
+
  public override bool IsForwardingEnabled {
  get {
  string iface_path = "/proc/sys/net/ipv4/conf/" + iface.Name + "/forwarding";
@@ -87,9 +99,10 @@
  return false;
  }
  }
+
  public override int Mtu {
  get {
- string iface_path = iface.IfacePath + "mtu";
+ string iface_path = (iface as LinuxNetworkInterface).IfacePath + "mtu";
  int ret = 0;
 
  if (File.Exists (iface_path)) {
@@ -105,10 +118,24 @@
 
  }
  }
-
- public override bool UsesWins {
+ }
+
+ sealed class MacOsIPv4InterfaceProperties : UnixIPv4InterfaceProperties
+ {
+ public MacOsIPv4InterfaceProperties (MacOsNetworkInterface iface)
+ : base (iface)
+ {
+ }
+
+ // dummy
+ public override bool IsForwardingEnabled {
  get { return false; }
  }
+
+ // dummy
+ public override int Mtu {
+ get { return 0; }
+ }
  }
 
  sealed class Win32IPv4InterfaceProperties : IPv4InterfaceProperties
Index: System.Net.NetworkInformation/IPInterfaceProperties.cs
===================================================================
--- System.Net.NetworkInformation/IPInterfaceProperties.cs (revision 133967)
+++ System.Net.NetworkInformation/IPInterfaceProperties.cs (working copy)
@@ -53,35 +53,26 @@
  public abstract IPAddressCollection WinsServersAddresses { get; }
  }
 
- class LinuxIPInterfaceProperties : IPInterfaceProperties
+ abstract class UnixIPInterfaceProperties : IPInterfaceProperties
  {
- IPv4InterfaceProperties ipv4iface_properties;
- LinuxNetworkInterface iface;
+ protected IPv4InterfaceProperties ipv4iface_properties;
+ protected UnixNetworkInterface iface;
  List <IPAddress> addresses;
  IPAddressCollection dns_servers;
  string dns_suffix;
  DateTime last_parse;
 
- public LinuxIPInterfaceProperties (LinuxNetworkInterface iface, List <IPAddress> addresses)
+ public UnixIPInterfaceProperties (UnixNetworkInterface iface, List <IPAddress> addresses)
  {
  this.iface = iface;
  this.addresses = addresses;
  }
 
- public override IPv4InterfaceProperties GetIPv4Properties ()
- {
- if (ipv4iface_properties == null)
- ipv4iface_properties = new LinuxIPv4InterfaceProperties (iface);
-
- return ipv4iface_properties;
- }
-
  public override IPv6InterfaceProperties GetIPv6Properties ()
  {
  throw new NotImplementedException ();
  }
 
-
  static Regex ns = new Regex (@"\s*nameserver\s+(?<address>.*)");
  static Regex search = new Regex (@"\s*search\s+(?<domain>.*)");
  void ParseResolvConf ()
@@ -234,6 +225,38 @@
  }
  }
 
+ class LinuxIPInterfaceProperties : UnixIPInterfaceProperties
+ {
+ public LinuxIPInterfaceProperties (LinuxNetworkInterface iface, List <IPAddress> addresses)
+ : base (iface, addresses)
+ {
+ }
+
+ public override IPv4InterfaceProperties GetIPv4Properties ()
+ {
+ if (ipv4iface_properties == null)
+ ipv4iface_properties = new LinuxIPv4InterfaceProperties (iface as LinuxNetworkInterface);
+
+ return ipv4iface_properties;
+ }
+ }
+
+ class MacOsIPInterfaceProperties : UnixIPInterfaceProperties
+ {
+ public MacOsIPInterfaceProperties (MacOsNetworkInterface iface, List <IPAddress> addresses)
+ : base (iface, addresses)
+ {
+ }
+
+ public override IPv4InterfaceProperties GetIPv4Properties ()
+ {
+ if (ipv4iface_properties == null)
+ ipv4iface_properties = new MacOsIPv4InterfaceProperties (iface as MacOsNetworkInterface);
+
+ return ipv4iface_properties;
+ }
+ }
+
  class Win32IPInterfaceProperties2 : IPInterfaceProperties
  {
  readonly Win32_IP_ADAPTER_ADDRESSES addr;
Index: System.Net.NetworkInformation/NetworkInterface.cs
===================================================================
--- System.Net.NetworkInformation/NetworkInterface.cs (revision 133967)
+++ System.Net.NetworkInformation/NetworkInterface.cs (working copy)
@@ -42,6 +42,9 @@
 
 namespace System.Net.NetworkInformation {
  public abstract class NetworkInterface {
+ [DllImport ("libc")]
+ static extern int uname (IntPtr buf);
+
  static Version windowsVer51 = new Version (5, 1);
  static internal readonly bool runningOnUnix = (Environment.OSVersion.Platform == PlatformID.Unix);
 
@@ -53,8 +56,20 @@
  public static NetworkInterface [] GetAllNetworkInterfaces ()
  {
  if (runningOnUnix) {
+ bool darwin = false;
+ IntPtr buf = Marshal.AllocHGlobal (8192);
+ if (uname (buf) == 0) {
+ string os = Marshal.PtrToStringAnsi (buf);
+ if (os == "Darwin")
+ darwin = true;
+ }
+ Marshal.FreeHGlobal (buf);
+
  try {
- return LinuxNetworkInterface.ImplGetAllNetworkInterfaces ();
+ if (darwin)
+ return MacOsNetworkInterface.ImplGetAllNetworkInterfaces ();
+ else
+ return LinuxNetworkInterface.ImplGetAllNetworkInterfaces ();
  } catch (SystemException ex) {
  throw ex;
  } catch {
@@ -87,7 +102,7 @@
  get {
  if (runningOnUnix) {
  try {
- return LinuxNetworkInterface.IfNameToIndex ("lo");
+ return UnixNetworkInterface.IfNameToIndex ("lo");
  } catch  {
  return 0;
  }
@@ -111,17 +126,103 @@
  public abstract bool SupportsMulticast { get; }
  }
 
+ abstract class UnixNetworkInterface : NetworkInterface
+ {
+ [DllImport("libc")]
+ static extern int if_nametoindex(string ifname);
+
+ protected IPv4InterfaceStatistics ipv4stats;
+ protected IPInterfaceProperties ipproperties;
+
+ string               name;
+ int                  index;
+ protected List <IPAddress> addresses;
+ byte[]               macAddress;
+ NetworkInterfaceType type;
+
+ internal UnixNetworkInterface (string name)
+ {
+ this.name = name;
+ addresses = new List<IPAddress> ();
+ }
+
+ public static int IfNameToIndex (string ifname)
+ {
+ return if_nametoindex(ifname);
+ }
+
+ internal void AddAddress (IPAddress address)
+ {
+ addresses.Add (address);
+ }
+
+ internal void SetLinkLayerInfo (int index, byte[] macAddress, NetworkInterfaceType type)
+ {
+ this.index = index;
+ this.macAddress = macAddress;
+ this.type = type;
+ }
+
+ public override PhysicalAddress GetPhysicalAddress ()
+ {
+ if (macAddress != null)
+ return new PhysicalAddress (macAddress);
+ else
+ return PhysicalAddress.None;
+ }
+
+ public override bool Supports (NetworkInterfaceComponent networkInterfaceComponent)
+ {
+ bool wantIPv4 = networkInterfaceComponent == NetworkInterfaceComponent.IPv4;
+ bool wantIPv6 = wantIPv4 ? false : networkInterfaceComponent == NetworkInterfaceComponent.IPv6;
+
+ foreach (IPAddress address in addresses) {
+ if (wantIPv4 && address.AddressFamily == AddressFamily.InterNetwork)
+ return true;
+ else if (wantIPv6 && address.AddressFamily == AddressFamily.InterNetworkV6)
+ return true;
+ }
+
+ return false;
+ }
+
+ public override string Description {
+ get { return name; }
+ }
+
+ public override string Id {
+ get { return name; }
+ }
+
+ public override bool IsReceiveOnly {
+ get { return false; }
+ }
+
+ public override string Name {
+ get { return name; }
+ }
+
+ public override NetworkInterfaceType NetworkInterfaceType {
+ get { return type; }
+ }
+
+ [MonoTODO ("Parse dmesg?")]
+ public override long Speed {
+ get {
+ // Bits/s
+ return 1000000;
+ }
+ }
+ }
+
  //
  // This class needs support from the libsupport.so library to fetch the
  // data using arch-specific ioctls.
  //
  // For this to work, we have to create this on the factory above.
  //
- class LinuxNetworkInterface : NetworkInterface
+ class LinuxNetworkInterface : UnixNetworkInterface
  {
- [DllImport("libc")]
- static extern int if_nametoindex(string ifname);
-
  [DllImport ("libc")]
  static extern int getifaddrs (out IntPtr ifap);
 
@@ -132,13 +233,6 @@
  const int AF_INET6  = 10;
  const int AF_PACKET = 17;
 
- IPv4InterfaceStatistics ipv4stats;
- IPInterfaceProperties ipproperties;
-
- string               name;
- int                  index;
- List <IPAddress>     addresses;
- byte[]               macAddress;
  NetworkInterfaceType type;
  string               iface_path;
  string               iface_operstate_path;
@@ -148,11 +242,6 @@
  get { return iface_path; }
  }
 
- public static int IfNameToIndex (string ifname)
- {
- return if_nametoindex(ifname);
- }
-
  public static NetworkInterface [] ImplGetAllNetworkInterfaces ()
  {
  var interfaces = new Dictionary <string, LinuxNetworkInterface> ();
@@ -246,8 +335,14 @@
  if (!address.Equals (IPAddress.None))
  iface.AddAddress (address);
 
- if (macAddress != null || type == NetworkInterfaceType.Loopback)
+ if (macAddress != null || type == NetworkInterfaceType.Loopback) {
+ if (type == NetworkInterfaceType.Ethernet) {
+ if (Directory.Exists(iface.IfacePath + "wireless")) {
+ type = NetworkInterfaceType.Wireless80211;
+ }
+ }
  iface.SetLinkLayerInfo (index, macAddress, type);
+ }
 
  next = addr.ifa_next;
  }
@@ -265,31 +360,13 @@
  }
 
  LinuxNetworkInterface (string name)
+ : base (name)
  {
- this.name = name;
- addresses = new List<IPAddress> ();
  iface_path = "/sys/class/net/" + name + "/";
  iface_operstate_path = iface_path + "operstate";
  iface_flags_path = iface_path + "flags";
  }
 
- internal void AddAddress (IPAddress address)
- {
- addresses.Add (address);
- }
-
- internal void SetLinkLayerInfo (int index, byte[] macAddress, NetworkInterfaceType type)
- {
- this.index = index;
- this.macAddress = macAddress;
- if (type == NetworkInterfaceType.Ethernet) {
- if (Directory.Exists(iface_path + "wireless")) {
- type = NetworkInterfaceType.Wireless80211;
- }
- }
- this.type = type;
- }
-
  public override IPInterfaceProperties GetIPProperties ()
  {
  if (ipproperties == null)
@@ -301,53 +378,9 @@
  {
  if (ipv4stats == null)
  ipv4stats = new LinuxIPv4InterfaceStatistics (this);
-
  return ipv4stats;
  }
 
- public override PhysicalAddress GetPhysicalAddress ()
- {
- if (macAddress != null)
- return new PhysicalAddress (macAddress);
- else
- return PhysicalAddress.None;
- }
-
- public override bool Supports (NetworkInterfaceComponent networkInterfaceComponent)
- {
- bool wantIPv4 = networkInterfaceComponent == NetworkInterfaceComponent.IPv4;
- bool wantIPv6 = wantIPv4 ? false : networkInterfaceComponent == NetworkInterfaceComponent.IPv6;
-
- foreach (IPAddress address in addresses) {
- if (wantIPv4 && address.AddressFamily == AddressFamily.InterNetwork)
- return true;
- else if (wantIPv6 && address.AddressFamily == AddressFamily.InterNetworkV6)
- return true;
-                        }
-
-                        return false;
- }
-
- public override string Description {
- get { return name; }
- }
-
- public override string Id {
- get { return name; }
- }
-
- public override bool IsReceiveOnly {
- get { return false; }
- }
-
- public override string Name {
- get { return name; }
- }
-
- public override NetworkInterfaceType NetworkInterfaceType {
- get { return type; }
- }
-
  public override OperationalStatus OperationalStatus {
  get {
  if (!Directory.Exists (iface_path))
@@ -384,14 +417,6 @@
  }
  }
 
- [MonoTODO ("Parse dmesg?")]
- public override long Speed {
- get {
- // Bits/s
- return 1000000;
- }
- }
-
  public override bool SupportsMulticast {
  get {
  if (!Directory.Exists (iface_path))
@@ -413,6 +438,143 @@
  }
  }
 
+ class MacOsNetworkInterface : UnixNetworkInterface
+ {
+ [DllImport ("libc")]
+ static extern int getifaddrs (out IntPtr ifap);
+
+ [DllImport ("libc")]
+ static extern void freeifaddrs (IntPtr ifap);
+
+ const int AF_INET   = 2;
+ const int AF_INET6  = 30;
+ const int AF_LINK = 18;
+
+ public static NetworkInterface [] ImplGetAllNetworkInterfaces ()
+ {
+ var interfaces = new Dictionary <string, MacOsNetworkInterface> ();
+ IntPtr ifap;
+ if (getifaddrs (out ifap) != 0)
+ throw new SystemException ("getifaddrs() failed");
+
+ try {
+ IntPtr next = ifap;
+ while (next != IntPtr.Zero) {
+ MacOsStructs.ifaddrs addr = (MacOsStructs.ifaddrs) Marshal.PtrToStructure (next, typeof (MacOsStructs.ifaddrs));
+ IPAddress address = IPAddress.None;
+ string    name = addr.ifa_name;
+ int       index = -1;
+ byte[]    macAddress = null;
+ NetworkInterfaceType type = NetworkInterfaceType.Unknown;
+
+ if (addr.ifa_addr != IntPtr.Zero) {
+ MacOsStructs.sockaddr sockaddr = (MacOsStructs.sockaddr) Marshal.PtrToStructure (addr.ifa_addr, typeof (MacOsStructs.sockaddr));
+
+ if (sockaddr.sa_family == AF_INET6) {
+ //sockaddr_in6 sockaddr6 = (sockaddr_in6) Marshal.PtrToStructure (addr.ifa_addr, typeof (sockaddr_in6));
+ //address = new IPAddress (sockaddr6.sin6_addr.u6_addr8, sockaddr6.sin6_scope_id);
+ } else if (sockaddr.sa_family == AF_INET) {
+ MacOsStructs.sockaddr_in sockaddrin = (MacOsStructs.sockaddr_in) Marshal.PtrToStructure (addr.ifa_addr, typeof (MacOsStructs.sockaddr_in));
+ address = new IPAddress (sockaddrin.sin_addr);
+ } else if (sockaddr.sa_family == AF_LINK) {
+ MacOsStructs.sockaddr_dl sockaddrdl = (MacOsStructs.sockaddr_dl) Marshal.PtrToStructure (addr.ifa_addr, typeof (MacOsStructs.sockaddr_dl));
+
+ macAddress = new byte [(int) sockaddrdl.sdl_alen];
+ Array.Copy (sockaddrdl.sdl_data, sockaddrdl.sdl_nlen, macAddress, 0, macAddress.Length);
+ index = sockaddrdl.sdl_index;
+
+ int hwtype = (int) sockaddrdl.sdl_type;
+ if (Enum.IsDefined (typeof (MacOsArpHardware), hwtype)) {
+ switch ((MacOsArpHardware) hwtype) {
+ case MacOsArpHardware.ETHER:
+ type = NetworkInterfaceType.Ethernet;
+ break;
+
+ case MacOsArpHardware.ATM:
+ type = NetworkInterfaceType.Atm;
+ break;
+
+ case MacOsArpHardware.SLIP:
+ type = NetworkInterfaceType.Slip;
+ break;
+
+ case MacOsArpHardware.PPP:
+ type = NetworkInterfaceType.Ppp;
+ break;
+
+ case MacOsArpHardware.LOOPBACK:
+ type = NetworkInterfaceType.Loopback;
+ macAddress = null;
+ break;
+
+ case MacOsArpHardware.FDDI:
+ type = NetworkInterfaceType.Fddi;
+ break;
+ }
+ }
+ }
+ }
+
+ MacOsNetworkInterface iface = null;
+
+ if (!interfaces.TryGetValue (name, out iface)) {
+ iface = new MacOsNetworkInterface (name);
+ interfaces.Add (name, iface);
+ }
+
+ if (!address.Equals (IPAddress.None))
+ iface.AddAddress (address);
+
+ if (macAddress != null || type == NetworkInterfaceType.Loopback)
+ iface.SetLinkLayerInfo (index, macAddress, type);
+
+ next = addr.ifa_next;
+ }
+ } finally {
+ freeifaddrs (ifap);
+ }
+
+ NetworkInterface [] result = new NetworkInterface [interfaces.Count];
+ int x = 0;
+ foreach (NetworkInterface thisInterface in interfaces.Values) {
+ result [x] = thisInterface;
+ x++;
+ }
+ return result;
+ }
+
+ MacOsNetworkInterface (string name)
+ : base (name)
+ {
+ }
+
+ public override IPInterfaceProperties GetIPProperties ()
+ {
+ if (ipproperties == null)
+ ipproperties = new MacOsIPInterfaceProperties (this, addresses);
+ return ipproperties;
+ }
+
+ public override IPv4InterfaceStatistics GetIPv4Statistics ()
+ {
+ if (ipv4stats == null)
+ ipv4stats = new MacOsIPv4InterfaceStatistics (this);
+ return ipv4stats;
+ }
+
+ public override OperationalStatus OperationalStatus {
+ get {
+ return OperationalStatus.Unknown;
+ }
+ }
+
+ public override bool SupportsMulticast {
+ get {
+ return false;
+ }
+ }
+ }
+
  class Win32NetworkInterface2 : NetworkInterface
  {
  [DllImport ("iphlpapi.dll", SetLastError = true)]

_______________________________________________
Mono-osx mailing list
Mono-osx@...
http://lists.ximian.com/mailman/listinfo/mono-osx

Re: [Mono-dev] [PATCH] Simple implementation of network interface properties for Mac OS X

by Alexander Shulgin :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Alex Shulgin wrote:
> Hi,
>
> In the current version System.Net.NetworkInformation.NetworkInterface
> provides limited information about network interfaces on the system
> (their names only).
>
> The attached patch adds support for NetworkInterfaceType and
> GetPhysicalAddress() on Mac OS.

Oops, I've almost forgot about IPv6... and missed the added file
MacOsNetworkInterfaceMarshal.

Please see the fixed patch instead.

--
Alex


Index: System.dll.sources
===================================================================
--- System.dll.sources (revision 133967)
+++ System.dll.sources (working copy)
@@ -761,6 +761,7 @@
 System.Net.NetworkInformation/IPv4InterfaceStatistics.cs
 System.Net.NetworkInformation/IPv6InterfaceProperties.cs
 System.Net.NetworkInformation/LinuxNetworkInterfaceMarshal.cs
+System.Net.NetworkInformation/MacOsNetworkInterfaceMarshal.cs
 System.Net.NetworkInformation/MulticastIPAddressInformationCollection.cs
 System.Net.NetworkInformation/MulticastIPAddressInformation.cs
 System.Net.NetworkInformation/NetBiosNodeType.cs
Index: System.Net.NetworkInformation/IPv4InterfaceStatistics.cs
===================================================================
--- System.Net.NetworkInformation/IPv4InterfaceStatistics.cs (revision 133967)
+++ System.Net.NetworkInformation/IPv4InterfaceStatistics.cs (working copy)
@@ -201,8 +201,65 @@
  return Read ("statistics/tx_packets");
  }
  }
+ }
 
+ // dummy class
+ class MacOsIPv4InterfaceStatistics : IPv4InterfaceStatistics
+ {
+ MacOsNetworkInterface macos;
 
+ public MacOsIPv4InterfaceStatistics (MacOsNetworkInterface parent)
+ {
+ macos = parent;
+ }
+
+ public override long BytesReceived {
+ get { return 0; }
+ }
+
+ public override long BytesSent {
+ get { return 0; }
+ }
+
+ public override long IncomingPacketsDiscarded {
+ get { return 0; }
+ }
+
+ public override long IncomingPacketsWithErrors {
+ get { return 0; }
+ }
+
+ public override long IncomingUnknownProtocolPackets {
+ get { return 0; }
+ }
+
+ public override long NonUnicastPacketsReceived {
+ get { return 0; }
+ }
+
+ public override long NonUnicastPacketsSent {
+ get { return 0; }
+ }
+
+ public override long OutgoingPacketsDiscarded {
+ get { return 0; }
+ }
+
+ public override long OutgoingPacketsWithErrors {
+ get { return 0; }
+ }
+
+ public override long OutputQueueLength {
+ get { return 0; }
+ }
+
+ public override long UnicastPacketsReceived {
+ get { return 0; }
+ }
+
+ public override long UnicastPacketsSent {
+ get { return 0; }
+ }
  }
 
 }
Index: System.Net.NetworkInformation/MacOsNetworkInterfaceMarshal.cs
===================================================================
--- System.Net.NetworkInformation/MacOsNetworkInterfaceMarshal.cs (revision 0)
+++ System.Net.NetworkInformation/MacOsNetworkInterfaceMarshal.cs (revision 0)
@@ -0,0 +1,73 @@
+#if NET_2_0
+using System;
+using System.Runtime.InteropServices;
+
+namespace System.Net.NetworkInformation {
+ namespace MacOsStructs {
+ internal struct ifaddrs
+ {
+ public IntPtr  ifa_next;
+ public string  ifa_name;
+ public uint    ifa_flags;
+ public IntPtr  ifa_addr;
+ public IntPtr  ifa_netmask;
+ public IntPtr  ifa_dstaddr;
+ public IntPtr  ifa_data;
+ }
+
+ internal struct sockaddr
+ {
+ public byte  sa_len;
+ public byte  sa_family;
+ }
+
+ internal struct sockaddr_in
+ {
+ public byte   sin_len;
+ public byte   sin_family;
+ public ushort sin_port;
+ public uint   sin_addr;
+ }
+
+ internal struct in6_addr
+ {
+ [MarshalAs (UnmanagedType.ByValArray, SizeConst=16)]
+ public byte[] u6_addr8;
+ }
+
+ internal struct sockaddr_in6
+ {
+ public byte     sin6_len;
+ public byte     sin6_family;
+ public ushort   sin6_port;
+ public uint     sin6_flowinfo;
+ public in6_addr sin6_addr;
+ public uint     sin6_scope_id;
+ }
+
+ internal struct sockaddr_dl
+ {
+ public byte   sdl_len;
+ public byte   sdl_family;
+ public ushort sdl_index;
+ public byte   sdl_type;
+ public byte   sdl_nlen;
+ public byte   sdl_alen;
+ public byte   sdl_slen;
+
+ [MarshalAs (UnmanagedType.ByValArray, SizeConst=12)]
+ public byte[] sdl_data;
+ }
+
+ }
+
+ internal enum MacOsArpHardware {
+ ETHER = 0x6,
+ ATM = 0x25,
+ SLIP = 0x1c,
+ PPP = 0x17,
+ LOOPBACK = 0x18,
+ FDDI = 0xf
+ }
+}
+#endif
Index: System.Net.NetworkInformation/IPv4InterfaceProperties.cs
===================================================================
--- System.Net.NetworkInformation/IPv4InterfaceProperties.cs (revision 133967)
+++ System.Net.NetworkInformation/IPv4InterfaceProperties.cs (working copy)
@@ -46,17 +46,17 @@
  public abstract bool UsesWins { get; }
  }
 
- sealed class LinuxIPv4InterfaceProperties : IPv4InterfaceProperties
+ abstract class UnixIPv4InterfaceProperties : IPv4InterfaceProperties
  {
- LinuxNetworkInterface iface;
+ protected UnixNetworkInterface iface;
 
- public LinuxIPv4InterfaceProperties (LinuxNetworkInterface iface)
+ public UnixIPv4InterfaceProperties (UnixNetworkInterface iface)
  {
  this.iface = iface;
  }
 
  public override int Index {
- get { return LinuxNetworkInterface.IfNameToIndex (iface.Name); }
+ get { return UnixNetworkInterface.IfNameToIndex (iface.Name); }
  }
 
  // TODO: how to discover that?
@@ -74,6 +74,18 @@
  get { return false; }
  }
 
+ public override bool UsesWins {
+ get { return false; }
+ }
+ }
+
+ sealed class LinuxIPv4InterfaceProperties : UnixIPv4InterfaceProperties
+ {
+ public LinuxIPv4InterfaceProperties (LinuxNetworkInterface iface)
+ : base (iface)
+ {
+ }
+
  public override bool IsForwardingEnabled {
  get {
  string iface_path = "/proc/sys/net/ipv4/conf/" + iface.Name + "/forwarding";
@@ -87,9 +99,10 @@
  return false;
  }
  }
+
  public override int Mtu {
  get {
- string iface_path = iface.IfacePath + "mtu";
+ string iface_path = (iface as LinuxNetworkInterface).IfacePath + "mtu";
  int ret = 0;
 
  if (File.Exists (iface_path)) {
@@ -105,10 +118,24 @@
 
  }
  }
-
- public override bool UsesWins {
+ }
+
+ sealed class MacOsIPv4InterfaceProperties : UnixIPv4InterfaceProperties
+ {
+ public MacOsIPv4InterfaceProperties (MacOsNetworkInterface iface)
+ : base (iface)
+ {
+ }
+
+ // dummy
+ public override bool IsForwardingEnabled {
  get { return false; }
  }
+
+ // dummy
+ public override int Mtu {
+ get { return 0; }
+ }
  }
 
  sealed class Win32IPv4InterfaceProperties : IPv4InterfaceProperties
Index: System.Net.NetworkInformation/IPInterfaceProperties.cs
===================================================================
--- System.Net.NetworkInformation/IPInterfaceProperties.cs (revision 133967)
+++ System.Net.NetworkInformation/IPInterfaceProperties.cs (working copy)
@@ -53,35 +53,26 @@
  public abstract IPAddressCollection WinsServersAddresses { get; }
  }
 
- class LinuxIPInterfaceProperties : IPInterfaceProperties
+ abstract class UnixIPInterfaceProperties : IPInterfaceProperties
  {
- IPv4InterfaceProperties ipv4iface_properties;
- LinuxNetworkInterface iface;
+ protected IPv4InterfaceProperties ipv4iface_properties;
+ protected UnixNetworkInterface iface;
  List <IPAddress> addresses;
  IPAddressCollection dns_servers;
  string dns_suffix;
  DateTime last_parse;
 
- public LinuxIPInterfaceProperties (LinuxNetworkInterface iface, List <IPAddress> addresses)
+ public UnixIPInterfaceProperties (UnixNetworkInterface iface, List <IPAddress> addresses)
  {
  this.iface = iface;
  this.addresses = addresses;
  }
 
- public override IPv4InterfaceProperties GetIPv4Properties ()
- {
- if (ipv4iface_properties == null)
- ipv4iface_properties = new LinuxIPv4InterfaceProperties (iface);
-
- return ipv4iface_properties;
- }
-
  public override IPv6InterfaceProperties GetIPv6Properties ()
  {
  throw new NotImplementedException ();
  }
 
-
  static Regex ns = new Regex (@"\s*nameserver\s+(?<address>.*)");
  static Regex search = new Regex (@"\s*search\s+(?<domain>.*)");
  void ParseResolvConf ()
@@ -234,6 +225,38 @@
  }
  }
 
+ class LinuxIPInterfaceProperties : UnixIPInterfaceProperties
+ {
+ public LinuxIPInterfaceProperties (LinuxNetworkInterface iface, List <IPAddress> addresses)
+ : base (iface, addresses)
+ {
+ }
+
+ public override IPv4InterfaceProperties GetIPv4Properties ()
+ {
+ if (ipv4iface_properties == null)
+ ipv4iface_properties = new LinuxIPv4InterfaceProperties (iface as LinuxNetworkInterface);
+
+ return ipv4iface_properties;
+ }
+ }
+
+ class MacOsIPInterfaceProperties : UnixIPInterfaceProperties
+ {
+ public MacOsIPInterfaceProperties (MacOsNetworkInterface iface, List <IPAddress> addresses)
+ : base (iface, addresses)
+ {
+ }
+
+ public override IPv4InterfaceProperties GetIPv4Properties ()
+ {
+ if (ipv4iface_properties == null)
+ ipv4iface_properties = new MacOsIPv4InterfaceProperties (iface as MacOsNetworkInterface);
+
+ return ipv4iface_properties;
+ }
+ }
+
  class Win32IPInterfaceProperties2 : IPInterfaceProperties
  {
  readonly Win32_IP_ADAPTER_ADDRESSES addr;
Index: System.Net.NetworkInformation/NetworkInterface.cs
===================================================================
--- System.Net.NetworkInformation/NetworkInterface.cs (revision 133967)
+++ System.Net.NetworkInformation/NetworkInterface.cs (working copy)
@@ -42,6 +42,9 @@
 
 namespace System.Net.NetworkInformation {
  public abstract class NetworkInterface {
+ [DllImport ("libc")]
+ static extern int uname (IntPtr buf);
+
  static Version windowsVer51 = new Version (5, 1);
  static internal readonly bool runningOnUnix = (Environment.OSVersion.Platform == PlatformID.Unix);
 
@@ -53,8 +56,20 @@
  public static NetworkInterface [] GetAllNetworkInterfaces ()
  {
  if (runningOnUnix) {
+ bool darwin = false;
+ IntPtr buf = Marshal.AllocHGlobal (8192);
+ if (uname (buf) == 0) {
+ string os = Marshal.PtrToStringAnsi (buf);
+ if (os == "Darwin")
+ darwin = true;
+ }
+ Marshal.FreeHGlobal (buf);
+
  try {
- return LinuxNetworkInterface.ImplGetAllNetworkInterfaces ();
+ if (darwin)
+ return MacOsNetworkInterface.ImplGetAllNetworkInterfaces ();
+ else
+ return LinuxNetworkInterface.ImplGetAllNetworkInterfaces ();
  } catch (SystemException ex) {
  throw ex;
  } catch {
@@ -87,7 +102,7 @@
  get {
  if (runningOnUnix) {
  try {
- return LinuxNetworkInterface.IfNameToIndex ("lo");
+ return UnixNetworkInterface.IfNameToIndex ("lo");
  } catch  {
  return 0;
  }
@@ -111,17 +126,103 @@
  public abstract bool SupportsMulticast { get; }
  }
 
+ abstract class UnixNetworkInterface : NetworkInterface
+ {
+ [DllImport("libc")]
+ static extern int if_nametoindex(string ifname);
+
+ protected IPv4InterfaceStatistics ipv4stats;
+ protected IPInterfaceProperties ipproperties;
+
+ string               name;
+ int                  index;
+ protected List <IPAddress> addresses;
+ byte[]               macAddress;
+ NetworkInterfaceType type;
+
+ internal UnixNetworkInterface (string name)
+ {
+ this.name = name;
+ addresses = new List<IPAddress> ();
+ }
+
+ public static int IfNameToIndex (string ifname)
+ {
+ return if_nametoindex(ifname);
+ }
+
+ internal void AddAddress (IPAddress address)
+ {
+ addresses.Add (address);
+ }
+
+ internal void SetLinkLayerInfo (int index, byte[] macAddress, NetworkInterfaceType type)
+ {
+ this.index = index;
+ this.macAddress = macAddress;
+ this.type = type;
+ }
+
+ public override PhysicalAddress GetPhysicalAddress ()
+ {
+ if (macAddress != null)
+ return new PhysicalAddress (macAddress);
+ else
+ return PhysicalAddress.None;
+ }
+
+ public override bool Supports (NetworkInterfaceComponent networkInterfaceComponent)
+ {
+ bool wantIPv4 = networkInterfaceComponent == NetworkInterfaceComponent.IPv4;
+ bool wantIPv6 = wantIPv4 ? false : networkInterfaceComponent == NetworkInterfaceComponent.IPv6;
+
+ foreach (IPAddress address in addresses) {
+ if (wantIPv4 && address.AddressFamily == AddressFamily.InterNetwork)
+ return true;
+ else if (wantIPv6 && address.AddressFamily == AddressFamily.InterNetworkV6)
+ return true;
+ }
+
+ return false;
+ }
+
+ public override string Description {
+ get { return name; }
+ }
+
+ public override string Id {
+ get { return name; }
+ }
+
+ public override bool IsReceiveOnly {
+ get { return false; }
+ }
+
+ public override string Name {
+ get { return name; }
+ }
+
+ public override NetworkInterfaceType NetworkInterfaceType {
+ get { return type; }
+ }
+
+ [MonoTODO ("Parse dmesg?")]
+ public override long Speed {
+ get {
+ // Bits/s
+ return 1000000;
+ }
+ }
+ }
+
  //
  // This class needs support from the libsupport.so library to fetch the
  // data using arch-specific ioctls.
  //
  // For this to work, we have to create this on the factory above.
  //
- class LinuxNetworkInterface : NetworkInterface
+ class LinuxNetworkInterface : UnixNetworkInterface
  {
- [DllImport("libc")]
- static extern int if_nametoindex(string ifname);
-
  [DllImport ("libc")]
  static extern int getifaddrs (out IntPtr ifap);
 
@@ -132,13 +233,6 @@
  const int AF_INET6  = 10;
  const int AF_PACKET = 17;
 
- IPv4InterfaceStatistics ipv4stats;
- IPInterfaceProperties ipproperties;
-
- string               name;
- int                  index;
- List <IPAddress>     addresses;
- byte[]               macAddress;
  NetworkInterfaceType type;
  string               iface_path;
  string               iface_operstate_path;
@@ -148,11 +242,6 @@
  get { return iface_path; }
  }
 
- public static int IfNameToIndex (string ifname)
- {
- return if_nametoindex(ifname);
- }
-
  public static NetworkInterface [] ImplGetAllNetworkInterfaces ()
  {
  var interfaces = new Dictionary <string, LinuxNetworkInterface> ();
@@ -246,8 +335,14 @@
  if (!address.Equals (IPAddress.None))
  iface.AddAddress (address);
 
- if (macAddress != null || type == NetworkInterfaceType.Loopback)
+ if (macAddress != null || type == NetworkInterfaceType.Loopback) {
+ if (type == NetworkInterfaceType.Ethernet) {
+ if (Directory.Exists(iface.IfacePath + "wireless")) {
+ type = NetworkInterfaceType.Wireless80211;
+ }
+ }
  iface.SetLinkLayerInfo (index, macAddress, type);
+ }
 
  next = addr.ifa_next;
  }
@@ -265,31 +360,13 @@
  }
 
  LinuxNetworkInterface (string name)
+ : base (name)
  {
- this.name = name;
- addresses = new List<IPAddress> ();
  iface_path = "/sys/class/net/" + name + "/";
  iface_operstate_path = iface_path + "operstate";
  iface_flags_path = iface_path + "flags";
  }
 
- internal void AddAddress (IPAddress address)
- {
- addresses.Add (address);
- }
-
- internal void SetLinkLayerInfo (int index, byte[] macAddress, NetworkInterfaceType type)
- {
- this.index = index;
- this.macAddress = macAddress;
- if (type == NetworkInterfaceType.Ethernet) {
- if (Directory.Exists(iface_path + "wireless")) {
- type = NetworkInterfaceType.Wireless80211;
- }
- }
- this.type = type;
- }
-
  public override IPInterfaceProperties GetIPProperties ()
  {
  if (ipproperties == null)
@@ -301,53 +378,9 @@
  {
  if (ipv4stats == null)
  ipv4stats = new LinuxIPv4InterfaceStatistics (this);
-
  return ipv4stats;
  }
 
- public override PhysicalAddress GetPhysicalAddress ()
- {
- if (macAddress != null)
- return new PhysicalAddress (macAddress);
- else
- return PhysicalAddress.None;
- }
-
- public override bool Supports (NetworkInterfaceComponent networkInterfaceComponent)
- {
- bool wantIPv4 = networkInterfaceComponent == NetworkInterfaceComponent.IPv4;
- bool wantIPv6 = wantIPv4 ? false : networkInterfaceComponent == NetworkInterfaceComponent.IPv6;
-
- foreach (IPAddress address in addresses) {
- if (wantIPv4 && address.AddressFamily == AddressFamily.InterNetwork)
- return true;
- else if (wantIPv6 && address.AddressFamily == AddressFamily.InterNetworkV6)
- return true;
-                        }
-
-                        return false;
- }
-
- public override string Description {
- get { return name; }
- }
-
- public override string Id {
- get { return name; }
- }
-
- public override bool IsReceiveOnly {
- get { return false; }
- }
-
- public override string Name {
- get { return name; }
- }
-
- public override NetworkInterfaceType NetworkInterfaceType {
- get { return type; }
- }
-
  public override OperationalStatus OperationalStatus {
  get {
  if (!Directory.Exists (iface_path))
@@ -384,14 +417,6 @@
  }
  }
 
- [MonoTODO ("Parse dmesg?")]
- public override long Speed {
- get {
- // Bits/s
- return 1000000;
- }
- }
-
  public override bool SupportsMulticast {
  get {
  if (!Directory.Exists (iface_path))
@@ -413,6 +438,143 @@
  }
  }
 
+ class MacOsNetworkInterface : UnixNetworkInterface
+ {
+ [DllImport ("libc")]
+ static extern int getifaddrs (out IntPtr ifap);
+
+ [DllImport ("libc")]
+ static extern void freeifaddrs (IntPtr ifap);
+
+ const int AF_INET  = 2;
+ const int AF_INET6 = 30;
+ const int AF_LINK  = 18;
+
+ public static NetworkInterface [] ImplGetAllNetworkInterfaces ()
+ {
+ var interfaces = new Dictionary <string, MacOsNetworkInterface> ();
+ IntPtr ifap;
+ if (getifaddrs (out ifap) != 0)
+ throw new SystemException ("getifaddrs() failed");
+
+ try {
+ IntPtr next = ifap;
+ while (next != IntPtr.Zero) {
+ MacOsStructs.ifaddrs addr = (MacOsStructs.ifaddrs) Marshal.PtrToStructure (next, typeof (MacOsStructs.ifaddrs));
+ IPAddress address = IPAddress.None;
+ string    name = addr.ifa_name;
+ int       index = -1;
+ byte[]    macAddress = null;
+ NetworkInterfaceType type = NetworkInterfaceType.Unknown;
+
+ if (addr.ifa_addr != IntPtr.Zero) {
+ MacOsStructs.sockaddr sockaddr = (MacOsStructs.sockaddr) Marshal.PtrToStructure (addr.ifa_addr, typeof (MacOsStructs.sockaddr));
+
+ if (sockaddr.sa_family == AF_INET6) {
+ MacOsStructs.sockaddr_in6 sockaddr6 = (MacOsStructs.sockaddr_in6) Marshal.PtrToStructure (addr.ifa_addr, typeof (MacOsStructs.sockaddr_in6));
+ address = new IPAddress (sockaddr6.sin6_addr.u6_addr8, sockaddr6.sin6_scope_id);
+ } else if (sockaddr.sa_family == AF_INET) {
+ MacOsStructs.sockaddr_in sockaddrin = (MacOsStructs.sockaddr_in) Marshal.PtrToStructure (addr.ifa_addr, typeof (MacOsStructs.sockaddr_in));
+ address = new IPAddress (sockaddrin.sin_addr);
+ } else if (sockaddr.sa_family == AF_LINK) {
+ MacOsStructs.sockaddr_dl sockaddrdl = (MacOsStructs.sockaddr_dl) Marshal.PtrToStructure (addr.ifa_addr, typeof (MacOsStructs.sockaddr_dl));
+
+ macAddress = new byte [(int) sockaddrdl.sdl_alen];
+ Array.Copy (sockaddrdl.sdl_data, sockaddrdl.sdl_nlen, macAddress, 0, macAddress.Length);
+ index = sockaddrdl.sdl_index;
+
+ int hwtype = (int) sockaddrdl.sdl_type;
+ if (Enum.IsDefined (typeof (MacOsArpHardware), hwtype)) {
+ switch ((MacOsArpHardware) hwtype) {
+ case MacOsArpHardware.ETHER:
+ type = NetworkInterfaceType.Ethernet;
+ break;
+
+ case MacOsArpHardware.ATM:
+ type = NetworkInterfaceType.Atm;
+ break;
+
+ case MacOsArpHardware.SLIP:
+ type = NetworkInterfaceType.Slip;
+ break;
+
+ case MacOsArpHardware.PPP:
+ type = NetworkInterfaceType.Ppp;
+ break;
+
+ case MacOsArpHardware.LOOPBACK:
+ type = NetworkInterfaceType.Loopback;
+ macAddress = null;
+ break;
+
+ case MacOsArpHardware.FDDI:
+ type = NetworkInterfaceType.Fddi;
+ break;
+ }
+ }
+ }
+ }
+
+ MacOsNetworkInterface iface = null;
+
+ if (!interfaces.TryGetValue (name, out iface)) {
+ iface = new MacOsNetworkInterface (name);
+ interfaces.Add (name, iface);
+ }
+
+ if (!address.Equals (IPAddress.None))
+ iface.AddAddress (address);
+
+ if (macAddress != null || type == NetworkInterfaceType.Loopback)
+ iface.SetLinkLayerInfo (index, macAddress, type);
+
+ next = addr.ifa_next;
+ }
+ } finally {
+ freeifaddrs (ifap);
+ }
+
+ NetworkInterface [] result = new NetworkInterface [interfaces.Count];
+ int x = 0;
+ foreach (NetworkInterface thisInterface in interfaces.Values) {
+ result [x] = thisInterface;
+ x++;
+ }
+ return result;
+ }
+
+ MacOsNetworkInterface (string name)
+ : base (name)
+ {
+ }
+
+ public override IPInterfaceProperties GetIPProperties ()
+ {
+ if (ipproperties == null)
+ ipproperties = new MacOsIPInterfaceProperties (this, addresses);
+ return ipproperties;
+ }
+
+ public override IPv4InterfaceStatistics GetIPv4Statistics ()
+ {
+ if (ipv4stats == null)
+ ipv4stats = new MacOsIPv4InterfaceStatistics (this);
+ return ipv4stats;
+ }
+
+ public override OperationalStatus OperationalStatus {
+ get {
+ return OperationalStatus.Unknown;
+ }
+ }
+
+ public override bool SupportsMulticast {
+ get {
+ return false;
+ }
+ }
+ }
+
  class Win32NetworkInterface2 : NetworkInterface
  {
  [DllImport ("iphlpapi.dll", SetLastError = true)]

_______________________________________________
Mono-osx mailing list
Mono-osx@...
http://lists.ximian.com/mailman/listinfo/mono-osx

Re: [Mono-dev] [PATCH] Simple implementation of network interface properties for Mac OS X

by Miguel de Icaza-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello Alex,

     Thanks for this patch submission;   I am going to test the patch  
on Mac and Linux and commit your code once it is ready.

Miguel.

On May 15, 2009, at 11:14 AM, Alex Shulgin wrote:

> Alex Shulgin wrote:
>> Hi,
>> In the current version  
>> System.Net.NetworkInformation.NetworkInterface provides limited  
>> information about network interfaces on the system (their names  
>> only).
>> The attached patch adds support for NetworkInterfaceType and  
>> GetPhysicalAddress() on Mac OS.
>
> Oops, I've almost forgot about IPv6... and missed the added file  
> MacOsNetworkInterfaceMarshal.
>
> Please see the fixed patch instead.
>
> --
> Alex
>
> Index: System.dll.sources
> ===================================================================
> --- System.dll.sources (revision 133967)
> +++ System.dll.sources (working copy)
> @@ -761,6 +761,7 @@
> System.Net.NetworkInformation/IPv4InterfaceStatistics.cs
> System.Net.NetworkInformation/IPv6InterfaceProperties.cs
> System.Net.NetworkInformation/LinuxNetworkInterfaceMarshal.cs
> +System.Net.NetworkInformation/MacOsNetworkInterfaceMarshal.cs
> System.Net.NetworkInformation/
> MulticastIPAddressInformationCollection.cs
> System.Net.NetworkInformation/MulticastIPAddressInformation.cs
> System.Net.NetworkInformation/NetBiosNodeType.cs
> Index: System.Net.NetworkInformation/IPv4InterfaceStatistics.cs
> ===================================================================
> --- System.Net.NetworkInformation/IPv4InterfaceStatistics.cs
> (revision 133967)
> +++ System.Net.NetworkInformation/IPv4InterfaceStatistics.cs
> (working copy)
> @@ -201,8 +201,65 @@
> return Read ("statistics/tx_packets");
> }
> }
> + }
>
> + // dummy class
> + class MacOsIPv4InterfaceStatistics : IPv4InterfaceStatistics
> + {
> + MacOsNetworkInterface macos;
>
> + public MacOsIPv4InterfaceStatistics (MacOsNetworkInterface parent)
> + {
> + macos = parent;
> + }
> +
> + public override long BytesReceived {
> + get { return 0; }
> + }
> +
> + public override long BytesSent {
> + get { return 0; }
> + }
> +
> + public override long IncomingPacketsDiscarded {
> + get { return 0; }
> + }
> +
> + public override long IncomingPacketsWithErrors {
> + get { return 0; }
> + }
> +
> + public override long IncomingUnknownProtocolPackets {
> + get { return 0; }
> + }
> +
> + public override long NonUnicastPacketsReceived {
> + get { return 0; }
> + }
> +
> + public override long NonUnicastPacketsSent {
> + get { return 0; }
> + }
> +
> + public override long OutgoingPacketsDiscarded {
> + get { return 0; }
> + }
> +
> + public override long OutgoingPacketsWithErrors {
> + get { return 0; }
> + }
> +
> + public override long OutputQueueLength {
> + get { return 0; }
> + }
> +
> + public override long UnicastPacketsReceived {
> + get { return 0; }
> + }
> +
> + public override long UnicastPacketsSent {
> + get { return 0; }
> + }
> }
>
> }
> Index: System.Net.NetworkInformation/MacOsNetworkInterfaceMarshal.cs
> ===================================================================
> --- System.Net.NetworkInformation/MacOsNetworkInterfaceMarshal.cs
> (revision 0)
> +++ System.Net.NetworkInformation/MacOsNetworkInterfaceMarshal.cs
> (revision 0)
> @@ -0,0 +1,73 @@
> +#if NET_2_0
> +using System;
> +using System.Runtime.InteropServices;
> +
> +namespace System.Net.NetworkInformation {
> + namespace MacOsStructs {
> + internal struct ifaddrs
> + {
> + public IntPtr  ifa_next;
> + public string  ifa_name;
> + public uint    ifa_flags;
> + public IntPtr  ifa_addr;
> + public IntPtr  ifa_netmask;
> + public IntPtr  ifa_dstaddr;
> + public IntPtr  ifa_data;
> + }
> +
> + internal struct sockaddr
> + {
> + public byte  sa_len;
> + public byte  sa_family;
> + }
> +
> + internal struct sockaddr_in
> + {
> + public byte   sin_len;
> + public byte   sin_family;
> + public ushort sin_port;
> + public uint   sin_addr;
> + }
> +
> + internal struct in6_addr
> + {
> + [MarshalAs (UnmanagedType.ByValArray, SizeConst=16)]
> + public byte[] u6_addr8;
> + }
> +
> + internal struct sockaddr_in6
> + {
> + public byte     sin6_len;
> + public byte     sin6_family;
> + public ushort   sin6_port;
> + public uint     sin6_flowinfo;
> + public in6_addr sin6_addr;
> + public uint     sin6_scope_id;
> + }
> +
> + internal struct sockaddr_dl
> + {
> + public byte   sdl_len;
> + public byte   sdl_family;
> + public ushort sdl_index;
> + public byte   sdl_type;
> + public byte   sdl_nlen;
> + public byte   sdl_alen;
> + public byte   sdl_slen;
> +
> + [MarshalAs (UnmanagedType.ByValArray, SizeConst=12)]
> + public byte[] sdl_data;
> + }
> +
> + }
> +
> + internal enum MacOsArpHardware {
> + ETHER = 0x6,
> + ATM = 0x25,
> + SLIP = 0x1c,
> + PPP = 0x17,
> + LOOPBACK = 0x18,
> + FDDI = 0xf
> + }
> +}
> +#endif
> Index: System.Net.NetworkInformation/IPv4InterfaceProperties.cs
> ===================================================================
> --- System.Net.NetworkInformation/IPv4InterfaceProperties.cs
> (revision 133967)
> +++ System.Net.NetworkInformation/IPv4InterfaceProperties.cs
> (working copy)
> @@ -46,17 +46,17 @@
> public abstract bool UsesWins { get; }
> }
>
> - sealed class LinuxIPv4InterfaceProperties : IPv4InterfaceProperties
> + abstract class UnixIPv4InterfaceProperties : IPv4InterfaceProperties
> {
> - LinuxNetworkInterface iface;
> + protected UnixNetworkInterface iface;
>
> - public LinuxIPv4InterfaceProperties (LinuxNetworkInterface iface)
> + public UnixIPv4InterfaceProperties (UnixNetworkInterface iface)
> {
> this.iface = iface;
> }
>
> public override int Index {
> - get { return LinuxNetworkInterface.IfNameToIndex (iface.Name); }
> + get { return UnixNetworkInterface.IfNameToIndex (iface.Name); }
> }
>
> // TODO: how to discover that?
> @@ -74,6 +74,18 @@
> get { return false; }
> }
>
> + public override bool UsesWins {
> + get { return false; }
> + }
> + }
> +
> + sealed class LinuxIPv4InterfaceProperties :  
> UnixIPv4InterfaceProperties
> + {
> + public LinuxIPv4InterfaceProperties (LinuxNetworkInterface iface)
> + : base (iface)
> + {
> + }
> +
> public override bool IsForwardingEnabled {
> get {
> string iface_path = "/proc/sys/net/ipv4/conf/" + iface.Name + "/
> forwarding";
> @@ -87,9 +99,10 @@
> return false;
> }
> }
> +
> public override int Mtu {
> get {
> - string iface_path = iface.IfacePath + "mtu";
> + string iface_path = (iface as LinuxNetworkInterface).IfacePath  
> + "mtu";
> int ret = 0;
>
> if (File.Exists (iface_path)) {
> @@ -105,10 +118,24 @@
>
> }
> }
> -
> - public override bool UsesWins {
> + }
> +
> + sealed class MacOsIPv4InterfaceProperties :  
> UnixIPv4InterfaceProperties
> + {
> + public MacOsIPv4InterfaceProperties (MacOsNetworkInterface iface)
> + : base (iface)
> + {
> + }
> +
> + // dummy
> + public override bool IsForwardingEnabled {
> get { return false; }
> }
> +
> + // dummy
> + public override int Mtu {
> + get { return 0; }
> + }
> }
>
> sealed class Win32IPv4InterfaceProperties : IPv4InterfaceProperties
> Index: System.Net.NetworkInformation/IPInterfaceProperties.cs
> ===================================================================
> --- System.Net.NetworkInformation/IPInterfaceProperties.cs (revision  
> 133967)
> +++ System.Net.NetworkInformation/IPInterfaceProperties.cs (working  
> copy)
> @@ -53,35 +53,26 @@
> public abstract IPAddressCollection WinsServersAddresses { get; }
> }
>
> - class LinuxIPInterfaceProperties : IPInterfaceProperties
> + abstract class UnixIPInterfaceProperties : IPInterfaceProperties
> {
> - IPv4InterfaceProperties ipv4iface_properties;
> - LinuxNetworkInterface iface;
> + protected IPv4InterfaceProperties ipv4iface_properties;
> + protected UnixNetworkInterface iface;
> List <IPAddress> addresses;
> IPAddressCollection dns_servers;
> string dns_suffix;
> DateTime last_parse;
>
> - public LinuxIPInterfaceProperties (LinuxNetworkInterface iface,  
> List <IPAddress> addresses)
> + public UnixIPInterfaceProperties (UnixNetworkInterface iface,  
> List <IPAddress> addresses)
> {
> this.iface = iface;
> this.addresses = addresses;
> }
>
> - public override IPv4InterfaceProperties GetIPv4Properties ()
> - {
> - if (ipv4iface_properties == null)
> - ipv4iface_properties = new LinuxIPv4InterfaceProperties (iface);
> -
> - return ipv4iface_properties;
> - }
> -
> public override IPv6InterfaceProperties GetIPv6Properties ()
> {
> throw new NotImplementedException ();
> }
>
> -
> static Regex ns = new Regex (@"\s*nameserver\s+(?<address>.*)");
> static Regex search = new Regex (@"\s*search\s+(?<domain>.*)");
> void ParseResolvConf ()
> @@ -234,6 +225,38 @@
> }
> }
>
> + class LinuxIPInterfaceProperties : UnixIPInterfaceProperties
> + {
> + public LinuxIPInterfaceProperties (LinuxNetworkInterface iface,  
> List <IPAddress> addresses)
> + : base (iface, addresses)
> + {
> + }
> +
> + public override IPv4InterfaceProperties GetIPv4Properties ()
> + {
> + if (ipv4iface_properties == null)
> + ipv4iface_properties = new LinuxIPv4InterfaceProperties (iface  
> as LinuxNetworkInterface);
> +
> + return ipv4iface_properties;
> + }
> + }
> +
> + class MacOsIPInterfaceProperties : UnixIPInterfaceProperties
> + {
> + public MacOsIPInterfaceProperties (MacOsNetworkInterface iface,  
> List <IPAddress> addresses)
> + : base (iface, addresses)
> + {
> + }
> +
> + public override IPv4InterfaceProperties GetIPv4Properties ()
> + {
> + if (ipv4iface_properties == null)
> + ipv4iface_properties = new MacOsIPv4InterfaceProperties (iface  
> as MacOsNetworkInterface);
> +
> + return ipv4iface_properties;
> + }
> + }
> +
> class Win32IPInterfaceProperties2 : IPInterfaceProperties
> {
> readonly Win32_IP_ADAPTER_ADDRESSES addr;
> Index: System.Net.NetworkInformation/NetworkInterface.cs
> ===================================================================
> --- System.Net.NetworkInformation/NetworkInterface.cs (revision  
> 133967)
> +++ System.Net.NetworkInformation/NetworkInterface.cs (working copy)
> @@ -42,6 +42,9 @@
>
> namespace System.Net.NetworkInformation {
> public abstract class NetworkInterface {
> + [DllImport ("libc")]
> + static extern int uname (IntPtr buf);
> +
> static Version windowsVer51 = new Version (5, 1);
> static internal readonly bool runningOnUnix =  
> (Environment.OSVersion.Platform == PlatformID.Unix);
>
> @@ -53,8 +56,20 @@
> public static NetworkInterface [] GetAllNetworkInterfaces ()
> {
> if (runningOnUnix) {
> + bool darwin = false;
> + IntPtr buf = Marshal.AllocHGlobal (8192);
> + if (uname (buf) == 0) {
> + string os = Marshal.PtrToStringAnsi (buf);
> + if (os == "Darwin")
> + darwin = true;
> + }
> + Marshal.FreeHGlobal (buf);
> +
> try {
> - return LinuxNetworkInterface.ImplGetAllNetworkInterfaces ();
> + if (darwin)
> + return MacOsNetworkInterface.ImplGetAllNetworkInterfaces ();
> + else
> + return LinuxNetworkInterface.ImplGetAllNetworkInterfaces ();
> } catch (SystemException ex) {
> throw ex;
> } catch {
> @@ -87,7 +102,7 @@
> get {
> if (runningOnUnix) {
> try {
> - return LinuxNetworkInterface.IfNameToIndex ("lo");
> + return UnixNetworkInterface.IfNameToIndex ("lo");
> } catch  {
> return 0;
> }
> @@ -111,17 +126,103 @@
> public abstract bool SupportsMulticast { get; }
> }
>
> + abstract class UnixNetworkInterface : NetworkInterface
> + {
> + [DllImport("libc")]
> + static extern int if_nametoindex(string ifname);
> +
> + protected IPv4InterfaceStatistics ipv4stats;
> + protected IPInterfaceProperties ipproperties;
> +
> + string               name;
> + int                  index;
> + protected List <IPAddress> addresses;
> + byte[]               macAddress;
> + NetworkInterfaceType type;
> +
> + internal UnixNetworkInterface (string name)
> + {
> + this.name = name;
> + addresses = new List<IPAddress> ();
> + }
> +
> + public static int IfNameToIndex (string ifname)
> + {
> + return if_nametoindex(ifname);
> + }
> +
> + internal void AddAddress (IPAddress address)
> + {
> + addresses.Add (address);
> + }
> +
> + internal void SetLinkLayerInfo (int index, byte[] macAddress,  
> NetworkInterfaceType type)
> + {
> + this.index = index;
> + this.macAddress = macAddress;
> + this.type = type;
> + }
> +
> + public override PhysicalAddress GetPhysicalAddress ()
> + {
> + if (macAddress != null)
> + return new PhysicalAddress (macAddress);
> + else
> + return PhysicalAddress.None;
> + }
> +
> + public override bool Supports (NetworkInterfaceComponent  
> networkInterfaceComponent)
> + {
> + bool wantIPv4 = networkInterfaceComponent ==  
> NetworkInterfaceComponent.IPv4;
> + bool wantIPv6 = wantIPv4 ? false : networkInterfaceComponent ==  
> NetworkInterfaceComponent.IPv6;
> +
> + foreach (IPAddress address in addresses) {
> + if (wantIPv4 && address.AddressFamily ==  
> AddressFamily.InterNetwork)
> + return true;
> + else if (wantIPv6 && address.AddressFamily ==  
> AddressFamily.InterNetworkV6)
> + return true;
> + }
> +
> + return false;
> + }
> +
> + public override string Description {
> + get { return name; }
> + }
> +
> + public override string Id {
> + get { return name; }
> + }
> +
> + public override bool IsReceiveOnly {
> + get { return false; }
> + }
> +
> + public override string Name {
> + get { return name; }
> + }
> +
> + public override NetworkInterfaceType NetworkInterfaceType {
> + get { return type; }
> + }
> +
> + [MonoTODO ("Parse dmesg?")]
> + public override long Speed {
> + get {
> + // Bits/s
> + return 1000000;
> + }
> + }
> + }
> +
> //
> // This class needs support from the libsupport.so library to fetch  
> the
> // data using arch-specific ioctls.
> //
> // For this to work, we have to create this on the factory above.
> //
> - class LinuxNetworkInterface : NetworkInterface
> + class LinuxNetworkInterface : UnixNetworkInterface
> {
> - [DllImport("libc")]
> - static extern int if_nametoindex(string ifname);
> -
> [DllImport ("libc")]
> static extern int getifaddrs (out IntPtr ifap);
>
> @@ -132,13 +233,6 @@
> const int AF_INET6  = 10;
> const int AF_PACKET = 17;
>
> - IPv4InterfaceStatistics ipv4stats;
> - IPInterfaceProperties ipproperties;
> -
> - string               name;
> - int                  index;
> - List <IPAddress>     addresses;
> - byte[]               macAddress;
> NetworkInterfaceType type;
> string               iface_path;
> string               iface_operstate_path;
> @@ -148,11 +242,6 @@
> get { return iface_path; }
> }
>
> - public static int IfNameToIndex (string ifname)
> - {
> - return if_nametoindex(ifname);
> - }
> -
> public static NetworkInterface [] ImplGetAllNetworkInterfaces ()
> {
> var interfaces = new Dictionary <string, LinuxNetworkInterface> ();
> @@ -246,8 +335,14 @@
> if (!address.Equals (IPAddress.None))
> iface.AddAddress (address);
>
> - if (macAddress != null || type == NetworkInterfaceType.Loopback)
> + if (macAddress != null || type ==  
> NetworkInterfaceType.Loopback) {
> + if (type == NetworkInterfaceType.Ethernet) {
> + if (Directory.Exists(iface.IfacePath + "wireless")) {
> + type = NetworkInterfaceType.Wireless80211;
> + }
> + }
> iface.SetLinkLayerInfo (index, macAddress, type);
> + }
>
> next = addr.ifa_next;
> }
> @@ -265,31 +360,13 @@
> }
>
> LinuxNetworkInterface (string name)
> + : base (name)
> {
> - this.name = name;
> - addresses = new List<IPAddress> ();
> iface_path = "/sys/class/net/" + name + "/";
> iface_operstate_path = iface_path + "operstate";
> iface_flags_path = iface_path + "flags";
> }
>
> - internal void AddAddress (IPAddress address)
> - {
> - addresses.Add (address);
> - }
> -
> - internal void SetLinkLayerInfo (int index, byte[] macAddress,  
> NetworkInterfaceType type)
> - {
> - this.index = index;
> - this.macAddress = macAddress;
> - if (type == NetworkInterfaceType.Ethernet) {
> - if (Directory.Exists(iface_path + "wireless")) {
> - type = NetworkInterfaceType.Wireless80211;
> - }
> - }
> - this.type = type;
> - }
> -
> public override IPInterfaceProperties GetIPProperties ()
> {
> if (ipproperties == null)
> @@ -301,53 +378,9 @@
> {
> if (ipv4stats == null)
> ipv4stats = new LinuxIPv4InterfaceStatistics (this);
> -
> return ipv4stats;
> }
>
> - public override PhysicalAddress GetPhysicalAddress ()
> - {
> - if (macAddress != null)
> - return new PhysicalAddress (macAddress);
> - else
> - return PhysicalAddress.None;
> - }
> -
> - public override bool Supports (NetworkInterfaceComponent  
> networkInterfaceComponent)
> - {
> - bool wantIPv4 = networkInterfaceComponent ==  
> NetworkInterfaceComponent.IPv4;
> - bool wantIPv6 = wantIPv4 ? false : networkInterfaceComponent ==  
> NetworkInterfaceComponent.IPv6;
> -
> - foreach (IPAddress address in addresses) {
> - if (wantIPv4 && address.AddressFamily ==  
> AddressFamily.InterNetwork)
> - return true;
> - else if (wantIPv6 && address.AddressFamily ==  
> AddressFamily.InterNetworkV6)
> - return true;
> -                        }
> -
> -                        return false;
> - }
> -
> - public override string Description {
> - get { return name; }
> - }
> -
> - public override string Id {
> - get { return name; }
> - }
> -
> - public override bool IsReceiveOnly {
> - get { return false; }
> - }
> -
> - public override string Name {
> - get { return name; }
> - }
> -
> - public override NetworkInterfaceType NetworkInterfaceType {
> - get { return type; }
> - }
> -
> public override OperationalStatus OperationalStatus {
> get {
> if (!Directory.Exists (iface_path))
> @@ -384,14 +417,6 @@
> }
> }
>
> - [MonoTODO ("Parse dmesg?")]
> - public override long Speed {
> - get {
> - // Bits/s
> - return 1000000;
> - }
> - }
> -
> public override bool SupportsMulticast {
> get {
> if (!Directory.Exists (iface_path))
> @@ -413,6 +438,143 @@
> }
> }
>
> + class MacOsNetworkInterface : UnixNetworkInterface
> + {
> + [DllImport ("libc")]
> + static extern int getifaddrs (out IntPtr ifap);
> +
> + [DllImport ("libc")]
> + static extern void freeifaddrs (IntPtr ifap);
> +
> + const int AF_INET  = 2;
> + const int AF_INET6 = 30;
> + const int AF_LINK  = 18;
> +
> + public static NetworkInterface [] ImplGetAllNetworkInterfaces ()
> + {
> + var interfaces = new Dictionary <string, MacOsNetworkInterface>  
> ();
> + IntPtr ifap;
> + if (getifaddrs (out ifap) != 0)
> + throw new SystemException ("getifaddrs() failed");
> +
> + try {
> + IntPtr next = ifap;
> + while (next != IntPtr.Zero) {
> + MacOsStructs.ifaddrs addr = (MacOsStructs.ifaddrs)  
> Marshal.PtrToStructure (next, typeof (MacOsStructs.ifaddrs));
> + IPAddress address = IPAddress.None;
> + string    name = addr.ifa_name;
> + int       index = -1;
> + byte[]    macAddress = null;
> + NetworkInterfaceType type = NetworkInterfaceType.Unknown;
> +
> + if (addr.ifa_addr != IntPtr.Zero) {
> + MacOsStructs.sockaddr sockaddr = (MacOsStructs.sockaddr)  
> Marshal.PtrToStructure (addr.ifa_addr, typeof  
> (MacOsStructs.sockaddr));
> +
> + if (sockaddr.sa_family == AF_INET6) {
> + MacOsStructs.sockaddr_in6 sockaddr6 =  
> (MacOsStructs.sockaddr_in6) Marshal.PtrToStructure (addr.ifa_addr,  
> typeof (MacOsStructs.sockaddr_in6));
> + address = new IPAddress (sockaddr6.sin6_addr.u6_addr8,  
> sockaddr6.sin6_scope_id);
> + } else if (sockaddr.sa_family == AF_INET) {
> + MacOsStructs.sockaddr_in sockaddrin =  
> (MacOsStructs.sockaddr_in) Marshal.PtrToStructure (addr.ifa_addr,  
> typeof (MacOsStructs.sockaddr_in));
> + address = new IPAddress (sockaddrin.sin_addr);
> + } else if (sockaddr.sa_family == AF_LINK) {
> + MacOsStructs.sockaddr_dl sockaddrdl =  
> (MacOsStructs.sockaddr_dl) Marshal.PtrToStructure (addr.ifa_addr,  
> typeof (MacOsStructs.sockaddr_dl));
> +
> + macAddress = new byte [(int) sockaddrdl.sdl_alen];
> + Array.Copy (sockaddrdl.sdl_data, sockaddrdl.sdl_nlen,  
> macAddress, 0, macAddress.Length);
> + index = sockaddrdl.sdl_index;
> +
> + int hwtype = (int) sockaddrdl.sdl_type;
> + if (Enum.IsDefined (typeof (MacOsArpHardware), hwtype)) {
> + switch ((MacOsArpHardware) hwtype) {
> + case MacOsArpHardware.ETHER:
> + type = NetworkInterfaceType.Ethernet;
> + break;
> +
> + case MacOsArpHardware.ATM:
> + type = NetworkInterfaceType.Atm;
> + break;
> +
> + case MacOsArpHardware.SLIP:
> + type = NetworkInterfaceType.Slip;
> + break;
> +
> + case MacOsArpHardware.PPP:
> + type = NetworkInterfaceType.Ppp;
> + break;
> +
> + case MacOsArpHardware.LOOPBACK:
> + type = NetworkInterfaceType.Loopback;
> + macAddress = null;
> + break;
> +
> + case MacOsArpHardware.FDDI:
> + type = NetworkInterfaceType.Fddi;
> + break;
> + }
> + }
> + }
> + }
> +
> + MacOsNetworkInterface iface = null;
> +
> + if (!interfaces.TryGetValue (name, out iface)) {
> + iface = new MacOsNetworkInterface (name);
> + interfaces.Add (name, iface);
> + }
> +
> + if (!address.Equals (IPAddress.None))
> + iface.AddAddress (address);
> +
> + if (macAddress != null || type == NetworkInterfaceType.Loopback)
> + iface.SetLinkLayerInfo (index, macAddress, type);
> +
> + next = addr.ifa_next;
> + }
> + } finally {
> + freeifaddrs (ifap);
> + }
> +
> + NetworkInterface [] result = new NetworkInterface  
> [interfaces.Count];
> + int x = 0;
> + foreach (NetworkInterface thisInterface in interfaces.Values) {
> + result [x] = thisInterface;
> + x++;
> + }
> + return result;
> + }
> +
> + MacOsNetworkInterface (string name)
> + : base (name)
> + {
> + }
> +
> + public override IPInterfaceProperties GetIPProperties ()
> + {
> + if (ipproperties == null)
> + ipproperties = new MacOsIPInterfaceProperties (this, addresses);
> + return ipproperties;
> + }
> +
> + public override IPv4InterfaceStatistics GetIPv4Statistics ()
> + {
> + if (ipv4stats == null)
> + ipv4stats = new MacOsIPv4InterfaceStatistics (this);
> + return ipv4stats;
> + }
> +
> + public override OperationalStatus OperationalStatus {
> + get {
> + return OperationalStatus.Unknown;
> + }
> + }
> +
> + public override bool SupportsMulticast {
> + get {
> + return false;
> + }
> + }
> + }
> +
> class Win32NetworkInterface2 : NetworkInterface
> {
> [DllImport ("iphlpapi.dll", SetLastError = true)]
> _______________________________________________
> Mono-osx mailing list
> Mono-osx@...
> http://lists.ximian.com/mailman/listinfo/mono-osx

_______________________________________________
Mono-osx mailing list
Mono-osx@...
http://lists.ximian.com/mailman/listinfo/mono-osx

Re: [Mono-dev] [PATCH] Simple implementation of network interface properties for Mac OS X

by Miguel de Icaza-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello,

     It seems that various parts of this patch could apply equally  
well to BSD-based operation systems.

     Anyone with Free/Net/Open BSD that would like to try this code out?

Miguel.
_______________________________________________
Mono-osx mailing list
Mono-osx@...
http://lists.ximian.com/mailman/listinfo/mono-osx

Re: [Mono-dev] [PATCH] Simple implementation of network interface properties for Mac OS X

by Alexander Shulgin :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Alex Shulgin wrote:

> Alex Shulgin wrote:
>> Hi,
>>
>> In the current version System.Net.NetworkInformation.NetworkInterface
>> provides limited information about network interfaces on the system
>> (their names only).
>>
>> The attached patch adds support for NetworkInterfaceType and
>> GetPhysicalAddress() on Mac OS.
>
> Oops, I've almost forgot about IPv6... and missed the added file
> MacOsNetworkInterfaceMarshal.
>
> Please see the fixed patch instead.
This worked fine, until one user reported a crash on Array.Copy in
NetworkInformation.MacOsNetworkInterface.ImplGetAllNetworkInterfaces().
  I traced this down to that I believe is a problem with non-standard
length interface name: thus the 12-byte buffer sockaddr_dl.sdl_data is
not enough.

I've noticed that sockaddr_dl contains sdl_len member which holds the
length of the whole sockaddr structure.  With that we can use
Marshal.Copy instead of Array.Copy to access data past default 12-byte
data array.  A patch against trunk is attached.

I didn't have a chance to try it with the problematic user, but still
would like someone to review the patch and comment on it.

--
Alex
PS: is there more appropriate way to increment IntPtr value w/o using
ToInt64()?

Index: System.Net.NetworkInformation/NetworkInterface.cs
===================================================================
--- System.Net.NetworkInformation/NetworkInterface.cs (revision 137150)
+++ System.Net.NetworkInformation/NetworkInterface.cs (working copy)
@@ -480,7 +480,8 @@
  MacOsStructs.sockaddr_dl sockaddrdl = (MacOsStructs.sockaddr_dl) Marshal.PtrToStructure (addr.ifa_addr, typeof (MacOsStructs.sockaddr_dl));
 
  macAddress = new byte [(int) sockaddrdl.sdl_alen];
- Array.Copy (sockaddrdl.sdl_data, sockaddrdl.sdl_nlen, macAddress, 0, macAddress.Length);
+ // copy `sdl_alen' bytes from `sdl_data + sdl_nlen'
+ Marshal.Copy ((IntPtr)(addr.ifa_addr.ToInt64 () + 8 + sockaddrdl.sdl_nlen), macAddress, 0, macAddress.Length);
  index = sockaddrdl.sdl_index;
 
  int hwtype = (int) sockaddrdl.sdl_type;

_______________________________________________
Mono-osx mailing list
Mono-osx@...
http://lists.ximian.com/mailman/listinfo/mono-osx

Re: [Mono-dev] [PATCH] Simple implementation of network interface properties for Mac OS X

by Alan McGovern-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hey,

On Tue, Jun 30, 2009 at 4:09 PM, Alex Shulgin <alexander.shulgin@...> wrote:
Alex Shulgin wrote:
Alex Shulgin wrote:
Hi,

In the current version System.Net.NetworkInformation.NetworkInterface provides limited information about network interfaces on the system (their names only).

The attached patch adds support for NetworkInterfaceType and GetPhysicalAddress() on Mac OS.

Oops, I've almost forgot about IPv6... and missed the added file MacOsNetworkInterfaceMarshal.

Please see the fixed patch instead.

This worked fine, until one user reported a crash on Array.Copy in NetworkInformation.MacOsNetworkInterface.ImplGetAllNetworkInterfaces().  I traced this down to that I believe is a problem with non-standard length interface name: thus the 12-byte buffer sockaddr_dl.sdl_data is not enough.

I've noticed that sockaddr_dl contains sdl_len member which holds the length of the whole sockaddr structure.  With that we can use Marshal.Copy instead of Array.Copy to access data past default 12-byte data array.  A patch against trunk is attached.

I didn't have a chance to try it with the problematic user, but still would like someone to review the patch and comment on it.

--
Alex
PS: is there more appropriate way to increment IntPtr value w/o using ToInt64()?

You could use a loop and Marshal.ReadByte (IntPtr ptr, int offset);

Alan.
 


_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@...
http://lists.ximian.com/mailman/listinfo/mono-devel-list



_______________________________________________
Mono-osx mailing list
Mono-osx@...
http://lists.ximian.com/mailman/listinfo/mono-osx

Re: [Mono-dev] [PATCH] Simple implementation of network interface properties for Mac OS X

by Alexander Shulgin :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Alan McGovern wrote:
> Hey,
>
[snip]
>     --
>     Alex
>     PS: is there more appropriate way to increment IntPtr value w/o
>     using ToInt64()?
>
>
> You could use a loop and Marshal.ReadByte (IntPtr ptr, int offset);

For this purpose, yes.  But what would you do if amount of data to read
is, say megabyte or more?

--
Alex

_______________________________________________
Mono-osx mailing list
Mono-osx@...
http://lists.ximian.com/mailman/listinfo/mono-osx