Imported Upstream version 6.0.0.172

Former-commit-id: f3cc9b82f3e5bd8f0fd3ebc098f789556b44e9cd
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2019-04-12 14:10:50 +00:00
parent 8016999e4d
commit 64ac736ec5
32155 changed files with 3981439 additions and 75368 deletions

View File

@@ -0,0 +1,85 @@
//
// System.Net.NetworkInformation.IPInterfaceProperties
//
// Authors:
// Gonzalo Paniagua Javier (gonzalo@novell.com)
// Atsushi Enomoto (atsushi@ximian.com)
//
// Copyright (c) 2006-2007 Novell, Inc. (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace System.Net.NetworkInformation {
class AixIPInterfaceProperties : UnixIPInterfaceProperties
{
private int _mtu;
public AixIPInterfaceProperties (AixNetworkInterface iface, List <IPAddress> addresses)
: this (iface, addresses, 0)
{
}
public AixIPInterfaceProperties (AixNetworkInterface iface, List <IPAddress> addresses, int mtu)
: base (iface, addresses)
{
_mtu = mtu;
}
public override IPv4InterfaceProperties GetIPv4Properties ()
{
if (ipv4iface_properties == null)
ipv4iface_properties = new AixIPv4InterfaceProperties (iface as AixNetworkInterface, _mtu);
return ipv4iface_properties;
}
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern static bool ParseRouteInfo_internal(string iface, out string[] gw_addr_list);
public override GatewayIPAddressInformationCollection GatewayAddresses {
get {
var gateways = new IPAddressCollection ();
string[] gw_addrlist;
if (!ParseRouteInfo_internal (this.iface.Name.ToString(), out gw_addrlist))
return new GatewayIPAddressInformationCollection ();
for(int i=0; i<gw_addrlist.Length; i++) {
try {
IPAddress ip = IPAddress.Parse(gw_addrlist[i]);
if (!ip.Equals (IPAddress.Any) && !gateways.Contains (ip))
gateways.InternalAdd (ip);
} catch (ArgumentNullException) {
/* Ignore this, as the
* internal call might have
* left some blank entries at
* the end of the array
*/
}
}
return SystemGatewayIPAddressInformation.ToGatewayIpAddressInformationCollection (gateways);
}
}
}
}

View File

@@ -0,0 +1,52 @@
//
// System.Net.NetworkInformation.IPv4InterfaceProperties
//
// Authors:
// Gonzalo Paniagua Javier (gonzalo@novell.com)
// Atsushi Enomoto (atsushi@ximian.com)
// Marek Habersack (mhabersack@novell.com)
//
// Copyright (c) 2006-2007 Novell, Inc. (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace System.Net.NetworkInformation {
sealed class AixIPv4InterfaceProperties : UnixIPv4InterfaceProperties
{
private int _mtu;
public AixIPv4InterfaceProperties (AixNetworkInterface iface, int mtu)
: base (iface)
{
_mtu = mtu;
}
// dummy
public override bool IsForwardingEnabled {
get { return false; }
}
public override int Mtu {
get { return _mtu; }
}
}
}

View File

@@ -0,0 +1,90 @@
//
// System.Net.NetworkInformation.IPv4InterfaceStatistics
//
// Authors:
// Gonzalo Paniagua Javier (gonzalo@novell.com)
// Atsushi Enomoto (atsushi@ximian.com)
// Miguel de Icaza (miguel@ximian.com)
//
// Copyright (c) 2006-2008 Novell, Inc. (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace System.Net.NetworkInformation {
// dummy class
class AixIPv4InterfaceStatistics : IPv4InterfaceStatistics
{
//AixNetworkInterface aix;
public AixIPv4InterfaceStatistics (AixNetworkInterface parent)
{
//aix = 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; }
}
}
}

View File

@@ -0,0 +1,337 @@
//
// System.Net.NetworkInformation.NetworkInterface
//
// Authors:
// Gonzalo Paniagua Javier (gonzalo@novell.com)
// Atsushi Enomoto (atsushi@ximian.com)
// Miguel de Icaza (miguel@novell.com)
// Eric Butler (eric@extremeboredom.net)
// Marek Habersack (mhabersack@novell.com)
// Marek Safar (marek.safar@gmail.com)
// Calvin Buckley (calvin@cmpct.info)
//
// Copyright (c) 2006-2008 Novell, Inc. (http://www.novell.com)
//
// Copyright (c) 2018 Calvin Buckley
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
namespace System.Net.NetworkInformation {
internal class AixNetworkInterfaceAPI : UnixNetworkInterfaceAPI
{
const int SOCK_DGRAM = 2;
// AIX doesn't have getifaddrs, (i does though) so we instead query the painful way via ioctl. For IBM's docs on this, see:
// https://www.ibm.com/support/knowledgecenter/en/ssw_aix_71/com.ibm.aix.commtrf2/ioctl_socket_control_operations.htm
[DllImport("libc", SetLastError = true)]
public static extern int socket (AixAddressFamily family, int type, int protocol);
[DllImport("libc")]
public static extern int close (int fd);
// overloads to make usage less painful
[DllImport("libc", SetLastError = true)]
public static extern int ioctl (int fd, AixIoctlRequest request, IntPtr arg);
[DllImport("libc", SetLastError = true)]
public static extern int ioctl (int fd, AixIoctlRequest request, ref int arg);
[DllImport("libc", SetLastError = true)]
public static extern int ioctl (int fd, AixIoctlRequest request, ref AixStructs.ifconf arg);
[DllImport("libc", SetLastError = true)]
public static extern int ioctl (int fd, AixIoctlRequest request, ref AixStructs.ifreq_flags arg);
[DllImport("libc", SetLastError = true)]
public static extern int ioctl (int fd, AixIoctlRequest request, ref AixStructs.ifreq_mtu arg);
[DllImport("libc", SetLastError = true)]
public static extern int ioctl (int fd, AixIoctlRequest request, ref AixStructs.ifreq_addrin arg);
static unsafe void ByteArrayCopy (byte* dst, byte* src, int elements)
{
for (int i = 0; i < 16; i++)
dst[i] = src[i];
}
public override NetworkInterface [] GetAllNetworkInterfaces ()
{
var interfaces = new Dictionary <string, AixNetworkInterface> ();
AixStructs.ifconf ifc;
ifc.ifc_len = 0;
ifc.ifc_buf = IntPtr.Zero;
int sockfd = -1;
try {
sockfd = socket (AixAddressFamily.AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1)
throw new SystemException ("socket for SIOCGIFCONF failed");
if (ioctl (sockfd, AixIoctlRequest.SIOCGSIZIFCONF, ref ifc.ifc_len) < 0 || ifc.ifc_len < 1) {
throw new SystemException ("ioctl for SIOCGSIZIFCONF failed");
}
ifc.ifc_buf = Marshal.AllocHGlobal(ifc.ifc_len);
if (ioctl (sockfd, AixIoctlRequest.SIOCGIFCONF, ref ifc) < 0)
throw new SystemException ("ioctl for SIOCGIFCONF failed");
// this is required because the buffer is an array of VARIABLE LENGTH structures, so sane marshalling is impossible
AixStructs.ifreq ifr;
var curPos = ifc.ifc_buf;
var endPos = ifc.ifc_buf.ToInt64() + ifc.ifc_len;
for (ifr = (AixStructs.ifreq)Marshal.PtrToStructure (curPos, typeof (AixStructs.ifreq));
curPos.ToInt64() < endPos;
// name length + sockaddr length (SIOCGIFCONF only deals in those)
curPos = curPos + (16 + ifr.ifru_addr.sa_len))
{
// update the structure for next increment
ifr = (AixStructs.ifreq)Marshal.PtrToStructure (curPos, typeof (AixStructs.ifreq));
// the goods
IPAddress address = IPAddress.None;
string name = null;
int index = -1;
byte[] macAddress = null;
var type = NetworkInterfaceType.Unknown;
unsafe {
name = Marshal.PtrToStringAnsi(new IntPtr(ifr.ifr_name));
}
if (Enum.IsDefined (typeof (AixAddressFamily), (int)ifr.ifru_addr.sa_family)) {
switch ((AixAddressFamily)ifr.ifru_addr.sa_family) {
case AixAddressFamily.AF_INET:
AixStructs.sockaddr_in sockaddrin =
(AixStructs.sockaddr_in)Marshal.PtrToStructure(curPos + 16, typeof (AixStructs.sockaddr_in));
address = new IPAddress (sockaddrin.sin_addr);
break;
case AixAddressFamily.AF_INET6:
AixStructs.sockaddr_in6 sockaddr6 =
(AixStructs.sockaddr_in6) Marshal.PtrToStructure(curPos + 16, typeof (AixStructs.sockaddr_in6));
address = new IPAddress (sockaddr6.sin6_addr.u6_addr8, sockaddr6.sin6_scope_id);
break;
// XXX: i never returns AF_LINK and SIOCGIFCONF under i doesn't return nameindex values; adapt MacOsNetworkInterface for Qp2getifaddrs instead
case AixAddressFamily.AF_LINK:
AixStructs.sockaddr_dl sockaddrdl = new AixStructs.sockaddr_dl();
sockaddrdl.Read (curPos + 16);
macAddress = new byte [(int) sockaddrdl.sdl_alen];
// copy mac address from sdl_data field starting at last index pos of interface name into array macaddress, starting
// at index 0
Array.Copy (sockaddrdl.sdl_data, sockaddrdl.sdl_nlen, macAddress, 0, Math.Min (macAddress.Length, sockaddrdl.sdl_data.Length - sockaddrdl.sdl_nlen));
index = sockaddrdl.sdl_index;
int hwtype = (int) sockaddrdl.sdl_type;
if (Enum.IsDefined (typeof (AixArpHardware), hwtype)) {
switch ((AixArpHardware) hwtype) {
case AixArpHardware.ETHER:
type = NetworkInterfaceType.Ethernet;
break;
case AixArpHardware.ATM:
type = NetworkInterfaceType.Atm;
break;
case AixArpHardware.SLIP:
type = NetworkInterfaceType.Slip;
break;
case AixArpHardware.PPP:
type = NetworkInterfaceType.Ppp;
break;
case AixArpHardware.LOOPBACK:
type = NetworkInterfaceType.Loopback;
macAddress = null;
break;
case AixArpHardware.FDDI:
type = NetworkInterfaceType.Fddi;
break;
}
}
break;
default: break;
}
}
// get flags
uint flags = 0;
int mtu = 0;
unsafe {
AixStructs.ifreq_flags ifrFlags = new AixStructs.ifreq_flags ();
ByteArrayCopy (ifrFlags.ifr_name, ifr.ifr_name, 16);
if (ioctl (sockfd, AixIoctlRequest.SIOCGIFFLAGS, ref ifrFlags) < 0)
throw new SystemException("ioctl for SIOCGIFFLAGS failed");
else
flags = ifrFlags.ifru_flags;
AixStructs.ifreq_mtu ifrMtu = new AixStructs.ifreq_mtu ();
ByteArrayCopy (ifrMtu.ifr_name, ifr.ifr_name, 16);
if (ioctl (sockfd, AixIoctlRequest.SIOCGIFMTU, ref ifrMtu) < 0) {
// it's not the end of the world if we don't get it
}
else
mtu = ifrMtu.ifru_mtu;
}
AixNetworkInterface iface = null;
// create interface if not already present
if (!interfaces.TryGetValue (name, out iface)) {
iface = new AixNetworkInterface (name, flags, mtu);
interfaces.Add (name, iface);
}
// if a new address has been found, add it
if (!address.Equals (IPAddress.None))
iface.AddAddress (address);
// set link layer info, if iface has macaddress or is loopback device
if (macAddress != null || type == NetworkInterfaceType.Loopback)
iface.SetLinkLayerInfo (index, macAddress, type);
}
} finally {
if (ifc.ifc_buf != IntPtr.Zero)
Marshal.FreeHGlobal(ifc.ifc_buf);
if (sockfd != -1)
close (sockfd);
}
NetworkInterface [] result = new NetworkInterface [interfaces.Count];
int x = 0;
foreach (NetworkInterface thisInterface in interfaces.Values) {
result [x] = thisInterface;
x++;
}
return result;
}
public override int GetLoopbackInterfaceIndex ()
{
// XXX: "*LOOPBACK" on i
return if_nametoindex ("lo0");
}
public override IPAddress GetNetMask (IPAddress address)
{
AixStructs.ifconf ifc;
ifc.ifc_len = 0;
ifc.ifc_buf = IntPtr.Zero;
int sockfd = -1;
try {
sockfd = socket (AixAddressFamily.AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1)
throw new SystemException ("socket for SIOCGIFCONF failed");
if (ioctl (sockfd, AixIoctlRequest.SIOCGSIZIFCONF, ref ifc.ifc_len) < 0 || ifc.ifc_len < 1)
throw new SystemException ("ioctl for SIOCGSIZIFCONF failed");
ifc.ifc_buf = Marshal.AllocHGlobal(ifc.ifc_len);
if (ioctl (sockfd, AixIoctlRequest.SIOCGIFCONF, ref ifc) < 0)
throw new SystemException ("ioctl for SIOCGIFCONF failed");
// this is required because the buffer is an array of VARIABLE LENGTH structures, so sane marshalling is impossible
AixStructs.ifreq ifr;
var curPos = ifc.ifc_buf;
var endPos = ifc.ifc_buf.ToInt64() + ifc.ifc_len;
for (ifr = (AixStructs.ifreq)Marshal.PtrToStructure (curPos, typeof (AixStructs.ifreq));
curPos.ToInt64() < endPos;
// name length + sockaddr length (SIOCGIFCONF only deals in those)
curPos += (16 + ifr.ifru_addr.sa_len))
{
// update the structure for next increment
ifr = (AixStructs.ifreq)Marshal.PtrToStructure (curPos, typeof (AixStructs.ifreq));
if (Enum.IsDefined (typeof (AixAddressFamily), (int)ifr.ifru_addr.sa_family)) {
switch ((AixAddressFamily)ifr.ifru_addr.sa_family) {
case AixAddressFamily.AF_INET:
AixStructs.sockaddr_in sockaddrin =
(AixStructs.sockaddr_in)Marshal.PtrToStructure(curPos + 16, typeof (AixStructs.sockaddr_in));
var saddress = new IPAddress (sockaddrin.sin_addr);
if (address.Equals (saddress)) {
AixStructs.ifreq_addrin ifrMask = new AixStructs.ifreq_addrin ();
unsafe {
ByteArrayCopy (ifrMask.ifr_name, ifr.ifr_name, 16);
}
// there's an IPv6 version of it too, but Mac OS doesn't try this, so
if (ioctl (sockfd, AixIoctlRequest.SIOCGIFNETMASK, ref ifrMask) < 0)
return new IPAddress(ifrMask.ifru_addr.sin_addr);
else
throw new SystemException("ioctl for SIOCGIFNETMASK failed");
}
break;
default: break;
}
}
}
} finally {
if (ifc.ifc_buf != IntPtr.Zero)
Marshal.FreeHGlobal(ifc.ifc_buf);
if (sockfd != -1)
close (sockfd);
}
return null;
}
}
sealed class AixNetworkInterface : UnixNetworkInterface
{
private uint _ifa_flags;
private int _ifru_mtu;
internal AixNetworkInterface (string name, uint ifa_flags, int ifru_mtu)
: base (name)
{
_ifa_flags = ifa_flags;
_ifru_mtu = ifru_mtu;
}
public override IPInterfaceProperties GetIPProperties ()
{
if (ipproperties == null)
ipproperties = new AixIPInterfaceProperties (this, addresses, _ifru_mtu);
return ipproperties;
}
public override IPv4InterfaceStatistics GetIPv4Statistics ()
{
if (ipv4stats == null)
ipv4stats = new AixIPv4InterfaceStatistics (this);
return ipv4stats;
}
public override OperationalStatus OperationalStatus {
get {
if(((AixInterfaceFlags)_ifa_flags & AixInterfaceFlags.IFF_UP) == AixInterfaceFlags.IFF_UP){
return OperationalStatus.Up;
}
return OperationalStatus.Unknown;
}
}
public override bool SupportsMulticast {
get {
return ((AixInterfaceFlags)_ifa_flags & AixInterfaceFlags.IFF_MULTICAST) == AixInterfaceFlags.IFF_MULTICAST;
}
}
}
}

View File

@@ -0,0 +1,166 @@
using System.Runtime.InteropServices;
namespace System.Net.NetworkInformation {
namespace AixStructs {
//[StructLayout(LayoutKind.Sequential)]
[StructLayout(LayoutKind.Explicit, Size = 16)]
internal struct ifconf
{
[FieldOffset (0)]
public int ifc_len; /* size of buffer */
[FieldOffset (8)]
public IntPtr ifc_buf; /* buffer address/array of structures returned */
}
// approximate the union members after the name with different structs
[StructLayout (LayoutKind.Explicit, CharSet=CharSet.Ansi, Size=18)]
internal unsafe struct ifreq
{
// it must be a byte array; a char array seems to want to be 2 bytes per element,
// and a ByVal string doesn't want to seem to marshal properly for being written to
[FieldOffset (0)]
public fixed byte ifr_name [16];
// you must peer into the family and length, then use ptr arith to get the rest
[FieldOffset (16)]
public sockaddr ifru_addr;
}
[StructLayout (LayoutKind.Explicit, CharSet=CharSet.Ansi, Size=24)]
internal unsafe struct ifreq_addrin
{
[FieldOffset (0)]
public fixed byte ifr_name [16];
[FieldOffset (16)]
public sockaddr_in ifru_addr;
}
// For SIOCGIFFLAGS
[StructLayout (LayoutKind.Explicit, CharSet=CharSet.Ansi, Size=20)]
internal unsafe struct ifreq_flags
{
[FieldOffset (0)]
public fixed byte ifr_name [16];
[FieldOffset (16)]
public uint ifru_flags;
}
// For SIOCGIFMTU
[StructLayout (LayoutKind.Explicit, CharSet=CharSet.Ansi, Size=20)]
internal unsafe struct ifreq_mtu
{
[FieldOffset (0)]
public fixed byte ifr_name [16];
[FieldOffset (16)]
public int ifru_mtu;
}
// the rest copied from Mac OS defs
[StructLayout(LayoutKind.Sequential)]
internal struct sockaddr
{
public byte sa_len;
public byte sa_family;
}
[StructLayout(LayoutKind.Sequential)]
internal struct sockaddr_in
{
public byte sin_len;
public byte sin_family;
public ushort sin_port;
public uint sin_addr;
}
[StructLayout(LayoutKind.Sequential)]
internal struct in6_addr
{
[MarshalAs (UnmanagedType.ByValArray, SizeConst=16)]
public byte[] u6_addr8;
}
[StructLayout(LayoutKind.Sequential)]
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;
}
[StructLayout(LayoutKind.Sequential)]
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;
public byte[] sdl_data;
internal void Read (IntPtr ptr)
{
sdl_len = Marshal.ReadByte (ptr, 0);
sdl_family = Marshal.ReadByte (ptr, 1);
sdl_index = (ushort) Marshal.ReadInt16 (ptr, 2);
sdl_type = Marshal.ReadByte (ptr, 4);
sdl_nlen = Marshal.ReadByte (ptr, 5);
sdl_alen = Marshal.ReadByte (ptr, 6);
sdl_slen = Marshal.ReadByte (ptr, 7);
sdl_data = new byte [Math.Max (12, sdl_len - 8)];
Marshal.Copy (new IntPtr (ptr.ToInt64 () + 8), sdl_data, 0, sdl_data.Length);
}
}
}
// see: net/if_types.h
internal enum AixArpHardware {
ETHER = 0x6,
ATM = 0x25,
SLIP = 0x1c,
PPP = 0x17,
LOOPBACK = 0x18,
FDDI = 0xf
}
// see: net/if.h
internal enum AixInterfaceFlags {
IFF_UP = 0x1, /* interface is up */
IFF_BROADCAST = 0x2, /* broadcast address valid */
IFF_DEBUG = 0x4, /* turn on debugging */
IFF_LOOPBACK = 0x8, /* is a loopback net */
IFF_POINTOPOINT = 0x10, /* interface is point-to-point link */
IFF_NOTRAILERS = 0x20, /* avoid use of trailers */
IFF_RUNNING = 0x40, /* resources allocated */
IFF_NOARP = 0x80, /* no address resolution protocol */
IFF_PROMISC = 0x100, /* receive all packets */
IFF_ALLMULTI = 0x200, /* receive all multicast packets */
IFF_OACTIVE = 0x400, /* transmission in progress */
IFF_SIMPLEX = 0x800, /* can't hear own transmissions */
IFF_LINK0 = 0x100000, /* per link layer defined bit */
IFF_LINK1 = 0x200000, /* per link layer defined bit */
IFF_LINK2 = 0x400000, /* per link layer defined bit */
IFF_MULTICAST = 0x8000000 /* supports multicast */
}
// Address families that matter to us
internal enum AixAddressFamily {
AF_INET = 2,
AF_INET6 = 24,
AF_LINK = 18,
}
// ioctl commands that matter to us
internal enum AixIoctlRequest : uint {
SIOCGSIZIFCONF = 0x4004696a, /* get the buffer size for SIOCGIFCONF */
SIOCGIFCONF = 0xc0106945, /* list network interfaces */
SIOCGIFFLAGS = 0xc0286911, /* get interface flags */
SIOCGIFNETMASK = 0xc0286925, /* get netmask for iface */
SIOCGIFMTU = 0xc0286956, /* get mtu for iface */
}
}

View File

@@ -280,6 +280,38 @@ namespace System.Net.NetworkInformation {
}
}
static TcpState UnixTcpStateToTcpState (int unixState)
{
//The values of these states in Linux are listed here:
//https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/net/tcp_states.h?id=HEAD
switch (unixState) {
case 1:
return TcpState.Established;
case 2:
return TcpState.SynSent;
case 3:
return TcpState.SynReceived;
case 4:
return TcpState.FinWait1;
case 5:
return TcpState.FinWait2;
case 6:
return TcpState.TimeWait;
case 7:
return TcpState.Closed;
case 8:
return TcpState.CloseWait;
case 9:
return TcpState.LastAck;
case 10:
return TcpState.Listen;
case 11:
return TcpState.Closing;
default:
return TcpState.Unknown;
}
}
public override TcpConnectionInformation [] GetActiveTcpConnections ()
{
List<string []> list = new List<string []> ();
@@ -291,7 +323,7 @@ namespace System.Net.NetworkInformation {
// sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
IPEndPoint local = ToEndpoint (list [i] [1]);
IPEndPoint remote = ToEndpoint (list [i] [2]);
TcpState state = (TcpState) int.Parse (list [i] [3], NumberStyles.HexNumber);
TcpState state = UnixTcpStateToTcpState (int.Parse (list [i] [3], NumberStyles.HexNumber));
ret [i] = new SystemTcpConnectionInformation (local, remote, state);
}
return ret;

View File

@@ -41,9 +41,15 @@ namespace System.Net.NetworkInformation {
bool runningOnUnix = (Environment.OSVersion.Platform == PlatformID.Unix);
if (runningOnUnix) {
// XXX: OpenBSD and NetBSD too? It seems other platforms map closer to the Mac OS version than Linux,
// even if not exactly; it seems Linux and/or glibc are the different ones.
if (Platform.IsMacOS || Platform.IsFreeBSD)
return new MacOsNetworkInterfaceAPI ();
// XXX: IBM i would be better with its own API targetting Qp2getifaddrs
if (Platform.IsAix || Platform.IsIBMi)
return new AixNetworkInterfaceAPI ();
return new LinuxNetworkInterfaceAPI ();
}