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
if_qflush defined in line 190; used 1 times
if_slowtimo defined in line 210; used 2 times
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
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

Defined variables

ifqmaxlen defined in line 31; used 1 times
  • in line 46

Defined macros

equal defined in line 90; used 3 times
Last modified: 1988-05-02
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4488
Valid CSS Valid XHTML 1.0 Strict