X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/8af3ca7cbf958446bd2336f89b1b5320bebb20fe..0b33b6b5cfae94a2537efa3d6777c55c11955bf1:/usr/src/sys/net/if.c diff --git a/usr/src/sys/net/if.c b/usr/src/sys/net/if.c index 7c548bdec8..947edfe151 100644 --- a/usr/src/sys/net/if.c +++ b/usr/src/sys/net/if.c @@ -1,9 +1,15 @@ -/* if.c 4.23 82/10/31 */ +/* if.c 6.2 83/09/27 */ #include "../h/param.h" #include "../h/systm.h" #include "../h/socket.h" #include "../h/protosw.h" +#include "../h/dir.h" +#include "../h/user.h" +#include "../h/kernel.h" +#include "../h/ioctl.h" +#include "../h/errno.h" + #include "../net/if.h" #include "../net/af.h" @@ -30,7 +36,7 @@ ifinit() if_slowtimo(); } -#if vax +#ifdef vax /* * Call each interface on a Unibus reset. */ @@ -41,7 +47,7 @@ ifubareset(uban) for (ifp = ifnet; ifp; ifp = ifp->if_next) if (ifp->if_reset) - (*ifp->if_reset)(uban); + (*ifp->if_reset)(ifp->if_unit, uban); } #endif @@ -140,6 +146,7 @@ if_ifwithaf(af) /* * Mark an interface down and notify protocols of * the transition. + * NOTE: must be called at splnet or eqivalent. */ if_down(ifp) register struct ifnet *ifp; @@ -158,14 +165,131 @@ if_slowtimo() { register struct ifnet *ifp; - for (ifp = ifnet; ifp; ifp = ifp->if_next) - if (ifp->if_timer && --ifp->if_timer == 0) { - if (ifp->if_watchdog == 0) { - printf("%s%d: no watchdog routine\n", - ifp->if_name, ifp->if_unit); - continue; - } + 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->if_unit); - } + } timeout(if_slowtimo, (caddr_t)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; + + for (cp = name; cp < name + IFNAMSIZ && *cp; cp++) + if (*cp >= '0' && *cp <= '9') + break; + if (*cp == '\0' || cp == name + IFNAMSIZ) + return ((struct ifnet *)0); + unit = *cp - '0', *cp = 0; + for (ifp = ifnet; ifp; ifp = ifp->if_next) { + if (bcmp(ifp->if_name, name, (unsigned)(cp - name))) + continue; + if (unit == ifp->if_unit) + break; + } + return (ifp); +} + +/* + * Interface ioctls. + */ +ifioctl(cmd, data) + int cmd; + caddr_t data; +{ + register struct ifnet *ifp; + register struct ifreq *ifr; + + switch (cmd) { + + case SIOCGIFCONF: + return (ifconf(cmd, data)); + + case SIOCSIFADDR: + case SIOCSIFFLAGS: + case SIOCSIFDSTADDR: + if (!suser()) + return (u.u_error); + break; + } + ifr = (struct ifreq *)data; + ifp = ifunit(ifr->ifr_name); + if (ifp == 0) + return (ENXIO); + switch (cmd) { + + case SIOCGIFADDR: + ifr->ifr_addr = ifp->if_addr; + break; + + case SIOCGIFDSTADDR: + if ((ifp->if_flags & IFF_POINTOPOINT) == 0) + return (EINVAL); + ifr->ifr_dstaddr = ifp->if_dstaddr; + break; + + case SIOCGIFFLAGS: + ifr->ifr_flags = ifp->if_flags; + break; + + case SIOCSIFFLAGS: + if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) { + int s = splimp(); + if_down(ifp); + splx(s); + } + ifp->if_flags = ifr->ifr_flags; + break; + + default: + if (ifp->if_ioctl == 0) + return (EOPNOTSUPP); + return ((*ifp->if_ioctl)(ifp, cmd, data)); + } + return (0); +} + +/* + * Return interface configuration + * of system. List may be used + * in later ioctl's (above) to get + * other information. + */ +/*ARGSUSED*/ +ifconf(cmd, data) + int cmd; + caddr_t data; +{ + register struct ifconf *ifc = (struct ifconf *)data; + register struct ifnet *ifp = ifnet; + register char *cp, *ep; + struct ifreq ifr, *ifrp; + int space = ifc->ifc_len, error = 0; + + ifrp = ifc->ifc_req; + ep = ifr.ifr_name + sizeof (ifr.ifr_name) - 2; + for (; space > sizeof (ifr) && ifp; ifp = ifp->if_next) { + bcopy(ifp->if_name, ifr.ifr_name, sizeof (ifr.ifr_name) - 2); + for (cp = ifr.ifr_name; cp < ep && *cp; cp++) + ; + *cp++ = '0' + ifp->if_unit; *cp = '\0'; + ifr.ifr_addr = ifp->if_addr; + error = copyout((caddr_t)&ifr, (caddr_t)ifrp, sizeof (ifr)); + if (error) + break; + space -= sizeof (ifr), ifrp++; + } + ifc->ifc_len -= space; + return (error); +}