xref: /csrg-svn/sys/net/if.c (revision 6333)
1*6333Ssam /*	if.c	4.11	82/03/28	*/
24944Swnj 
34944Swnj #include "../h/param.h"
44944Swnj #include "../h/systm.h"
5*6333Ssam #include "../h/socket.h"
65083Swnj #include "../net/in.h"
75083Swnj #include "../net/in_systm.h"
84944Swnj #include "../net/if.h"
9*6333Ssam #include "../net/af.h"
104944Swnj 
116207Swnj int	ifqmaxlen = IFQ_MAXLEN;
126207Swnj 
13*6333Ssam /*
14*6333Ssam  * Network interface utility routines.
15*6333Ssam  *
16*6333Ssam  * Routines with if_ifwith* names take sockaddr *'s as
17*6333Ssam  * parameters.  Other routines take value parameters,
18*6333Ssam  * e.g. if_ifwithnet takes the network number.
19*6333Ssam  */
20*6333Ssam 
215206Swnj ifinit()
225206Swnj {
235206Swnj 	register struct ifnet *ifp;
245206Swnj 
255206Swnj 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
266207Swnj 		if (ifp->if_init) {
27*6333Ssam 			(*ifp->if_init)(ifp->if_unit);
286207Swnj 			if (ifp->if_snd.ifq_maxlen == 0)
296207Swnj 				ifp->if_snd.ifq_maxlen = ifqmaxlen;
306207Swnj 		}
315206Swnj }
325206Swnj 
33*6333Ssam /*
34*6333Ssam  * Call each interface on a Unibus reset.
35*6333Ssam  */
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 
46*6333Ssam /*
47*6333Ssam  * Attach an interface to the
48*6333Ssam  * list of "active" interfaces.
49*6333Ssam  */
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 
61*6333Ssam /*
62*6333Ssam  * Locate an interface based on a complete address.
63*6333Ssam  */
644951Swnj /*ARGSUSED*/
654951Swnj struct ifnet *
66*6333Ssam if_ifwithaddr(addr)
67*6333Ssam 	struct sockaddr *addr;
684944Swnj {
694944Swnj 	register struct ifnet *ifp;
704944Swnj 
714951Swnj COUNT(IF_IFWITHADDR);
72*6333Ssam #define	equal(a1, a2) \
73*6333Ssam 	(bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0)
74*6333Ssam 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
75*6333Ssam 		if (ifp->if_addr.sa_family != addr->sa_family)
76*6333Ssam 			continue;
77*6333Ssam 		if (equal(&ifp->if_addr, addr))
784944Swnj 			break;
79*6333Ssam 		if ((ifp->if_flags & IFF_BROADCAST) &&
80*6333Ssam 		    equal(&ifp->if_broadaddr, addr))
81*6333Ssam 			break;
82*6333Ssam 	}
834944Swnj 	return (ifp);
844944Swnj }
854944Swnj 
86*6333Ssam /*
87*6333Ssam  * Find an interface on a specific network.  If many, choice
88*6333Ssam  * is first found.
89*6333Ssam  */
904951Swnj struct ifnet *
91*6333Ssam if_ifwithnet(addr)
92*6333Ssam 	register struct sockaddr *addr;
934944Swnj {
944944Swnj 	register struct ifnet *ifp;
95*6333Ssam 	register int af = addr->sa_family;
96*6333Ssam 	register int (*netmatch)() = afswitch[af].af_netmatch;
974944Swnj 
98*6333Ssam 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
99*6333Ssam 		if (af != ifp->if_addr.sa_family)
100*6333Ssam 			continue;
101*6333Ssam 		if ((*netmatch)(addr, &ifp->if_addr))
102*6333Ssam 			break;
103*6333Ssam 	}
104*6333Ssam 	return (ifp);
105*6333Ssam }
106*6333Ssam 
107*6333Ssam /*
108*6333Ssam  * As above, but parameter is network number.
109*6333Ssam  */
110*6333Ssam struct ifnet *
111*6333Ssam if_ifonnetof(net)
112*6333Ssam 	register int net;
113*6333Ssam {
114*6333Ssam 	register struct ifnet *ifp;
115*6333Ssam 
1164944Swnj 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
1174944Swnj 		if (ifp->if_net == net)
1184944Swnj 			break;
1194944Swnj 	return (ifp);
1204944Swnj }
1214944Swnj 
122*6333Ssam /*
123*6333Ssam  * Find an interface using a specific address family
124*6333Ssam  */
1255083Swnj struct ifnet *
126*6333Ssam if_ifwithaf(af)
127*6333Ssam 	register int af;
1285083Swnj {
129*6333Ssam 	register struct ifnet *ifp;
1305083Swnj 
131*6333Ssam 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
132*6333Ssam 		if (ifp->if_addr.sa_family == af)
133*6333Ssam 			break;
134*6333Ssam 	return (ifp);
1355083Swnj }
1365104Swnj 
137*6333Ssam /*
138*6333Ssam  * Formulate an Internet address from network + host.  Used in
139*6333Ssam  * building addresses stored in the ifnet structure.
140*6333Ssam  */
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 }
158