diff options
Diffstat (limited to 'c/src/exec/libnetworking/net/if.c')
-rw-r--r-- | c/src/exec/libnetworking/net/if.c | 783 |
1 files changed, 0 insertions, 783 deletions
diff --git a/c/src/exec/libnetworking/net/if.c b/c/src/exec/libnetworking/net/if.c deleted file mode 100644 index af6f003de3..0000000000 --- a/c/src/exec/libnetworking/net/if.c +++ /dev/null @@ -1,783 +0,0 @@ -/* - * Copyright (c) 1980, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)if.c 8.3 (Berkeley) 1/4/94 - * $Id$ - */ - -#include <sys/param.h> -#include <sys/queue.h> -#include <sys/mbuf.h> -#include <sys/systm.h> -#include <sys/proc.h> -#include <sys/socket.h> -#include <sys/socketvar.h> -#include <sys/protosw.h> -#include <sys/kernel.h> -#include <sys/ioctl.h> -#include <sys/errno.h> -#include <sys/syslog.h> -#include <sys/sysctl.h> - -#include <net/if.h> -#include <net/if_dl.h> -#include <net/if_types.h> -#include <net/radix.h> - -/* - * System initialization - */ - -static int ifconf __P((int, caddr_t)); - void ifinit __P((void *)); -static void if_qflush __P((struct ifqueue *)); -static void if_slowtimo __P((void *)); -static void link_rtrequest __P((int, struct rtentry *, struct sockaddr *)); - -SYSINIT(interfaces, SI_SUB_PROTO_IF, SI_ORDER_FIRST, ifinit, NULL) - - -int ifqmaxlen = IFQ_MAXLEN; -struct ifnet *ifnet; - -/* - * Network interface utility routines. - * - * Routines with ifa_ifwith* names take sockaddr *'s as - * parameters. - * - * This routine assumes that it will be called at splimp() or higher. - */ -/* ARGSUSED*/ -void -ifinit(dummy) - void *dummy; -{ - register struct ifnet *ifp; - - for (ifp = ifnet; ifp; ifp = ifp->if_next) - if (ifp->if_snd.ifq_maxlen == 0) - ifp->if_snd.ifq_maxlen = ifqmaxlen; - if_slowtimo(0); -} - -int if_index = 0; -struct ifaddr **ifnet_addrs; - - -/* - * Attach an interface to the - * list of "active" interfaces. - */ -void -if_attach(ifp) - struct ifnet *ifp; -{ - unsigned socksize, ifasize; - int namelen, masklen; - char workbuf[64]; - register struct ifnet **p = &ifnet; - register struct sockaddr_dl *sdl; - register struct ifaddr *ifa; - static int if_indexlim = 8; - - - while (*p) - p = &((*p)->if_next); - *p = ifp; - ifp->if_index = ++if_index; - microtime(&ifp->if_lastchange); - if (ifnet_addrs == 0 || if_index >= if_indexlim) { - unsigned n = (if_indexlim <<= 1) * sizeof(ifa); - struct ifaddr **q = (struct ifaddr **) - malloc(n, M_IFADDR, M_WAITOK); - bzero((caddr_t)q, n); - if (ifnet_addrs) { - bcopy((caddr_t)ifnet_addrs, (caddr_t)q, n/2); - free((caddr_t)ifnet_addrs, M_IFADDR); - } - ifnet_addrs = q; - } - /* - * create a Link Level name for this device - */ - namelen = sprintf(workbuf, "%s%d", ifp->if_name, ifp->if_unit); -#define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m)) - masklen = _offsetof(struct sockaddr_dl, sdl_data[0]) + namelen; - socksize = masklen + ifp->if_addrlen; -#define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1))) - socksize = ROUNDUP(socksize); - if (socksize < sizeof(*sdl)) - socksize = sizeof(*sdl); - ifasize = sizeof(*ifa) + 2 * socksize; - ifa = (struct ifaddr *)malloc(ifasize, M_IFADDR, M_WAITOK); - if (ifa) { - bzero((caddr_t)ifa, ifasize); - sdl = (struct sockaddr_dl *)(ifa + 1); - sdl->sdl_len = socksize; - sdl->sdl_family = AF_LINK; - bcopy(workbuf, sdl->sdl_data, namelen); - sdl->sdl_nlen = namelen; - sdl->sdl_index = ifp->if_index; - sdl->sdl_type = ifp->if_type; - ifnet_addrs[if_index - 1] = ifa; - ifa->ifa_ifp = ifp; - ifa->ifa_next = ifp->if_addrlist; - ifa->ifa_rtrequest = link_rtrequest; - ifp->if_addrlist = ifa; - ifa->ifa_addr = (struct sockaddr *)sdl; - - sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl); - ifa->ifa_netmask = (struct sockaddr *)sdl; - sdl->sdl_len = masklen; - while (namelen != 0) - sdl->sdl_data[--namelen] = 0xff; - } -} -/* - * Locate an interface based on a complete address. - */ -/*ARGSUSED*/ -struct ifaddr * -ifa_ifwithaddr(addr) - register struct sockaddr *addr; -{ - register struct ifnet *ifp; - register struct ifaddr *ifa; - -#define equal(a1, a2) \ - (bcmp((caddr_t)(a1), (caddr_t)(a2), ((struct sockaddr *)(a1))->sa_len) == 0) - for (ifp = ifnet; ifp; ifp = ifp->if_next) - for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { - if (ifa->ifa_addr->sa_family != addr->sa_family) - continue; - if (equal(addr, ifa->ifa_addr)) - return (ifa); - if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr && - equal(ifa->ifa_broadaddr, addr)) - return (ifa); - } - return ((struct ifaddr *)0); -} -/* - * Locate the point to point interface with a given destination address. - */ -/*ARGSUSED*/ -struct ifaddr * -ifa_ifwithdstaddr(addr) - register struct sockaddr *addr; -{ - register struct ifnet *ifp; - register struct ifaddr *ifa; - - for (ifp = ifnet; ifp; ifp = ifp->if_next) - if (ifp->if_flags & IFF_POINTOPOINT) - for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { - if (ifa->ifa_addr->sa_family != addr->sa_family) - continue; - if (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr)) - return (ifa); - } - return ((struct ifaddr *)0); -} - -/* - * Find an interface on a specific network. If many, choice - * is most specific found. - */ -struct ifaddr * -ifa_ifwithnet(addr) - struct sockaddr *addr; -{ - register struct ifnet *ifp; - register struct ifaddr *ifa; - struct ifaddr *ifa_maybe = (struct ifaddr *) 0; - u_int af = addr->sa_family; - char *addr_data = addr->sa_data, *cplim; - - if (af == AF_LINK) { - register struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr; - if (sdl->sdl_index && sdl->sdl_index <= if_index) - return (ifnet_addrs[sdl->sdl_index - 1]); - } - for (ifp = ifnet; ifp; ifp = ifp->if_next) { - for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { - register char *cp, *cp2, *cp3; - - if (ifa->ifa_addr->sa_family != af) - next: continue; - if (ifp->if_flags & IFF_POINTOPOINT) { - if (ifa->ifa_dstaddr != 0 - && equal(addr, ifa->ifa_dstaddr)) - return (ifa); - } else { - /* - * if we have a special address handler, - * then use it instead of the generic one. - */ - if (ifa->ifa_claim_addr) { - if ((*ifa->ifa_claim_addr)(ifa, addr)) { - return (ifa); - } else { - continue; - } - } - - /* - * Scan all the bits in the ifa's address. - * If a bit dissagrees with what we are - * looking for, mask it with the netmask - * to see if it really matters. - * (A byte at a time) - */ - if (ifa->ifa_netmask == 0) - continue; - cp = addr_data; - cp2 = ifa->ifa_addr->sa_data; - cp3 = ifa->ifa_netmask->sa_data; - cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask; - while (cp3 < cplim) - if ((*cp++ ^ *cp2++) & *cp3++) - goto next; - if (ifa_maybe == 0 || - rn_refines((caddr_t)ifa->ifa_netmask, - (caddr_t)ifa_maybe->ifa_netmask)) - ifa_maybe = ifa; - } - } - } - return (ifa_maybe); -} - -/* - * Find an interface address specific to an interface best matching - * a given address. - */ -struct ifaddr * -ifaof_ifpforaddr(addr, ifp) - struct sockaddr *addr; - register struct ifnet *ifp; -{ - register struct ifaddr *ifa; - register char *cp, *cp2, *cp3; - register char *cplim; - struct ifaddr *ifa_maybe = 0; - u_int af = addr->sa_family; - - if (af >= AF_MAX) - return (0); - for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { - if (ifa->ifa_addr->sa_family != af) - continue; - if (ifa_maybe == 0) - ifa_maybe = ifa; - if (ifa->ifa_netmask == 0) { - if (equal(addr, ifa->ifa_addr) || - (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr))) - return (ifa); - continue; - } - if (ifp->if_flags & IFF_POINTOPOINT) { - if (equal(addr, ifa->ifa_dstaddr)) - return (ifa); - } else { - cp = addr->sa_data; - cp2 = ifa->ifa_addr->sa_data; - cp3 = ifa->ifa_netmask->sa_data; - cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask; - for (; cp3 < cplim; cp3++) - if ((*cp++ ^ *cp2++) & *cp3) - break; - if (cp3 == cplim) - return (ifa); - } - } - return (ifa_maybe); -} - -#include <net/route.h> - -/* - * Default action when installing a route with a Link Level gateway. - * Lookup an appropriate real ifa to point to. - * This should be moved to /sys/net/link.c eventually. - */ -static void -link_rtrequest(cmd, rt, sa) - int cmd; - register struct rtentry *rt; - struct sockaddr *sa; -{ - register struct ifaddr *ifa; - struct sockaddr *dst; - struct ifnet *ifp; - - if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) || - ((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0)) - return; - ifa = ifaof_ifpforaddr(dst, ifp); - if (ifa) { - IFAFREE(rt->rt_ifa); - rt->rt_ifa = ifa; - ifa->ifa_refcnt++; - if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest) - ifa->ifa_rtrequest(cmd, rt, sa); - } -} - -/* - * Mark an interface down and notify protocols of - * the transition. - * NOTE: must be called at splnet or eqivalent. - */ -void -if_down(ifp) - register struct ifnet *ifp; -{ - register struct ifaddr *ifa; - - ifp->if_flags &= ~IFF_UP; - microtime(&ifp->if_lastchange); - for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) - pfctlinput(PRC_IFDOWN, ifa->ifa_addr); - if_qflush(&ifp->if_snd); - rt_ifmsg(ifp); -} - -/* - * Mark an interface up and notify protocols of - * the transition. - * NOTE: must be called at splnet or eqivalent. - */ -void -if_up(ifp) - register struct ifnet *ifp; -{ - - ifp->if_flags |= IFF_UP; - microtime(&ifp->if_lastchange); -#ifdef notyet - register struct ifaddr *ifa; - /* this has no effect on IP, and will kill all iso connections XXX */ - for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) - pfctlinput(PRC_IFUP, ifa->ifa_addr); -#endif - rt_ifmsg(ifp); -} - -/* - * Flush an interface queue. - */ -static void -if_qflush(ifq) - register struct ifqueue *ifq; -{ - register struct mbuf *m, *n; - - n = ifq->ifq_head; - while ((m = n) != 0) { - n = m->m_act; - m_freem(m); - } - ifq->ifq_head = 0; - ifq->ifq_tail = 0; - ifq->ifq_len = 0; -} - -/* - * Handle interface watchdog timer routines. Called - * from softclock, we decrement timers (if set) and - * call the appropriate interface routine on expiration. - */ -static void -if_slowtimo(arg) - void *arg; -{ - register struct ifnet *ifp; - int s = splimp(); - - for (ifp = ifnet; ifp; ifp = ifp->if_next) { - if (ifp->if_timer == 0 || --ifp->if_timer) - continue; - if (ifp->if_watchdog) - (*ifp->if_watchdog)(ifp); - } - splx(s); - timeout(if_slowtimo, (void *)0, hz / IFNET_SLOWHZ); -} - -/* - * Map interface name to - * interface structure pointer. - */ -struct ifnet * -ifunit(name) - register char *name; -{ - register char *cp; - register struct ifnet *ifp; - int unit; - unsigned len; - char *ep, c; - - for (cp = name; cp < name + IFNAMSIZ && *cp; cp++) - if (*cp >= '0' && *cp <= '9') - break; - if (*cp == '\0' || cp == name + IFNAMSIZ) - return ((struct ifnet *)0); - /* - * Save first char of unit, and pointer to it, - * so we can put a null there to avoid matching - * initial substrings of interface names. - */ - len = cp - name + 1; - c = *cp; - ep = cp; - for (unit = 0; *cp >= '0' && *cp <= '9'; ) - unit = unit * 10 + *cp++ - '0'; - if (*cp != '\0') - return 0; /* no trailing garbage allowed */ - *ep = 0; - for (ifp = ifnet; ifp; ifp = ifp->if_next) { - if (bcmp(ifp->if_name, name, len)) - continue; - if (unit == ifp->if_unit) - break; - } - *ep = c; - return (ifp); -} - -/* - * Interface ioctls. - */ -int -ifioctl(so, cmd, data, p) - struct socket *so; - int cmd; - caddr_t data; - struct proc *p; -{ - register struct ifnet *ifp; - register struct ifreq *ifr; - int error; - - switch (cmd) { - - case SIOCGIFCONF: - case OSIOCGIFCONF: - return (ifconf(cmd, data)); - } - ifr = (struct ifreq *)data; - ifp = ifunit(ifr->ifr_name); - if (ifp == 0) - return (ENXIO); - switch (cmd) { - - case SIOCGIFFLAGS: - ifr->ifr_flags = ifp->if_flags; - break; - - case SIOCGIFMETRIC: - ifr->ifr_metric = ifp->if_metric; - break; - - case SIOCGIFMTU: - ifr->ifr_mtu = ifp->if_mtu; - break; - - case SIOCGIFPHYS: - ifr->ifr_phys = ifp->if_physical; - break; - - case SIOCSIFFLAGS: - error = suser(p->p_ucred, &p->p_acflag); - if (error) - return (error); - if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) { - int s = splimp(); - if_down(ifp); - splx(s); - } - if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) { - int s = splimp(); - if_up(ifp); - splx(s); - } - ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) | - (ifr->ifr_flags &~ IFF_CANTCHANGE); - if (ifp->if_ioctl) - (void) (*ifp->if_ioctl)(ifp, cmd, data); - microtime(&ifp->if_lastchange); - break; - - case SIOCSIFMETRIC: - error = suser(p->p_ucred, &p->p_acflag); - if (error) - return (error); - ifp->if_metric = ifr->ifr_metric; - microtime(&ifp->if_lastchange); - break; - - case SIOCSIFPHYS: - error = suser(p->p_ucred, &p->p_acflag); - if (error) - return error; - if (!ifp->if_ioctl) - return EOPNOTSUPP; - error = (*ifp->if_ioctl)(ifp, cmd, data); - if (error == 0) - microtime(&ifp->if_lastchange); - return(error); - - case SIOCSIFMTU: - error = suser(p->p_ucred, &p->p_acflag); - if (error) - return (error); - if (ifp->if_ioctl == NULL) - return (EOPNOTSUPP); - /* - * 72 was chosen below because it is the size of a TCP/IP - * header (40) + the minimum mss (32). - */ - if (ifr->ifr_mtu < 72 || ifr->ifr_mtu > 65535) - return (EINVAL); - error = (*ifp->if_ioctl)(ifp, cmd, data); - if (error == 0) - microtime(&ifp->if_lastchange); - return(error); - - case SIOCADDMULTI: - case SIOCDELMULTI: - error = suser(p->p_ucred, &p->p_acflag); - if (error) - return (error); - if (ifp->if_ioctl == NULL) - return (EOPNOTSUPP); - error = (*ifp->if_ioctl)(ifp, cmd, data); - if (error == 0 ) - microtime(&ifp->if_lastchange); - return(error); - - case SIOCSIFMEDIA: - error = suser(p->p_ucred, &p->p_acflag); - if (error) - return (error); - if (ifp->if_ioctl == 0) - return (EOPNOTSUPP); - error = (*ifp->if_ioctl)(ifp, cmd, data); - if (error == 0) - microtime(&ifp->if_lastchange); - return error; - - case SIOCGIFMEDIA: - if (ifp->if_ioctl == 0) - return (EOPNOTSUPP); - return ((*ifp->if_ioctl)(ifp, cmd, data)); - - default: - if (so->so_proto == 0) - return (EOPNOTSUPP); -#ifndef COMPAT_43 - return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, - data, - ifp)); -#else - { - int ocmd = cmd; - - switch (cmd) { - - case SIOCSIFDSTADDR: - case SIOCSIFADDR: - case SIOCSIFBRDADDR: - case SIOCSIFNETMASK: -#if BYTE_ORDER != BIG_ENDIAN - if (ifr->ifr_addr.sa_family == 0 && - ifr->ifr_addr.sa_len < 16) { - ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len; - ifr->ifr_addr.sa_len = 16; - } -#else - if (ifr->ifr_addr.sa_len == 0) - ifr->ifr_addr.sa_len = 16; -#endif - break; - - case OSIOCGIFADDR: - cmd = SIOCGIFADDR; - break; - - case OSIOCGIFDSTADDR: - cmd = SIOCGIFDSTADDR; - break; - - case OSIOCGIFBRDADDR: - cmd = SIOCGIFBRDADDR; - break; - - case OSIOCGIFNETMASK: - cmd = SIOCGIFNETMASK; - } - error = ((*so->so_proto->pr_usrreqs->pru_control)(so, - cmd, - data, - ifp)); - switch (ocmd) { - - case OSIOCGIFADDR: - case OSIOCGIFDSTADDR: - case OSIOCGIFBRDADDR: - case OSIOCGIFNETMASK: - *(u_short *)&ifr->ifr_addr = ifr->ifr_addr.sa_family; - } - return (error); - - } -#endif - } - return (0); -} - -/* - * Set/clear promiscuous mode on interface ifp based on the truth value - * of pswitch. The calls are reference counted so that only the first - * "on" request actually has an effect, as does the final "off" request. - * Results are undefined if the "off" and "on" requests are not matched. - */ -int -ifpromisc(ifp, pswitch) - struct ifnet *ifp; - int pswitch; -{ - struct ifreq ifr; - - if (pswitch) { - /* - * If the device is not configured up, we cannot put it in - * promiscuous mode. - */ - if ((ifp->if_flags & IFF_UP) == 0) - return (ENETDOWN); - if (ifp->if_pcount++ != 0) - return (0); - ifp->if_flags |= IFF_PROMISC; - log(LOG_INFO, "%s%d: promiscuous mode enabled\n", - ifp->if_name, ifp->if_unit); - } else { - if (--ifp->if_pcount > 0) - return (0); - ifp->if_flags &= ~IFF_PROMISC; - } - ifr.ifr_flags = ifp->if_flags; - return ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr)); -} - -/* - * Return interface configuration - * of system. List may be used - * in later ioctl's (above) to get - * other information. - */ -/*ARGSUSED*/ -static int -ifconf(cmd, data) - int cmd; - caddr_t data; -{ - register struct ifconf *ifc = (struct ifconf *)data; - register struct ifnet *ifp = ifnet; - register struct ifaddr *ifa; - struct ifreq ifr, *ifrp; - int space = ifc->ifc_len, error = 0; - - ifrp = ifc->ifc_req; - for (; space > sizeof (ifr) && ifp; ifp = ifp->if_next) { - char workbuf[64]; - int ifnlen; - - ifnlen = sprintf(workbuf, "%s%d", ifp->if_name, ifp->if_unit); - if(ifnlen + 1 > sizeof ifr.ifr_name) { - error = ENAMETOOLONG; - } else { - strcpy(ifr.ifr_name, workbuf); - } - - if ((ifa = ifp->if_addrlist) == 0) { - bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr)); - error = copyout((caddr_t)&ifr, (caddr_t)ifrp, - sizeof (ifr)); - if (error) - break; - space -= sizeof (ifr), ifrp++; - } else - for ( ; space > sizeof (ifr) && ifa; ifa = ifa->ifa_next) { - register struct sockaddr *sa = ifa->ifa_addr; -#ifdef COMPAT_43 - if (cmd == OSIOCGIFCONF) { - struct osockaddr *osa = - (struct osockaddr *)&ifr.ifr_addr; - ifr.ifr_addr = *sa; - osa->sa_family = sa->sa_family; - error = copyout((caddr_t)&ifr, (caddr_t)ifrp, - sizeof (ifr)); - ifrp++; - } else -#endif - if (sa->sa_len <= sizeof(*sa)) { - ifr.ifr_addr = *sa; - error = copyout((caddr_t)&ifr, (caddr_t)ifrp, - sizeof (ifr)); - ifrp++; - } else { - space -= sa->sa_len - sizeof(*sa); - if (space < sizeof (ifr)) - break; - error = copyout((caddr_t)&ifr, (caddr_t)ifrp, - sizeof (ifr.ifr_name)); - if (error == 0) - error = copyout((caddr_t)sa, - (caddr_t)&ifrp->ifr_addr, sa->sa_len); - ifrp = (struct ifreq *) - (sa->sa_len + (caddr_t)&ifrp->ifr_addr); - } - if (error) - break; - space -= sizeof (ifr); - } - } - ifc->ifc_len -= space; - return (error); -} - -SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW, 0, "Link layers"); -SYSCTL_NODE(_net_link, 0, generic, CTLFLAG_RW, 0, "Generic link-management"); |