xref: /original-bsd/sys/net/if.c (revision a13d7ea1)
1 /*	if.c	4.11	82/03/28	*/
2 
3 #include "../h/param.h"
4 #include "../h/systm.h"
5 #include "../h/socket.h"
6 #include "../net/in.h"
7 #include "../net/in_systm.h"
8 #include "../net/if.h"
9 #include "../net/af.h"
10 
11 int	ifqmaxlen = IFQ_MAXLEN;
12 
13 /*
14  * Network interface utility routines.
15  *
16  * Routines with if_ifwith* names take sockaddr *'s as
17  * parameters.  Other routines take value parameters,
18  * e.g. if_ifwithnet takes the network number.
19  */
20 
21 ifinit()
22 {
23 	register struct ifnet *ifp;
24 
25 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
26 		if (ifp->if_init) {
27 			(*ifp->if_init)(ifp->if_unit);
28 			if (ifp->if_snd.ifq_maxlen == 0)
29 				ifp->if_snd.ifq_maxlen = ifqmaxlen;
30 		}
31 }
32 
33 /*
34  * Call each interface on a Unibus reset.
35  */
36 ifubareset(uban)
37 	int uban;
38 {
39 	register struct ifnet *ifp;
40 
41 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
42 		if (ifp->if_ubareset)
43 			(*ifp->if_ubareset)(uban);
44 }
45 
46 /*
47  * Attach an interface to the
48  * list of "active" interfaces.
49  */
50 if_attach(ifp)
51 	struct ifnet *ifp;
52 {
53 	register struct ifnet **p = &ifnet;
54 
55 COUNT(IF_ATTACH);
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 COUNT(IF_IFWITHADDR);
72 #define	equal(a1, a2) \
73 	(bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0)
74 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
75 		if (ifp->if_addr.sa_family != addr->sa_family)
76 			continue;
77 		if (equal(&ifp->if_addr, addr))
78 			break;
79 		if ((ifp->if_flags & IFF_BROADCAST) &&
80 		    equal(&ifp->if_broadaddr, addr))
81 			break;
82 	}
83 	return (ifp);
84 }
85 
86 /*
87  * Find an interface on a specific network.  If many, choice
88  * is first found.
89  */
90 struct ifnet *
91 if_ifwithnet(addr)
92 	register struct sockaddr *addr;
93 {
94 	register struct ifnet *ifp;
95 	register int af = addr->sa_family;
96 	register int (*netmatch)() = afswitch[af].af_netmatch;
97 
98 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
99 		if (af != ifp->if_addr.sa_family)
100 			continue;
101 		if ((*netmatch)(addr, &ifp->if_addr))
102 			break;
103 	}
104 	return (ifp);
105 }
106 
107 /*
108  * As above, but parameter is network number.
109  */
110 struct ifnet *
111 if_ifonnetof(net)
112 	register int net;
113 {
114 	register struct ifnet *ifp;
115 
116 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
117 		if (ifp->if_net == net)
118 			break;
119 	return (ifp);
120 }
121 
122 /*
123  * Find an interface using a specific address family
124  */
125 struct ifnet *
126 if_ifwithaf(af)
127 	register int af;
128 {
129 	register struct ifnet *ifp;
130 
131 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
132 		if (ifp->if_addr.sa_family == af)
133 			break;
134 	return (ifp);
135 }
136 
137 /*
138  * Formulate an Internet address from network + host.  Used in
139  * building addresses stored in the ifnet structure.
140  */
141 struct in_addr
142 if_makeaddr(net, host)
143 	int net, host;
144 {
145 	u_long addr;
146 
147 	if (net < 128)
148 		addr = (net << 24) | host;
149 	else if (net < 65536)
150 		addr = (net << 16) | host;
151 	else
152 		addr = (net << 8) | host;
153 #ifdef vax
154 	addr = htonl(addr);
155 #endif
156 	return (*(struct in_addr *)&addr);
157 }
158