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