xref: /csrg-svn/sys/net/if.c (revision 7264)
1*7264Ssam /*	if.c	4.18	82/06/23	*/
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 
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 
716333Ssam #define	equal(a1, a2) \
726333Ssam 	(bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0)
736333Ssam 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
746333Ssam 		if (ifp->if_addr.sa_family != addr->sa_family)
756333Ssam 			continue;
766333Ssam 		if (equal(&ifp->if_addr, addr))
774944Swnj 			break;
786333Ssam 		if ((ifp->if_flags & IFF_BROADCAST) &&
796333Ssam 		    equal(&ifp->if_broadaddr, addr))
806333Ssam 			break;
816333Ssam 	}
824944Swnj 	return (ifp);
834944Swnj }
844944Swnj 
856333Ssam /*
866333Ssam  * Find an interface on a specific network.  If many, choice
876333Ssam  * is first found.
886333Ssam  */
894951Swnj struct ifnet *
906333Ssam if_ifwithnet(addr)
916333Ssam 	register struct sockaddr *addr;
924944Swnj {
934944Swnj 	register struct ifnet *ifp;
946333Ssam 	register int af = addr->sa_family;
956619Ssam 	register int (*netmatch)();
964944Swnj 
976619Ssam 	if (af >= AF_MAX)
986619Ssam 		return (0);
996619Ssam 	netmatch = afswitch[af].af_netmatch;
1006333Ssam 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
1016333Ssam 		if (af != ifp->if_addr.sa_family)
1026333Ssam 			continue;
1036333Ssam 		if ((*netmatch)(addr, &ifp->if_addr))
1046333Ssam 			break;
1056333Ssam 	}
1066333Ssam 	return (ifp);
1076333Ssam }
1086333Ssam 
1096333Ssam /*
1106333Ssam  * As above, but parameter is network number.
1116333Ssam  */
1126333Ssam struct ifnet *
1136333Ssam if_ifonnetof(net)
1146333Ssam 	register int net;
1156333Ssam {
1166333Ssam 	register struct ifnet *ifp;
1176333Ssam 
1184944Swnj 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
1194944Swnj 		if (ifp->if_net == net)
1204944Swnj 			break;
1214944Swnj 	return (ifp);
1224944Swnj }
1234944Swnj 
1246333Ssam /*
1256333Ssam  * Find an interface using a specific address family
1266333Ssam  */
1275083Swnj struct ifnet *
1286333Ssam if_ifwithaf(af)
1296333Ssam 	register int af;
1305083Swnj {
1316333Ssam 	register struct ifnet *ifp;
1325083Swnj 
1336333Ssam 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
1346333Ssam 		if (ifp->if_addr.sa_family == af)
1356333Ssam 			break;
1366333Ssam 	return (ifp);
1375083Swnj }
1385104Swnj 
1396333Ssam /*
1406582Ssam  * Mark an interface down and notify protocols of
1416582Ssam  * the transition.
1426582Ssam  */
1436582Ssam if_down(ifp)
1446582Ssam 	register struct ifnet *ifp;
1456582Ssam {
1466582Ssam 	ifp->if_flags &= ~IFF_UP;
1476582Ssam 	pfctlinput(PRC_IFDOWN, (caddr_t)&ifp->if_addr);
1486582Ssam }
149*7264Ssam 
150*7264Ssam /*
151*7264Ssam  * Handle interface watchdog timer routines.  Called
152*7264Ssam  * from softclock, we decrement timers (if set) and
153*7264Ssam  * call the appropriate interface routine on expiration.
154*7264Ssam  */
155*7264Ssam if_slowtimo()
156*7264Ssam {
157*7264Ssam 	register struct ifnet *ifp;
158*7264Ssam 
159*7264Ssam 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
160*7264Ssam 		if (ifp->if_timer && --ifp->if_timer == 0) {
161*7264Ssam 			if (ifp->if_watchdog == 0) {
162*7264Ssam 				printf("%s%d: no watchdog routine\n",
163*7264Ssam 					ifp->if_name, ifp->if_unit);
164*7264Ssam 				continue;
165*7264Ssam 			}
166*7264Ssam 			(*ifp->if_watchdog)(ifp->if_unit);
167*7264Ssam 		}
168*7264Ssam }
169