|
|
1.1 ! root 1: /* if.c 6.2 83/09/27 */ ! 2: ! 3: #include "../h/param.h" ! 4: #include "../h/systm.h" ! 5: #include "../h/socket.h" ! 6: #include "../h/protosw.h" ! 7: #include "../h/dir.h" ! 8: #include "../h/user.h" ! 9: #include "../h/kernel.h" ! 10: #include "../h/ioctl.h" ! 11: #include "../h/errno.h" ! 12: ! 13: #include "../net/if.h" ! 14: #include "../net/af.h" ! 15: ! 16: int ifqmaxlen = IFQ_MAXLEN; ! 17: ! 18: /* ! 19: * Network interface utility routines. ! 20: * ! 21: * Routines with if_ifwith* names take sockaddr *'s as ! 22: * parameters. Other routines take value parameters, ! 23: * e.g. if_ifwithnet takes the network number. ! 24: */ ! 25: ! 26: ifinit() ! 27: { ! 28: register struct ifnet *ifp; ! 29: ! 30: for (ifp = ifnet; ifp; ifp = ifp->if_next) ! 31: if (ifp->if_init) { ! 32: (*ifp->if_init)(ifp->if_unit); ! 33: if (ifp->if_snd.ifq_maxlen == 0) ! 34: ifp->if_snd.ifq_maxlen = ifqmaxlen; ! 35: } ! 36: if_slowtimo(); ! 37: } ! 38: ! 39: #ifdef vax ! 40: /* ! 41: * Call each interface on a Unibus reset. ! 42: */ ! 43: ifubareset(uban) ! 44: int uban; ! 45: { ! 46: register struct ifnet *ifp; ! 47: ! 48: for (ifp = ifnet; ifp; ifp = ifp->if_next) ! 49: if (ifp->if_reset) ! 50: (*ifp->if_reset)(ifp->if_unit, uban); ! 51: } ! 52: #endif ! 53: ! 54: /* ! 55: * Attach an interface to the ! 56: * list of "active" interfaces. ! 57: */ ! 58: if_attach(ifp) ! 59: struct ifnet *ifp; ! 60: { ! 61: register struct ifnet **p = &ifnet; ! 62: ! 63: while (*p) ! 64: p = &((*p)->if_next); ! 65: *p = ifp; ! 66: } ! 67: ! 68: /* ! 69: * Locate an interface based on a complete address. ! 70: */ ! 71: /*ARGSUSED*/ ! 72: struct ifnet * ! 73: if_ifwithaddr(addr) ! 74: struct sockaddr *addr; ! 75: { ! 76: register struct ifnet *ifp; ! 77: ! 78: #define equal(a1, a2) \ ! 79: (bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0) ! 80: for (ifp = ifnet; ifp; ifp = ifp->if_next) { ! 81: if (ifp->if_addr.sa_family != addr->sa_family) ! 82: continue; ! 83: if (equal(&ifp->if_addr, addr)) ! 84: break; ! 85: if ((ifp->if_flags & IFF_BROADCAST) && ! 86: equal(&ifp->if_broadaddr, addr)) ! 87: break; ! 88: } ! 89: return (ifp); ! 90: } ! 91: ! 92: /* ! 93: * Find an interface on a specific network. If many, choice ! 94: * is first found. ! 95: */ ! 96: struct ifnet * ! 97: if_ifwithnet(addr) ! 98: register struct sockaddr *addr; ! 99: { ! 100: register struct ifnet *ifp; ! 101: register u_int af = addr->sa_family; ! 102: register int (*netmatch)(); ! 103: ! 104: if (af >= AF_MAX) ! 105: return (0); ! 106: netmatch = afswitch[af].af_netmatch; ! 107: for (ifp = ifnet; ifp; ifp = ifp->if_next) { ! 108: if (af != ifp->if_addr.sa_family) ! 109: continue; ! 110: if ((*netmatch)(addr, &ifp->if_addr)) ! 111: break; ! 112: } ! 113: return (ifp); ! 114: } ! 115: ! 116: /* ! 117: * As above, but parameter is network number. ! 118: */ ! 119: struct ifnet * ! 120: if_ifonnetof(net) ! 121: register int net; ! 122: { ! 123: register struct ifnet *ifp; ! 124: ! 125: for (ifp = ifnet; ifp; ifp = ifp->if_next) ! 126: if (ifp->if_net == net) ! 127: break; ! 128: return (ifp); ! 129: } ! 130: ! 131: /* ! 132: * Find an interface using a specific address family ! 133: */ ! 134: struct ifnet * ! 135: if_ifwithaf(af) ! 136: register int af; ! 137: { ! 138: register struct ifnet *ifp; ! 139: ! 140: for (ifp = ifnet; ifp; ifp = ifp->if_next) ! 141: if (ifp->if_addr.sa_family == af) ! 142: break; ! 143: return (ifp); ! 144: } ! 145: ! 146: /* ! 147: * Mark an interface down and notify protocols of ! 148: * the transition. ! 149: * NOTE: must be called at splnet or eqivalent. ! 150: */ ! 151: if_down(ifp) ! 152: register struct ifnet *ifp; ! 153: { ! 154: ! 155: ifp->if_flags &= ~IFF_UP; ! 156: pfctlinput(PRC_IFDOWN, (caddr_t)&ifp->if_addr); ! 157: } ! 158: ! 159: /* ! 160: * Handle interface watchdog timer routines. Called ! 161: * from softclock, we decrement timers (if set) and ! 162: * call the appropriate interface routine on expiration. ! 163: */ ! 164: if_slowtimo() ! 165: { ! 166: register struct ifnet *ifp; ! 167: ! 168: for (ifp = ifnet; ifp; ifp = ifp->if_next) { ! 169: if (ifp->if_timer == 0 || --ifp->if_timer) ! 170: continue; ! 171: if (ifp->if_watchdog) ! 172: (*ifp->if_watchdog)(ifp->if_unit); ! 173: } ! 174: timeout(if_slowtimo, (caddr_t)0, hz / IFNET_SLOWHZ); ! 175: } ! 176: ! 177: /* ! 178: * Map interface name to ! 179: * interface structure pointer. ! 180: */ ! 181: struct ifnet * ! 182: ifunit(name) ! 183: register char *name; ! 184: { ! 185: register char *cp; ! 186: register struct ifnet *ifp; ! 187: int unit; ! 188: ! 189: for (cp = name; cp < name + IFNAMSIZ && *cp; cp++) ! 190: if (*cp >= '0' && *cp <= '9') ! 191: break; ! 192: if (*cp == '\0' || cp == name + IFNAMSIZ) ! 193: return ((struct ifnet *)0); ! 194: unit = *cp - '0', *cp = 0; ! 195: for (ifp = ifnet; ifp; ifp = ifp->if_next) { ! 196: if (bcmp(ifp->if_name, name, (unsigned)(cp - name))) ! 197: continue; ! 198: if (unit == ifp->if_unit) ! 199: break; ! 200: } ! 201: return (ifp); ! 202: } ! 203: ! 204: /* ! 205: * Interface ioctls. ! 206: */ ! 207: ifioctl(cmd, data) ! 208: int cmd; ! 209: caddr_t data; ! 210: { ! 211: register struct ifnet *ifp; ! 212: register struct ifreq *ifr; ! 213: ! 214: switch (cmd) { ! 215: ! 216: case SIOCGIFCONF: ! 217: return (ifconf(cmd, data)); ! 218: ! 219: case SIOCSIFADDR: ! 220: case SIOCSIFFLAGS: ! 221: case SIOCSIFDSTADDR: ! 222: if (!suser()) ! 223: return (u.u_error); ! 224: break; ! 225: } ! 226: ifr = (struct ifreq *)data; ! 227: ifp = ifunit(ifr->ifr_name); ! 228: if (ifp == 0) ! 229: return (ENXIO); ! 230: switch (cmd) { ! 231: ! 232: case SIOCGIFADDR: ! 233: ifr->ifr_addr = ifp->if_addr; ! 234: break; ! 235: ! 236: case SIOCGIFDSTADDR: ! 237: if ((ifp->if_flags & IFF_POINTOPOINT) == 0) ! 238: return (EINVAL); ! 239: ifr->ifr_dstaddr = ifp->if_dstaddr; ! 240: break; ! 241: ! 242: case SIOCGIFFLAGS: ! 243: ifr->ifr_flags = ifp->if_flags; ! 244: break; ! 245: ! 246: case SIOCSIFFLAGS: ! 247: if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) { ! 248: int s = splimp(); ! 249: if_down(ifp); ! 250: splx(s); ! 251: } ! 252: ifp->if_flags = ifr->ifr_flags; ! 253: break; ! 254: ! 255: default: ! 256: if (ifp->if_ioctl == 0) ! 257: return (EOPNOTSUPP); ! 258: return ((*ifp->if_ioctl)(ifp, cmd, data)); ! 259: } ! 260: return (0); ! 261: } ! 262: ! 263: /* ! 264: * Return interface configuration ! 265: * of system. List may be used ! 266: * in later ioctl's (above) to get ! 267: * other information. ! 268: */ ! 269: /*ARGSUSED*/ ! 270: ifconf(cmd, data) ! 271: int cmd; ! 272: caddr_t data; ! 273: { ! 274: register struct ifconf *ifc = (struct ifconf *)data; ! 275: register struct ifnet *ifp = ifnet; ! 276: register char *cp, *ep; ! 277: struct ifreq ifr, *ifrp; ! 278: int space = ifc->ifc_len, error = 0; ! 279: ! 280: ifrp = ifc->ifc_req; ! 281: ep = ifr.ifr_name + sizeof (ifr.ifr_name) - 2; ! 282: for (; space > sizeof (ifr) && ifp; ifp = ifp->if_next) { ! 283: bcopy(ifp->if_name, ifr.ifr_name, sizeof (ifr.ifr_name) - 2); ! 284: for (cp = ifr.ifr_name; cp < ep && *cp; cp++) ! 285: ; ! 286: *cp++ = '0' + ifp->if_unit; *cp = '\0'; ! 287: ifr.ifr_addr = ifp->if_addr; ! 288: error = copyout((caddr_t)&ifr, (caddr_t)ifrp, sizeof (ifr)); ! 289: if (error) ! 290: break; ! 291: space -= sizeof (ifr), ifrp++; ! 292: } ! 293: ifc->ifc_len -= space; ! 294: return (error); ! 295: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.