The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/compat/darwin/darwin_route.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: darwin_route.c,v 1.14 2008/04/28 20:23:41 martin Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 2004 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Emmanuel Dreyfus.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __KERNEL_RCSID(0, "$NetBSD: darwin_route.c,v 1.14 2008/04/28 20:23:41 martin Exp $");
   34 
   35 #include <sys/errno.h>
   36 #include <sys/systm.h>
   37 #include <sys/malloc.h>
   38 
   39 #include <net/if.h>
   40 
   41 #include <compat/darwin/darwin_socket.h>
   42 #include <compat/darwin/darwin_route.h>
   43 
   44 static int darwin_copyout_sockaddr(struct sockaddr *, char **, size_t *, size_t);
   45 
   46 #define ALIGN(a)        (((a) + 3) & ~0x3UL)
   47 int
   48 darwin_ifaddrs(int af, char *dst, size_t *sizep)
   49 {
   50         struct darwin_if_msghdr dim;
   51         struct ifnet *ifp;
   52         int error;
   53         int index = 1;
   54         size_t size = 0;
   55         size_t maxsize = *sizep;
   56         uint8_t family;
   57 
   58         af = darwin_to_native_af[af];
   59 
   60         IFNET_FOREACH(ifp) {
   61                 struct ifaddr *ifa;
   62                 struct sockaddr *laddr = NULL;
   63 
   64                 /*
   65                  * Find the link layer info as it is needed
   66                  * for computing darwin_if_msghdr's dim_len
   67                  */
   68                 IFADDR_FOREACH(ifa, ifp) {
   69                         if ((ifa->ifa_addr) &&
   70                             (ifa->ifa_addr->sa_family == AF_LINK)) {
   71                                 laddr = (struct sockaddr *)ifa->ifa_addr;
   72                                 break;
   73                         }
   74                 }
   75 
   76                 if (laddr == NULL) {
   77 #ifdef DEBUG_DARWIN
   78                         printf("darwin_ifaddrs: cannot find link address\n");
   79 #endif
   80                         continue;
   81                 }
   82 
   83                 dim.dim_len = sizeof(dim) + ALIGN(laddr->sa_len);
   84                 dim.dim_vers = DARWIN_RTM_VERSION;
   85                 dim.dim_type = DARWIN_RTM_IFINFO;
   86                 dim.dim_addrs = DARWIN_RTA_IFP;
   87                 dim.dim_flags = ifp->if_flags & 0xffff;
   88                 dim.dim_index = index++;
   89 
   90                 dim.dim_data.did_type = ifp->if_data.ifi_type; /* XXX */
   91                 dim.dim_data.did_typelen = 0 ;/* XXX */
   92                 dim.dim_data.did_physical = 0; /* XXX */
   93                 dim.dim_data.did_addrlen = ifp->if_data.ifi_addrlen;
   94                 dim.dim_data.did_hdrlen = ifp->if_data.ifi_hdrlen;
   95                 dim.dim_data.did_recquota = 0; /* XXX */
   96                 dim.dim_data.did_xmitquota = 0; /* XXX */
   97                 dim.dim_data.did_mtu = ifp->if_data.ifi_mtu;
   98                 dim.dim_data.did_metric = ifp->if_data.ifi_metric;
   99                 dim.dim_data.did_baudrate = ifp->if_data.ifi_baudrate;
  100                 dim.dim_data.did_ipackets = ifp->if_data.ifi_ipackets;
  101                 dim.dim_data.did_ierrors = ifp->if_data.ifi_ierrors;
  102                 dim.dim_data.did_opackets = ifp->if_data.ifi_opackets;
  103                 dim.dim_data.did_oerrors = ifp->if_data.ifi_oerrors;
  104                 dim.dim_data.did_collisions = ifp->if_data.ifi_collisions;
  105                 dim.dim_data.did_ibytes = ifp->if_data.ifi_ibytes;
  106                 dim.dim_data.did_obytes = ifp->if_data.ifi_obytes;
  107                 dim.dim_data.did_imcasts = ifp->if_data.ifi_imcasts;
  108                 dim.dim_data.did_omcasts = ifp->if_data.ifi_omcasts;
  109                 dim.dim_data.did_iqdrops = ifp->if_data.ifi_iqdrops;
  110                 dim.dim_data.did_noproto = ifp->if_data.ifi_noproto;
  111                 dim.dim_data.did_lastchange.tv_sec =
  112                     ifp->if_data.ifi_lastchange.tv_sec;
  113                 dim.dim_data.did_lastchange.tv_usec =
  114                     ifp->if_data.ifi_lastchange.tv_usec;
  115                 dim.dim_data.did_default_proto = 0; /* XXX */
  116                 dim.dim_data.did_hwassist = 0; /* XXX */
  117 
  118                 size += sizeof(dim);
  119                 if (dst && (size <= maxsize)) {
  120                         if ((error = copyout(&dim, dst, sizeof(dim))) != 0)
  121                                 return error;
  122                         dst += sizeof(dim);
  123                 }
  124 
  125                 /* Copy the link sockaddr. */
  126                 size += ALIGN(laddr->sa_len);
  127                 if (dst && (size <= maxsize)) {
  128                         if ((error = copyout(laddr, dst, laddr->sa_len)) != 0)
  129                                 return error;
  130                         family = native_to_darwin_af[laddr->sa_family];
  131                         error = copyout(&family,
  132                             &((struct sockaddr *)dst)->sa_family, 1);
  133                         if (error != 0)
  134                                 return error;
  135                         dst += ALIGN(laddr->sa_len);
  136                 }
  137 
  138                 IFADDR_FOREACH(ifa, ifp) {
  139                         struct darwin_ifa_msghdr diam;
  140                         int iaf;
  141 
  142                         if (ifa->ifa_addr) {
  143                                 iaf = ifa->ifa_addr->sa_family;
  144                                 if ((af != 0) && (iaf != af))
  145                                         continue;
  146                                 if (iaf > AF_MAX)
  147                                         continue;
  148                                 if (iaf == 0)
  149                                         continue;
  150                                 if (native_to_darwin_af[iaf] == 0)
  151                                         continue;
  152                                 /* Already handled earlier */
  153                                 if (iaf == AF_LINK)
  154                                         continue;
  155                         }
  156 
  157                         bzero(&diam, sizeof(diam));
  158 
  159                         diam.diam_len = sizeof(diam);
  160                         diam.diam_vers = DARWIN_RTM_VERSION;
  161                         diam.diam_type = DARWIN_RTM_NEWADDR;
  162 
  163                         /*
  164                          * XXX the following code assumes that
  165                          * Darwin sockaddr have the same size as
  166                          * the original.
  167                          */
  168                         if (ifa->ifa_addr) {
  169                                 diam.diam_addrs |= DARWIN_RTA_IFA;
  170                                 diam.diam_len += ALIGN(ifa->ifa_addr->sa_len);
  171                         }
  172                         if (ifa->ifa_netmask) {
  173                                 diam.diam_addrs |= DARWIN_RTA_NETMASK;
  174                                 diam.diam_len +=
  175                                     ALIGN(ifa->ifa_netmask->sa_len);
  176                         }
  177                         if ((ifa->ifa_dstaddr != NULL) &&
  178                             (ifp->if_flags & IFF_POINTOPOINT)) {
  179                                 diam.diam_addrs |= DARWIN_RTA_DST;
  180                                 diam.diam_len +=
  181                                     ALIGN(ifa->ifa_dstaddr->sa_len);
  182                         }
  183                         if ((ifa->ifa_broadaddr != NULL) &&
  184                             (ifp->if_flags & IFF_BROADCAST)) {
  185                                 diam.diam_addrs |= DARWIN_RTA_BRD;
  186                                 diam.diam_len +=
  187                                     ALIGN(ifa->ifa_broadaddr->sa_len);
  188                         }
  189 
  190                         diam.diam_flags = (int)ifa->ifa_flags;
  191                         diam.diam_index = dim.dim_index;
  192                         diam.diam_metric = ifa->ifa_metric;
  193 
  194                         size += sizeof(diam);
  195                         if (dst && (size <= maxsize)) {
  196                                 error = copyout(&diam, dst, sizeof(diam));
  197                                 if (error != 0)
  198                                         return error;
  199                                 dst += sizeof(diam);
  200                         }
  201 
  202                         /*
  203                          * Interface netmask
  204                          * We sometime lack the af in native version:
  205                          * copy it from ifa_addr.
  206                          */
  207                         if (diam.diam_addrs & DARWIN_RTA_NETMASK) {
  208                                 struct sockaddr_storage ss;
  209 
  210                                 memcpy(&ss, ifa->ifa_netmask,
  211                                     ifa->ifa_netmask->sa_len);
  212                                 if ((ss.ss_family == 0) &&
  213                                     (ifa->ifa_addr != NULL) &&
  214                                     (ifa->ifa_addr->sa_family != 0))
  215                                         ss.ss_family =
  216                                             ifa->ifa_addr->sa_family;
  217 
  218                                 if ((error = darwin_copyout_sockaddr(
  219                                     (struct sockaddr *)&ss, &dst,
  220                                     &size, maxsize)) != 0)
  221                                         return error;
  222                         }
  223 
  224                         /* Interface address */
  225                         if (diam.diam_addrs & DARWIN_RTA_IFA)
  226                                 if ((error = darwin_copyout_sockaddr(ifa->ifa_addr,
  227                                     &dst, &size, maxsize)) != 0)
  228                                         return error;
  229 
  230                         /* Interface remote address */
  231                         if (diam.diam_addrs & DARWIN_RTA_DST)
  232                                 if ((error = darwin_copyout_sockaddr(ifa->ifa_dstaddr,
  233                                     &dst, &size, maxsize)) != 0)
  234                                         return error;
  235 
  236                         /* Interface broadcast address */
  237                         if (diam.diam_addrs & DARWIN_RTA_BRD)
  238                                 if ((error =
  239                                     darwin_copyout_sockaddr(ifa->ifa_broadaddr,
  240                                     &dst, &size, maxsize)) != 0)
  241                                         return error;
  242                 }
  243         }
  244 
  245         *sizep = size;
  246 
  247         if (dst && (size > maxsize))
  248                 return ENOMEM;
  249 
  250         return 0;
  251 }
  252 
  253 
  254 static int
  255 darwin_copyout_sockaddr(struct sockaddr *sap, char **dstp, size_t *sizep, size_t maxsize)
  256 {
  257         size_t len;
  258         int error;
  259         uint8_t family;
  260 
  261         len = sap->sa_len;
  262 
  263         *sizep += ALIGN(len);
  264         if (*dstp && (*sizep <= maxsize)) {
  265                 if ((error = copyout(sap, *dstp, len)) != 0)
  266                         return error;
  267                 family = native_to_darwin_af[sap->sa_family];
  268                 error = copyout(&family,
  269                     &((struct sockaddr *)*dstp)->sa_family, 1);
  270                 if (error != 0)
  271                         return error;
  272                 *dstp += ALIGN(len);
  273         }
  274 
  275         return 0;
  276 }

Cache object: a5679e0eda8dc6f5a1e9461d65689634


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.