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

Defined functions

if_down defined in line 170; used 6 times
if_slowtimo defined in line 185; used 2 times
ifa_ifwithaf defined in line 150; never used
ifconf defined in line 301; used 1 times
ifinit defined in line 34; used 1 times
ifioctl defined in line 228; used 1 times
ifubareset defined in line 48; used 1 times
ifunit defined in line 202; used 1 times

Defined variables

ifqmaxlen defined in line 25; used 1 times
  • in line 40

Defined macros

equal defined in line 84; used 3 times
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1896
Valid CSS Valid XHTML 1.0 Strict