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