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 static extern int ioctl(int fd, AixIoctlRequest request, ref AixStructs.ifreq_flags arg);