xref: /csrg-svn/sys/net/if.c (revision 6582)
1 /*	if.c	4.14	82/04/24	*/
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 COUNT(IF_ATTACH);
57 	while (*p)
58 		p = &((*p)->if_next);
59 	*p = ifp;
60 }
61 
62 /*
63  * Locate an interface based on a complete address.
64  */
65 /*ARGSUSED*/
66 struct ifnet *
67 if_ifwithaddr(addr)
68 	struct sockaddr *addr;
69 {
70 	register struct ifnet *ifp;
71 
72 COUNT(IF_IFWITHADDR);
73 #define	equal(a1, a2) \
74 	(bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0)
75 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
76 		if (ifp->if_addr.sa_family != addr->sa_family)
77 			continue;
78 		if (equal(&ifp->if_addr, addr))
79 			break;
80 		if ((ifp->if_flags & IFF_BROADCAST) &&
81 		    equal(&ifp->if_broadaddr, addr))
82 			break;
83 	}
84 	return (ifp);
85 }
86 
87 /*
88  * Find an interface on a specific network.  If many, choice
89  * is first found.
90  */
91 struct ifnet *
92 if_ifwithnet(addr)
93 	register struct sockaddr *addr;
94 {
95 	register struct ifnet *ifp;
96 	register int af = addr->sa_family;
97 	register int (*netmatch)() = afswitch[af].af_netmatch;
98 
99 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
100 		if (af != ifp->if_addr.sa_family)
101 			continue;
102 		if ((*netmatch)(addr, &ifp->if_addr))
103 			break;
104 	}
105 	return (ifp);
106 }
107 
108 /*
109  * As above, but parameter is network number.
110  */
111 struct ifnet *
112 if_ifonnetof(net)
113 	register int net;
114 {
115 	register struct ifnet *ifp;
116 
117 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
118 		if (ifp->if_net == net)
119 			break;
120 	return (ifp);
121 }
122 
123 /*
124  * Find an interface using a specific address family
125  */
126 struct ifnet *
127 if_ifwithaf(af)
128 	register int af;
129 {
130 	register struct ifnet *ifp;
131 
132 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
133 		if (ifp->if_addr.sa_family == af)
134 			break;
135 	return (ifp);
136 }
137 
138 /*
139  * Mark an interface down and notify protocols of
140  * the transition.
141  */
142 if_down(ifp)
143 	register struct ifnet *ifp;
144 {
145 	ifp->if_flags &= ~IFF_UP;
146 	pfctlinput(PRC_IFDOWN, (caddr_t)&ifp->if_addr);
147 }
148 
149 /*
150  * Formulate an Internet address from network + host.  Used in
151  * building addresses stored in the ifnet structure.
152  */
153 struct in_addr
154 if_makeaddr(net, host)
155 	int net, host;
156 {
157 	u_long addr;
158 
159 	if (net < 128)
160 		addr = (net << 24) | host;
161 	else if (net < 65536)
162 		addr = (net << 16) | host;
163 	else
164 		addr = (net << 8) | host;
165 #ifdef vax
166 	addr = htonl(addr);
167 #endif
168 	return (*(struct in_addr *)&addr);
169 }
170 
171 /*
172  * Initialize an interface's routing
173  * table entry according to the network.
174  * INTERNET SPECIFIC.
175  */
176 if_rtinit(ifp, flags)
177 	register struct ifnet *ifp;
178 	int flags;
179 {
180 	struct sockaddr_in sin;
181 
182 	if (ifp->if_flags & IFF_ROUTE)
183 		return;
184 	bzero((caddr_t)&sin, sizeof (sin));
185 	sin.sin_family = AF_INET;
186 	sin.sin_addr = if_makeaddr(ifp->if_net, 0);
187 	rtinit(&sin, &ifp->if_addr, flags);
188 }
189