void mono_address_init (MonoAddress *out_addr, int family, void *in_addr) { memset (out_addr, 0, sizeof (MonoAddress)); out_addr->family = family; memcpy (&out_addr->addr, in_addr, mono_address_size_for_family (family)); }
void * mono_get_local_interfaces (int family, int *interface_count) { struct ifaddrs *ifap = NULL, *cur; int if_count = 0; gboolean ignore_loopback = FALSE; void *result; char *result_ptr; *interface_count = 0; if (!mono_address_size_for_family (family)) return NULL; if (getifaddrs (&ifap)) return NULL; for (cur = ifap; cur; cur = cur->ifa_next) { //ignore interfaces with no address assigned if (!cur->ifa_addr) continue; //ignore interfaces that don't belong to @family if (cur->ifa_addr->sa_family != family) continue; //ignore interfaces that are down if ((cur->ifa_flags & IFF_UP) == 0) continue; //If we have a non-loopback iface, don't return any loopback if ((cur->ifa_flags & IFF_LOOPBACK) == 0) ignore_loopback = TRUE; if_count++; } result_ptr = result = g_malloc (if_count * mono_address_size_for_family (family)); for (cur = ifap; cur; cur = cur->ifa_next) { if (!cur->ifa_addr) continue; if (cur->ifa_addr->sa_family != family) continue; if ((cur->ifa_flags & IFF_UP) == 0) continue; //we decrement if_count because it did not on the previous loop. if (ignore_loopback && (cur->ifa_flags & IFF_LOOPBACK)) { --if_count; continue; } memcpy (result_ptr, get_address_from_sockaddr (cur->ifa_addr), mono_address_size_for_family (family)); result_ptr += mono_address_size_for_family (family); } g_assert (result_ptr <= (char*)result + if_count * mono_address_size_for_family (family)); freeifaddrs (ifap); *interface_count = if_count; return result; }
void * mono_get_local_interfaces (int family, int *interface_count) { int fd; struct ifconf ifc; struct ifreq *ifr; int if_count = 0; gboolean ignore_loopback = FALSE; void *result = NULL; char *result_ptr; *interface_count = 0; if (!mono_address_size_for_family (family)) return NULL; fd = socket (family, SOCK_STREAM, 0); if (fd == -1) return NULL; memset (&ifc, 0, sizeof (ifc)); ifc.ifc_len = IFCONF_BUFF_SIZE; ifc.ifc_buf = (char *)g_malloc (IFCONF_BUFF_SIZE); /* We can't have such huge buffers on the stack. */ if (ioctl (fd, SIOCGIFCONF, &ifc) < 0) goto done; FOREACH_IFR (ifr, ifc) { struct ifreq iflags; //only return addresses of the same type as @family if (ifr->ifr_addr.sa_family != family) { ifr->ifr_name [0] = '\0'; continue; } strcpy (iflags.ifr_name, ifr->ifr_name); //ignore interfaces we can't get props for if (ioctl (fd, SIOCGIFFLAGS, &iflags) < 0) { ifr->ifr_name [0] = '\0'; continue; } //ignore interfaces that are down if ((iflags.ifr_flags & IFF_UP) == 0) { ifr->ifr_name [0] = '\0'; continue; } //If we have a non-loopback iface, don't return any loopback if ((iflags.ifr_flags & IFF_LOOPBACK) == 0) { ignore_loopback = TRUE; ifr->ifr_name [0] = 1;//1 means non-loopback } else { ifr->ifr_name [0] = 2; //2 means loopback } ++if_count; } result = (char *)g_malloc (if_count * mono_address_size_for_family (family)); result_ptr = (char *)result; FOREACH_IFR (ifr, ifc) { if (ifr->ifr_name [0] == '\0') continue; if (ignore_loopback && ifr->ifr_name [0] == 2) { --if_count; continue; } memcpy (result_ptr, get_address_from_sockaddr (&ifr->ifr_addr), mono_address_size_for_family (family)); result_ptr += mono_address_size_for_family (family); } g_assert (result_ptr <= (char*)result + if_count * mono_address_size_for_family (family)); done: *interface_count = if_count; g_free (ifc.ifc_buf); close (fd); return result; }