xref: /original-bsd/sys/net/if.c (revision f0fd5f8a)
1 /*	if.c	4.24	82/11/13	*/
2 
3 #include "../h/param.h"
4 #include "../h/systm.h"
5 #include "../h/socket.h"
6 #include "../h/protosw.h"
7 #include "../net/if.h"
8 #include "../net/af.h"
9 
10 int	ifqmaxlen = IFQ_MAXLEN;
11 
12 /*
13  * Network interface utility routines.
14  *
15  * Routines with if_ifwith* names take sockaddr *'s as
16  * parameters.  Other routines take value parameters,
17  * e.g. if_ifwithnet takes the network number.
18  */
19 
20 ifinit()
21 {
22 	register struct ifnet *ifp;
23 
24 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
25 		if (ifp->if_init) {
26 			(*ifp->if_init)(ifp->if_unit);
27 			if (ifp->if_snd.ifq_maxlen == 0)
28 				ifp->if_snd.ifq_maxlen = ifqmaxlen;
29 		}
30 	if_slowtimo();
31 }
32 
33 #if vax
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_reset)
44 			(*ifp->if_reset)(uban);
45 }
46 #endif
47 
48 /*
49  * Attach an interface to the
50  * list of "active" interfaces.
51  */
52 if_attach(ifp)
53 	struct ifnet *ifp;
54 {
55 	register struct ifnet **p = &ifnet;
56 
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 #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 u_int af = addr->sa_family;
96 	register int (*netmatch)();
97 
98 	if (af >= AF_MAX)
99 		return (0);
100 	netmatch = afswitch[af].af_netmatch;
101 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
102 		if (af != ifp->if_addr.sa_family)
103 			continue;
104 		if ((*netmatch)(addr, &ifp->if_addr))
105 			break;
106 	}
107 	return (ifp);
108 }
109 
110 /*
111  * As above, but parameter is network number.
112  */
113 struct ifnet *
114 if_ifonnetof(net)
115 	register int net;
116 {
117 	register struct ifnet *ifp;
118 
119 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
120 		if (ifp->if_net == net)
121 			break;
122 	return (ifp);
123 }
124 
125 /*
126  * Find an interface using a specific address family
127  */
128 struct ifnet *
129 if_ifwithaf(af)
130 	register int af;
131 {
132 	register struct ifnet *ifp;
133 
134 	for (ifp = ifnet; ifp; ifp = ifp->if_next)
135 		if (ifp->if_addr.sa_family == af)
136 			break;
137 	return (ifp);
138 }
139 
140 /*
141  * Mark an interface down and notify protocols of
142  * the transition.
143  * NOTE: must be called at splnet or eqivalent.
144  */
145 if_down(ifp)
146 	register struct ifnet *ifp;
147 {
148 
149 	ifp->if_flags &= ~IFF_UP;
150 	pfctlinput(PRC_IFDOWN, (caddr_t)&ifp->if_addr);
151 }
152 
153 /*
154  * Handle interface watchdog timer routines.  Called
155  * from softclock, we decrement timers (if set) and
156  * call the appropriate interface routine on expiration.
157  */
158 if_slowtimo()
159 {
160 	register struct ifnet *ifp;
161 
162 	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
163 		if (ifp->if_timer == 0 || --ifp->if_timer)
164 			continue;
165 		if (ifp->if_watchdog)
166 			(*ifp->if_watchdog)(ifp->if_unit);
167 	}
168 	timeout(if_slowtimo, (caddr_t)0, hz / IFNET_SLOWHZ);
169 }
170