xref: /csrg-svn/sys/net/if.c (revision 8393)
1*8393Swnj /*	if.c	4.20	82/10/09	*/
24944Swnj 
34944Swnj #include "../h/param.h"
44944Swnj #include "../h/systm.h"
56333Ssam #include "../h/socket.h"
66582Ssam #include "../h/protosw.h"
74944Swnj #include "../net/if.h"
86333Ssam #include "../net/af.h"
94944Swnj 
106207Swnj int	ifqmaxlen = IFQ_MAXLEN;
116207Swnj 
126333Ssam /*
136333Ssam  * Network interface utility routines.
146333Ssam  *
156333Ssam  * Routines with if_ifwith* names take sockaddr *'s as
166333Ssam  * parameters.  Other routines take value parameters,
176333Ssam  * e.g. if_ifwithnet takes the network number.
186333Ssam  */
196333Ssam 
205206Swnj ifinit()
215206Swnj {
225206Swnj 	register struct ifnet *ifp;
235206Swnj 
245206Swnj 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
256207Swnj 		if (ifp->if_init) {
266333Ssam 			(*ifp->if_init)(ifp->if_unit);
276207Swnj 			if (ifp->if_snd.ifq_maxlen == 0)
286207Swnj 				ifp->if_snd.ifq_maxlen = ifqmaxlen;
296207Swnj 		}
308173Sroot 	if_slowtimo();
315206Swnj }
325206Swnj 
33*8393Swnj #if vax
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 }
46*8393Swnj #endif
475206Swnj 
486333Ssam /*
496333Ssam  * Attach an interface to the
506333Ssam  * list of "active" interfaces.
516333Ssam  */
525160Swnj if_attach(ifp)
535160Swnj 	struct ifnet *ifp;
545160Swnj {
555698Swnj 	register struct ifnet **p = &ifnet;
565160Swnj 
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 
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;
95*8393Swnj 	register u_int af = addr->sa_family;
966619Ssam 	register int (*netmatch)();
974944Swnj 
986619Ssam 	if (af >= AF_MAX)
996619Ssam 		return (0);
1006619Ssam 	netmatch = afswitch[af].af_netmatch;
1016333Ssam 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
1026333Ssam 		if (af != ifp->if_addr.sa_family)
1036333Ssam 			continue;
1046333Ssam 		if ((*netmatch)(addr, &ifp->if_addr))
1056333Ssam 			break;
1066333Ssam 	}
1076333Ssam 	return (ifp);
1086333Ssam }
1096333Ssam 
1106333Ssam /*
1116333Ssam  * As above, but parameter is network number.
1126333Ssam  */
1136333Ssam struct ifnet *
1146333Ssam if_ifonnetof(net)
1156333Ssam 	register int net;
1166333Ssam {
1176333Ssam 	register struct ifnet *ifp;
1186333Ssam 
1194944Swnj 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
1204944Swnj 		if (ifp->if_net == net)
1214944Swnj 			break;
1224944Swnj 	return (ifp);
1234944Swnj }
1244944Swnj 
1256333Ssam /*
1266333Ssam  * Find an interface using a specific address family
1276333Ssam  */
1285083Swnj struct ifnet *
1296333Ssam if_ifwithaf(af)
1306333Ssam 	register int af;
1315083Swnj {
1326333Ssam 	register struct ifnet *ifp;
1335083Swnj 
1346333Ssam 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
1356333Ssam 		if (ifp->if_addr.sa_family == af)
1366333Ssam 			break;
1376333Ssam 	return (ifp);
1385083Swnj }
1395104Swnj 
1406333Ssam /*
1416582Ssam  * Mark an interface down and notify protocols of
1426582Ssam  * the transition.
1436582Ssam  */
1446582Ssam if_down(ifp)
1456582Ssam 	register struct ifnet *ifp;
1466582Ssam {
1478173Sroot 
1486582Ssam 	ifp->if_flags &= ~IFF_UP;
1496582Ssam 	pfctlinput(PRC_IFDOWN, (caddr_t)&ifp->if_addr);
1506582Ssam }
1517264Ssam 
1527264Ssam /*
1537264Ssam  * Handle interface watchdog timer routines.  Called
1547264Ssam  * from softclock, we decrement timers (if set) and
1557264Ssam  * call the appropriate interface routine on expiration.
1567264Ssam  */
1577264Ssam if_slowtimo()
1587264Ssam {
1597264Ssam 	register struct ifnet *ifp;
1607264Ssam 
1617264Ssam 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
1627264Ssam 		if (ifp->if_timer && --ifp->if_timer == 0) {
1637264Ssam 			if (ifp->if_watchdog == 0) {
1647264Ssam 				printf("%s%d: no watchdog routine\n",
1657264Ssam 					ifp->if_name, ifp->if_unit);
1667264Ssam 				continue;
1677264Ssam 			}
1687264Ssam 			(*ifp->if_watchdog)(ifp->if_unit);
1697264Ssam 		}
1708173Sroot 	timeout(if_slowtimo, 0, hz / IFNET_SLOWHZ);
1717264Ssam }
172