xref: /csrg-svn/sys/net/if.c (revision 6377)
1*6377Ssam /*	if.c	4.13	82/03/30	*/
24944Swnj 
34944Swnj #include "../h/param.h"
44944Swnj #include "../h/systm.h"
56333Ssam #include "../h/socket.h"
65083Swnj #include "../net/in.h"
75083Swnj #include "../net/in_systm.h"
84944Swnj #include "../net/if.h"
96333Ssam #include "../net/af.h"
104944Swnj 
116207Swnj int	ifqmaxlen = IFQ_MAXLEN;
126207Swnj 
136333Ssam /*
146333Ssam  * Network interface utility routines.
156333Ssam  *
166333Ssam  * Routines with if_ifwith* names take sockaddr *'s as
176333Ssam  * parameters.  Other routines take value parameters,
186333Ssam  * e.g. if_ifwithnet takes the network number.
196333Ssam  */
206333Ssam 
215206Swnj ifinit()
225206Swnj {
235206Swnj 	register struct ifnet *ifp;
245206Swnj 
255206Swnj 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
266207Swnj 		if (ifp->if_init) {
276333Ssam 			(*ifp->if_init)(ifp->if_unit);
286207Swnj 			if (ifp->if_snd.ifq_maxlen == 0)
296207Swnj 				ifp->if_snd.ifq_maxlen = ifqmaxlen;
306207Swnj 		}
315206Swnj }
325206Swnj 
336333Ssam /*
346333Ssam  * Call each interface on a Unibus reset.
356333Ssam  */
365206Swnj ifubareset(uban)
375206Swnj 	int uban;
385206Swnj {
395206Swnj 	register struct ifnet *ifp;
405206Swnj 
415206Swnj 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
425206Swnj 		if (ifp->if_ubareset)
435206Swnj 			(*ifp->if_ubareset)(uban);
445206Swnj }
455206Swnj 
466333Ssam /*
476333Ssam  * Attach an interface to the
486333Ssam  * list of "active" interfaces.
496333Ssam  */
505160Swnj if_attach(ifp)
515160Swnj 	struct ifnet *ifp;
525160Swnj {
535698Swnj 	register struct ifnet **p = &ifnet;
545160Swnj 
555160Swnj COUNT(IF_ATTACH);
565698Swnj 	while (*p)
575698Swnj 		p = &((*p)->if_next);
585698Swnj 	*p = ifp;
595160Swnj }
605160Swnj 
616333Ssam /*
626333Ssam  * Locate an interface based on a complete address.
636333Ssam  */
644951Swnj /*ARGSUSED*/
654951Swnj struct ifnet *
666333Ssam if_ifwithaddr(addr)
676333Ssam 	struct sockaddr *addr;
684944Swnj {
694944Swnj 	register struct ifnet *ifp;
704944Swnj 
714951Swnj COUNT(IF_IFWITHADDR);
726333Ssam #define	equal(a1, a2) \
736333Ssam 	(bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0)
746333Ssam 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
756333Ssam 		if (ifp->if_addr.sa_family != addr->sa_family)
766333Ssam 			continue;
776333Ssam 		if (equal(&ifp->if_addr, addr))
784944Swnj 			break;
796333Ssam 		if ((ifp->if_flags & IFF_BROADCAST) &&
806333Ssam 		    equal(&ifp->if_broadaddr, addr))
816333Ssam 			break;
826333Ssam 	}
834944Swnj 	return (ifp);
844944Swnj }
854944Swnj 
866333Ssam /*
876333Ssam  * Find an interface on a specific network.  If many, choice
886333Ssam  * is first found.
896333Ssam  */
904951Swnj struct ifnet *
916333Ssam if_ifwithnet(addr)
926333Ssam 	register struct sockaddr *addr;
934944Swnj {
944944Swnj 	register struct ifnet *ifp;
956333Ssam 	register int af = addr->sa_family;
966333Ssam 	register int (*netmatch)() = afswitch[af].af_netmatch;
974944Swnj 
986333Ssam 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
996333Ssam 		if (af != ifp->if_addr.sa_family)
1006333Ssam 			continue;
1016333Ssam 		if ((*netmatch)(addr, &ifp->if_addr))
1026333Ssam 			break;
1036333Ssam 	}
1046333Ssam 	return (ifp);
1056333Ssam }
1066333Ssam 
1076333Ssam /*
1086333Ssam  * As above, but parameter is network number.
1096333Ssam  */
1106333Ssam struct ifnet *
1116333Ssam if_ifonnetof(net)
1126333Ssam 	register int net;
1136333Ssam {
1146333Ssam 	register struct ifnet *ifp;
1156333Ssam 
1164944Swnj 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
1174944Swnj 		if (ifp->if_net == net)
1184944Swnj 			break;
1194944Swnj 	return (ifp);
1204944Swnj }
1214944Swnj 
1226333Ssam /*
1236333Ssam  * Find an interface using a specific address family
1246333Ssam  */
1255083Swnj struct ifnet *
1266333Ssam if_ifwithaf(af)
1276333Ssam 	register int af;
1285083Swnj {
1296333Ssam 	register struct ifnet *ifp;
1305083Swnj 
1316333Ssam 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
1326333Ssam 		if (ifp->if_addr.sa_family == af)
1336333Ssam 			break;
1346333Ssam 	return (ifp);
1355083Swnj }
1365104Swnj 
1376333Ssam /*
1386333Ssam  * Formulate an Internet address from network + host.  Used in
1396333Ssam  * building addresses stored in the ifnet structure.
1406333Ssam  */
1415104Swnj struct in_addr
1425104Swnj if_makeaddr(net, host)
1435104Swnj 	int net, host;
1445104Swnj {
1455104Swnj 	u_long addr;
1465104Swnj 
1475104Swnj 	if (net < 128)
1485206Swnj 		addr = (net << 24) | host;
1495104Swnj 	else if (net < 65536)
1505206Swnj 		addr = (net << 16) | host;
1515104Swnj 	else
1525206Swnj 		addr = (net << 8) | host;
1535685Ssam #ifdef vax
1545104Swnj 	addr = htonl(addr);
1555685Ssam #endif
1565104Swnj 	return (*(struct in_addr *)&addr);
1575104Swnj }
1586363Ssam 
1596363Ssam /*
1606363Ssam  * Initialize an interface's routing
1616363Ssam  * table entry according to the network.
1626363Ssam  * INTERNET SPECIFIC.
1636363Ssam  */
1646363Ssam if_rtinit(ifp, flags)
1656363Ssam 	register struct ifnet *ifp;
1666363Ssam 	int flags;
1676363Ssam {
1686363Ssam 	struct sockaddr_in sin;
1696363Ssam 
1706363Ssam 	if (ifp->if_flags & IFF_ROUTE)
1716363Ssam 		return;
1726363Ssam 	bzero((caddr_t)&sin, sizeof (sin));
1736363Ssam 	sin.sin_family = AF_INET;
1746363Ssam 	sin.sin_addr = if_makeaddr(ifp->if_net, 0);
175*6377Ssam 	rtinit(&sin, &ifp->if_addr, flags);
1766363Ssam }
177