Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/external/apache2/mDNSResponder/dist/mDNSPosix Add a simpler ...



details:   https://anonhg.NetBSD.org/src/rev/ed2c660ae23e
branches:  trunk
changeset: 445952:ed2c660ae23e
user:      christos <christos%NetBSD.org@localhost>
date:      Sun Nov 18 18:55:49 2018 +0000

description:
Add a simpler version to do interface enumeration that uses getifaddrs(3)

diffstat:

 external/apache2/mDNSResponder/dist/mDNSPosix/mDNSBSD.c |  314 ++++++++++++++++
 external/apache2/mDNSResponder/dist/mDNSPosix/mDNSUNP.c |    8 +
 2 files changed, 322 insertions(+), 0 deletions(-)

diffs (truncated from 338 to 300 lines):

diff -r 055761747539 -r ed2c660ae23e external/apache2/mDNSResponder/dist/mDNSPosix/mDNSBSD.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/external/apache2/mDNSResponder/dist/mDNSPosix/mDNSBSD.c   Sun Nov 18 18:55:49 2018 +0000
@@ -0,0 +1,314 @@
+/* -*- Mode: C; tab-width: 4 -*-
+ *
+ * Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mDNSUNP.h"
+#include <ifaddrs.h>
+
+#include <assert.h>
+#include <err.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <netinet/in_var.h>
+#include <net/if_dl.h>
+
+static int
+copyaddr(struct sockaddr **dst, const struct sockaddr *src, socklen_t len)
+{
+       if (src == NULL)
+               return 1;
+
+       *dst = calloc(1, len);
+       if (*dst == NULL)
+               return 0;
+
+       memcpy(*dst, src, len);
+       return 1;
+}
+
+struct ifi_info *
+get_ifi_info(int family, int doaliases)
+{
+       struct ifi_info *ifi, *ifihead, **ifipnext, *ifipold, **ifiptr;
+       struct ifaddrs *ifal, *ifa;
+
+       if (getifaddrs(&ifal) == -1) {
+               warn("getifaddrs");
+               return NULL;
+       }
+
+       ifihead = NULL;
+       ifipnext = &ifihead;
+
+       for (ifa = ifal; ifa; ifa = ifa->ifa_next) {
+               struct sockaddr *sa = ifa->ifa_addr;
+               int flags = ifa->ifa_flags;
+               int addrflags = ifa->ifa_addrflags;
+
+#if 0
+               /*
+                * Include the loopback so that we return at least one
+                * address, so that mdnsd does not exit before we get
+                * a dhcp address
+                */
+               if (flags & IFF_LOOPBACK)
+                       continue;       /* ignore loopback interfaces */
+#endif
+
+               if ((flags & IFF_UP) == 0)
+                       continue;       /* ignore if interface not up */
+
+               if (sa == NULL || sa->sa_family != family)
+                       continue;       /* ignore if not the desired family */
+
+               switch (sa->sa_family) {
+               case AF_INET:
+                       if (addrflags & (IN_IFF_NOTREADY | IN_IFF_DETACHED))
+                               continue;
+
+                       break;
+#if defined(AF_INET6) && HAVE_IPV6
+               case AF_INET6:
+                       if (addrflags & (IN6_IFF_NOTREADY | IN6_IFF_DETACHED))
+                               continue;
+#endif
+                       break;
+               default:
+                       continue;
+               }
+
+               ifi = calloc(1, sizeof(*ifi));
+               if (ifi == NULL)
+                       goto gotError;
+
+               ifipold   = *ifipnext;          /* need this later */
+               ifiptr    = ifipnext;
+               *ifipnext = ifi;                /* prev points to new one */
+               ifipnext  = &ifi->ifi_next;     /* pointer to next one */
+
+               ifi->ifi_flags = flags;         /* IFF_xxx values */
+               ifi->ifi_myflags = 0;           /* IFI_xxx values */
+               ifi->ifi_index = if_nametoindex(ifa->ifa_name);
+               memcpy(ifi->ifi_name, ifa->ifa_name, IFI_NAME);
+               ifi->ifi_name[IFI_NAME-1] = '\0';
+               if (!copyaddr(&ifi->ifi_addr, ifa->ifa_addr, sa->sa_len))
+                       goto gotError;
+               if (!copyaddr(&ifi->ifi_netmask, ifa->ifa_netmask, sa->sa_len))
+                       goto gotError;
+
+               if ((flags & IFF_BROADCAST) && !copyaddr(&ifi->ifi_brdaddr,
+                   ifa->ifa_broadaddr, sa->sa_len))
+                       goto gotError;
+               if ((flags & IFF_POINTOPOINT) && !copyaddr(&ifi->ifi_dstaddr,
+                   ifa->ifa_dstaddr, sa->sa_len))
+                       goto gotError;
+       }
+
+       goto done;
+
+gotError:
+       warn("can't allocate memory");
+       if (ifihead != NULL) {
+               free_ifi_info(ifihead);
+               ifihead = NULL;
+       }
+
+       freeifaddrs(ifal);
+done:
+       return ifihead;    /* pointer to first structure in linked list */
+}
+
+void
+free_ifi_info(struct ifi_info *ifihead)
+{
+       struct ifi_info *ifi, *ififree;
+
+       for (ifi = ifihead; (ififree = ifi) != NULL;) {
+               free(ifi->ifi_addr);
+               free(ifi->ifi_netmask);
+               free(ifi->ifi_brdaddr);
+               free(ifi->ifi_dstaddr);
+               ifi = ifi->ifi_next;
+               free(ififree);
+       }
+}
+
+ssize_t
+recvfrom_flags(int fd, void *ptr, size_t nbytes, int *flagsp,
+    struct sockaddr *sa, socklen_t *salenptr, struct my_in_pktinfo *pktp,
+    u_char *ttl)
+{
+    struct msghdr msg;
+    struct iovec iov[1];
+    ssize_t n;
+
+#ifdef CMSG_FIRSTHDR
+    struct cmsghdr  *cmptr;
+    union {
+        struct cmsghdr cm;
+        char control[1024];
+    } control_un;
+
+    *ttl = 255;         // If kernel fails to provide TTL data then assume the TTL was 255 as it should be
+
+    msg.msg_control = control_un.control;
+    msg.msg_controllen = sizeof(control_un.control);
+    msg.msg_flags = 0;
+#else
+    memset(&msg, 0, sizeof(msg));   /* make certain msg_accrightslen = 0 */
+#endif /* CMSG_FIRSTHDR */
+
+    msg.msg_name = (char *) sa;
+    msg.msg_namelen = *salenptr;
+    iov[0].iov_base = (char *)ptr;
+    iov[0].iov_len = nbytes;
+    msg.msg_iov = iov;
+    msg.msg_iovlen = 1;
+
+    if ( (n = recvmsg(fd, &msg, *flagsp)) < 0)
+        return(n);
+
+    *salenptr = msg.msg_namelen;    /* pass back results */
+    if (pktp) {
+        /* 0.0.0.0, i/f = -1 */
+        /* We set the interface to -1 so that the caller can
+           tell whether we returned a meaningful value or
+           just some default.  Previously this code just
+           set the value to 0, but I'm concerned that 0
+           might be a valid interface value.
+         */
+        memset(pktp, 0, sizeof(struct my_in_pktinfo));
+        pktp->ipi_ifindex = -1;
+    }
+/* end recvfrom_flags1 */
+
+/* include recvfrom_flags2 */
+#ifndef CMSG_FIRSTHDR
+    #warning CMSG_FIRSTHDR not defined. Will not be able to determine destination address, received interface, etc.
+    *flagsp = 0;                    /* pass back results */
+    return(n);
+#else
+
+    *flagsp = msg.msg_flags;        /* pass back results */
+    if (msg.msg_controllen < (socklen_t)sizeof(struct cmsghdr) ||
+        (msg.msg_flags & MSG_CTRUNC) || pktp == NULL)
+        return(n);
+
+    for (cmptr = CMSG_FIRSTHDR(&msg); cmptr != NULL;
+         cmptr = CMSG_NXTHDR(&msg, cmptr)) {
+
+#ifdef  IP_PKTINFO
+#if in_pktinfo_definition_is_missing
+        struct in_pktinfo
+        {
+            int ipi_ifindex;
+            struct in_addr ipi_spec_dst;
+            struct in_addr ipi_addr;
+        };
+#endif
+        if (cmptr->cmsg_level == IPPROTO_IP &&
+            cmptr->cmsg_type == IP_PKTINFO) {
+            struct in_pktinfo *tmp;
+            struct sockaddr_in *sin = (struct sockaddr_in*)&pktp->ipi_addr;
+
+            tmp = (struct in_pktinfo *) CMSG_DATA(cmptr);
+            sin->sin_family = AF_INET;
+            sin->sin_addr = tmp->ipi_addr;
+            sin->sin_port = 0;
+            pktp->ipi_ifindex = tmp->ipi_ifindex;
+            continue;
+        }
+#endif
+
+#ifdef  IP_RECVDSTADDR
+        if (cmptr->cmsg_level == IPPROTO_IP &&
+            cmptr->cmsg_type == IP_RECVDSTADDR) {
+            struct sockaddr_in *sin = (struct sockaddr_in*)&pktp->ipi_addr;
+
+            sin->sin_family = AF_INET;
+            sin->sin_addr = *(struct in_addr*)CMSG_DATA(cmptr);
+            sin->sin_port = 0;
+            continue;
+        }
+#endif
+
+#ifdef  IP_RECVIF
+        if (cmptr->cmsg_level == IPPROTO_IP &&
+            cmptr->cmsg_type == IP_RECVIF) {
+            struct sockaddr_dl  *sdl = (struct sockaddr_dl *) CMSG_DATA(cmptr);
+#ifndef HAVE_BROKEN_RECVIF_NAME
+            int nameLen = (sdl->sdl_nlen < IFI_NAME - 1) ? sdl->sdl_nlen : (IFI_NAME - 1);
+            strncpy(pktp->ipi_ifname, sdl->sdl_data, nameLen);
+#endif
+            pktp->ipi_ifindex = sdl->sdl_index;
+#ifdef HAVE_BROKEN_RECVIF_NAME
+            if (sdl->sdl_index == 0) {
+                pktp->ipi_ifindex = *(uint_t*)sdl;
+            }
+#endif
+            assert(pktp->ipi_ifname[IFI_NAME - 1] == 0);
+            // null terminated because of memset above
+            continue;
+        }
+#endif
+
+#ifdef  IP_RECVTTL
+        if (cmptr->cmsg_level == IPPROTO_IP &&
+            cmptr->cmsg_type == IP_RECVTTL) {
+            *ttl = *(u_char*)CMSG_DATA(cmptr);
+            continue;
+        }
+        else if (cmptr->cmsg_level == IPPROTO_IP &&
+                 cmptr->cmsg_type == IP_TTL) {  // some implementations seem to send IP_TTL instead of IP_RECVTTL
+            *ttl = *(int*)CMSG_DATA(cmptr);
+            continue;
+        }
+#endif
+
+#if defined(IPV6_PKTINFO) && HAVE_IPV6
+        if (cmptr->cmsg_level == IPPROTO_IPV6 &&
+            cmptr->cmsg_type  == IPV6_2292_PKTINFO) {
+            struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)&pktp->ipi_addr;
+            struct in6_pktinfo *ip6_info = (struct in6_pktinfo*)CMSG_DATA(cmptr);
+
+            sin6->sin6_family   = AF_INET6;
+#ifndef NOT_HAVE_SA_LEN
+            sin6->sin6_len      = sizeof(*sin6);
+#endif
+            sin6->sin6_addr     = ip6_info->ipi6_addr;
+            sin6->sin6_flowinfo = 0;
+            sin6->sin6_scope_id = 0;



Home | Main Index | Thread Index | Old Index