Module: kamailio Branch: master Commit: ce1138d2d8962296de2867d5751abf770b035da3 URL: https://github.com/kamailio/kamailio/commit/ce1138d2d8962296de2867d5751abf77...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Daniel-Constantin Mierla miconda@gmail.com Date: 2019-04-22T20:20:18+02:00
core: helper function to get scope id for ipv6 network interface
---
Modified: src/core/socket_info.c Modified: src/core/socket_info.h
---
Diff: https://github.com/kamailio/kamailio/commit/ce1138d2d8962296de2867d5751abf77... Patch: https://github.com/kamailio/kamailio/commit/ce1138d2d8962296de2867d5751abf77...
---
diff --git a/src/core/socket_info.c b/src/core/socket_info.c index 1f2850a67b..c77e4b8227 100644 --- a/src/core/socket_info.c +++ b/src/core/socket_info.c @@ -42,6 +42,7 @@ #include <sys/ioctl.h> #include <net/if.h> #include <ifaddrs.h> +#include <netdb.h> #ifdef HAVE_SYS_SOCKIO_H #include <sys/sockio.h> #endif @@ -100,6 +101,54 @@ #define addr_info_listins sock_listins #define addr_info_listrm sock_listrm
+/** + * return the scope for IPv6 interface matching the ipval parameter + * - needed for binding to link local IPv6 addresses + */ +unsigned int ipv6_get_netif_scope(const char *ipval) +{ + struct ifaddrs *netiflist = NULL; + struct ifaddrs *netif = NULL; + char ipaddr[NI_MAXHOST]; + unsigned int iscope = 0; + int i = 0; + int r = 0; + + /* walk over the list of all network interface addresses */ + if(getifaddrs(&netiflist)!=0) { + LM_ERR("failed to get network interfaces - errno: %d\n", errno); + return 0; + } + for(netif = netiflist; netif; netif = netif->ifa_next) { + /* only active and ipv6 */ + if (netif->ifa_addr && (netif->ifa_flags & IFF_UP) + && netif->ifa_addr->sa_family==AF_INET6) { + r = getnameinfo(netif->ifa_addr, sizeof(struct sockaddr_in6), + ipaddr, sizeof(ipaddr), NULL, 0, NI_NUMERICHOST); + if(r!=0) { + LM_ERR("failed to get the name info - ret: %d\n", r); + goto done; + } + /* strip the interface name after */ + for(i=0; ipaddr[i]; i++) { + if(ipaddr[i]=='%') { + ipaddr[i]='\0'; + break; + } + } + /* if the ips matche, get scope index from interface name */ + if(strcmp(ipaddr, ipval)==0){ + iscope=if_nametoindex(netif->ifa_name); + goto done; + } + } + } + +done: + freeifaddrs(netiflist); + return iscope; +} + inline static void addr_info_list_ins_lst(struct addr_info* lst, struct addr_info* after) { diff --git a/src/core/socket_info.h b/src/core/socket_info.h index abc6a150aa..e8c684407c 100644 --- a/src/core/socket_info.h +++ b/src/core/socket_info.h @@ -151,4 +151,6 @@ typedef struct _sr_phostp { struct socket_info* lookup_local_socket(str *phostp); int parse_protohostport(str* ins, sr_phostp_t *r);
+unsigned int ipv6_get_netif_scope(const char *ipval); + #endif