diff --git a/src/common/netif/netif_haiku.c b/src/common/netif/netif_haiku.c index 914db83e2..06f8e90b6 100644 --- a/src/common/netif/netif_haiku.c +++ b/src/common/netif/netif_haiku.c @@ -41,9 +41,11 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) while (interface < end) { if (interface->ifr_route.flags & RTF_DEFAULT) { + // interface->ifr_metric? strlcpy(result->ifName, interface->ifr_name, IF_NAMESIZE); result->ifIndex = if_nametoindex(interface->ifr_name); - // TODO: Get the preferred source address + if (interface->ifr_route.source) + result->preferredSourceAddrV4 = ((struct sockaddr_in*)interface->ifr_route.source)->sin_addr.s_addr; return true; } @@ -55,8 +57,7 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) if (interface->ifr_route.gateway != NULL) addressSize += interface->ifr_route.gateway->sa_len; - interface = (struct ifreq*)((addr_t)interface + IF_NAMESIZE - + sizeof(struct route_entry) + addressSize); + interface = (struct ifreq*)((addr_t)interface + IF_NAMESIZE + sizeof(struct route_entry) + addressSize); } return false; @@ -64,6 +65,48 @@ bool ffNetifGetDefaultRouteImplV4(FFNetifDefaultRouteResult* result) bool ffNetifGetDefaultRouteImplV6(FFNetifDefaultRouteResult* result) { - // TODO: AF_INET6 + FF_AUTO_CLOSE_FD int pfRoute = socket(AF_INET, SOCK_RAW, AF_INET6); + if (pfRoute < 0) + return false; + + struct ifconf config; + config.ifc_len = sizeof(config.ifc_value); + if (ioctl(pfRoute, SIOCGRTSIZE, &config, sizeof(struct ifconf)) < 0) + return false; + + int size = config.ifc_value; + if (size <= 0) + return false; + + FF_AUTO_FREE void *buffer = malloc((size_t) size); + if (buffer == NULL) { + return false; + } + + config.ifc_len = size; + config.ifc_buf = buffer; + if (ioctl(pfRoute, SIOCGRTTABLE, &config, sizeof(struct ifconf)) < 0) + return false; + + struct ifreq *interface = (struct ifreq*)buffer; + struct ifreq *end = (struct ifreq*)((uint8_t*)buffer + size); + + while (interface < end) { + if (interface->ifr_route.flags & RTF_DEFAULT) { + strlcpy(result->ifName, interface->ifr_name, IF_NAMESIZE); + result->ifIndex = if_nametoindex(interface->ifr_name); + return true; + } + + size_t addressSize = 0; + if (interface->ifr_route.destination != NULL) + addressSize += interface->ifr_route.destination->sa_len; + if (interface->ifr_route.mask != NULL) + addressSize += interface->ifr_route.mask->sa_len; + if (interface->ifr_route.gateway != NULL) + addressSize += interface->ifr_route.gateway->sa_len; + + interface = (struct ifreq*)((addr_t)interface + IF_NAMESIZE + sizeof(struct route_entry) + addressSize); + } return false; }