X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/f1b2fa5b8a62e80603e6c83b87eaf0b06db3818e..39674d5f4e66e750df77c36159b66e1554511bb5:/usr/src/sys/net/if.c diff --git a/usr/src/sys/net/if.c b/usr/src/sys/net/if.c index 1cd6adb347..ee6ef4f778 100644 --- a/usr/src/sys/net/if.c +++ b/usr/src/sys/net/if.c @@ -1,51 +1,155 @@ -/* if.c 4.4 81/11/29 */ +/* if.c 4.14 82/04/24 */ #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 "../net/if.h" +#include "../net/af.h" +int ifqmaxlen = IFQ_MAXLEN; + +/* + * Network interface utility routines. + * + * Routines with if_ifwith* names take sockaddr *'s as + * parameters. Other routines take value parameters, + * e.g. if_ifwithnet takes the network number. + */ + +ifinit() +{ + register struct ifnet *ifp; + + for (ifp = ifnet; ifp; ifp = ifp->if_next) + if (ifp->if_init) { + (*ifp->if_init)(ifp->if_unit); + if (ifp->if_snd.ifq_maxlen == 0) + ifp->if_snd.ifq_maxlen = ifqmaxlen; + } +} + +/* + * Call each interface on a Unibus reset. + */ +ifubareset(uban) + int uban; +{ + register struct ifnet *ifp; + + for (ifp = ifnet; ifp; ifp = ifp->if_next) + if (ifp->if_ubareset) + (*ifp->if_ubareset)(uban); +} + +/* + * Attach an interface to the + * list of "active" interfaces. + */ +if_attach(ifp) + struct ifnet *ifp; +{ + register struct ifnet **p = &ifnet; + +COUNT(IF_ATTACH); + while (*p) + p = &((*p)->if_next); + *p = ifp; +} + +/* + * Locate an interface based on a complete address. + */ /*ARGSUSED*/ struct ifnet * -if_ifwithaddr(in) - struct in_addr in; +if_ifwithaddr(addr) + struct sockaddr *addr; { register struct ifnet *ifp; COUNT(IF_IFWITHADDR); - for (ifp = ifnet; ifp; ifp = ifp->if_next) - if (ifp->if_addr.s_addr == in.s_addr) +#define equal(a1, a2) \ + (bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0) + for (ifp = ifnet; ifp; ifp = ifp->if_next) { + if (ifp->if_addr.sa_family != addr->sa_family) + continue; + if (equal(&ifp->if_addr, addr)) + break; + if ((ifp->if_flags & IFF_BROADCAST) && + equal(&ifp->if_broadaddr, addr)) break; + } return (ifp); } -/*ARGSUSED*/ +/* + * Find an interface on a specific network. If many, choice + * is first found. + */ struct ifnet * -if_ifonnetof(in) - struct in_addr in; +if_ifwithnet(addr) + register struct sockaddr *addr; +{ + register struct ifnet *ifp; + register int af = addr->sa_family; + register int (*netmatch)() = afswitch[af].af_netmatch; + + for (ifp = ifnet; ifp; ifp = ifp->if_next) { + if (af != ifp->if_addr.sa_family) + continue; + if ((*netmatch)(addr, &ifp->if_addr)) + break; + } + return (ifp); +} + +/* + * As above, but parameter is network number. + */ +struct ifnet * +if_ifonnetof(net) + register int net; { register struct ifnet *ifp; - int net; -COUNT(IF_IFONNETOF); - net = in.s_net; /* XXX */ for (ifp = ifnet; ifp; ifp = ifp->if_next) if (ifp->if_net == net) break; return (ifp); } -/*ARGSUSED*/ +/* + * Find an interface using a specific address family + */ struct ifnet * -if_gatewayfor(addr) - struct in_addr addr; +if_ifwithaf(af) + register int af; { + register struct ifnet *ifp; -COUNT(IF_GATEWAYFOR); - return (0); + for (ifp = ifnet; ifp; ifp = ifp->if_next) + if (ifp->if_addr.sa_family == af) + break; + return (ifp); +} + +/* + * Mark an interface down and notify protocols of + * the transition. + */ +if_down(ifp) + register struct ifnet *ifp; +{ + ifp->if_flags &= ~IFF_UP; + pfctlinput(PRC_IFDOWN, (caddr_t)&ifp->if_addr); } +/* + * Formulate an Internet address from network + host. Used in + * building addresses stored in the ifnet structure. + */ struct in_addr if_makeaddr(net, host) int net, host; @@ -53,11 +157,32 @@ if_makeaddr(net, host) u_long addr; if (net < 128) - addr = (host << 8) | net; + addr = (net << 24) | host; else if (net < 65536) - addr = (host << 16) | net; + addr = (net << 16) | host; else - addr = (host << 24) | net; + addr = (net << 8) | host; +#ifdef vax addr = htonl(addr); +#endif return (*(struct in_addr *)&addr); } + +/* + * Initialize an interface's routing + * table entry according to the network. + * INTERNET SPECIFIC. + */ +if_rtinit(ifp, flags) + register struct ifnet *ifp; + int flags; +{ + struct sockaddr_in sin; + + if (ifp->if_flags & IFF_ROUTE) + return; + bzero((caddr_t)&sin, sizeof (sin)); + sin.sin_family = AF_INET; + sin.sin_addr = if_makeaddr(ifp->if_net, 0); + rtinit(&sin, &ifp->if_addr, flags); +}