# 2.11BSD#431 - /usr/src/sys/net/if.c

##### Functions

    if_attach         X
    if_down           X
    if_qflush         X
    if_slowtimo       X
    ifa_ifwithaddr    X
    ifa_ifwithaf      X
    ifa_ifwithdstaddr X
    ifa_ifwithnet     X
    ifconf            X
    ifinit            X
    ifioctl           X
    ifubareset        X
    ifunit            X

##### Variables

    ifqmaxlen         X

##### Macros

    equal             X

       1: /*
       2:  * Copyright (c) 1980, 1986 Regents of the University of California.
       3:  * All rights reserved.
       4:  *
       5:  * Redistribution and use in source and binary forms are permitted
       6:  * provided that this notice is preserved and that due credit is given
       7:  * to the University of California at Berkeley. The name of the University
       8:  * may not be used to endorse or promote products derived from this
       9:  * software without specific prior written permission. This software
      10:  * is provided ``as is'' without express or implied warranty.
      11:  *
      12:  *	%W% (Berkeley) %G%
      13:  */
      14:
      15: #include "param.h"
      16: #include "mbuf.h"
      17: #include "systm.h"
      18: #include "socket.h"
      19: #include "socketvar.h"
      20: #include "protosw.h"
      21: #include "user.h"
      22: #include "kernel.h"
      23: #include "ioctl.h"
      24: #include "errno.h"
      25:
      26: #include "if.h"
      27: #include "af.h"
      28:
      29: #include "ether.h"
      30:
      31: int ifqmaxlen = IFQ_MAXLEN;
      32:
      33: /*
      34:  * Network interface utility routines.
      35:  *
      36:  * Routines with ifa_ifwith* names take sockaddr *'s as
      37:  * parameters.
      38:  */
      39:
      40: ifinit()
      41: {
      42:     register struct ifnet *ifp;
      43:
      44:     for (ifp = ifnet; ifp; ifp = ifp->if_next)
      45:         if (ifp->if_snd.ifq_maxlen == 0)
      46:             ifp->if_snd.ifq_maxlen = ifqmaxlen;
      47:     if_slowtimo();
      48: }
      49:
      50: #ifdef vax
      51: /*
      52:  * Call each interface on a Unibus reset.
      53:  */
      54: ifubareset(uban)
      55:     int uban;
      56: {
      57:     register struct ifnet *ifp;
      58:
      59:     for (ifp = ifnet; ifp; ifp = ifp->if_next)
      60:         if (ifp->if_reset)
      61:             (*ifp->if_reset)(ifp->if_unit, uban);
      62: }
      63: #endif
      64:
      65: /*
      66:  * Attach an interface to the
      67:  * list of "active" interfaces.
      68:  */
      69: if_attach(ifp)
      70:     struct ifnet *ifp;
      71: {
      72:     register struct ifnet **p = &ifnet;
      73:
      74:     while (*p)
      75:         p = &((*p)->if_next);
      76:     *p = ifp;
      77: }
      78:
      79: /*
      80:  * Locate an interface based on a complete address.
      81:  */
      82: /*ARGSUSED*/
      83: struct ifaddr *
      84: ifa_ifwithaddr(addr)
      85:     struct sockaddr *addr;
      86: {
      87:     register struct ifnet *ifp;
      88:     register struct ifaddr *ifa;
      89:
      90: #define equal(a1, a2) \
      91:     (bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0)
      92:     for (ifp = ifnet; ifp; ifp = ifp->if_next)
      93:         for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
      94:         if (ifa->ifa_addr.sa_family != addr->sa_family)
      95:             continue;
      96:         if (equal(&ifa->ifa_addr, addr))
      97:             return (ifa);
      98:         if ((ifp->if_flags & IFF_BROADCAST) &&
      99:             equal(&ifa->ifa_broadaddr, addr))
     100:             return (ifa);
     101:     }
     102:     return ((struct ifaddr *)0);
     103: }
     104: /*
     105:  * Locate the point to point interface with a given destination address.
     106:  */
     107: /*ARGSUSED*/
     108: struct ifaddr *
     109: ifa_ifwithdstaddr(addr)
     110:     struct sockaddr *addr;
     111: {
     112:     register struct ifnet *ifp;
     113:     register struct ifaddr *ifa;
     114:
     115:     for (ifp = ifnet; ifp; ifp = ifp->if_next)
     116:         if (ifp->if_flags & IFF_POINTOPOINT)
     117:         for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
     118:             if (ifa->ifa_addr.sa_family != addr->sa_family)
     119:                 continue;
     120:             if (equal(&ifa->ifa_dstaddr, addr))
     121:                 return (ifa);
     122:     }
     123:     return ((struct ifaddr *)0);
     124: }
     125:
     126: /*
     127:  * Find an interface on a specific network.  If many, choice
     128:  * is first found.
     129:  */
     130: struct ifaddr *
     131: ifa_ifwithnet(addr)
     132:     register struct sockaddr *addr;
     133: {
     134:     register struct ifnet *ifp;
     135:     register struct ifaddr *ifa;
     136:     register u_int af = addr->sa_family;
     137:     register int (*netmatch)();
     138:
     139:     if (af >= AF_MAX)
     140:         return (0);
     141:     netmatch = afswitch[af].af_netmatch;
     142:     for (ifp = ifnet; ifp; ifp = ifp->if_next)
     143:         for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
     144:         if (ifa->ifa_addr.sa_family != addr->sa_family)
     145:             continue;
     146:         if ((*netmatch)(&ifa->ifa_addr, addr))
     147:             return (ifa);
     148:     }
     149:     return ((struct ifaddr *)0);
     150: }
     151:
     152: #ifdef notdef
     153: /*
     154:  * Find an interface using a specific address family
     155:  */
     156: struct ifaddr *
     157: ifa_ifwithaf(af)
     158:     register int af;
     159: {
     160:     register struct ifnet *ifp;
     161:     register struct ifaddr *ifa;
     162:
     163:     for (ifp = ifnet; ifp; ifp = ifp->if_next)
     164:         for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
     165:         if (ifa->ifa_addr.sa_family == af)
     166:             return (ifa);
     167:     return ((struct ifaddr *)0);
     168: }
     169: #endif
     170:
     171: /*
     172:  * Mark an interface down and notify protocols of
     173:  * the transition.
     174:  * NOTE: must be called at splnet or eqivalent.
     175:  */
     176: if_down(ifp)
     177:     register struct ifnet *ifp;
     178: {
     179:     register struct ifaddr *ifa;
     180:
     181:     ifp->if_flags &= ~IFF_UP;
     182:     for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
     183:         pfctlinput(PRC_IFDOWN, &ifa->ifa_addr);
     184:     if_qflush(&ifp->if_snd);
     185: }
     186:
     187: /*
     188:  * Flush an interface queue.
     189:  */
     190: if_qflush(ifq)
     191:     register struct ifqueue *ifq;
     192: {
     193:     register struct mbuf *m, *n;
     194:
     195:     n = ifq->ifq_head;
     196:     while (m = n) {
     197:         n = m->m_act;
     198:         m_freem(m);
     199:     }
     200:     ifq->ifq_head = 0;
     201:     ifq->ifq_tail = 0;
     202:     ifq->ifq_len = 0;
     203: }
     204:
     205: /*
     206:  * Handle interface watchdog timer routines.  Called
     207:  * from softclock, we decrement timers (if set) and
     208:  * call the appropriate interface routine on expiration.
     209:  */
     210: if_slowtimo()
     211: {
     212: extern int hz;
     213:     register struct ifnet *ifp;
     214:
     215:     for (ifp = ifnet; ifp; ifp = ifp->if_next) {
     216:         if (ifp->if_timer == 0 || --ifp->if_timer)
     217:             continue;
     218:         if (ifp->if_watchdog)
     219:             (*ifp->if_watchdog)(ifp->if_unit);
     220:     }
     221:     TIMEOUT(if_slowtimo, (caddr_t)0, hz / IFNET_SLOWHZ);
     222: }
     223:
     224: /*
     225:  * Map interface name to
     226:  * interface structure pointer.
     227:  */
     228: struct ifnet *
     229: ifunit(name)
     230:     register char *name;
     231: {
     232:     register char *cp;
     233:     register struct ifnet *ifp;
     234:     int unit;
     235:
     236:     for (cp = name; cp < name + IFNAMSIZ && *cp; cp++)
     237:         if (*cp >= '0' && *cp <= '9')
     238:             break;
     239:     if (*cp == '\0' || cp == name + IFNAMSIZ)
     240:         return ((struct ifnet *)0);
     241:     unit = *cp - '0';
     242:     for (ifp = ifnet; ifp; ifp = ifp->if_next) {
     243:         if (bcmp(ifp->if_name, name, (unsigned)(cp - name)))
     244:             continue;
     245:         if (unit == ifp->if_unit)
     246:             break;
     247:     }
     248:     return (ifp);
     249: }
     250:
     251: /*
     252:  * Interface ioctls.
     253:  */
     254: ifioctl(so, cmd, data)
     255:     struct socket *so;
     256:     int cmd;
     257:     caddr_t data;
     258: {
     259:     register struct ifnet *ifp;
     260:     register struct ifreq *ifr;
     261:
     262:     switch (cmd) {
     263:
     264:     case SIOCGIFCONF:
     265:         return (ifconf(cmd, data));
     266:
     267: #if defined(INET) && NETHER > 0
     268:     case SIOCSARP:
     269:     case SIOCDARP:
     270:         if (!suser())
     271:             return (u.u_error);
     272:         /* FALL THROUGH */
     273:     case SIOCGARP:
     274:         return (arpioctl(cmd, data));
     275: #endif
     276:     }
     277:
     278:     ifr = (struct ifreq *)data;
     279:     ifp = ifunit(ifr->ifr_name);
     280:     if (ifp == 0)
     281:         return (ENXIO);
     282:     switch (cmd) {
     283:
     284:     case SIOCGIFFLAGS:
     285:         ifr->ifr_flags = ifp->if_flags;
     286:         break;
     287:
     288:     case SIOCGIFMETRIC:
     289:         ifr->ifr_metric = ifp->if_metric;
     290:         break;
     291:
     292:     case SIOCSIFFLAGS:
     293:         if (!suser())
     294:             return (u.u_error);
     295:         if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) {
     296:             int s = splimp();
     297:             if_down(ifp);
     298:             splx(s);
     299:         }
     300:         ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
     301:             (ifr->ifr_flags &~ IFF_CANTCHANGE);
     302:         if (ifp->if_ioctl)
     303:             (void) (*ifp->if_ioctl)(ifp, cmd, data);
     304:         break;
     305:
     306:     case SIOCSIFMETRIC:
     307:         if (!suser())
     308:             return (u.u_error);
     309:         ifp->if_metric = ifr->ifr_metric;
     310:         break;
     311:
     312:     default:
     313:         if (so->so_proto == 0)
     314:             return (EOPNOTSUPP);
     315:         return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
     316:             cmd, data, ifp));
     317:     }
     318:     return (0);
     319: }
     320:
     321: /*
     322:  * Return interface configuration
     323:  * of system.  List may be used
     324:  * in later ioctl's (above) to get
     325:  * other information.
     326:  */
     327: /*ARGSUSED*/
     328: ifconf(cmd, data)
     329:     int cmd;
     330:     caddr_t data;
     331: {
     332:     register struct ifconf *ifc = (struct ifconf *)data;
     333:     register struct ifnet *ifp = ifnet;
     334:     register struct ifaddr *ifa;
     335:     register char *cp, *ep;
     336:     struct ifreq ifr, *ifrp;
     337:     int space = ifc->ifc_len, error = 0;
     338:
     339:     ifrp = ifc->ifc_req;
     340:     ep = ifr.ifr_name + sizeof (ifr.ifr_name) - 2;
     341:     for (; space > sizeof (ifr) && ifp; ifp = ifp->if_next) {
     342:         bcopy(ifp->if_name, ifr.ifr_name, sizeof (ifr.ifr_name) - 2);
     343:         for (cp = ifr.ifr_name; cp < ep && *cp; cp++)
     344:             ;
     345:         *cp++ = '0' + ifp->if_unit; *cp = '\0';
     346:         if ((ifa = ifp->if_addrlist) == 0) {
     347:             bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
     348:             error = copyout((caddr_t)&ifr, (caddr_t)ifrp, sizeof (ifr));
     349:             if (error)
     350:                 break;
     351:             space -= sizeof (ifr), ifrp++;
     352:         } else
     353:             for ( ; space > sizeof (ifr) && ifa; ifa = ifa->ifa_next) {
     354:             ifr.ifr_addr = ifa->ifa_addr;
     355:             error = copyout((caddr_t)&ifr, (caddr_t)ifrp, sizeof (ifr));
     356:             if (error)
     357:                 break;
     358:             space -= sizeof (ifr), ifrp++;
     359:         }
     360:     }
     361:     ifc->ifc_len -= space;
     362:     return (error);
     363: }

#### Defined functions

if_attach defined in line 69; never used
if_down defined in line 176; used 1 times

- in line 297

if_qflush defined in line 190; used 1 times

- in line 184

if_slowtimo defined in line 210; used 2 times

- in line 47, 221

ifa_ifwithaddr defined in line 83; never used
ifa_ifwithaf defined in line 156; never used
ifa_ifwithdstaddr defined in line 108; never used
ifa_ifwithnet defined in line 130; never used
ifconf defined in line 328; used 1 times

- in line 265

ifinit defined in line 40; never used
ifioctl defined in line 254; never used
ifubareset defined in line 54; never used
ifunit defined in line 228; used 1 times

- in line 279

#### Defined variables

ifqmaxlen defined in line 31; used 1 times

- in line 46

#### Defined macros

equal defined in line 90; used 3 times

- in line 96-99(2), 120

Last modified: 1988-05-02 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1816 |