X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/4023eed27a3d5dfd1145560a2a8cc42880469c82..0b33b6b5cfae94a2537efa3d6777c55c11955bf1:/usr/src/sys/net/if.c diff --git a/usr/src/sys/net/if.c b/usr/src/sys/net/if.c index 0fcf3c8a7e..947edfe151 100644 --- a/usr/src/sys/net/if.c +++ b/usr/src/sys/net/if.c @@ -1,11 +1,15 @@ -/* if.c 4.17 82/06/20 */ +/* if.c 6.2 83/09/27 */ #include "../h/param.h" #include "../h/systm.h" #include "../h/socket.h" #include "../h/protosw.h" -#include "../net/in.h" -#include "../net/in_systm.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" @@ -29,8 +33,10 @@ ifinit() if (ifp->if_snd.ifq_maxlen == 0) ifp->if_snd.ifq_maxlen = ifqmaxlen; } + if_slowtimo(); } +#ifdef vax /* * Call each interface on a Unibus reset. */ @@ -40,9 +46,10 @@ ifubareset(uban) register struct ifnet *ifp; for (ifp = ifnet; ifp; ifp = ifp->if_next) - if (ifp->if_ubareset) - (*ifp->if_ubareset)(uban); + if (ifp->if_reset) + (*ifp->if_reset)(ifp->if_unit, uban); } +#endif /* * Attach an interface to the @@ -91,7 +98,7 @@ if_ifwithnet(addr) register struct sockaddr *addr; { register struct ifnet *ifp; - register int af = addr->sa_family; + register u_int af = addr->sa_family; register int (*netmatch)(); if (af >= AF_MAX) @@ -139,10 +146,150 @@ 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; { + ifp->if_flags &= ~IFF_UP; pfctlinput(PRC_IFDOWN, (caddr_t)&ifp->if_addr); } + +/* + * Handle interface watchdog timer routines. Called + * from softclock, we decrement timers (if set) and + * call the appropriate interface routine on expiration. + */ +if_slowtimo() +{ + register struct ifnet *ifp; + + 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); +}