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/net/if.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 /*
    2  * Copyright (c) 1980, 1986, 1993
    3  *      The Regents of the University of California.  All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 3. All advertising materials mentioning features or use of this software
   14  *    must display the following acknowledgement:
   15  *      This product includes software developed by the University of
   16  *      California, Berkeley and its contributors.
   17  * 4. Neither the name of the University nor the names of its contributors
   18  *    may be used to endorse or promote products derived from this software
   19  *    without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   31  * SUCH DAMAGE.
   32  *
   33  *      @(#)if.c        8.3 (Berkeley) 1/4/94
   34  * $FreeBSD$
   35  */
   36 
   37 #include "opt_compat.h"
   38 #include "opt_inet6.h"
   39 #include "opt_inet.h"
   40 
   41 #include <sys/param.h>
   42 #include <sys/malloc.h>
   43 #include <sys/mbuf.h>
   44 #include <sys/systm.h>
   45 #include <sys/proc.h>
   46 #include <sys/socket.h>
   47 #include <sys/socketvar.h>
   48 #include <sys/protosw.h>
   49 #include <sys/kernel.h>
   50 #include <sys/sockio.h>
   51 #include <sys/syslog.h>
   52 #include <sys/sysctl.h>
   53 
   54 #include <net/if.h>
   55 #include <net/if_arp.h>
   56 #include <net/if_dl.h>
   57 #include <net/if_types.h>
   58 #include <net/if_var.h>
   59 #include <net/radix.h>
   60 #include <net/route.h>
   61 #include <machine/stdarg.h>
   62 
   63 #if defined(INET) || defined(INET6)
   64 /*XXX*/
   65 #include <netinet/in.h>
   66 #include <netinet/in_var.h>
   67 #include <netinet/if_ether.h>
   68 #ifdef INET6
   69 #include <machine/clock.h> /* XXX: temporal workaround for fxp issue */
   70 #include <netinet6/in6_var.h>
   71 #include <netinet6/in6_ifattach.h>
   72 #endif
   73 #endif
   74 
   75 /*
   76  * System initialization
   77  */
   78 
   79 static int ifconf __P((u_long, caddr_t));
   80 static void ifinit __P((void *));
   81 static void if_qflush __P((struct ifqueue *));
   82 static void if_slowtimo __P((void *));
   83 static void link_rtrequest __P((int, struct rtentry *, struct rt_addrinfo *));
   84 static int  if_rtdel __P((struct radix_node *, void *));
   85 
   86 SYSINIT(interfaces, SI_SUB_PROTO_IF, SI_ORDER_FIRST, ifinit, NULL)
   87 
   88 MALLOC_DEFINE(M_IFADDR, "ifaddr", "interface address");
   89 MALLOC_DEFINE(M_IFMADDR, "ether_multi", "link-level multicast address");
   90 
   91 int     ifqmaxlen = IFQ_MAXLEN;
   92 struct  ifnethead ifnet;        /* depend on static init XXX */
   93 
   94 #ifdef INET6
   95 /*
   96  * XXX: declare here to avoid to include many inet6 related files..
   97  * should be more generalized?
   98  */
   99 extern void     nd6_setmtu __P((struct ifnet *));
  100 #endif
  101 
  102 struct if_clone *if_clone_lookup __P((const char *, int *));
  103 int if_clone_list __P((struct if_clonereq *));
  104 
  105 LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners);
  106 int if_cloners_count;
  107 
  108 /*
  109  * Network interface utility routines.
  110  *
  111  * Routines with ifa_ifwith* names take sockaddr *'s as
  112  * parameters.
  113  */
  114 /* ARGSUSED*/
  115 void
  116 ifinit(dummy)
  117         void *dummy;
  118 {
  119         struct ifnet *ifp;
  120         int s;
  121 
  122         s = splimp();
  123         TAILQ_FOREACH(ifp, &ifnet, if_link) {
  124                 if (ifp->if_snd.ifq_maxlen == 0) {
  125                         printf("%s%d XXX: driver didn't set ifq_maxlen\n",
  126                             ifp->if_name, ifp->if_unit);
  127                         ifp->if_snd.ifq_maxlen = ifqmaxlen;
  128                 }
  129         }
  130         splx(s);
  131         if_slowtimo(0);
  132 }
  133 
  134 int if_index = 0;
  135 struct ifaddr **ifnet_addrs;
  136 struct ifnet **ifindex2ifnet = NULL;
  137 
  138 
  139 /*
  140  * Attach an interface to the
  141  * list of "active" interfaces.
  142  */
  143 void
  144 if_attach(ifp)
  145         struct ifnet *ifp;
  146 {
  147         unsigned socksize, ifasize;
  148         int namelen, masklen;
  149         char workbuf[64];
  150         register struct sockaddr_dl *sdl;
  151         register struct ifaddr *ifa;
  152         static int if_indexlim = 8;
  153         static int inited;
  154 
  155         if (!inited) {
  156                 TAILQ_INIT(&ifnet);
  157                 inited = 1;
  158         }
  159 
  160         TAILQ_INSERT_TAIL(&ifnet, ifp, if_link);
  161         ifp->if_index = ++if_index;
  162         /*
  163          * XXX -
  164          * The old code would work if the interface passed a pre-existing
  165          * chain of ifaddrs to this code.  We don't trust our callers to
  166          * properly initialize the tailq, however, so we no longer allow
  167          * this unlikely case.
  168          */
  169         TAILQ_INIT(&ifp->if_addrhead);
  170         TAILQ_INIT(&ifp->if_prefixhead);
  171         LIST_INIT(&ifp->if_multiaddrs);
  172         getmicrotime(&ifp->if_lastchange);
  173         if (ifnet_addrs == 0 || if_index >= if_indexlim) {
  174                 unsigned n = (if_indexlim <<= 1) * sizeof(ifa);
  175                 caddr_t q = malloc(n, M_IFADDR, M_WAITOK);
  176                 bzero(q, n);
  177                 if (ifnet_addrs) {
  178                         bcopy((caddr_t)ifnet_addrs, (caddr_t)q, n/2);
  179                         free((caddr_t)ifnet_addrs, M_IFADDR);
  180                 }
  181                 ifnet_addrs = (struct ifaddr **)q;
  182 
  183                 /* grow ifindex2ifnet */
  184                 n = if_indexlim * sizeof(struct ifnet *);
  185                 q = malloc(n, M_IFADDR, M_WAITOK);
  186                 bzero(q, n);
  187                 if (ifindex2ifnet) {
  188                         bcopy((caddr_t)ifindex2ifnet, q, n/2);
  189                         free((caddr_t)ifindex2ifnet, M_IFADDR);
  190                 }
  191                 ifindex2ifnet = (struct ifnet **)q;
  192         }
  193 
  194         ifindex2ifnet[if_index] = ifp;
  195 
  196         ifp->if_data.ifi_datalen = sizeof(struct if_data);
  197 
  198         /*
  199          * create a Link Level name for this device
  200          */
  201         namelen = snprintf(workbuf, sizeof(workbuf),
  202             "%s%d", ifp->if_name, ifp->if_unit);
  203 #define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))
  204         masklen = _offsetof(struct sockaddr_dl, sdl_data[0]) + namelen;
  205         socksize = masklen + ifp->if_addrlen;
  206 #define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1)))
  207         if (socksize < sizeof(*sdl))
  208                 socksize = sizeof(*sdl);
  209         socksize = ROUNDUP(socksize);
  210         ifasize = sizeof(*ifa) + 2 * socksize;
  211         ifa = (struct ifaddr *)malloc(ifasize, M_IFADDR, M_WAITOK);
  212         if (ifa) {
  213                 bzero((caddr_t)ifa, ifasize);
  214                 sdl = (struct sockaddr_dl *)(ifa + 1);
  215                 sdl->sdl_len = socksize;
  216                 sdl->sdl_family = AF_LINK;
  217                 bcopy(workbuf, sdl->sdl_data, namelen);
  218                 sdl->sdl_nlen = namelen;
  219                 sdl->sdl_index = ifp->if_index;
  220                 sdl->sdl_type = ifp->if_type;
  221                 ifnet_addrs[if_index - 1] = ifa;
  222                 ifa->ifa_ifp = ifp;
  223                 ifa->ifa_rtrequest = link_rtrequest;
  224                 ifa->ifa_addr = (struct sockaddr *)sdl;
  225                 sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl);
  226                 ifa->ifa_netmask = (struct sockaddr *)sdl;
  227                 sdl->sdl_len = masklen;
  228                 while (namelen != 0)
  229                         sdl->sdl_data[--namelen] = 0xff;
  230                 TAILQ_INSERT_HEAD(&ifp->if_addrhead, ifa, ifa_link);
  231         }
  232 
  233         /* Announce the interface. */
  234         rt_ifannouncemsg(ifp, IFAN_ARRIVAL);
  235 }
  236 
  237 /*
  238  * Detach an interface, removing it from the
  239  * list of "active" interfaces.
  240  */
  241 void
  242 if_detach(ifp)
  243         struct ifnet *ifp;
  244 {
  245         struct ifaddr *ifa, *next;
  246         struct radix_node_head  *rnh;
  247         int s;
  248         int i;
  249         struct ifnet *iter;
  250         int found;
  251 
  252         /*
  253          * Remove routes and flush queues.
  254          */
  255         s = splnet();
  256         if_down(ifp);
  257 
  258         /*
  259          * Remove address from ifnet_addrs[] and maybe decrement if_index.
  260          * Clean up all addresses.
  261          */
  262         ifnet_addrs[ifp->if_index - 1] = 0;
  263         while (if_index > 0 && ifnet_addrs[if_index - 1] == 0)
  264                 if_index--;
  265 
  266         for (ifa = TAILQ_FIRST(&ifp->if_addrhead); ifa; ifa = next) {
  267                 next = TAILQ_NEXT(ifa, ifa_link);
  268 
  269                 if (ifa->ifa_addr->sa_family == AF_LINK)
  270                         continue;
  271 #ifdef INET
  272                 /* XXX: Ugly!! ad hoc just for INET */
  273                 if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) {
  274                         struct ifaliasreq ifr;
  275 
  276                         bzero(&ifr, sizeof(ifr));
  277                         ifr.ifra_addr = *ifa->ifa_addr;
  278                         if (ifa->ifa_dstaddr)
  279                                 ifr.ifra_broadaddr = *ifa->ifa_dstaddr;
  280                         if (in_control(NULL, SIOCDIFADDR, (caddr_t)&ifr, ifp,
  281                             NULL) == 0)
  282                                 continue;
  283                 }
  284 #endif /* INET */
  285 #ifdef INET6
  286                 if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET6) {
  287                         in6_purgeaddr(ifa);
  288                         /* ifp_addrhead is already updated */
  289                         continue;
  290                 }
  291 #endif /* INET6 */
  292                 TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link);
  293                 IFAFREE(ifa);
  294         }
  295 
  296 #ifdef INET6
  297         /*
  298          * Remove all IPv6 kernel structs related to ifp.  This should be done
  299          * before removing routing entries below, since IPv6 interface direct
  300          * routes are expected to be removed by the IPv6-specific kernel API.
  301          * Otherwise, the kernel will detect some inconsistency and bark it.
  302          */
  303         in6_ifdetach(ifp);
  304 #endif
  305 
  306         /* We can now free link ifaddr. */
  307         if (!TAILQ_EMPTY(&ifp->if_addrhead)) {
  308                 ifa = TAILQ_FIRST(&ifp->if_addrhead);
  309                 TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link);
  310                 IFAFREE(ifa);
  311         }
  312 
  313         /*
  314          * Delete all remaining routes using this interface
  315          * Unfortuneatly the only way to do this is to slog through
  316          * the entire routing table looking for routes which point
  317          * to this interface...oh well...
  318          */
  319         for (i = 1; i <= AF_MAX; i++) {
  320                 if ((rnh = rt_tables[i]) == NULL)
  321                         continue;
  322                 (void) rnh->rnh_walktree(rnh, if_rtdel, ifp);
  323         }
  324 
  325         /* Announce that the interface is gone. */
  326         rt_ifannouncemsg(ifp, IFAN_DEPARTURE);
  327 
  328         ifindex2ifnet[ifp->if_index] = NULL;
  329 
  330         found = 0;
  331         TAILQ_FOREACH(iter, &ifnet, if_link)
  332                 if (iter == ifp) {
  333                         found = 1;
  334                         break;
  335                 }
  336         if (found)
  337                 TAILQ_REMOVE(&ifnet, ifp, if_link);
  338         splx(s);
  339 }
  340 
  341 /*
  342  * Delete Routes for a Network Interface
  343  * 
  344  * Called for each routing entry via the rnh->rnh_walktree() call above
  345  * to delete all route entries referencing a detaching network interface.
  346  *
  347  * Arguments:
  348  *      rn      pointer to node in the routing table
  349  *      arg     argument passed to rnh->rnh_walktree() - detaching interface
  350  *
  351  * Returns:
  352  *      0       successful
  353  *      errno   failed - reason indicated
  354  *
  355  */
  356 static int
  357 if_rtdel(rn, arg)
  358         struct radix_node       *rn;
  359         void                    *arg;
  360 {
  361         struct rtentry  *rt = (struct rtentry *)rn;
  362         struct ifnet    *ifp = arg;
  363         int             err;
  364 
  365         if (rt->rt_ifp == ifp) {
  366 
  367                 /*
  368                  * Protect (sorta) against walktree recursion problems
  369                  * with cloned routes
  370                  */
  371                 if ((rt->rt_flags & RTF_UP) == 0)
  372                         return (0);
  373 
  374                 err = rtrequest(RTM_DELETE, rt_key(rt), rt->rt_gateway,
  375                                 rt_mask(rt), rt->rt_flags,
  376                                 (struct rtentry **) NULL);
  377                 if (err) {
  378                         log(LOG_WARNING, "if_rtdel: error %d\n", err);
  379                 }
  380         }
  381 
  382         return (0);
  383 }
  384 
  385 /*
  386  * Create a clone network interface.
  387  */
  388 int
  389 if_clone_create(name, len)
  390         char *name;
  391         int len;
  392 {
  393         struct if_clone *ifc;
  394         char *dp;
  395         int wildcard;
  396         int unit;
  397         int err;
  398 
  399         ifc = if_clone_lookup(name, &unit);
  400         if (ifc == NULL)
  401                 return (EINVAL);
  402 
  403         if (ifunit(name) != NULL)
  404                 return (EEXIST);
  405 
  406         wildcard = (unit < 0);
  407 
  408         err = (*ifc->ifc_create)(ifc, &unit);
  409         if (err != 0)
  410                 return (err);
  411 
  412         /* In the wildcard case, we need to update the name. */
  413         if (wildcard) {
  414                 for (dp = name; *dp != '\0'; dp++);
  415                 if (snprintf(dp, len - (dp-name), "%d", unit) >
  416                     len - (dp-name) - 1) {
  417                         /*
  418                          * This can only be a programmer error and
  419                          * there's no straightforward way to recover if
  420                          * it happens.
  421                          */
  422                         panic("if_clone_create(): interface name too long");
  423                 }
  424                         
  425         }
  426 
  427         return (0);
  428 }
  429 
  430 /*
  431  * Destroy a clone network interface.
  432  */
  433 int
  434 if_clone_destroy(name)
  435         const char *name;
  436 {
  437         struct if_clone *ifc;
  438         struct ifnet *ifp;
  439 
  440         ifc = if_clone_lookup(name, NULL);
  441         if (ifc == NULL)
  442                 return (EINVAL);
  443 
  444         ifp = ifunit(name);
  445         if (ifp == NULL)
  446                 return (ENXIO);
  447 
  448         if (ifc->ifc_destroy == NULL)
  449                 return (EOPNOTSUPP);
  450 
  451         (*ifc->ifc_destroy)(ifp);
  452         return (0);
  453 }
  454 
  455 /*
  456  * Look up a network interface cloner.
  457  */
  458 struct if_clone *
  459 if_clone_lookup(name, unitp)
  460         const char *name;
  461         int *unitp;
  462 {
  463         struct if_clone *ifc;
  464         const char *cp;
  465         int i;
  466 
  467         for (ifc = LIST_FIRST(&if_cloners); ifc != NULL;) {
  468                 for (cp = name, i = 0; i < ifc->ifc_namelen; i++, cp++) {
  469                         if (ifc->ifc_name[i] != *cp)
  470                                 goto next_ifc;
  471                 }
  472                 goto found_name;
  473  next_ifc:
  474                 ifc = LIST_NEXT(ifc, ifc_list);
  475         }
  476 
  477         /* No match. */
  478         return ((struct if_clone *)NULL);
  479 
  480  found_name:
  481         if (*cp == '\0') {
  482                 i = -1;
  483         } else {
  484                 for (i = 0; *cp != '\0'; cp++) {
  485                         if (*cp < '' || *cp > '9') {
  486                                 /* Bogus unit number. */
  487                                 return (NULL);
  488                         }
  489                         i = (i * 10) + (*cp - '');
  490                 }
  491         }
  492 
  493         if (unitp != NULL)
  494                 *unitp = i;
  495         return (ifc);
  496 }
  497 
  498 /*
  499  * Register a network interface cloner.
  500  */
  501 void
  502 if_clone_attach(ifc)
  503         struct if_clone *ifc;
  504 {
  505 
  506         LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list);
  507         if_cloners_count++;
  508 }
  509 
  510 /*
  511  * Unregister a network interface cloner.
  512  */
  513 void
  514 if_clone_detach(ifc)
  515         struct if_clone *ifc;
  516 {
  517 
  518         LIST_REMOVE(ifc, ifc_list);
  519         if_cloners_count--;
  520 }
  521 
  522 /*
  523  * Provide list of interface cloners to userspace.
  524  */
  525 int
  526 if_clone_list(ifcr)
  527         struct if_clonereq *ifcr;
  528 {
  529         char outbuf[IFNAMSIZ], *dst;
  530         struct if_clone *ifc;
  531         int count, error = 0;
  532 
  533         ifcr->ifcr_total = if_cloners_count;
  534         if ((dst = ifcr->ifcr_buffer) == NULL) {
  535                 /* Just asking how many there are. */
  536                 return (0);
  537         }
  538 
  539         if (ifcr->ifcr_count < 0)
  540                 return (EINVAL);
  541 
  542         count = (if_cloners_count < ifcr->ifcr_count) ?
  543             if_cloners_count : ifcr->ifcr_count;
  544 
  545         for (ifc = LIST_FIRST(&if_cloners); ifc != NULL && count != 0;
  546              ifc = LIST_NEXT(ifc, ifc_list), count--, dst += IFNAMSIZ) {
  547                 strncpy(outbuf, ifc->ifc_name, IFNAMSIZ);
  548                 outbuf[IFNAMSIZ - 1] = '\0';    /* sanity */
  549                 error = copyout(outbuf, dst, IFNAMSIZ);
  550                 if (error)
  551                         break;
  552         }
  553 
  554         return (error);
  555 }
  556 
  557 /*
  558  * Locate an interface based on a complete address.
  559  */
  560 /*ARGSUSED*/
  561 struct ifaddr *
  562 ifa_ifwithaddr(addr)
  563         register struct sockaddr *addr;
  564 {
  565         register struct ifnet *ifp;
  566         register struct ifaddr *ifa;
  567 
  568 #define equal(a1, a2) \
  569   (bcmp((caddr_t)(a1), (caddr_t)(a2), ((struct sockaddr *)(a1))->sa_len) == 0)
  570         TAILQ_FOREACH(ifp, &ifnet, if_link)
  571             TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
  572                 if (ifa->ifa_addr->sa_family != addr->sa_family)
  573                         continue;
  574                 if (equal(addr, ifa->ifa_addr))
  575                         return (ifa);
  576                 if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr &&
  577                     /* IP6 doesn't have broadcast */
  578                     ifa->ifa_broadaddr->sa_len != 0 &&
  579                     equal(ifa->ifa_broadaddr, addr))
  580                         return (ifa);
  581         }
  582         return ((struct ifaddr *)0);
  583 }
  584 /*
  585  * Locate the point to point interface with a given destination address.
  586  */
  587 /*ARGSUSED*/
  588 struct ifaddr *
  589 ifa_ifwithdstaddr(addr)
  590         register struct sockaddr *addr;
  591 {
  592         register struct ifnet *ifp;
  593         register struct ifaddr *ifa;
  594 
  595         TAILQ_FOREACH(ifp, &ifnet, if_link)
  596             if (ifp->if_flags & IFF_POINTOPOINT)
  597                 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
  598                         if (ifa->ifa_addr->sa_family != addr->sa_family)
  599                                 continue;
  600                         if (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr))
  601                                 return (ifa);
  602         }
  603         return ((struct ifaddr *)0);
  604 }
  605 
  606 /*
  607  * Find an interface on a specific network.  If many, choice
  608  * is most specific found.
  609  */
  610 struct ifaddr *
  611 ifa_ifwithnet(addr)
  612         struct sockaddr *addr;
  613 {
  614         register struct ifnet *ifp;
  615         register struct ifaddr *ifa;
  616         struct ifaddr *ifa_maybe = (struct ifaddr *) 0;
  617         u_int af = addr->sa_family;
  618         char *addr_data = addr->sa_data, *cplim;
  619 
  620         /*
  621          * AF_LINK addresses can be looked up directly by their index number,
  622          * so do that if we can.
  623          */
  624         if (af == AF_LINK) {
  625             register struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr;
  626             if (sdl->sdl_index && sdl->sdl_index <= if_index)
  627                 return (ifnet_addrs[sdl->sdl_index - 1]);
  628         }
  629 
  630         /*
  631          * Scan though each interface, looking for ones that have
  632          * addresses in this address family.
  633          */
  634         TAILQ_FOREACH(ifp, &ifnet, if_link) {
  635                 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
  636                         register char *cp, *cp2, *cp3;
  637 
  638                         if (ifa->ifa_addr->sa_family != af)
  639 next:                           continue;
  640                         if (af == AF_INET && ifp->if_flags & IFF_POINTOPOINT) {
  641                                 /*
  642                                  * This is a bit broken as it doesn't
  643                                  * take into account that the remote end may
  644                                  * be a single node in the network we are
  645                                  * looking for.
  646                                  * The trouble is that we don't know the
  647                                  * netmask for the remote end.
  648                                  */
  649                                 if (ifa->ifa_dstaddr != 0
  650                                     && equal(addr, ifa->ifa_dstaddr))
  651                                         return (ifa);
  652                         } else {
  653                                 /*
  654                                  * if we have a special address handler,
  655                                  * then use it instead of the generic one.
  656                                  */
  657                                 if (ifa->ifa_claim_addr) {
  658                                         if ((*ifa->ifa_claim_addr)(ifa, addr)) {
  659                                                 return (ifa);
  660                                         } else {
  661                                                 continue;
  662                                         }
  663                                 }
  664 
  665                                 /*
  666                                  * Scan all the bits in the ifa's address.
  667                                  * If a bit dissagrees with what we are
  668                                  * looking for, mask it with the netmask
  669                                  * to see if it really matters.
  670                                  * (A byte at a time)
  671                                  */
  672                                 if (ifa->ifa_netmask == 0)
  673                                         continue;
  674                                 cp = addr_data;
  675                                 cp2 = ifa->ifa_addr->sa_data;
  676                                 cp3 = ifa->ifa_netmask->sa_data;
  677                                 cplim = ifa->ifa_netmask->sa_len
  678                                         + (char *)ifa->ifa_netmask;
  679                                 while (cp3 < cplim)
  680                                         if ((*cp++ ^ *cp2++) & *cp3++)
  681                                                 goto next; /* next address! */
  682                                 /*
  683                                  * If the netmask of what we just found
  684                                  * is more specific than what we had before
  685                                  * (if we had one) then remember the new one
  686                                  * before continuing to search
  687                                  * for an even better one.
  688                                  */
  689                                 if (ifa_maybe == 0 ||
  690                                     rn_refines((caddr_t)ifa->ifa_netmask,
  691                                     (caddr_t)ifa_maybe->ifa_netmask))
  692                                         ifa_maybe = ifa;
  693                         }
  694                 }
  695         }
  696         return (ifa_maybe);
  697 }
  698 
  699 /*
  700  * Find an interface address specific to an interface best matching
  701  * a given address.
  702  */
  703 struct ifaddr *
  704 ifaof_ifpforaddr(addr, ifp)
  705         struct sockaddr *addr;
  706         register struct ifnet *ifp;
  707 {
  708         register struct ifaddr *ifa;
  709         register char *cp, *cp2, *cp3;
  710         register char *cplim;
  711         struct ifaddr *ifa_maybe = 0;
  712         u_int af = addr->sa_family;
  713 
  714         if (af >= AF_MAX)
  715                 return (0);
  716         TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
  717                 if (ifa->ifa_addr->sa_family != af)
  718                         continue;
  719                 if (ifa_maybe == 0)
  720                         ifa_maybe = ifa;
  721                 if (ifa->ifa_netmask == 0) {
  722                         if (equal(addr, ifa->ifa_addr) ||
  723                             (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr)))
  724                                 return (ifa);
  725                         continue;
  726                 }
  727                 if (ifp->if_flags & IFF_POINTOPOINT) {
  728                         if (equal(addr, ifa->ifa_dstaddr))
  729                                 return (ifa);
  730                 } else {
  731                         cp = addr->sa_data;
  732                         cp2 = ifa->ifa_addr->sa_data;
  733                         cp3 = ifa->ifa_netmask->sa_data;
  734                         cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
  735                         for (; cp3 < cplim; cp3++)
  736                                 if ((*cp++ ^ *cp2++) & *cp3)
  737                                         break;
  738                         if (cp3 == cplim)
  739                                 return (ifa);
  740                 }
  741         }
  742         return (ifa_maybe);
  743 }
  744 
  745 #include <net/route.h>
  746 
  747 /*
  748  * Default action when installing a route with a Link Level gateway.
  749  * Lookup an appropriate real ifa to point to.
  750  * This should be moved to /sys/net/link.c eventually.
  751  */
  752 static void
  753 link_rtrequest(cmd, rt, info)
  754         int cmd;
  755         register struct rtentry *rt;
  756         struct rt_addrinfo *info;
  757 {
  758         register struct ifaddr *ifa;
  759         struct sockaddr *dst;
  760         struct ifnet *ifp;
  761 
  762         if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) ||
  763             ((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0))
  764                 return;
  765         ifa = ifaof_ifpforaddr(dst, ifp);
  766         if (ifa) {
  767                 IFAFREE(rt->rt_ifa);
  768                 rt->rt_ifa = ifa;
  769                 ifa->ifa_refcnt++;
  770                 if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest)
  771                         ifa->ifa_rtrequest(cmd, rt, info);
  772         }
  773 }
  774 
  775 /*
  776  * Mark an interface down and notify protocols of
  777  * the transition.
  778  * NOTE: must be called at splnet or eqivalent.
  779  */
  780 void
  781 if_unroute(ifp, flag, fam)
  782         register struct ifnet *ifp;
  783         int flag, fam;
  784 {
  785         register struct ifaddr *ifa;
  786 
  787         ifp->if_flags &= ~flag;
  788         getmicrotime(&ifp->if_lastchange);
  789         TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
  790                 if (fam == PF_UNSPEC || (fam == ifa->ifa_addr->sa_family))
  791                         pfctlinput(PRC_IFDOWN, ifa->ifa_addr);
  792         if_qflush(&ifp->if_snd);
  793         rt_ifmsg(ifp);
  794 }
  795 
  796 /*
  797  * Mark an interface up and notify protocols of
  798  * the transition.
  799  * NOTE: must be called at splnet or eqivalent.
  800  */
  801 void
  802 if_route(ifp, flag, fam)
  803         register struct ifnet *ifp;
  804         int flag, fam;
  805 {
  806         register struct ifaddr *ifa;
  807 
  808         ifp->if_flags |= flag;
  809         getmicrotime(&ifp->if_lastchange);
  810         TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
  811                 if (fam == PF_UNSPEC || (fam == ifa->ifa_addr->sa_family))
  812                         pfctlinput(PRC_IFUP, ifa->ifa_addr);
  813         rt_ifmsg(ifp);
  814 #ifdef INET6
  815         in6_if_up(ifp);
  816 #endif
  817 }
  818 
  819 /*
  820  * Mark an interface down and notify protocols of
  821  * the transition.
  822  * NOTE: must be called at splnet or eqivalent.
  823  */
  824 void
  825 if_down(ifp)
  826         register struct ifnet *ifp;
  827 {
  828 
  829         if_unroute(ifp, IFF_UP, AF_UNSPEC);
  830 }
  831 
  832 /*
  833  * Mark an interface up and notify protocols of
  834  * the transition.
  835  * NOTE: must be called at splnet or eqivalent.
  836  */
  837 void
  838 if_up(ifp)
  839         register struct ifnet *ifp;
  840 {
  841 
  842         if_route(ifp, IFF_UP, AF_UNSPEC);
  843 }
  844 
  845 /*
  846  * Flush an interface queue.
  847  */
  848 static void
  849 if_qflush(ifq)
  850         register struct ifqueue *ifq;
  851 {
  852         register struct mbuf *m, *n;
  853 
  854         n = ifq->ifq_head;
  855         while ((m = n) != 0) {
  856                 n = m->m_act;
  857                 m_freem(m);
  858         }
  859         ifq->ifq_head = 0;
  860         ifq->ifq_tail = 0;
  861         ifq->ifq_len = 0;
  862 }
  863 
  864 /*
  865  * Handle interface watchdog timer routines.  Called
  866  * from softclock, we decrement timers (if set) and
  867  * call the appropriate interface routine on expiration.
  868  */
  869 static void
  870 if_slowtimo(arg)
  871         void *arg;
  872 {
  873         register struct ifnet *ifp;
  874         int s = splimp();
  875 
  876         TAILQ_FOREACH(ifp, &ifnet, if_link) {
  877                 if (ifp->if_timer == 0 || --ifp->if_timer)
  878                         continue;
  879                 if (ifp->if_watchdog)
  880                         (*ifp->if_watchdog)(ifp);
  881         }
  882         splx(s);
  883         timeout(if_slowtimo, (void *)0, hz / IFNET_SLOWHZ);
  884 }
  885 
  886 /*
  887  * Map interface name to
  888  * interface structure pointer.
  889  */
  890 struct ifnet *
  891 ifunit(const char *name)
  892 {
  893         char namebuf[IFNAMSIZ + 1];
  894         const char *cp;
  895         struct ifnet *ifp;
  896         int unit;
  897         unsigned len, m;
  898         char c;
  899 
  900         len = strlen(name);
  901         if (len < 2 || len > IFNAMSIZ)
  902                 return NULL;
  903         cp = name + len - 1;
  904         c = *cp;
  905         if (c < '' || c > '9')
  906                 return NULL;            /* trailing garbage */
  907         unit = 0;
  908         m = 1;
  909         do {
  910                 if (cp == name)
  911                         return NULL;    /* no interface name */
  912                 unit += (c - '') * m;
  913                 if (unit > 1000000)
  914                         return NULL;    /* number is unreasonable */
  915                 m *= 10;
  916                 c = *--cp;
  917         } while (c >= '' && c <= '9');
  918         len = cp - name + 1;
  919         bcopy(name, namebuf, len);
  920         namebuf[len] = '\0';
  921         /*
  922          * Now search all the interfaces for this name/number
  923          */
  924         TAILQ_FOREACH(ifp, &ifnet, if_link) {
  925                 if (strcmp(ifp->if_name, namebuf))
  926                         continue;
  927                 if (unit == ifp->if_unit)
  928                         break;
  929         }
  930         return (ifp);
  931 }
  932 
  933 
  934 /*
  935  * Map interface name in a sockaddr_dl to
  936  * interface structure pointer.
  937  */
  938 struct ifnet *
  939 if_withname(sa)
  940         struct sockaddr *sa;
  941 {
  942         char ifname[IFNAMSIZ+1];
  943         struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;
  944 
  945         if ( (sa->sa_family != AF_LINK) || (sdl->sdl_nlen == 0) ||
  946              (sdl->sdl_nlen > IFNAMSIZ) )
  947                 return NULL;
  948 
  949         /*
  950          * ifunit wants a null-terminated name.  It may not be null-terminated
  951          * in the sockaddr.  We don't want to change the caller's sockaddr,
  952          * and there might not be room to put the trailing null anyway, so we
  953          * make a local copy that we know we can null terminate safely.
  954          */
  955 
  956         bcopy(sdl->sdl_data, ifname, sdl->sdl_nlen);
  957         ifname[sdl->sdl_nlen] = '\0';
  958         return ifunit(ifname);
  959 }
  960 
  961 
  962 /*
  963  * Interface ioctls.
  964  */
  965 int
  966 ifioctl(so, cmd, data, p)
  967         struct socket *so;
  968         u_long cmd;
  969         caddr_t data;
  970         struct proc *p;
  971 {
  972         register struct ifnet *ifp;
  973         register struct ifreq *ifr;
  974         struct ifstat *ifs;
  975         int error;
  976         short oif_flags;
  977         int new_flags;
  978 
  979         switch (cmd) {
  980 
  981         case SIOCGIFCONF:
  982         case OSIOCGIFCONF:
  983                 return (ifconf(cmd, data));
  984         }
  985         ifr = (struct ifreq *)data;
  986 
  987         switch (cmd) {
  988         case SIOCIFCREATE:
  989         case SIOCIFDESTROY:
  990                 if ((error = suser(p)) != 0)
  991                         return (error);
  992                 return ((cmd == SIOCIFCREATE) ?
  993                         if_clone_create(ifr->ifr_name, sizeof(ifr->ifr_name)) :
  994                         if_clone_destroy(ifr->ifr_name));
  995         
  996         case SIOCIFGCLONERS:
  997                 return (if_clone_list((struct if_clonereq *)data));
  998         }
  999 
 1000         ifp = ifunit(ifr->ifr_name);
 1001         if (ifp == 0)
 1002                 return (ENXIO);
 1003         switch (cmd) {
 1004 
 1005         case SIOCGIFFLAGS:
 1006                 ifr->ifr_flags = ifp->if_flags;
 1007                 ifr->ifr_flagshigh = ifp->if_ipending >> 16;
 1008                 break;
 1009 
 1010         case SIOCGIFCAP:
 1011                 ifr->ifr_reqcap = ifp->if_capabilities;
 1012                 ifr->ifr_curcap = ifp->if_capenable;
 1013                 break;
 1014 
 1015         case SIOCGIFMETRIC:
 1016                 ifr->ifr_metric = ifp->if_metric;
 1017                 break;
 1018 
 1019         case SIOCGIFMTU:
 1020                 ifr->ifr_mtu = ifp->if_mtu;
 1021                 break;
 1022 
 1023         case SIOCGIFPHYS:
 1024                 ifr->ifr_phys = ifp->if_physical;
 1025                 break;
 1026 
 1027         case SIOCSIFFLAGS:
 1028                 error = suser(p);
 1029                 if (error)
 1030                         return (error);
 1031                 new_flags = (ifr->ifr_flags & 0xffff) |
 1032                     (ifr->ifr_flagshigh << 16);
 1033                 if (ifp->if_flags & IFF_SMART) {
 1034                         /* Smart drivers twiddle their own routes */
 1035                 } else if (ifp->if_flags & IFF_UP &&
 1036                     (new_flags & IFF_UP) == 0) {
 1037                         int s = splimp();
 1038                         if_down(ifp);
 1039                         splx(s);
 1040                 } else if (new_flags & IFF_UP &&
 1041                     (ifp->if_flags & IFF_UP) == 0) {
 1042                         int s = splimp();
 1043                         if_up(ifp);
 1044                         splx(s);
 1045                 }
 1046                 ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
 1047                         (new_flags &~ IFF_CANTCHANGE);
 1048                 ifp->if_ipending = (ifp->if_ipending & IFF_CANTCHANGE) |
 1049                         (new_flags &~ IFF_CANTCHANGE);
 1050                 if (new_flags & IFF_PPROMISC) {
 1051                         /* Permanently promiscuous mode requested */
 1052                         ifp->if_flags |= IFF_PROMISC;
 1053                 } else if (ifp->if_pcount == 0) {
 1054                         ifp->if_flags &= ~IFF_PROMISC;
 1055                 }
 1056                 if (ifp->if_ioctl)
 1057                         (void) (*ifp->if_ioctl)(ifp, cmd, data);
 1058                 getmicrotime(&ifp->if_lastchange);
 1059                 break;
 1060 
 1061         case SIOCSIFCAP:
 1062                 error = suser(p);
 1063                 if (error)
 1064                         return (error);
 1065                 if (ifr->ifr_reqcap & ~ifp->if_capabilities)
 1066                         return (EINVAL);
 1067                 (void) (*ifp->if_ioctl)(ifp, cmd, data);
 1068                 break;
 1069 
 1070         case SIOCSIFMETRIC:
 1071                 error = suser(p);
 1072                 if (error)
 1073                         return (error);
 1074                 ifp->if_metric = ifr->ifr_metric;
 1075                 getmicrotime(&ifp->if_lastchange);
 1076                 break;
 1077 
 1078         case SIOCSIFPHYS:
 1079                 error = suser(p);
 1080                 if (error)
 1081                         return error;
 1082                 if (!ifp->if_ioctl)
 1083                         return EOPNOTSUPP;
 1084                 error = (*ifp->if_ioctl)(ifp, cmd, data);
 1085                 if (error == 0)
 1086                         getmicrotime(&ifp->if_lastchange);
 1087                 return(error);
 1088 
 1089         case SIOCSIFMTU:
 1090         {
 1091                 u_long oldmtu = ifp->if_mtu;
 1092 
 1093                 error = suser(p);
 1094                 if (error)
 1095                         return (error);
 1096                 if (ifp->if_ioctl == NULL)
 1097                         return (EOPNOTSUPP);
 1098                 if (ifr->ifr_mtu < IF_MINMTU || ifr->ifr_mtu > IF_MAXMTU)
 1099                         return (EINVAL);
 1100                 error = (*ifp->if_ioctl)(ifp, cmd, data);
 1101                 if (error == 0) {
 1102                         getmicrotime(&ifp->if_lastchange);
 1103                         rt_ifmsg(ifp);
 1104                 }
 1105                 /*
 1106                  * If the link MTU changed, do network layer specific procedure.
 1107                  */
 1108                 if (ifp->if_mtu != oldmtu) {
 1109 #ifdef INET6
 1110                         nd6_setmtu(ifp);
 1111 #endif
 1112                 }
 1113                 return (error);
 1114         }
 1115 
 1116         case SIOCADDMULTI:
 1117         case SIOCDELMULTI:
 1118                 error = suser(p);
 1119                 if (error)
 1120                         return (error);
 1121 
 1122                 /* Don't allow group membership on non-multicast interfaces. */
 1123                 if ((ifp->if_flags & IFF_MULTICAST) == 0)
 1124                         return EOPNOTSUPP;
 1125 
 1126                 /* Don't let users screw up protocols' entries. */
 1127                 if (ifr->ifr_addr.sa_family != AF_LINK)
 1128                         return EINVAL;
 1129 
 1130                 if (cmd == SIOCADDMULTI) {
 1131                         struct ifmultiaddr *ifma;
 1132                         error = if_addmulti(ifp, &ifr->ifr_addr, &ifma);
 1133                 } else {
 1134                         error = if_delmulti(ifp, &ifr->ifr_addr);
 1135                 }
 1136                 if (error == 0)
 1137                         getmicrotime(&ifp->if_lastchange);
 1138                 return error;
 1139 
 1140         case SIOCSIFPHYADDR:
 1141         case SIOCDIFPHYADDR:
 1142 #ifdef INET6
 1143         case SIOCSIFPHYADDR_IN6:
 1144 #endif
 1145         case SIOCSLIFPHYADDR:
 1146         case SIOCSIFMEDIA:
 1147         case SIOCSIFGENERIC:
 1148                 error = suser(p);
 1149                 if (error)
 1150                         return (error);
 1151                 if (ifp->if_ioctl == 0)
 1152                         return (EOPNOTSUPP);
 1153                 error = (*ifp->if_ioctl)(ifp, cmd, data);
 1154                 if (error == 0)
 1155                         getmicrotime(&ifp->if_lastchange);
 1156                 return error;
 1157 
 1158         case SIOCGIFSTATUS:
 1159                 ifs = (struct ifstat *)data;
 1160                 ifs->ascii[0] = '\0';
 1161                 
 1162         case SIOCGIFPSRCADDR:
 1163         case SIOCGIFPDSTADDR:
 1164         case SIOCGLIFPHYADDR:
 1165         case SIOCGIFMEDIA:
 1166         case SIOCGIFGENERIC:
 1167                 if (ifp->if_ioctl == 0)
 1168                         return (EOPNOTSUPP);
 1169                 return ((*ifp->if_ioctl)(ifp, cmd, data));
 1170 
 1171         case SIOCSIFLLADDR:
 1172                 error = suser(p);
 1173                 if (error)
 1174                         return (error);
 1175                 return if_setlladdr(ifp,
 1176                     ifr->ifr_addr.sa_data, ifr->ifr_addr.sa_len);
 1177 
 1178         default:
 1179                 oif_flags = ifp->if_flags;
 1180                 if (so->so_proto == 0)
 1181                         return (EOPNOTSUPP);
 1182 #ifndef COMPAT_43
 1183                 error = ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd,
 1184                                                                  data,
 1185                                                                  ifp, p));
 1186 #else
 1187             {
 1188                 int ocmd = cmd;
 1189 
 1190                 switch (cmd) {
 1191 
 1192                 case SIOCSIFDSTADDR:
 1193                 case SIOCSIFADDR:
 1194                 case SIOCSIFBRDADDR:
 1195                 case SIOCSIFNETMASK:
 1196 #if BYTE_ORDER != BIG_ENDIAN
 1197                         if (ifr->ifr_addr.sa_family == 0 &&
 1198                             ifr->ifr_addr.sa_len < 16) {
 1199                                 ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len;
 1200                                 ifr->ifr_addr.sa_len = 16;
 1201                         }
 1202 #else
 1203                         if (ifr->ifr_addr.sa_len == 0)
 1204                                 ifr->ifr_addr.sa_len = 16;
 1205 #endif
 1206                         break;
 1207 
 1208                 case OSIOCGIFADDR:
 1209                         cmd = SIOCGIFADDR;
 1210                         break;
 1211 
 1212                 case OSIOCGIFDSTADDR:
 1213                         cmd = SIOCGIFDSTADDR;
 1214                         break;
 1215 
 1216                 case OSIOCGIFBRDADDR:
 1217                         cmd = SIOCGIFBRDADDR;
 1218                         break;
 1219 
 1220                 case OSIOCGIFNETMASK:
 1221                         cmd = SIOCGIFNETMASK;
 1222                 }
 1223                 error =  ((*so->so_proto->pr_usrreqs->pru_control)(so,
 1224                                                                    cmd,
 1225                                                                    data,
 1226                                                                    ifp, p));
 1227                 switch (ocmd) {
 1228 
 1229                 case OSIOCGIFADDR:
 1230                 case OSIOCGIFDSTADDR:
 1231                 case OSIOCGIFBRDADDR:
 1232                 case OSIOCGIFNETMASK:
 1233                         *(u_short *)&ifr->ifr_addr = ifr->ifr_addr.sa_family;
 1234 
 1235                 }
 1236             }
 1237 #endif /* COMPAT_43 */
 1238 
 1239                 if ((oif_flags ^ ifp->if_flags) & IFF_UP) {
 1240 #ifdef INET6
 1241                         DELAY(100);/* XXX: temporary workaround for fxp issue*/
 1242                         if (ifp->if_flags & IFF_UP) {
 1243                                 int s = splimp();
 1244                                 in6_if_up(ifp);
 1245                                 splx(s);
 1246                         }
 1247 #endif
 1248                 }
 1249                 return (error);
 1250 
 1251         }
 1252         return (0);
 1253 }
 1254 
 1255 /*
 1256  * Set/clear promiscuous mode on interface ifp based on the truth value
 1257  * of pswitch.  The calls are reference counted so that only the first
 1258  * "on" request actually has an effect, as does the final "off" request.
 1259  * Results are undefined if the "off" and "on" requests are not matched.
 1260  */
 1261 int
 1262 ifpromisc(ifp, pswitch)
 1263         struct ifnet *ifp;
 1264         int pswitch;
 1265 {
 1266         struct ifreq ifr;
 1267         int error;
 1268         int oldflags;
 1269 
 1270         oldflags = ifp->if_flags;
 1271         if (ifp->if_ipending & IFF_PPROMISC) {
 1272                 /* Do nothing if device is in permanently promiscuous mode */
 1273                 ifp->if_pcount += pswitch ? 1 : -1;
 1274                 return (0);
 1275         }
 1276         if (pswitch) {
 1277                 /*
 1278                  * If the device is not configured up, we cannot put it in
 1279                  * promiscuous mode.
 1280                  */
 1281                 if ((ifp->if_flags & IFF_UP) == 0)
 1282                         return (ENETDOWN);
 1283                 if (ifp->if_pcount++ != 0)
 1284                         return (0);
 1285                 ifp->if_flags |= IFF_PROMISC;
 1286                 log(LOG_INFO, "%s%d: promiscuous mode enabled\n",
 1287                     ifp->if_name, ifp->if_unit);
 1288         } else {
 1289                 if (--ifp->if_pcount > 0)
 1290                         return (0);
 1291                 ifp->if_flags &= ~IFF_PROMISC;
 1292                 log(LOG_INFO, "%s%d: promiscuous mode disabled\n",
 1293                     ifp->if_name, ifp->if_unit);
 1294         }
 1295         ifr.ifr_flags = ifp->if_flags;
 1296         ifr.ifr_flagshigh = ifp->if_ipending >> 16;
 1297         error = (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr);
 1298         if (error == 0)
 1299                 rt_ifmsg(ifp);
 1300         else
 1301                 ifp->if_flags = oldflags;
 1302         return error;
 1303 }
 1304 
 1305 /*
 1306  * Return interface configuration
 1307  * of system.  List may be used
 1308  * in later ioctl's (above) to get
 1309  * other information.
 1310  */
 1311 /*ARGSUSED*/
 1312 static int
 1313 ifconf(cmd, data)
 1314         u_long cmd;
 1315         caddr_t data;
 1316 {
 1317         register struct ifconf *ifc = (struct ifconf *)data;
 1318         register struct ifnet *ifp;
 1319         register struct ifaddr *ifa;
 1320         struct sockaddr *sa;
 1321         struct ifreq ifr, *ifrp;
 1322         int space = ifc->ifc_len, error = 0;
 1323 
 1324         ifrp = ifc->ifc_req;
 1325         TAILQ_FOREACH(ifp, &ifnet, if_link) {
 1326                 char workbuf[64];
 1327                 int ifnlen, addrs;
 1328 
 1329                 /*
 1330                  * Zero the ifr_name buffer to make sure we don't
 1331                  * disclose the contents of the stack.
 1332                  */
 1333                 memset(ifr.ifr_name, 0, sizeof(ifr.ifr_name));
 1334 
 1335                 if (space <= sizeof (ifr))
 1336                         break;
 1337                 ifnlen = snprintf(workbuf, sizeof(workbuf),
 1338                     "%s%d", ifp->if_name, ifp->if_unit);
 1339                 if(ifnlen + 1 > sizeof ifr.ifr_name) {
 1340                         error = ENAMETOOLONG;
 1341                         break;
 1342                 } else {
 1343                         strcpy(ifr.ifr_name, workbuf);
 1344                 }
 1345 
 1346                 addrs = 0;
 1347                 ifa = ifp->if_addrhead.tqh_first;
 1348                 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
 1349                         if (space <= sizeof(ifr))
 1350                                 break;
 1351                         sa = ifa->ifa_addr;
 1352                         if (curproc->p_prison && prison_if(curproc, sa))
 1353                                 continue;
 1354                         addrs++;
 1355 #ifdef COMPAT_43
 1356                         if (cmd == OSIOCGIFCONF) {
 1357                                 struct osockaddr *osa =
 1358                                          (struct osockaddr *)&ifr.ifr_addr;
 1359                                 ifr.ifr_addr = *sa;
 1360                                 osa->sa_family = sa->sa_family;
 1361                                 error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
 1362                                                 sizeof (ifr));
 1363                                 ifrp++;
 1364                         } else
 1365 #endif
 1366                         if (sa->sa_len <= sizeof(*sa)) {
 1367                                 ifr.ifr_addr = *sa;
 1368                                 error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
 1369                                                 sizeof (ifr));
 1370                                 ifrp++;
 1371                         } else {
 1372                                 if (space < sizeof (ifr) + sa->sa_len -
 1373                                             sizeof(*sa))
 1374                                         break;
 1375                                 space -= sa->sa_len - sizeof(*sa);
 1376                                 error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
 1377                                                 sizeof (ifr.ifr_name));
 1378                                 if (error == 0)
 1379                                     error = copyout((caddr_t)sa,
 1380                                       (caddr_t)&ifrp->ifr_addr, sa->sa_len);
 1381                                 ifrp = (struct ifreq *)
 1382                                         (sa->sa_len + (caddr_t)&ifrp->ifr_addr);
 1383                         }
 1384                         if (error)
 1385                                 break;
 1386                         space -= sizeof (ifr);
 1387                 }
 1388                 if (error)
 1389                         break;
 1390                 if (!addrs) {
 1391                         bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
 1392                         error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
 1393                             sizeof (ifr));
 1394                         if (error)
 1395                                 break;
 1396                         space -= sizeof (ifr);
 1397                         ifrp++;
 1398                 }
 1399         }
 1400         ifc->ifc_len -= space;
 1401         return (error);
 1402 }
 1403 
 1404 /*
 1405  * Just like if_promisc(), but for all-multicast-reception mode.
 1406  */
 1407 int
 1408 if_allmulti(ifp, onswitch)
 1409         struct ifnet *ifp;
 1410         int onswitch;
 1411 {
 1412         int error = 0;
 1413         int s = splimp();
 1414         struct ifreq ifr;
 1415 
 1416         if (onswitch) {
 1417                 if (ifp->if_amcount++ == 0) {
 1418                         ifp->if_flags |= IFF_ALLMULTI;
 1419                         ifr.ifr_flags = ifp->if_flags;
 1420                         ifr.ifr_flagshigh = ifp->if_ipending >> 16;
 1421                         error = ifp->if_ioctl(ifp, SIOCSIFFLAGS, (caddr_t)&ifr);
 1422                 }
 1423         } else {
 1424                 if (ifp->if_amcount > 1) {
 1425                         ifp->if_amcount--;
 1426                 } else {
 1427                         ifp->if_amcount = 0;
 1428                         ifp->if_flags &= ~IFF_ALLMULTI;
 1429                         ifr.ifr_flags = ifp->if_flags;
 1430                         ifr.ifr_flagshigh = ifp->if_ipending >> 16;
 1431                         error = ifp->if_ioctl(ifp, SIOCSIFFLAGS, (caddr_t)&ifr);
 1432                 }
 1433         }
 1434         splx(s);
 1435 
 1436         if (error == 0)
 1437                 rt_ifmsg(ifp);
 1438         return error;
 1439 }
 1440 
 1441 /*
 1442  * Add a multicast listenership to the interface in question.
 1443  * The link layer provides a routine which converts
 1444  */
 1445 int
 1446 if_addmulti(ifp, sa, retifma)
 1447         struct ifnet *ifp;      /* interface to manipulate */
 1448         struct sockaddr *sa;    /* address to add */
 1449         struct ifmultiaddr **retifma;
 1450 {
 1451         struct sockaddr *llsa, *dupsa;
 1452         int error, s;
 1453         struct ifmultiaddr *ifma;
 1454 
 1455         /*
 1456          * If the matching multicast address already exists
 1457          * then don't add a new one, just add a reference
 1458          */
 1459         LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
 1460                 if (equal(sa, ifma->ifma_addr)) {
 1461                         ifma->ifma_refcount++;
 1462                         if (retifma)
 1463                                 *retifma = ifma;
 1464                         return 0;
 1465                 }
 1466         }
 1467 
 1468         /*
 1469          * Give the link layer a chance to accept/reject it, and also
 1470          * find out which AF_LINK address this maps to, if it isn't one
 1471          * already.
 1472          */
 1473         if (ifp->if_resolvemulti) {
 1474                 error = ifp->if_resolvemulti(ifp, &llsa, sa);
 1475                 if (error) return error;
 1476         } else {
 1477                 llsa = 0;
 1478         }
 1479 
 1480         MALLOC(ifma, struct ifmultiaddr *, sizeof *ifma, M_IFMADDR, M_WAITOK);
 1481         MALLOC(dupsa, struct sockaddr *, sa->sa_len, M_IFMADDR, M_WAITOK);
 1482         bcopy(sa, dupsa, sa->sa_len);
 1483 
 1484         ifma->ifma_addr = dupsa;
 1485         ifma->ifma_lladdr = llsa;
 1486         ifma->ifma_ifp = ifp;
 1487         ifma->ifma_refcount = 1;
 1488         ifma->ifma_protospec = 0;
 1489         rt_newmaddrmsg(RTM_NEWMADDR, ifma);
 1490 
 1491         /*
 1492          * Some network interfaces can scan the address list at
 1493          * interrupt time; lock them out.
 1494          */
 1495         s = splimp();
 1496         LIST_INSERT_HEAD(&ifp->if_multiaddrs, ifma, ifma_link);
 1497         splx(s);
 1498         *retifma = ifma;
 1499 
 1500         if (llsa != 0) {
 1501                 LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
 1502                         if (equal(ifma->ifma_addr, llsa))
 1503                                 break;
 1504                 }
 1505                 if (ifma) {
 1506                         ifma->ifma_refcount++;
 1507                 } else {
 1508                         MALLOC(ifma, struct ifmultiaddr *, sizeof *ifma,
 1509                                M_IFMADDR, M_WAITOK);
 1510                         MALLOC(dupsa, struct sockaddr *, llsa->sa_len,
 1511                                M_IFMADDR, M_WAITOK);
 1512                         bcopy(llsa, dupsa, llsa->sa_len);
 1513                         ifma->ifma_addr = dupsa;
 1514                         ifma->ifma_lladdr = NULL;
 1515                         ifma->ifma_ifp = ifp;
 1516                         ifma->ifma_refcount = 1;
 1517                         ifma->ifma_protospec = 0;
 1518                         s = splimp();
 1519                         LIST_INSERT_HEAD(&ifp->if_multiaddrs, ifma, ifma_link);
 1520                         splx(s);
 1521                 }
 1522         }
 1523         /*
 1524          * We are certain we have added something, so call down to the
 1525          * interface to let them know about it.
 1526          */
 1527         s = splimp();
 1528         ifp->if_ioctl(ifp, SIOCADDMULTI, 0);
 1529         splx(s);
 1530 
 1531         return 0;
 1532 }
 1533 
 1534 /*
 1535  * Remove a reference to a multicast address on this interface.  Yell
 1536  * if the request does not match an existing membership.
 1537  */
 1538 int
 1539 if_delmulti(ifp, sa)
 1540         struct ifnet *ifp;
 1541         struct sockaddr *sa;
 1542 {
 1543         struct ifmultiaddr *ifma;
 1544         int s;
 1545 
 1546         LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
 1547                 if (equal(sa, ifma->ifma_addr))
 1548                         break;
 1549         if (ifma == 0)
 1550                 return ENOENT;
 1551 
 1552         if (ifma->ifma_refcount > 1) {
 1553                 ifma->ifma_refcount--;
 1554                 return 0;
 1555         }
 1556 
 1557         rt_newmaddrmsg(RTM_DELMADDR, ifma);
 1558         sa = ifma->ifma_lladdr;
 1559         s = splimp();
 1560         LIST_REMOVE(ifma, ifma_link);
 1561         /*
 1562          * Make sure the interface driver is notified
 1563          * in the case of a link layer mcast group being left.
 1564          */
 1565         if (ifma->ifma_addr->sa_family == AF_LINK && sa == 0)
 1566                 ifp->if_ioctl(ifp, SIOCDELMULTI, 0);
 1567         splx(s);
 1568         free(ifma->ifma_addr, M_IFMADDR);
 1569         free(ifma, M_IFMADDR);
 1570         if (sa == 0)
 1571                 return 0;
 1572 
 1573         /*
 1574          * Now look for the link-layer address which corresponds to
 1575          * this network address.  It had been squirreled away in
 1576          * ifma->ifma_lladdr for this purpose (so we don't have
 1577          * to call ifp->if_resolvemulti() again), and we saved that
 1578          * value in sa above.  If some nasty deleted the
 1579          * link-layer address out from underneath us, we can deal because
 1580          * the address we stored was is not the same as the one which was
 1581          * in the record for the link-layer address.  (So we don't complain
 1582          * in that case.)
 1583          */
 1584         LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
 1585                 if (equal(sa, ifma->ifma_addr))
 1586                         break;
 1587         if (ifma == 0)
 1588                 return 0;
 1589 
 1590         if (ifma->ifma_refcount > 1) {
 1591                 ifma->ifma_refcount--;
 1592                 return 0;
 1593         }
 1594 
 1595         s = splimp();
 1596         LIST_REMOVE(ifma, ifma_link);
 1597         ifp->if_ioctl(ifp, SIOCDELMULTI, 0);
 1598         splx(s);
 1599         free(ifma->ifma_addr, M_IFMADDR);
 1600         free(sa, M_IFMADDR);
 1601         free(ifma, M_IFMADDR);
 1602 
 1603         return 0;
 1604 }
 1605 
 1606 /*
 1607  * Set the link layer address on an interface.
 1608  *
 1609  * At this time we only support certain types of interfaces,
 1610  * and we don't allow the length of the address to change.
 1611  */
 1612 int
 1613 if_setlladdr(struct ifnet *ifp, const u_char *lladdr, int len)
 1614 {
 1615         struct sockaddr_dl *sdl;
 1616         struct ifaddr *ifa;
 1617         struct ifreq ifr;
 1618 
 1619         ifa = ifnet_addrs[ifp->if_index - 1];
 1620         if (ifa == NULL)
 1621                 return (EINVAL);
 1622         sdl = (struct sockaddr_dl *)ifa->ifa_addr;
 1623         if (sdl == NULL)
 1624                 return (EINVAL);
 1625         if (len != sdl->sdl_alen)       /* don't allow length to change */
 1626                 return (EINVAL);
 1627         switch (ifp->if_type) {
 1628         case IFT_ETHER:                 /* these types use struct arpcom */
 1629         case IFT_FDDI:
 1630         case IFT_XETHER:
 1631         case IFT_ISO88025:
 1632         case IFT_L2VLAN:
 1633                 bcopy(lladdr, ((struct arpcom *)ifp->if_softc)->ac_enaddr, len);
 1634                 /* FALLTHROUGH */
 1635         case IFT_ARCNET:
 1636                 bcopy(lladdr, LLADDR(sdl), len);
 1637                 break;
 1638         default:
 1639                 return (ENODEV);
 1640         }
 1641         /*
 1642          * If the interface is already up, we need
 1643          * to re-init it in order to reprogram its
 1644          * address filter.
 1645          */
 1646         if ((ifp->if_flags & IFF_UP) != 0) {
 1647                 ifp->if_flags &= ~IFF_UP;
 1648                 ifr.ifr_flags = ifp->if_flags;
 1649                 ifr.ifr_flagshigh = ifp->if_ipending >> 16;
 1650                 (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr);
 1651                 ifp->if_flags |= IFF_UP;
 1652                 ifr.ifr_flags = ifp->if_flags;
 1653                 ifr.ifr_flagshigh = ifp->if_ipending >> 16;
 1654                 (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr);
 1655 #ifdef INET
 1656                 /*
 1657                  * Also send gratuitous ARPs to notify other nodes about
 1658                  * the address change.
 1659                  */
 1660                 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
 1661                         if (ifa->ifa_addr != NULL &&
 1662                             ifa->ifa_addr->sa_family == AF_INET)
 1663                                 arp_ifinit(ifp, ifa);
 1664                 }
 1665 #endif
 1666         }
 1667         return (0);
 1668 }
 1669 
 1670 struct ifmultiaddr *
 1671 ifmaof_ifpforaddr(sa, ifp)
 1672         struct sockaddr *sa;
 1673         struct ifnet *ifp;
 1674 {
 1675         struct ifmultiaddr *ifma;
 1676 
 1677         LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
 1678                 if (equal(ifma->ifma_addr, sa))
 1679                         break;
 1680 
 1681         return ifma;
 1682 }
 1683 
 1684 int
 1685 if_printf(struct ifnet *ifp, const char *fmt, ...)
 1686 {
 1687         va_list ap;
 1688         int retval;
 1689 
 1690         retval = printf("%s%d: ", ifp->if_name, ifp->if_unit);
 1691         va_start(ap, fmt);
 1692         retval += vprintf(fmt, ap);
 1693         va_end(ap);
 1694         return (retval);
 1695 }
 1696 
 1697 SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW, 0, "Link layers");
 1698 SYSCTL_NODE(_net_link, 0, generic, CTLFLAG_RW, 0, "Generic link-management");

Cache object: 2ec7cefcdca41cf41729aeedaabdf7a7


[ 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.