xref: /csrg-svn/sys/net/if.c (revision 7234)
1 /*	if.c	4.17	82/06/20	*/
2 
3 #include "../h/param.h"
4 #include "../h/systm.h"
5 #include "../h/socket.h"
6 #include "../h/protosw.h"
7 #include "../net/in.h"
8 #include "../net/in_systm.h"
9 #include "../net/if.h"
10 #include "../net/af.h"
11 
12 int	ifqmaxlen = IFQ_MAXLEN;
13 
14 /*
15  * Network interface utility routines.
16  *
17  * Routines with if_ifwith* names take sockaddr *'s as
18  * parameters.  Other routines take value parameters,
19  * e.g. if_ifwithnet takes the network number.
20  */
21 
22 ifinit()
23 {
24 	register struct ifnet *ifp;
25 
26 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
27 		if (ifp->if_init) {
28 			(*ifp->if_init)(ifp->if_unit);
29 			if (ifp->if_snd.ifq_maxlen == 0)
30 				ifp->if_snd.ifq_maxlen = ifqmaxlen;
31 		}
32 }
33 
34 /*
35  * Call each interface on a Unibus reset.
36  */
37 ifubareset(uban)
38 	int uban;
39 {
40 	register struct ifnet *ifp;
41 
42 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
43 		if (ifp->if_ubareset)
44 			(*ifp->if_ubareset)(uban);
45 }
46 
47 /*
48  * Attach an interface to the
49  * list of "active" interfaces.
50  */
51 if_attach(ifp)
52 	struct ifnet *ifp;
53 {
54 	register struct ifnet **p = &ifnet;
55 
56 	while (*p)
57 		p = &((*p)->if_next);
58 	*p = ifp;
59 }
60 
61 /*
62  * Locate an interface based on a complete address.
63  */
64 /*ARGSUSED*/
65 struct ifnet *
66 if_ifwithaddr(addr)
67 	struct sockaddr *addr;
68 {
69 	register struct ifnet *ifp;
70 
71 #define	equal(a1, a2) \
72 	(bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0)
73 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
74 		if (ifp->if_addr.sa_family != addr->sa_family)
75 			continue;
76 		if (equal(&ifp->if_addr, addr))
77 			break;
78 		if ((ifp->if_flags & IFF_BROADCAST) &&
79 		    equal(&ifp->if_broadaddr, addr))
80 			break;
81 	}
82 	return (ifp);
83 }
84 
85 /*
86  * Find an interface on a specific network.  If many, choice
87  * is first found.
88  */
89 struct ifnet *
90 if_ifwithnet(addr)
91 	register struct sockaddr *addr;
92 {
93 	register struct ifnet *ifp;
94 	register int af = addr->sa_family;
95 	register int (*netmatch)();
96 
97 	if (af >= AF_MAX)
98 		return (0);
99 	netmatch = afswitch[af].af_netmatch;
100 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
101 		if (af != ifp->if_addr.sa_family)
102 			continue;
103 		if ((*netmatch)(addr, &ifp->if_addr))
104 			break;
105 	}
106 	return (ifp);
107 }
108 
109 /*
110  * As above, but parameter is network number.
111  */
112 struct ifnet *
113 if_ifonnetof(net)
114 	register int net;
115 {
116 	register struct ifnet *ifp;
117 
118 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
119 		if (ifp->if_net == net)
120 			break;
121 	return (ifp);
122 }
123 
124 /*
125  * Find an interface using a specific address family
126  */
127 struct ifnet *
128 if_ifwithaf(af)
129 	register int af;
130 {
131 	register struct ifnet *ifp;
132 
133 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
134 		if (ifp->if_addr.sa_family == af)
135 			break;
136 	return (ifp);
137 }
138 
139 /*
140  * Mark an interface down and notify protocols of
141  * the transition.
142  */
143 if_down(ifp)
144 	register struct ifnet *ifp;
145 {
146 	ifp->if_flags &= ~IFF_UP;
147 	pfctlinput(PRC_IFDOWN, (caddr_t)&ifp->if_addr);
148 }
149