xref: /csrg-svn/sys/net/if.c (revision 6619)
1*6619Ssam /*	if.c	4.15	82/05/04	*/
24944Swnj 
34944Swnj #include "../h/param.h"
44944Swnj #include "../h/systm.h"
56333Ssam #include "../h/socket.h"
66582Ssam #include "../h/protosw.h"
75083Swnj #include "../net/in.h"
85083Swnj #include "../net/in_systm.h"
94944Swnj #include "../net/if.h"
106333Ssam #include "../net/af.h"
114944Swnj 
126207Swnj int	ifqmaxlen = IFQ_MAXLEN;
136207Swnj 
146333Ssam /*
156333Ssam  * Network interface utility routines.
166333Ssam  *
176333Ssam  * Routines with if_ifwith* names take sockaddr *'s as
186333Ssam  * parameters.  Other routines take value parameters,
196333Ssam  * e.g. if_ifwithnet takes the network number.
206333Ssam  */
216333Ssam 
225206Swnj ifinit()
235206Swnj {
245206Swnj 	register struct ifnet *ifp;
255206Swnj 
265206Swnj 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
276207Swnj 		if (ifp->if_init) {
286333Ssam 			(*ifp->if_init)(ifp->if_unit);
296207Swnj 			if (ifp->if_snd.ifq_maxlen == 0)
306207Swnj 				ifp->if_snd.ifq_maxlen = ifqmaxlen;
316207Swnj 		}
325206Swnj }
335206Swnj 
346333Ssam /*
356333Ssam  * Call each interface on a Unibus reset.
366333Ssam  */
375206Swnj ifubareset(uban)
385206Swnj 	int uban;
395206Swnj {
405206Swnj 	register struct ifnet *ifp;
415206Swnj 
425206Swnj 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
435206Swnj 		if (ifp->if_ubareset)
445206Swnj 			(*ifp->if_ubareset)(uban);
455206Swnj }
465206Swnj 
476333Ssam /*
486333Ssam  * Attach an interface to the
496333Ssam  * list of "active" interfaces.
506333Ssam  */
515160Swnj if_attach(ifp)
525160Swnj 	struct ifnet *ifp;
535160Swnj {
545698Swnj 	register struct ifnet **p = &ifnet;
555160Swnj 
565160Swnj COUNT(IF_ATTACH);
575698Swnj 	while (*p)
585698Swnj 		p = &((*p)->if_next);
595698Swnj 	*p = ifp;
605160Swnj }
615160Swnj 
626333Ssam /*
636333Ssam  * Locate an interface based on a complete address.
646333Ssam  */
654951Swnj /*ARGSUSED*/
664951Swnj struct ifnet *
676333Ssam if_ifwithaddr(addr)
686333Ssam 	struct sockaddr *addr;
694944Swnj {
704944Swnj 	register struct ifnet *ifp;
714944Swnj 
724951Swnj COUNT(IF_IFWITHADDR);
736333Ssam #define	equal(a1, a2) \
746333Ssam 	(bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0)
756333Ssam 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
766333Ssam 		if (ifp->if_addr.sa_family != addr->sa_family)
776333Ssam 			continue;
786333Ssam 		if (equal(&ifp->if_addr, addr))
794944Swnj 			break;
806333Ssam 		if ((ifp->if_flags & IFF_BROADCAST) &&
816333Ssam 		    equal(&ifp->if_broadaddr, addr))
826333Ssam 			break;
836333Ssam 	}
844944Swnj 	return (ifp);
854944Swnj }
864944Swnj 
876333Ssam /*
886333Ssam  * Find an interface on a specific network.  If many, choice
896333Ssam  * is first found.
906333Ssam  */
914951Swnj struct ifnet *
926333Ssam if_ifwithnet(addr)
936333Ssam 	register struct sockaddr *addr;
944944Swnj {
954944Swnj 	register struct ifnet *ifp;
966333Ssam 	register int af = addr->sa_family;
97*6619Ssam 	register int (*netmatch)();
984944Swnj 
99*6619Ssam 	if (af >= AF_MAX)
100*6619Ssam 		return (0);
101*6619Ssam 	netmatch = afswitch[af].af_netmatch;
1026333Ssam 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
1036333Ssam 		if (af != ifp->if_addr.sa_family)
1046333Ssam 			continue;
1056333Ssam 		if ((*netmatch)(addr, &ifp->if_addr))
1066333Ssam 			break;
1076333Ssam 	}
1086333Ssam 	return (ifp);
1096333Ssam }
1106333Ssam 
1116333Ssam /*
1126333Ssam  * As above, but parameter is network number.
1136333Ssam  */
1146333Ssam struct ifnet *
1156333Ssam if_ifonnetof(net)
1166333Ssam 	register int net;
1176333Ssam {
1186333Ssam 	register struct ifnet *ifp;
1196333Ssam 
1204944Swnj 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
1214944Swnj 		if (ifp->if_net == net)
1224944Swnj 			break;
1234944Swnj 	return (ifp);
1244944Swnj }
1254944Swnj 
1266333Ssam /*
1276333Ssam  * Find an interface using a specific address family
1286333Ssam  */
1295083Swnj struct ifnet *
1306333Ssam if_ifwithaf(af)
1316333Ssam 	register int af;
1325083Swnj {
1336333Ssam 	register struct ifnet *ifp;
1345083Swnj 
1356333Ssam 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
1366333Ssam 		if (ifp->if_addr.sa_family == af)
1376333Ssam 			break;
1386333Ssam 	return (ifp);
1395083Swnj }
1405104Swnj 
1416333Ssam /*
1426582Ssam  * Mark an interface down and notify protocols of
1436582Ssam  * the transition.
1446582Ssam  */
1456582Ssam if_down(ifp)
1466582Ssam 	register struct ifnet *ifp;
1476582Ssam {
1486582Ssam 	ifp->if_flags &= ~IFF_UP;
1496582Ssam 	pfctlinput(PRC_IFDOWN, (caddr_t)&ifp->if_addr);
1506582Ssam }
1516582Ssam 
1526582Ssam /*
1536333Ssam  * Formulate an Internet address from network + host.  Used in
1546333Ssam  * building addresses stored in the ifnet structure.
1556333Ssam  */
1565104Swnj struct in_addr
1575104Swnj if_makeaddr(net, host)
1585104Swnj 	int net, host;
1595104Swnj {
1605104Swnj 	u_long addr;
1615104Swnj 
1625104Swnj 	if (net < 128)
1635206Swnj 		addr = (net << 24) | host;
1645104Swnj 	else if (net < 65536)
1655206Swnj 		addr = (net << 16) | host;
1665104Swnj 	else
1675206Swnj 		addr = (net << 8) | host;
1685685Ssam #ifdef vax
1695104Swnj 	addr = htonl(addr);
1705685Ssam #endif
1715104Swnj 	return (*(struct in_addr *)&addr);
1725104Swnj }
1736363Ssam 
1746363Ssam /*
1756363Ssam  * Initialize an interface's routing
1766363Ssam  * table entry according to the network.
1776363Ssam  * INTERNET SPECIFIC.
1786363Ssam  */
1796363Ssam if_rtinit(ifp, flags)
1806363Ssam 	register struct ifnet *ifp;
1816363Ssam 	int flags;
1826363Ssam {
1836363Ssam 	struct sockaddr_in sin;
1846363Ssam 
1856363Ssam 	if (ifp->if_flags & IFF_ROUTE)
1866363Ssam 		return;
1876363Ssam 	bzero((caddr_t)&sin, sizeof (sin));
1886363Ssam 	sin.sin_family = AF_INET;
1896363Ssam 	sin.sin_addr = if_makeaddr(ifp->if_net, 0);
1906377Ssam 	rtinit(&sin, &ifp->if_addr, flags);
1916363Ssam }
192