From 788a39e40b42bd070afa3e12a4cee4c137db2037 Mon Sep 17 00:00:00 2001 From: cyrus Date: Thu, 10 Apr 2014 09:50:11 +0000 Subject: [PATCH] mdnsresponder: several Linux-related fixes (thanks Markus Stenberg) git-svn-id: svn://svn.openwrt.org/openwrt/packages@40441 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- net/mdnsresponder/Makefile | 6 +- net/mdnsresponder/files/mdnsd.hotplug | 5 - net/mdnsresponder/patches/002-newer-bison.patch | 29 -- ...v6-sockets-to-interface-due-to-link-local.patch | 32 -- net/mdnsresponder/patches/100-linux_fixes.patch | 562 +++++++++++++++++++++ 5 files changed, 566 insertions(+), 68 deletions(-) delete mode 100644 net/mdnsresponder/files/mdnsd.hotplug delete mode 100644 net/mdnsresponder/patches/002-newer-bison.patch delete mode 100644 net/mdnsresponder/patches/100-Binding-IPv6-sockets-to-interface-due-to-link-local.patch create mode 100644 net/mdnsresponder/patches/100-linux_fixes.patch diff --git a/net/mdnsresponder/Makefile b/net/mdnsresponder/Makefile index 331308e97..e3f91e2d7 100644 --- a/net/mdnsresponder/Makefile +++ b/net/mdnsresponder/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=mDNSResponder PKG_VERSION:=544 -PKG_RELEASE:=3 +PKG_RELEASE:=4 PKG_SOURCE:=mDNSResponder-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=http://opensource.apple.com/tarballs/mDNSResponder/ @@ -22,6 +22,9 @@ PKG_INSTALL:=1 include $(INCLUDE_DIR)/package.mk +# sys/capability.h is not part of *libc* +PKG_BUILD_DEPENDS:=libcap + define Package/mDNSResponder/Default SECTION:=net CATEGORY:=Network @@ -146,7 +149,6 @@ define Package/mdnsd/install $(INSTALL_DIR) $(1)/usr/sbin/ $(CP) $(PKG_INSTALL_DIR)/usr/sbin/mdnsd $(1)/usr/sbin/ $(INSTALL_DIR) $(1)/etc/hotplug.d/iface - $(INSTALL_DATA) ./files/mdnsd.hotplug $(1)/etc/hotplug.d/iface $(INSTALL_DIR) $(1)/etc/init.d $(INSTALL_BIN) ./files/mdnsd.init $(1)/etc/init.d/mdnsd $(INSTALL_DIR) $(1)/usr/lib/ diff --git a/net/mdnsresponder/files/mdnsd.hotplug b/net/mdnsresponder/files/mdnsd.hotplug deleted file mode 100644 index c4e850c53..000000000 --- a/net/mdnsresponder/files/mdnsd.hotplug +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -/etc/init.d/mdnsd enabled || exit 0 -[ "$ACTION" = ifupdate -a -z "$IFUPDATE_ADDRESSES" ] && exit 0 -logger -t mdnsd "Restarting mdnsd due to $ACTION of $INTERFACE ($DEVICE)" -/etc/init.d/mdnsd restart diff --git a/net/mdnsresponder/patches/002-newer-bison.patch b/net/mdnsresponder/patches/002-newer-bison.patch deleted file mode 100644 index b996aff6f..000000000 --- a/net/mdnsresponder/patches/002-newer-bison.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- a/mDNSShared/dnsextd_parser.y -+++ b/mDNSShared/dnsextd_parser.y -@@ -15,6 +15,8 @@ - * limitations under the License. - */ - -+%parse-param { void *context } -+ - %{ - #include - #include -@@ -23,7 +25,7 @@ - #include "DebugServices.h" - #include "dnsextd.h" - --void yyerror( const char* error ); -+void yyerror( void *context, const char* error ); - int yylex(void); - - -@@ -378,7 +380,7 @@ int yywrap(void); - - extern int yylineno; - --void yyerror( const char *str ) -+void yyerror( void *context, const char *str ) - { - fprintf( stderr,"%s:%d: error: %s\n", g_filename, yylineno, str ); - } diff --git a/net/mdnsresponder/patches/100-Binding-IPv6-sockets-to-interface-due-to-link-local.patch b/net/mdnsresponder/patches/100-Binding-IPv6-sockets-to-interface-due-to-link-local.patch deleted file mode 100644 index ebac1116f..000000000 --- a/net/mdnsresponder/patches/100-Binding-IPv6-sockets-to-interface-due-to-link-local.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 094714725481da5cfbeaa9e4c713633f3fd0dcc4 Mon Sep 17 00:00:00 2001 -From: Markus Stenberg -Date: Wed, 19 Feb 2014 19:21:40 +0200 -Subject: mdnsresponder: [PATCH] Binding IPv6 sockets to interface - -Due to link-local addresses, otherwise responses may wind up in wrong -places and mdnsd is quite confused. - ---- - .../patches/003-ipv6-bind-to-interface.patch | 22 ++++++++++++++++++++ - 1 file changed, 22 insertions(+) - ---- mDNSResponder-544.source/mDNSPosix/mDNSPosix.c 2013-12-14 22:54:24.000000000 +0200 -+++ mDNSResponder-544/mDNSPosix/mDNSPosix.c 2014-02-19 18:59:55.000000000 +0200 -@@ -784,6 +784,17 @@ - if (err < 0) { err = errno; perror("setsockopt - IPV6_MULTICAST_HOPS"); } - } - -+#ifdef __linux__ -+#ifdef SO_BINDTODEVICE -+ if (err == 0) -+ { -+ char ifname[IFNAMSIZ]; -+ if (if_indextoname(interfaceIndex, ifname)) -+ err = setsockopt(*sktPtr, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname)); -+ } -+#endif /* SO_BINDTODEVICE */ -+#endif /* __linux__ */ -+ - // And start listening for packets - if (err == 0) - { diff --git a/net/mdnsresponder/patches/100-linux_fixes.patch b/net/mdnsresponder/patches/100-linux_fixes.patch new file mode 100644 index 000000000..851dd31df --- /dev/null +++ b/net/mdnsresponder/patches/100-linux_fixes.patch @@ -0,0 +1,562 @@ +diff --git a/.gitignore b/.gitignore +new file mode 100644 +index 0000000..920cdfc +--- /dev/null ++++ b/.gitignore +@@ -0,0 +1,4 @@ ++Clients/build ++mDNSPosix/build ++mDNSPosix/objects ++ +diff --git a/mDNSPosix/PosixDaemon.c b/mDNSPosix/PosixDaemon.c +index 88b3292..e86a6c7 100644 +--- a/mDNSPosix/PosixDaemon.c ++++ b/mDNSPosix/PosixDaemon.c +@@ -37,6 +37,11 @@ + #include + #include + #include ++#ifdef __linux__ ++#include /* !!! We require libcap-dev for this. Oh well. */ ++/* prctl is required to enable inheriting of capabilities across setuid */ ++#include ++#endif /* __linux__ */ + + #if __APPLE__ + #undef daemon +@@ -184,16 +189,50 @@ int main(int argc, char **argv) + + Reconfigure(&mDNSStorage); + ++#ifdef __linux__ ++ /* ++ * SO_BINDTODEVICE is privileged operation; however, we can get ++ * around it using capabilities instead of remaining root. ++ */ ++ if (mStatus_NoError == err) ++ { ++ if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) ++ perror("prctl PR_SET_KEEPCAPS"); ++ } ++#endif /* __linux__ */ ++ + // Now that we're finished with anything privileged, switch over to running as "nobody" + if (mStatus_NoError == err) + { + const struct passwd *pw = getpwnam("nobody"); + if (pw != NULL) ++ { + setuid(pw->pw_uid); ++#ifdef __linux__ ++ struct __user_cap_header_struct ch; ++ struct __user_cap_data_struct cd[_LINUX_CAPABILITY_U32S_3]; ++ ++ memset(&ch, 0, sizeof(ch)); ++ ch.version = _LINUX_CAPABILITY_VERSION_3; ++ ch.pid = getpid(); ++ memset(&cd[0], 0, sizeof(cd)); ++ /* CAP_NET_RAW is required to use SO_BINDTODEVICE */ ++ int caps = CAP_TO_MASK(CAP_NET_RAW); ++ cd[0].permitted = caps; ++ cd[0].effective = caps; ++ if (capset(&ch, &cd[0]) < 0) ++ perror("capset"); ++#endif /* __linux__ */ ++ } + else + LogMsg("WARNING: mdnsd continuing as root because user \"nobody\" does not exist"); + } + ++#ifdef __linux__ ++ if (mStatus_NoError == err) ++ err = mDNSPlatformPosixRefreshInterfaceList(&mDNSStorage); ++#endif /* __linux__ */ ++ + if (mStatus_NoError == err) + err = MainLoop(&mDNSStorage); + +diff --git a/mDNSPosix/Responder.c b/mDNSPosix/Responder.c +index 3996b7b..e58d8eb 100755 +--- a/mDNSPosix/Responder.c ++++ b/mDNSPosix/Responder.c +@@ -603,7 +603,8 @@ static mStatus RegisterServicesInFile(const char *filePath) + status = mStatus_UnknownErr; + } + +- assert(0 == fclose(fp)); ++ int rv = fclose(fp); ++ assert(0 == rv); + + return status; + } +diff --git a/mDNSPosix/mDNSPosix.c b/mDNSPosix/mDNSPosix.c +index 953bf64..4e481ea 100755 +--- a/mDNSPosix/mDNSPosix.c ++++ b/mDNSPosix/mDNSPosix.c +@@ -136,7 +136,7 @@ mDNSlocal void SockAddrTomDNSAddr(const struct sockaddr *const sa, mDNSAddr *ipA + + // mDNS core calls this routine when it needs to send a packet. + mDNSexport mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const msg, const mDNSu8 *const end, +- mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst, ++ mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst, + mDNSIPPort dstPort, mDNSBool useBackgroundTrafficClass) + { + int err = 0; +@@ -574,9 +574,17 @@ mDNSlocal void FreePosixNetworkInterface(PosixNetworkInterface *intf) + { + assert(intf != NULL); + if (intf->intfName != NULL) free((void *)intf->intfName); +- if (intf->multicastSocket4 != -1) assert(close(intf->multicastSocket4) == 0); ++ if (intf->multicastSocket4 != -1) ++ { ++ int rv = close(intf->multicastSocket4); ++ assert(rv == 0); ++ } + #if HAVE_IPV6 +- if (intf->multicastSocket6 != -1) assert(close(intf->multicastSocket6) == 0); ++ if (intf->multicastSocket6 != -1) ++ { ++ int rv = close(intf->multicastSocket6); ++ assert(rv == 0); ++ } + #endif + free(intf); + } +@@ -703,6 +711,29 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf + if (err < 0) { err = errno; perror("setsockopt - IP_MULTICAST_TTL"); } + } + ++#ifdef __linux__ ++#ifdef SO_BINDTODEVICE ++ if (err == 0 && interfaceIndex) ++ { ++ char ifname[IFNAMSIZ]; ++ if (if_indextoname(interfaceIndex, ifname)) ++ { ++ err = setsockopt(*sktPtr, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname)); ++ if (err < 0) ++ { ++ err = errno; ++ perror("setsockopt - SO_BINDTODEVICE"); ++ } ++ } ++ else ++ { ++ err = errno; ++ perror("if_indextoname"); ++ } ++ } ++#endif /* SO_BINDTODEVICE */ ++#endif /* __linux__ */ ++ + // And start listening for packets + if (err == 0) + { +@@ -784,6 +815,29 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf + if (err < 0) { err = errno; perror("setsockopt - IPV6_MULTICAST_HOPS"); } + } + ++#ifdef __linux__ ++#ifdef SO_BINDTODEVICE ++ if (err == 0 && interfaceIndex) ++ { ++ char ifname[IFNAMSIZ]; ++ if (if_indextoname(interfaceIndex, ifname)) ++ { ++ err = setsockopt(*sktPtr, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname)); ++ if (err < 0) ++ { ++ err = errno; ++ perror("setsockopt - SO_BINDTODEVICE"); ++ } ++ } ++ else ++ { ++ err = errno; ++ perror("if_indextoname"); ++ } ++ } ++#endif /* SO_BINDTODEVICE */ ++#endif /* __linux__ */ ++ + // And start listening for packets + if (err == 0) + { +@@ -815,7 +869,12 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf + } + + // Clean up +- if (err != 0 && *sktPtr != -1) { assert(close(*sktPtr) == 0); *sktPtr = -1; } ++ if (err != 0 && *sktPtr != -1) ++ { ++ int rv = close(*sktPtr); ++ assert(rv == 0); ++ *sktPtr = -1; ++ } + assert((err == 0) == (*sktPtr != -1)); + return err; + } +@@ -994,7 +1053,7 @@ mDNSlocal mStatus OpenIfNotifySocket(int *pFD) + /* Subscribe the socket to Link & IP addr notifications. */ + mDNSPlatformMemZero(&snl, sizeof snl); + snl.nl_family = AF_NETLINK; +- snl.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR; ++ snl.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR; + ret = bind(sock, (struct sockaddr *) &snl, sizeof snl); + if (0 == ret) + *pFD = sock; +@@ -1072,11 +1131,18 @@ mDNSlocal mDNSu32 ProcessRoutingNotification(int sd) + PrintNetLinkMsg(pNLMsg); + #endif + ++ // this result isn't used anywhere as a number, just as ++ // non-zero - however, I have seen devices with more than 32 ++ // interfaces at some point.. ++ // (on Linux, every tunnel increases index for example) ++ + // Process the NetLink message + if (pNLMsg->nlmsg_type == RTM_GETLINK || pNLMsg->nlmsg_type == RTM_NEWLINK) +- result |= 1 << ((struct ifinfomsg*) NLMSG_DATA(pNLMsg))->ifi_index; ++ result |= 1; ++ // << ((struct ifinfomsg*) NLMSG_DATA(pNLMsg))->ifi_index; + else if (pNLMsg->nlmsg_type == RTM_DELADDR || pNLMsg->nlmsg_type == RTM_NEWADDR) +- result |= 1 << ((struct ifaddrmsg*) NLMSG_DATA(pNLMsg))->ifa_index; ++ result |= 1; ++ // << ((struct ifaddrmsg*) NLMSG_DATA(pNLMsg))->ifa_index; + + // Advance pNLMsg to the next message in the buffer + if ((pNLMsg->nlmsg_flags & NLM_F_MULTI) != 0 && pNLMsg->nlmsg_type != NLMSG_DONE) +@@ -1247,8 +1313,12 @@ mDNSexport mStatus mDNSPlatformInit(mDNS *const m) + if (err == mStatus_NoError) err = SetupSocket(&sa, zeroIPPort, 0, &m->p->unicastSocket6); + #endif + ++ // In Linux case, we can't set up sockets with different owner - ++ // it blows up SO_REUSEPORT. So we do this step bit later. ++#ifndef __linux__ + // Tell mDNS core about the network interfaces on this machine. + if (err == mStatus_NoError) err = SetupInterfaceList(m); ++#endif /* !__linux__ */ + + // Tell mDNS core about DNS Servers + mDNS_Lock(m); +@@ -1281,9 +1351,17 @@ mDNSexport void mDNSPlatformClose(mDNS *const m) + { + assert(m != NULL); + ClearInterfaceList(m); +- if (m->p->unicastSocket4 != -1) assert(close(m->p->unicastSocket4) == 0); ++ if (m->p->unicastSocket4 != -1) ++ { ++ int rv = close(m->p->unicastSocket4); ++ assert(rv == 0); ++ } + #if HAVE_IPV6 +- if (m->p->unicastSocket6 != -1) assert(close(m->p->unicastSocket6) == 0); ++ if (m->p->unicastSocket6 != -1) ++ { ++ int rv = close(m->p->unicastSocket6); ++ assert(rv == 0); ++ } + #endif + } + +@@ -1533,14 +1611,14 @@ mDNSexport mStatus mDNSPlatformClearSPSMACAddr(void) + mDNSexport mDNSu16 mDNSPlatformGetUDPPort(UDPSocket *sock) + { + (void) sock; // unused +- ++ + return (mDNSu16)-1; + } + + mDNSexport mDNSBool mDNSPlatformInterfaceIsD2D(mDNSInterfaceID InterfaceID) + { + (void) InterfaceID; // unused +- ++ + return mDNSfalse; + } + +diff --git a/mDNSPosix/mDNSUNP.c b/mDNSPosix/mDNSUNP.c +index b392fc7..9f85e0e 100755 +--- a/mDNSPosix/mDNSUNP.c ++++ b/mDNSPosix/mDNSUNP.c +@@ -61,154 +61,86 @@ + #endif + + #if defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX +-#include +-#include +- +-/* Converts a prefix length to IPv6 network mask */ +-void plen_to_mask(int plen, char *addr) { +- int i; +- int colons=7; /* Number of colons in IPv6 address */ +- int bits_in_block=16; /* Bits per IPv6 block */ +- for(i=0; i<=colons; i++) { +- int block, ones=0xffff, ones_in_block; +- if (plen>bits_in_block) ones_in_block=bits_in_block; +- else ones_in_block=plen; +- block = ones & (ones << (bits_in_block-ones_in_block)); +- i==0 ? sprintf(addr, "%x", block) : sprintf(addr, "%s:%x", addr, block); +- plen -= ones_in_block; +- } +-} ++#include ++#include ++ + +-/* Gets IPv6 interface information from the /proc filesystem in linux*/ +-struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases) ++/* Correct way to deal with this is just to use getifaddrs (glibc ++ * 2.3.3+ and various BSDs, but BSDs are 'slightly different' just to ++ * make life interesting). We assume Linux getifaddrs is available, ++ * and if not, please upgrade. */ ++struct ifi_info *get_ifi_info_linuxv6(int doaliases) + { +- struct ifi_info *ifi, *ifihead, **ifipnext, *ifipold, **ifiptr; +- FILE *fp; +- char addr[8][5]; +- int flags, myflags, index, plen, scope; +- char ifname[9], lastname[IFNAMSIZ]; +- char addr6[32+7+1]; /* don't forget the seven ':' */ +- struct addrinfo hints, *res0; +- struct sockaddr_in6 *sin6; +- struct in6_addr *addrptr; +- int err; +- int sockfd = -1; +- struct ifreq ifr; +- +- res0=NULL; +- ifihead = NULL; +- ifipnext = &ifihead; +- lastname[0] = 0; ++ struct ifaddrs *ifap, *ifa; ++ struct ifi_info *ifi = NULL, *head = NULL; + +- if ((fp = fopen(PROC_IFINET6_PATH, "r")) != NULL) { +- sockfd = socket(AF_INET6, SOCK_DGRAM, 0); +- if (sockfd < 0) { +- goto gotError; ++ /* doaliases seems always true in the calls in current code */ ++ assert(doaliases); ++ ++ if (getifaddrs(&ifap) < 0) ++ { ++ return NULL; ++ } ++ for (ifa = ifap ; ifa ; ifa = ifa->ifa_next) ++ { ++ /* Care only about IPv6 addresses on non-point-to-point links. */ ++ if (!ifa->ifa_addr ++ || ifa->ifa_addr->sa_family != AF_INET6) ++ continue; ++ ifi = calloc(1, sizeof(*ifi)); ++ if (!ifi) ++ break; ++ strncpy(ifi->ifi_name, ifa->ifa_name, IFI_NAME); ++ /* We ignore ifi_{haddr,hlen}, everyone else does too */ ++ ifi->ifi_flags = ifa->ifa_flags; ++ /* We ignore ifi_myflags; IFI_ALIAS isn't used anywhere */ ++ ifi->ifi_index = if_nametoindex(ifa->ifa_name); ++ if (!(ifi->ifi_addr = malloc(sizeof(struct sockaddr_in6)))) ++ break; ++ memcpy(ifi->ifi_addr, ifa->ifa_addr, sizeof(struct sockaddr_in6)); ++ ++ if (ifa->ifa_netmask) ++ { ++ if (!(ifi->ifi_netmask = malloc(sizeof(struct sockaddr_in6)))) ++ break; ++ memcpy(ifi->ifi_netmask, ifa->ifa_netmask, ++ sizeof(struct sockaddr_in6)); + } +- while (fscanf(fp, +- "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %8s\n", +- addr[0],addr[1],addr[2],addr[3], +- addr[4],addr[5],addr[6],addr[7], +- &index, &plen, &scope, &flags, ifname) != EOF) { +- +- myflags = 0; +- if (strncmp(lastname, ifname, IFNAMSIZ) == 0) { +- if (doaliases == 0) +- continue; /* already processed this interface */ +- myflags = IFI_ALIAS; +- } +- memcpy(lastname, ifname, IFNAMSIZ); +- ifi = (struct ifi_info*)calloc(1, sizeof(struct ifi_info)); +- if (ifi == NULL) { +- goto gotError; +- } + +- ifipold = *ifipnext; /* need this later */ +- ifiptr = ifipnext; +- *ifipnext = ifi; /* prev points to this new one */ +- ifipnext = &ifi->ifi_next; /* pointer to next one goes here */ +- +- sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s", +- addr[0],addr[1],addr[2],addr[3], +- addr[4],addr[5],addr[6],addr[7]); +- +- /* Add address of the interface */ +- memset(&hints, 0, sizeof(hints)); +- hints.ai_family = AF_INET6; +- hints.ai_flags = AI_NUMERICHOST; +- err = getaddrinfo(addr6, NULL, &hints, &res0); +- if (err) { +- goto gotError; +- } +- ifi->ifi_addr = calloc(1, sizeof(struct sockaddr_in6)); +- if (ifi->ifi_addr == NULL) { +- goto gotError; +- } +- memcpy(ifi->ifi_addr, res0->ai_addr, sizeof(struct sockaddr_in6)); ++ if (!(ifi->ifi_addr = malloc(sizeof(struct sockaddr_in6)))) ++ break; ++ memcpy(ifi->ifi_addr, ifa->ifa_addr, sizeof(struct sockaddr_in6)); + +- /* Add netmask of the interface */ +- char ipv6addr[INET6_ADDRSTRLEN]; +- plen_to_mask(plen, ipv6addr); +- ifi->ifi_netmask = calloc(1, sizeof(struct sockaddr_in6)); +- if (ifi->ifi_addr == NULL) { +- goto gotError; +- } +- sin6=calloc(1, sizeof(struct sockaddr_in6)); +- addrptr=calloc(1, sizeof(struct in6_addr)); +- inet_pton(family, ipv6addr, addrptr); +- sin6->sin6_family=family; +- sin6->sin6_addr=*addrptr; +- sin6->sin6_scope_id=scope; +- memcpy(ifi->ifi_netmask, sin6, sizeof(struct sockaddr_in6)); +- free(sin6); +- +- +- /* Add interface name */ +- memcpy(ifi->ifi_name, ifname, IFI_NAME); +- +- /* Add interface index */ +- ifi->ifi_index = index; +- +- /* Add interface flags*/ +- memcpy(ifr.ifr_name, ifname, IFNAMSIZ); +- if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) { +- if (errno == EADDRNOTAVAIL) { +- /* +- * If the main interface is configured with no IP address but +- * an alias interface exists with an IP address, you get +- * EADDRNOTAVAIL for the main interface +- */ +- free(ifi->ifi_addr); +- free(ifi); +- ifipnext = ifiptr; +- *ifipnext = ifipold; +- continue; +- } else { +- goto gotError; +- } +- } +- ifi->ifi_flags = ifr.ifr_flags; +- freeaddrinfo(res0); +- res0=NULL; +- } +- } +- goto done; + +-gotError: +- if (ifihead != NULL) { +- free_ifi_info(ifihead); +- ifihead = NULL; +- } +- if (res0 != NULL) { +- freeaddrinfo(res0); +- res0=NULL; +- } +-done: +- if (sockfd != -1) { +- assert(close(sockfd) == 0); ++ if (ifa->ifa_flags & IFF_POINTOPOINT && ifa->ifa_dstaddr) ++ { ++ if (!(ifi->ifi_dstaddr = malloc(sizeof(struct sockaddr_in6)))) ++ break; ++ memcpy(ifi->ifi_dstaddr, ifa->ifa_dstaddr, ++ sizeof(struct sockaddr_in6)); ++ } ++ else if (ifa->ifa_broadaddr) ++ { ++ if (!(ifi->ifi_brdaddr = malloc(sizeof(struct sockaddr_in6)))) ++ break; ++ memcpy(ifi->ifi_brdaddr, ifa->ifa_broadaddr, ++ sizeof(struct sockaddr_in6)); ++ } ++ ifi->ifi_next = head; ++ head = ifi; ++ ifi = NULL; ++ }; ++ if (ifi) ++ { ++ /* An error occurred. Let's bail out. */ ++ ifi->ifi_next = head; ++ free_ifi_info(head); ++ return NULL; + } +- return(ifihead); /* pointer to first structure in linked list */ ++ freeifaddrs(ifap); ++ return head; + } ++ + #endif // defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX + + struct ifi_info *get_ifi_info(int family, int doaliases) +@@ -229,7 +161,7 @@ struct ifi_info *get_ifi_info(int family, int doaliases) + #endif + + #if defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX +- if (family == AF_INET6) return get_ifi_info_linuxv6(family, doaliases); ++ if (family == AF_INET6) return get_ifi_info_linuxv6(doaliases); + #endif + + sockfd = -1; +diff --git a/mDNSPosix/mDNSUNP.h b/mDNSPosix/mDNSUNP.h +index cc81b7d..e710087 100755 +--- a/mDNSPosix/mDNSUNP.h ++++ b/mDNSPosix/mDNSUNP.h +@@ -97,8 +97,7 @@ struct ifi_info { + }; + + #if defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX +-#define PROC_IFINET6_PATH "/proc/net/if_inet6" +-extern struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases); ++extern struct ifi_info *get_ifi_info_linuxv6(int doaliases); + #endif + + #if defined(AF_INET6) && HAVE_IPV6 +diff --git a/mDNSShared/dnsextd_parser.y b/mDNSShared/dnsextd_parser.y +index 18c5990..d4b63ce 100644 +--- a/mDNSShared/dnsextd_parser.y ++++ b/mDNSShared/dnsextd_parser.y +@@ -15,6 +15,8 @@ + * limitations under the License. + */ + ++%parse-param { void *context } ++ + %{ + #include + #include +@@ -23,7 +25,7 @@ + #include "DebugServices.h" + #include "dnsextd.h" + +-void yyerror( const char* error ); ++void yyerror( void *context, const char* error ); + int yylex(void); + + +@@ -378,7 +380,7 @@ int yywrap(void); + + extern int yylineno; + +-void yyerror( const char *str ) ++void yyerror( void *context, const char *str ) + { + fprintf( stderr,"%s:%d: error: %s\n", g_filename, yylineno, str ); + } -- 2.11.0