xref: /original-bsd/sys/net/if.c (revision fbed46ce)
1 /*	if.c	4.15	82/05/04	*/
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)();
98 
99 	if (af >= AF_MAX)
100 		return (0);
101 	netmatch = afswitch[af].af_netmatch;
102 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
103 		if (af != ifp->if_addr.sa_family)
104 			continue;
105 		if ((*netmatch)(addr, &ifp->if_addr))
106 			break;
107 	}
108 	return (ifp);
109 }
110 
111 /*
112  * As above, but parameter is network number.
113  */
114 struct ifnet *
115 if_ifonnetof(net)
116 	register int net;
117 {
118 	register struct ifnet *ifp;
119 
120 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
121 		if (ifp->if_net == net)
122 			break;
123 	return (ifp);
124 }
125 
126 /*
127  * Find an interface using a specific address family
128  */
129 struct ifnet *
130 if_ifwithaf(af)
131 	register int af;
132 {
133 	register struct ifnet *ifp;
134 
135 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
136 		if (ifp->if_addr.sa_family == af)
137 			break;
138 	return (ifp);
139 }
140 
141 /*
142  * Mark an interface down and notify protocols of
143  * the transition.
144  */
145 if_down(ifp)
146 	register struct ifnet *ifp;
147 {
148 	ifp->if_flags &= ~IFF_UP;
149 	pfctlinput(PRC_IFDOWN, (caddr_t)&ifp->if_addr);
150 }
151 
152 /*
153  * Formulate an Internet address from network + host.  Used in
154  * building addresses stored in the ifnet structure.
155  */
156 struct in_addr
157 if_makeaddr(net, host)
158 	int net, host;
159 {
160 	u_long addr;
161 
162 	if (net < 128)
163 		addr = (net << 24) | host;
164 	else if (net < 65536)
165 		addr = (net << 16) | host;
166 	else
167 		addr = (net << 8) | host;
168 #ifdef vax
169 	addr = htonl(addr);
170 #endif
171 	return (*(struct in_addr *)&addr);
172 }
173 
174 /*
175  * Initialize an interface's routing
176  * table entry according to the network.
177  * INTERNET SPECIFIC.
178  */
179 if_rtinit(ifp, flags)
180 	register struct ifnet *ifp;
181 	int flags;
182 {
183 	struct sockaddr_in sin;
184 
185 	if (ifp->if_flags & IFF_ROUTE)
186 		return;
187 	bzero((caddr_t)&sin, sizeof (sin));
188 	sin.sin_family = AF_INET;
189 	sin.sin_addr = if_makeaddr(ifp->if_net, 0);
190 	rtinit(&sin, &ifp->if_addr, flags);
191 }
192