xref: /csrg-svn/sys/deprecated/bbnnet/in.c (revision 25202)
1*25202Skarels #ifdef	RCSIDENT
2*25202Skarels static char rcsident[] = "$Header: in.c,v 1.28 85/04/08 15:06:03 walsh Exp $";
3*25202Skarels #endif
4*25202Skarels 
5*25202Skarels #include "../h/param.h"
6*25202Skarels #include "../h/mbuf.h"
7*25202Skarels #include "../h/protosw.h"
8*25202Skarels #include "../h/socket.h"
9*25202Skarels #include "../h/socketvar.h"
10*25202Skarels #include "../h/errno.h"
11*25202Skarels #include "../h/ioctl.h"
12*25202Skarels #include "../h/dir.h"
13*25202Skarels #include "../h/user.h"
14*25202Skarels 
15*25202Skarels #include "../net/if.h"
16*25202Skarels #include "../net/route.h"
17*25202Skarels #include "../net/af.h"
18*25202Skarels #include "../net/netisr.h"
19*25202Skarels #include "../vax/mtpr.h"
20*25202Skarels 
21*25202Skarels #include "../bbnnet/in.h"
22*25202Skarels #include "../bbnnet/net.h"
23*25202Skarels #include "../bbnnet/in_pcb.h"
24*25202Skarels #include "../bbnnet/in_var.h"
25*25202Skarels #include "../bbnnet/fsm.h"
26*25202Skarels #include "../bbnnet/tcp.h"
27*25202Skarels #include "../bbnnet/udp.h"
28*25202Skarels #include "../bbnnet/ip.h"
29*25202Skarels #include "../bbnnet/icmp.h"
30*25202Skarels 
31*25202Skarels #ifdef BBNNET
32*25202Skarels 
33*25202Skarels struct in_ifaddr *in_ifaddr;	/* list of Internet addresses for interfaces */
34*25202Skarels 
35*25202Skarels #define	IN_CLASSA(i)		((((long)(i))&0x80000000)==0)
36*25202Skarels #define	IN_CLASSA_NET		0xff000000
37*25202Skarels #define	IN_CLASSA_NSHIFT	24
38*25202Skarels #define	IN_CLASSA_HOST		0x00ffffff
39*25202Skarels 
40*25202Skarels #define	IN_CLASSB(i)		((((long)(i))&0xc0000000)==0x80000000)
41*25202Skarels #define	IN_CLASSB_NET		0xffff0000
42*25202Skarels #define	IN_CLASSB_NSHIFT	16
43*25202Skarels #define	IN_CLASSB_HOST		0x0000ffff
44*25202Skarels 
45*25202Skarels #define	IN_CLASSC(i)		((((long)(i))&0xc0000000)==0xc0000000)
46*25202Skarels #define	IN_CLASSC_NET		0xffffff00
47*25202Skarels #define	IN_CLASSC_NSHIFT	8
48*25202Skarels #define	IN_CLASSC_HOST		0x000000ff
49*25202Skarels /*
50*25202Skarels  * little utility routines
51*25202Skarels  * cannot be macros because called from non-IP segments of the code.
52*25202Skarels  */
53*25202Skarels 
54*25202Skarels in_lnaof(ip_addr)
55*25202Skarels struct in_addr ip_addr;
56*25202Skarels {
57*25202Skarels     /*
58*25202Skarels      * 1/27/84 Berkeley interface of programs to kernel uses net ordering
59*25202Skarels      * This subr used for SIOCSIFADDR ioctl
60*25202Skarels      */
61*25202Skarels     register u_long i = ntohl(ip_addr.s_addr);
62*25202Skarels 
63*25202Skarels     if (IN_CLASSA(i))
64*25202Skarels 	return ((i)&IN_CLASSA_HOST);
65*25202Skarels     else if (IN_CLASSB(i))
66*25202Skarels 	return ((i)&IN_CLASSB_HOST);
67*25202Skarels     else
68*25202Skarels 	return ((i)&IN_CLASSC_HOST);
69*25202Skarels }
70*25202Skarels 
71*25202Skarels #ifdef unused
72*25202Skarels in_netof(ip_addr)
73*25202Skarels struct in_addr ip_addr;
74*25202Skarels {
75*25202Skarels     register u_long i = ntohl(ip_addr.s_addr);
76*25202Skarels 
77*25202Skarels     if (IN_CLASSA(i))
78*25202Skarels 	return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
79*25202Skarels     else if (IN_CLASSB(i))
80*25202Skarels 	return (((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
81*25202Skarels     else
82*25202Skarels 	return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
83*25202Skarels }
84*25202Skarels #endif
85*25202Skarels 
86*25202Skarels /*
87*25202Skarels  * hash an internet address for routing lookups
88*25202Skarels  * host part of the address is byte-swapped to put host-specific
89*25202Skarels  * bits in the low byte (only the low LOG2(RTHASHSIZ) bits are used by rtalloc)
90*25202Skarels  */
91*25202Skarels 
92*25202Skarels inet_hash(sin, hp)
93*25202Skarels register struct sockaddr_in *sin;
94*25202Skarels struct afhash *hp;
95*25202Skarels {
96*25202Skarels     hp->afh_nethash = NETHASH(sin->sin_addr);
97*25202Skarels     hp->afh_hosthash = HOSTHASH(sin->sin_addr.s_addr);
98*25202Skarels }
99*25202Skarels 
100*25202Skarels inet_netmatch(sin1, sin2)
101*25202Skarels struct sockaddr_in *sin1, *sin2;
102*25202Skarels {
103*25202Skarels 
104*25202Skarels     return (iptonet(sin1->sin_addr) == iptonet(sin2->sin_addr));
105*25202Skarels }
106*25202Skarels 
107*25202Skarels /*
108*25202Skarels  * Formulate an Internet address from network + host.
109*25202Skarels  */
110*25202Skarels struct in_addr in_makeaddr(net, host)
111*25202Skarels u_long net, host;
112*25202Skarels {
113*25202Skarels     register struct in_ifaddr *ia;
114*25202Skarels     register u_long mask;
115*25202Skarels     u_long addr;
116*25202Skarels 
117*25202Skarels     if (IN_CLASSA(net))
118*25202Skarels 	mask = IN_CLASSA_HOST;
119*25202Skarels     else if (IN_CLASSB(net))
120*25202Skarels 	mask = IN_CLASSB_HOST;
121*25202Skarels     else
122*25202Skarels 	mask = IN_CLASSC_HOST;
123*25202Skarels 
124*25202Skarels     for (ia = in_ifaddr; ia; ia = ia->ia_next)
125*25202Skarels 	if ((ia->ia_netmask & net) == ia->ia_net)
126*25202Skarels 	{
127*25202Skarels 	    mask = ~ia->ia_subnetmask;
128*25202Skarels 	    break;
129*25202Skarels 	}
130*25202Skarels 
131*25202Skarels     addr = htonl(net | (host & mask));
132*25202Skarels     return (*(struct in_addr *)&addr);
133*25202Skarels }
134*25202Skarels 
135*25202Skarels /*
136*25202Skarels  * Return 1 if the address is a local broadcast address.
137*25202Skarels  */
138*25202Skarels in_broadcast(in)
139*25202Skarels struct in_addr in;
140*25202Skarels {
141*25202Skarels     register struct in_ifaddr *ia;
142*25202Skarels 
143*25202Skarels     /*
144*25202Skarels      * Look through the list of addresses for a match
145*25202Skarels      * with a broadcast address.
146*25202Skarels      */
147*25202Skarels     for (ia = in_ifaddr; ia; ia = ia->ia_next)
148*25202Skarels 	if (((struct sockaddr_in *)&ia->ia_broadaddr)->sin_addr.s_addr ==
149*25202Skarels 	in.s_addr && (ia->ia_ifp->if_flags & IFF_BROADCAST))
150*25202Skarels 	return (TRUE);
151*25202Skarels     return (FALSE);
152*25202Skarels }
153*25202Skarels 
154*25202Skarels /*
155*25202Skarels  * Return the network number from an internet address.
156*25202Skarels  */
157*25202Skarels iptonet (in)
158*25202Skarels struct in_addr in;
159*25202Skarels {
160*25202Skarels     register u_long i = ntohl(in.s_addr);
161*25202Skarels     register u_long net;
162*25202Skarels     register struct in_ifaddr *ia;
163*25202Skarels 
164*25202Skarels     if (IN_CLASSA(i))
165*25202Skarels 	net = i & IN_CLASSA_NET;
166*25202Skarels     else if (IN_CLASSB(i))
167*25202Skarels 	net = i & IN_CLASSB_NET;
168*25202Skarels     else
169*25202Skarels 	net = i & IN_CLASSC_NET;
170*25202Skarels 
171*25202Skarels     /*
172*25202Skarels      * Check whether network is a subnet;
173*25202Skarels      * if so, return subnet number.
174*25202Skarels      */
175*25202Skarels     for (ia = in_ifaddr; ia; ia = ia->ia_next)
176*25202Skarels 	if (net == ia->ia_net)
177*25202Skarels 	    return (i & ia->ia_subnetmask);
178*25202Skarels 
179*25202Skarels     return (net);
180*25202Skarels }
181*25202Skarels 
182*25202Skarels #ifdef unused
183*25202Skarels /*
184*25202Skarels  * Return the host portion of an internet address.
185*25202Skarels  */
186*25202Skarels iptohost (in)
187*25202Skarels struct in_addr in;
188*25202Skarels {
189*25202Skarels     register u_long i = ntohl(in.s_addr);
190*25202Skarels     register u_long net, host;
191*25202Skarels     register struct in_ifaddr *ia;
192*25202Skarels 
193*25202Skarels     if (IN_CLASSA(i))
194*25202Skarels     {
195*25202Skarels 	net = i & IN_CLASSA_NET;
196*25202Skarels 	host = i & IN_CLASSA_HOST;
197*25202Skarels     }
198*25202Skarels     else if (IN_CLASSB(i))
199*25202Skarels     {
200*25202Skarels 	net = i & IN_CLASSB_NET;
201*25202Skarels 	host = i & IN_CLASSB_HOST;
202*25202Skarels     }
203*25202Skarels     else
204*25202Skarels     {
205*25202Skarels 	net = i & IN_CLASSC_NET;
206*25202Skarels 	host = i & IN_CLASSC_HOST;
207*25202Skarels     }
208*25202Skarels 
209*25202Skarels     /*
210*25202Skarels      * Check whether network is a subnet;
211*25202Skarels      * if so, use the modified interpretation of `host'.
212*25202Skarels      */
213*25202Skarels     for (ia = in_ifaddr; ia; ia = ia->ia_next)
214*25202Skarels 	if (net == ia->ia_net)
215*25202Skarels 	    return (host & ~ia->ia_subnetmask);
216*25202Skarels 
217*25202Skarels     return (host);
218*25202Skarels }
219*25202Skarels #endif
220*25202Skarels 
221*25202Skarels #ifdef unused
222*25202Skarels /*
223*25202Skarels  * Return TRUE if an internet address is for a ``local'' host
224*25202Skarels  * (one to which we have a connection through a local logical net).
225*25202Skarels  */
226*25202Skarels in_localaddr(in)
227*25202Skarels struct in_addr in;
228*25202Skarels {
229*25202Skarels     register u_long i = ntohl(in.s_addr);
230*25202Skarels     register u_long net;
231*25202Skarels     register struct in_ifaddr *ia;
232*25202Skarels 
233*25202Skarels     if (IN_CLASSA(i))
234*25202Skarels 	net = i & IN_CLASSA_NET;
235*25202Skarels     else if (IN_CLASSB(i))
236*25202Skarels 	net = i & IN_CLASSB_NET;
237*25202Skarels     else
238*25202Skarels 	net = i & IN_CLASSC_NET;
239*25202Skarels 
240*25202Skarels     for (ia = in_ifaddr; ia; ia = ia->ia_next)
241*25202Skarels 	if (net == ia->ia_net)
242*25202Skarels 	    return (TRUE);
243*25202Skarels 
244*25202Skarels     return (FALSE);
245*25202Skarels }
246*25202Skarels #endif
247*25202Skarels 
248*25202Skarels /*
249*25202Skarels  * because defaults are a bit messy here, the ARP and interface layers
250*25202Skarels  * are both handled here....
251*25202Skarels  */
252*25202Skarels 
253*25202Skarels /* ARGSUSED */
254*25202Skarels in_ioctl(optname, optval)
255*25202Skarels int optname;
256*25202Skarels struct mbuf **optval;
257*25202Skarels {
258*25202Skarels     extern struct ifnet *ifunit();
259*25202Skarels     register struct ifreq *ifr = (struct ifreq *)optval;
260*25202Skarels     register struct ifnet *ifp = ifunit(ifr->ifr_name);
261*25202Skarels     register struct in_ifaddr *ia = NULL;
262*25202Skarels     struct ifaddr *ifa;
263*25202Skarels     struct mbuf *m;
264*25202Skarels     int error = 0;
265*25202Skarels 
266*25202Skarels     /*
267*25202Skarels      *  ARP
268*25202Skarels      */
269*25202Skarels     switch (optname)
270*25202Skarels     {
271*25202Skarels       case SIOCSARP:
272*25202Skarels       case SIOCDARP:
273*25202Skarels 	if (!suser())
274*25202Skarels 	    return(u.u_error);
275*25202Skarels 
276*25202Skarels 	/* fall thru */
277*25202Skarels 
278*25202Skarels       case SIOCGARP:
279*25202Skarels 	return(arpioctl(optname,(caddr_t)optval));
280*25202Skarels     }
281*25202Skarels 
282*25202Skarels     /*
283*25202Skarels      * Find address for this interface, if it exists.
284*25202Skarels      */
285*25202Skarels     if (ifp)
286*25202Skarels 	for (ia = in_ifaddr; ia; ia = ia->ia_next)
287*25202Skarels 	    if (ia->ia_ifp == ifp)
288*25202Skarels 		break;
289*25202Skarels 
290*25202Skarels     /*
291*25202Skarels      * Interface stuff
292*25202Skarels      */
293*25202Skarels 
294*25202Skarels     switch (optname)
295*25202Skarels     {
296*25202Skarels 
297*25202Skarels       case SIOCGIFADDR:
298*25202Skarels       case SIOCGIFBRDADDR:
299*25202Skarels       case SIOCGIFDSTADDR:
300*25202Skarels       case SIOCGIFNETMASK:
301*25202Skarels 	if (ia == (struct in_ifaddr *) NULL)
302*25202Skarels 	    return(EADDRNOTAVAIL);
303*25202Skarels 	break;
304*25202Skarels 
305*25202Skarels       case SIOCSIFADDR:
306*25202Skarels       case SIOCSIFDSTADDR:
307*25202Skarels       case SIOCSIFBRDADDR:
308*25202Skarels       case SIOCSIFNETMASK:
309*25202Skarels 	if (!suser())
310*25202Skarels 	    return(u.u_error);
311*25202Skarels 
312*25202Skarels 	if (ifp == NULL)
313*25202Skarels 	    panic("in_control");
314*25202Skarels 	if (ia == (struct in_ifaddr *) NULL)
315*25202Skarels 	{
316*25202Skarels 	    m = m_getclr(M_WAIT, MT_IFADDR);
317*25202Skarels 	    if (m == (struct mbuf *)NULL)
318*25202Skarels 		return(ENOBUFS);
319*25202Skarels 	    if (ia = in_ifaddr)
320*25202Skarels 	    {
321*25202Skarels 		for ( ; ia->ia_next; ia = ia->ia_next)
322*25202Skarels 		    ;
323*25202Skarels 		ia->ia_next = mtod(m, struct in_ifaddr *);
324*25202Skarels 	    }
325*25202Skarels 	    else
326*25202Skarels 	        in_ifaddr = mtod(m, struct in_ifaddr *);
327*25202Skarels 	    ia = mtod(m, struct in_ifaddr *);
328*25202Skarels 	    if (ifa = ifp->if_addrlist)
329*25202Skarels 	    {
330*25202Skarels 		for ( ; ifa->ifa_next; ifa = ifa->ifa_next)
331*25202Skarels 		    ;
332*25202Skarels 		ifa->ifa_next = (struct ifaddr *) ia;
333*25202Skarels 	    }
334*25202Skarels 	    else
335*25202Skarels 	        ifp->if_addrlist = (struct ifaddr *) ia;
336*25202Skarels 	    ia->ia_ifp = ifp;
337*25202Skarels 	    IA_SIN(ia)->sin_family = AF_INET;
338*25202Skarels 	}
339*25202Skarels 	break;
340*25202Skarels     }
341*25202Skarels 
342*25202Skarels     switch (optname)
343*25202Skarels     {
344*25202Skarels 
345*25202Skarels       case SIOCGIFADDR:
346*25202Skarels 	ifr->ifr_addr = ia->ia_addr;
347*25202Skarels 	break;
348*25202Skarels 
349*25202Skarels       case SIOCGIFBRDADDR:
350*25202Skarels 	if ((ifp->if_flags & IFF_BROADCAST) == 0)
351*25202Skarels 	    return(EINVAL);
352*25202Skarels 	ifr->ifr_dstaddr = ia->ia_broadaddr;
353*25202Skarels 	break;
354*25202Skarels 
355*25202Skarels       case SIOCGIFDSTADDR:
356*25202Skarels 	if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
357*25202Skarels 	    return(EINVAL);
358*25202Skarels 	ifr->ifr_dstaddr = ia->ia_dstaddr;
359*25202Skarels 	break;
360*25202Skarels 
361*25202Skarels       case SIOCGIFNETMASK:
362*25202Skarels #define	satosin(sa)	((struct sockaddr_in *)(sa))
363*25202Skarels 	satosin(&ifr->ifr_addr)->sin_family = AF_INET;
364*25202Skarels 	satosin(&ifr->ifr_addr)->sin_addr.s_addr = htonl(ia->ia_subnetmask);
365*25202Skarels 	break;
366*25202Skarels 
367*25202Skarels       case SIOCSIFDSTADDR:
368*25202Skarels 	if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
369*25202Skarels 	    return(EINVAL);
370*25202Skarels 
371*25202Skarels 	if (ifp->if_ioctl &&
372*25202Skarels 	    (error = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR, ia)))
373*25202Skarels 	    return(error);
374*25202Skarels 
375*25202Skarels 	ia->ia_dstaddr = ifr->ifr_dstaddr;
376*25202Skarels 	break;
377*25202Skarels 
378*25202Skarels       case SIOCSIFBRDADDR:
379*25202Skarels 	if ((ifp->if_flags & IFF_BROADCAST) == 0)
380*25202Skarels 	    return(EINVAL);
381*25202Skarels 
382*25202Skarels 	ia->ia_broadaddr = ifr->ifr_broadaddr;
383*25202Skarels 	break;
384*25202Skarels 
385*25202Skarels       case SIOCSIFADDR:
386*25202Skarels 	return(in_ifinit(ifp, ia, (struct sockaddr_in *)&ifr->ifr_addr));
387*25202Skarels 
388*25202Skarels       case SIOCSIFNETMASK:
389*25202Skarels 	ia->ia_subnetmask =
390*25202Skarels 	    ntohl(satosin(&ifr->ifr_addr)->sin_addr.s_addr);
391*25202Skarels 	break;
392*25202Skarels 
393*25202Skarels       default:
394*25202Skarels 	if (ifp == NULL || ifp->if_ioctl == 0)
395*25202Skarels 	    return(EOPNOTSUPP);
396*25202Skarels 
397*25202Skarels 	return(((*ifp->if_ioctl)(ifp, optname, (caddr_t)optval)));
398*25202Skarels     }
399*25202Skarels 
400*25202Skarels     return (0);
401*25202Skarels }
402*25202Skarels 
403*25202Skarels /*
404*25202Skarels  * Initialize an interface's internet address
405*25202Skarels  * and routing table entry.
406*25202Skarels  */
407*25202Skarels in_ifinit(ifp, ia, sin)
408*25202Skarels register struct ifnet *ifp;
409*25202Skarels register struct in_ifaddr *ia;
410*25202Skarels struct sockaddr_in *sin;
411*25202Skarels {
412*25202Skarels     register u_long i = ntohl(sin->sin_addr.s_addr);
413*25202Skarels     struct sockaddr_in netaddr;
414*25202Skarels     int s = splimp(), error;
415*25202Skarels 
416*25202Skarels     bzero((caddr_t)&netaddr, sizeof (netaddr));
417*25202Skarels     netaddr.sin_family = AF_INET;
418*25202Skarels     /*
419*25202Skarels      * Delete any previous route for an old address.
420*25202Skarels      */
421*25202Skarels     if (ia->ia_flags & IFA_ROUTE)
422*25202Skarels     {
423*25202Skarels 	if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
424*25202Skarels 	{
425*25202Skarels 	    netaddr.sin_addr = in_makeaddr(ia->ia_subnet, INADDR_ANY);
426*25202Skarels 	    rtinit((struct sockaddr *)&netaddr, &ia->ia_addr, -1);
427*25202Skarels 	}
428*25202Skarels 	else
429*25202Skarels 	    rtinit((struct sockaddr *)&ia->ia_dstaddr, &ia->ia_addr, -1);
430*25202Skarels 	ia->ia_flags &= ~IFA_ROUTE;
431*25202Skarels     }
432*25202Skarels     ia->ia_addr = *(struct sockaddr *)sin;
433*25202Skarels     if (IN_CLASSA(i))
434*25202Skarels 	ia->ia_netmask = IN_CLASSA_NET;
435*25202Skarels     else if (IN_CLASSB(i))
436*25202Skarels 	ia->ia_netmask = IN_CLASSB_NET;
437*25202Skarels     else
438*25202Skarels 	ia->ia_netmask = IN_CLASSC_NET;
439*25202Skarels     ia->ia_net = i & ia->ia_netmask;
440*25202Skarels     /*
441*25202Skarels      * The subnet mask includes at least the standard network part,
442*25202Skarels      * but may already have been set to a larger value.
443*25202Skarels      */
444*25202Skarels     ia->ia_subnetmask |= ia->ia_netmask;
445*25202Skarels     ia->ia_subnet = i & ia->ia_subnetmask;
446*25202Skarels     if (ifp->if_flags & IFF_BROADCAST)
447*25202Skarels     {
448*25202Skarels 	ia->ia_broadaddr.sa_family = AF_INET;
449*25202Skarels 	satoipa(&ia->ia_broadaddr) = in_makeaddr(ia->ia_subnet, INADDR_BROADCAST);
450*25202Skarels     }
451*25202Skarels 
452*25202Skarels     /*
453*25202Skarels      * Give the interface a chance to initialize
454*25202Skarels      * if this is its first address,
455*25202Skarels      * and to validate the address if necessary.
456*25202Skarels      */
457*25202Skarels     if (ifp->if_ioctl && (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia)))
458*25202Skarels     {
459*25202Skarels 	splx(s);
460*25202Skarels 	bzero((caddr_t)&ia->ia_addr, sizeof(ia->ia_addr));
461*25202Skarels 	return (error);
462*25202Skarels     }
463*25202Skarels     splx(s);
464*25202Skarels     /*
465*25202Skarels      * Add route for the network.
466*25202Skarels      */
467*25202Skarels     if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
468*25202Skarels     {
469*25202Skarels 	netaddr.sin_addr = in_makeaddr(ia->ia_subnet, INADDR_ANY);
470*25202Skarels 	rtinit((struct sockaddr *)&netaddr, &ia->ia_addr, RTF_UP);
471*25202Skarels     }
472*25202Skarels     else
473*25202Skarels 	rtinit((struct sockaddr *)&ia->ia_dstaddr, &ia->ia_addr, RTF_HOST|RTF_UP);
474*25202Skarels     ia->ia_flags |= IFA_ROUTE;
475*25202Skarels     return (0);
476*25202Skarels }
477*25202Skarels 
478*25202Skarels /*
479*25202Skarels  * return address info for specified address
480*25202Skarels  */
481*25202Skarels 
482*25202Skarels struct in_ifaddr *in_iawithaddr(addr,bcast)
483*25202Skarels struct in_addr addr;
484*25202Skarels int bcast;	/* look for broadcast addrs */
485*25202Skarels {
486*25202Skarels     register struct in_ifaddr *ia;
487*25202Skarels 
488*25202Skarels     for (ia = in_ifaddr; ia; ia = ia->ia_next)
489*25202Skarels     {
490*25202Skarels 	if (IA_INADDR(ia).s_addr == addr.s_addr)
491*25202Skarels 	    return(ia);
492*25202Skarels 
493*25202Skarels 	if (bcast)
494*25202Skarels 	    if (IA_B_INADDR(ia).s_addr == addr.s_addr)
495*25202Skarels 	        return(ia);
496*25202Skarels     }
497*25202Skarels 
498*25202Skarels     return(ia);
499*25202Skarels }
500*25202Skarels 
501*25202Skarels struct in_ifaddr *in_iawithnet(addr)
502*25202Skarels struct in_addr addr;
503*25202Skarels {
504*25202Skarels     register struct in_ifaddr *ia;
505*25202Skarels     register u_long net;
506*25202Skarels 
507*25202Skarels     net = iptonet(addr);
508*25202Skarels 
509*25202Skarels     for(ia = in_ifaddr; ia; ia = ia->ia_next)
510*25202Skarels     {
511*25202Skarels 	if (iptonet(IA_INADDR(ia)) == net)
512*25202Skarels 	    return(ia);
513*25202Skarels     }
514*25202Skarels 
515*25202Skarels     return(ia);
516*25202Skarels }
517*25202Skarels 
518*25202Skarels struct in_ifaddr *in_iafromif(ifp)
519*25202Skarels struct ifnet *ifp;
520*25202Skarels {
521*25202Skarels     register struct ifaddr *ifa;
522*25202Skarels 
523*25202Skarels     for(ifa = ifp->if_addrlist; ifa != NULL; ifa = ifa->ifa_next)
524*25202Skarels 	if (ifa->ifa_addr.sa_family == AF_INET)
525*25202Skarels 	    break;
526*25202Skarels 
527*25202Skarels     return((struct in_ifaddr *)ifa);
528*25202Skarels }
529*25202Skarels 
530*25202Skarels #ifdef unused
531*25202Skarels /*
532*25202Skarels  * Return address info for specified internet network.
533*25202Skarels  */
534*25202Skarels struct in_ifaddr *in_iaonnetof(net)
535*25202Skarels u_long net;
536*25202Skarels {
537*25202Skarels     register struct in_ifaddr *ia;
538*25202Skarels 
539*25202Skarels     for (ia = in_ifaddr; ia; ia = ia->ia_next)
540*25202Skarels 	if (ia->ia_subnet == net)
541*25202Skarels 	    return (ia);
542*25202Skarels 
543*25202Skarels     return ((struct in_ifaddr *) NULL);
544*25202Skarels }
545*25202Skarels #endif
546*25202Skarels #endif
547