コード例 #1
0
        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);
        }
コード例 #2
0
 public static extern int ioctl(int fd, AixIoctlRequest request, ref AixStructs.ifreq_flags arg);