xref: /original-bsd/sys/netinet/in.c (revision 4f00418d)
1 /*
2  * Copyright (c) 1982, 1986, 1991, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)in.c	8.1 (Berkeley) 06/10/93
8  */
9 
10 #include <sys/param.h>
11 #include <sys/ioctl.h>
12 #include <sys/errno.h>
13 #include <sys/malloc.h>
14 #include <sys/socket.h>
15 #include <sys/socketvar.h>
16 
17 #include <net/if.h>
18 #include <net/route.h>
19 #include <net/af.h>
20 
21 #include <netinet/in_systm.h>
22 #include <netinet/in.h>
23 #include <netinet/in_var.h>
24 #include <netinet/if_ether.h>
25 
26 #ifdef INET
27 /*
28  * Return the network number from an internet address.
29  */
30 u_long
31 in_netof(in)
32 	struct in_addr in;
33 {
34 	register u_long i = ntohl(in.s_addr);
35 	register u_long net;
36 	register struct in_ifaddr *ia;
37 
38 	if (IN_CLASSA(i))
39 		net = i & IN_CLASSA_NET;
40 	else if (IN_CLASSB(i))
41 		net = i & IN_CLASSB_NET;
42 	else if (IN_CLASSC(i))
43 		net = i & IN_CLASSC_NET;
44 	else if (IN_CLASSD(i))
45 		net = i & IN_CLASSD_NET;
46 	else
47 		return (0);
48 
49 	/*
50 	 * Check whether network is a subnet;
51 	 * if so, return subnet number.
52 	 */
53 	for (ia = in_ifaddr; ia; ia = ia->ia_next)
54 		if (net == ia->ia_net)
55 			return (i & ia->ia_subnetmask);
56 	return (net);
57 }
58 
59 #ifndef SUBNETSARELOCAL
60 #define	SUBNETSARELOCAL	1
61 #endif
62 int subnetsarelocal = SUBNETSARELOCAL;
63 /*
64  * Return 1 if an internet address is for a ``local'' host
65  * (one to which we have a connection).  If subnetsarelocal
66  * is true, this includes other subnets of the local net.
67  * Otherwise, it includes only the directly-connected (sub)nets.
68  */
69 in_localaddr(in)
70 	struct in_addr in;
71 {
72 	register u_long i = ntohl(in.s_addr);
73 	register struct in_ifaddr *ia;
74 
75 	if (subnetsarelocal) {
76 		for (ia = in_ifaddr; ia; ia = ia->ia_next)
77 			if ((i & ia->ia_netmask) == ia->ia_net)
78 				return (1);
79 	} else {
80 		for (ia = in_ifaddr; ia; ia = ia->ia_next)
81 			if ((i & ia->ia_subnetmask) == ia->ia_subnet)
82 				return (1);
83 	}
84 	return (0);
85 }
86 
87 /*
88  * Determine whether an IP address is in a reserved set of addresses
89  * that may not be forwarded, or whether datagrams to that destination
90  * may be forwarded.
91  */
92 in_canforward(in)
93 	struct in_addr in;
94 {
95 	register u_long i = ntohl(in.s_addr);
96 	register u_long net;
97 
98 	if (IN_EXPERIMENTAL(i) || IN_MULTICAST(i))
99 		return (0);
100 	if (IN_CLASSA(i)) {
101 		net = i & IN_CLASSA_NET;
102 		if (net == 0 || net == (IN_LOOPBACKNET << IN_CLASSA_NSHIFT))
103 			return (0);
104 	}
105 	return (1);
106 }
107 
108 /*
109  * Trim a mask in a sockaddr
110  */
111 void
112 in_socktrim(ap)
113 struct sockaddr_in *ap;
114 {
115     register char *cplim = (char *) &ap->sin_addr;
116     register char *cp = (char *) (&ap->sin_addr + 1);
117 
118     ap->sin_len = 0;
119     while (--cp > cplim)
120         if (*cp) {
121 	    (ap)->sin_len = cp - (char *) (ap) + 1;
122 	    break;
123 	}
124 }
125 
126 int	in_interfaces;		/* number of external internet interfaces */
127 extern	struct ifnet loif;
128 
129 /*
130  * Generic internet control operations (ioctl's).
131  * Ifp is 0 if not an interface-specific ioctl.
132  */
133 /* ARGSUSED */
134 in_control(so, cmd, data, ifp)
135 	struct socket *so;
136 	int cmd;
137 	caddr_t data;
138 	register struct ifnet *ifp;
139 {
140 	register struct ifreq *ifr = (struct ifreq *)data;
141 	register struct in_ifaddr *ia = 0;
142 	register struct ifaddr *ifa;
143 	struct in_ifaddr *oia;
144 	struct in_aliasreq *ifra = (struct in_aliasreq *)data;
145 	struct sockaddr_in oldaddr;
146 	int error, hostIsNew, maskIsNew;
147 	u_long i;
148 
149 	/*
150 	 * Find address for this interface, if it exists.
151 	 */
152 	if (ifp)
153 		for (ia = in_ifaddr; ia; ia = ia->ia_next)
154 			if (ia->ia_ifp == ifp)
155 				break;
156 
157 	switch (cmd) {
158 
159 	case SIOCAIFADDR:
160 	case SIOCDIFADDR:
161 		if (ifra->ifra_addr.sin_family == AF_INET)
162 		    for (oia = ia; ia; ia = ia->ia_next) {
163 			if (ia->ia_ifp == ifp  &&
164 			    ia->ia_addr.sin_addr.s_addr ==
165 				ifra->ifra_addr.sin_addr.s_addr)
166 			    break;
167 		}
168 		if (cmd == SIOCDIFADDR && ia == 0)
169 			return (EADDRNOTAVAIL);
170 		/* FALLTHROUGH */
171 	case SIOCSIFADDR:
172 	case SIOCSIFNETMASK:
173 	case SIOCSIFDSTADDR:
174 		if ((so->so_state & SS_PRIV) == 0)
175 			return (EPERM);
176 
177 		if (ifp == 0)
178 			panic("in_control");
179 		if (ia == (struct in_ifaddr *)0) {
180 			oia = (struct in_ifaddr *)
181 				malloc(sizeof *oia, M_IFADDR, M_WAITOK);
182 			if (oia == (struct in_ifaddr *)NULL)
183 				return (ENOBUFS);
184 			bzero((caddr_t)oia, sizeof *oia);
185 			if (ia = in_ifaddr) {
186 				for ( ; ia->ia_next; ia = ia->ia_next)
187 					continue;
188 				ia->ia_next = oia;
189 			} else
190 				in_ifaddr = oia;
191 			ia = oia;
192 			if (ifa = ifp->if_addrlist) {
193 				for ( ; ifa->ifa_next; ifa = ifa->ifa_next)
194 					continue;
195 				ifa->ifa_next = (struct ifaddr *) ia;
196 			} else
197 				ifp->if_addrlist = (struct ifaddr *) ia;
198 			ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
199 			ia->ia_ifa.ifa_dstaddr
200 					= (struct sockaddr *)&ia->ia_dstaddr;
201 			ia->ia_ifa.ifa_netmask
202 					= (struct sockaddr *)&ia->ia_sockmask;
203 			ia->ia_sockmask.sin_len = 8;
204 			if (ifp->if_flags & IFF_BROADCAST) {
205 				ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr);
206 				ia->ia_broadaddr.sin_family = AF_INET;
207 			}
208 			ia->ia_ifp = ifp;
209 			if (ifp != &loif)
210 				in_interfaces++;
211 		}
212 		break;
213 
214 	case SIOCSIFBRDADDR:
215 		if ((so->so_state & SS_PRIV) == 0)
216 			return (EPERM);
217 		/* FALLTHROUGH */
218 
219 	case SIOCGIFADDR:
220 	case SIOCGIFNETMASK:
221 	case SIOCGIFDSTADDR:
222 	case SIOCGIFBRDADDR:
223 		if (ia == (struct in_ifaddr *)0)
224 			return (EADDRNOTAVAIL);
225 		break;
226 	}
227 	switch (cmd) {
228 
229 	case SIOCGIFADDR:
230 		*((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_addr;
231 		break;
232 
233 	case SIOCGIFBRDADDR:
234 		if ((ifp->if_flags & IFF_BROADCAST) == 0)
235 			return (EINVAL);
236 		*((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_broadaddr;
237 		break;
238 
239 	case SIOCGIFDSTADDR:
240 		if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
241 			return (EINVAL);
242 		*((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_dstaddr;
243 		break;
244 
245 	case SIOCGIFNETMASK:
246 		*((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_sockmask;
247 		break;
248 
249 	case SIOCSIFDSTADDR:
250 		if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
251 			return (EINVAL);
252 		oldaddr = ia->ia_dstaddr;
253 		ia->ia_dstaddr = *(struct sockaddr_in *)&ifr->ifr_dstaddr;
254 		if (ifp->if_ioctl && (error = (*ifp->if_ioctl)
255 					(ifp, SIOCSIFDSTADDR, (caddr_t)ia))) {
256 			ia->ia_dstaddr = oldaddr;
257 			return (error);
258 		}
259 		if (ia->ia_flags & IFA_ROUTE) {
260 			ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&oldaddr;
261 			rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
262 			ia->ia_ifa.ifa_dstaddr =
263 					(struct sockaddr *)&ia->ia_dstaddr;
264 			rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
265 		}
266 		break;
267 
268 	case SIOCSIFBRDADDR:
269 		if ((ifp->if_flags & IFF_BROADCAST) == 0)
270 			return (EINVAL);
271 		ia->ia_broadaddr = *(struct sockaddr_in *)&ifr->ifr_broadaddr;
272 		break;
273 
274 	case SIOCSIFADDR:
275 		return (in_ifinit(ifp, ia,
276 		    (struct sockaddr_in *) &ifr->ifr_addr, 1));
277 
278 	case SIOCSIFNETMASK:
279 		i = ifra->ifra_addr.sin_addr.s_addr;
280 		ia->ia_subnetmask = ntohl(ia->ia_sockmask.sin_addr.s_addr = i);
281 		break;
282 
283 	case SIOCAIFADDR:
284 		maskIsNew = 0;
285 		hostIsNew = 1;
286 		error = 0;
287 		if (ia->ia_addr.sin_family == AF_INET) {
288 			if (ifra->ifra_addr.sin_len == 0) {
289 				ifra->ifra_addr = ia->ia_addr;
290 				hostIsNew = 0;
291 			} else if (ifra->ifra_addr.sin_addr.s_addr ==
292 					       ia->ia_addr.sin_addr.s_addr)
293 				hostIsNew = 0;
294 		}
295 		if (ifra->ifra_mask.sin_len) {
296 			in_ifscrub(ifp, ia);
297 			ia->ia_sockmask = ifra->ifra_mask;
298 			ia->ia_subnetmask =
299 			     ntohl(ia->ia_sockmask.sin_addr.s_addr);
300 			maskIsNew = 1;
301 		}
302 		if ((ifp->if_flags & IFF_POINTOPOINT) &&
303 		    (ifra->ifra_dstaddr.sin_family == AF_INET)) {
304 			in_ifscrub(ifp, ia);
305 			ia->ia_dstaddr = ifra->ifra_dstaddr;
306 			maskIsNew  = 1; /* We lie; but the effect's the same */
307 		}
308 		if (ifra->ifra_addr.sin_family == AF_INET &&
309 		    (hostIsNew || maskIsNew))
310 			error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0);
311 		if ((ifp->if_flags & IFF_BROADCAST) &&
312 		    (ifra->ifra_broadaddr.sin_family == AF_INET))
313 			ia->ia_broadaddr = ifra->ifra_broadaddr;
314 		return (error);
315 
316 	case SIOCDIFADDR:
317 		in_ifscrub(ifp, ia);
318 		if ((ifa = ifp->if_addrlist) == (struct ifaddr *)ia)
319 			ifp->if_addrlist = ifa->ifa_next;
320 		else {
321 			while (ifa->ifa_next &&
322 			       (ifa->ifa_next != (struct ifaddr *)ia))
323 				    ifa = ifa->ifa_next;
324 			if (ifa->ifa_next)
325 				ifa->ifa_next = ((struct ifaddr *)ia)->ifa_next;
326 			else
327 				printf("Couldn't unlink inifaddr from ifp\n");
328 		}
329 		oia = ia;
330 		if (oia == (ia = in_ifaddr))
331 			in_ifaddr = ia->ia_next;
332 		else {
333 			while (ia->ia_next && (ia->ia_next != oia))
334 				ia = ia->ia_next;
335 			if (ia->ia_next)
336 				ia->ia_next = oia->ia_next;
337 			else
338 				printf("Didn't unlink inifadr from list\n");
339 		}
340 		IFAFREE((&oia->ia_ifa));
341 		break;
342 
343 	default:
344 		if (ifp == 0 || ifp->if_ioctl == 0)
345 			return (EOPNOTSUPP);
346 		return ((*ifp->if_ioctl)(ifp, cmd, data));
347 	}
348 	return (0);
349 }
350 
351 /*
352  * Delete any existing route for an interface.
353  */
354 void
355 in_ifscrub(ifp, ia)
356 	register struct ifnet *ifp;
357 	register struct in_ifaddr *ia;
358 {
359 
360 	if ((ia->ia_flags & IFA_ROUTE) == 0)
361 		return;
362 	if (ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT))
363 		rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
364 	else
365 		rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0);
366 	ia->ia_flags &= ~IFA_ROUTE;
367 }
368 
369 /*
370  * Initialize an interface's internet address
371  * and routing table entry.
372  */
373 in_ifinit(ifp, ia, sin, scrub)
374 	register struct ifnet *ifp;
375 	register struct in_ifaddr *ia;
376 	struct sockaddr_in *sin;
377 	int scrub;
378 {
379 	register u_long i = ntohl(sin->sin_addr.s_addr);
380 	struct sockaddr_in oldaddr;
381 	int s = splimp(), flags = RTF_UP, error, ether_output();
382 
383 	oldaddr = ia->ia_addr;
384 	ia->ia_addr = *sin;
385 	/*
386 	 * Give the interface a chance to initialize
387 	 * if this is its first address,
388 	 * and to validate the address if necessary.
389 	 */
390 	if (ifp->if_ioctl &&
391 	    (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia))) {
392 		splx(s);
393 		ia->ia_addr = oldaddr;
394 		return (error);
395 	}
396 	if (ifp->if_output == ether_output) { /* XXX: Another Kludge */
397 		ia->ia_ifa.ifa_rtrequest = arp_rtrequest;
398 		ia->ia_ifa.ifa_flags |= RTF_CLONING;
399 	}
400 	splx(s);
401 	if (scrub) {
402 		ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
403 		in_ifscrub(ifp, ia);
404 		ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
405 	}
406 	if (IN_CLASSA(i))
407 		ia->ia_netmask = IN_CLASSA_NET;
408 	else if (IN_CLASSB(i))
409 		ia->ia_netmask = IN_CLASSB_NET;
410 	else
411 		ia->ia_netmask = IN_CLASSC_NET;
412 	/*
413 	 * The subnet mask usually includes at least the standard network part,
414 	 * but may may be smaller in the case of supernetting.
415 	 * If it is set, we believe it.
416 	 */
417 	if (ia->ia_subnetmask == 0) {
418 		ia->ia_subnetmask = ia->ia_netmask;
419 		ia->ia_sockmask.sin_addr.s_addr = htonl(ia->ia_subnetmask);
420 	} else
421 		ia->ia_netmask &= ia->ia_subnetmask;
422 	ia->ia_net = i & ia->ia_netmask;
423 	ia->ia_subnet = i & ia->ia_subnetmask;
424 	in_socktrim(&ia->ia_sockmask);
425 	/*
426 	 * Add route for the network.
427 	 */
428 	ia->ia_ifa.ifa_metric = ifp->if_metric;
429 	if (ifp->if_flags & IFF_BROADCAST) {
430 		ia->ia_broadaddr.sin_addr.s_addr =
431 			htonl(ia->ia_subnet | ~ia->ia_subnetmask);
432 		ia->ia_netbroadcast.s_addr =
433 			htonl(ia->ia_net | ~ ia->ia_netmask);
434 	} else if (ifp->if_flags & IFF_LOOPBACK) {
435 		ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
436 		flags |= RTF_HOST;
437 	} else if (ifp->if_flags & IFF_POINTOPOINT) {
438 		if (ia->ia_dstaddr.sin_family != AF_INET)
439 			return (0);
440 		flags |= RTF_HOST;
441 	}
442 	if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, flags)) == 0)
443 		ia->ia_flags |= IFA_ROUTE;
444 	/*
445 	 * If the interface supports multicast, join the "all hosts"
446 	 * multicast group on that interface.
447 	 */
448 	if (ifp->if_flags & IFF_MULTICAST) {
449 		struct in_addr addr;
450 
451 		addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP);
452 		in_addmulti(&addr, ifp);
453 	}
454 	return (error);
455 }
456 
457 
458 /*
459  * Return 1 if the address might be a local broadcast address.
460  */
461 in_broadcast(in, ifp)
462 	struct in_addr in;
463         struct ifnet *ifp;
464 {
465 	register struct ifaddr *ifa;
466 	u_long t;
467 
468 	if (in.s_addr == INADDR_BROADCAST ||
469 	    in.s_addr == INADDR_ANY)
470 		return 1;
471 	if ((ifp->if_flags & IFF_BROADCAST) == 0)
472 		return 0;
473 	t = ntohl(in.s_addr);
474 	/*
475 	 * Look through the list of addresses for a match
476 	 * with a broadcast address.
477 	 */
478 #define ia ((struct in_ifaddr *)ifa)
479 	for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
480 		if (ifa->ifa_addr->sa_family == AF_INET &&
481 		    (in.s_addr == ia->ia_broadaddr.sin_addr.s_addr ||
482 		     in.s_addr == ia->ia_netbroadcast.s_addr ||
483 		     /*
484 		      * Check for old-style (host 0) broadcast.
485 		      */
486 		     t == ia->ia_subnet || t == ia->ia_net))
487 			    return 1;
488 	return (0);
489 #undef ia
490 }
491 /*
492  * Add an address to the list of IP multicast addresses for a given interface.
493  */
494 struct in_multi *
495 in_addmulti(ap, ifp)
496 	register struct in_addr *ap;
497 	register struct ifnet *ifp;
498 {
499 	register struct in_multi *inm;
500 	struct ifreq ifr;
501 	struct in_ifaddr *ia;
502 	int s = splnet();
503 
504 	/*
505 	 * See if address already in list.
506 	 */
507 	IN_LOOKUP_MULTI(*ap, ifp, inm);
508 	if (inm != NULL) {
509 		/*
510 		 * Found it; just increment the reference count.
511 		 */
512 		++inm->inm_refcount;
513 	}
514 	else {
515 		/*
516 		 * New address; allocate a new multicast record
517 		 * and link it into the interface's multicast list.
518 		 */
519 		inm = (struct in_multi *)malloc(sizeof(*inm),
520 		    M_IPMADDR, M_NOWAIT);
521 		if (inm == NULL) {
522 			splx(s);
523 			return (NULL);
524 		}
525 		inm->inm_addr = *ap;
526 		inm->inm_ifp = ifp;
527 		inm->inm_refcount = 1;
528 		IFP_TO_IA(ifp, ia);
529 		if (ia == NULL) {
530 			free(inm, M_IPMADDR);
531 			splx(s);
532 			return (NULL);
533 		}
534 		inm->inm_ia = ia;
535 		inm->inm_next = ia->ia_multiaddrs;
536 		ia->ia_multiaddrs = inm;
537 		/*
538 		 * Ask the network driver to update its multicast reception
539 		 * filter appropriately for the new address.
540 		 */
541 		((struct sockaddr_in *)&ifr.ifr_addr)->sin_family = AF_INET;
542 		((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr = *ap;
543 		if ((ifp->if_ioctl == NULL) ||
544 		    (*ifp->if_ioctl)(ifp, SIOCADDMULTI,(caddr_t)&ifr) != 0) {
545 			ia->ia_multiaddrs = inm->inm_next;
546 			free(inm, M_IPMADDR);
547 			splx(s);
548 			return (NULL);
549 		}
550 		/*
551 		 * Let IGMP know that we have joined a new IP multicast group.
552 		 */
553 		igmp_joingroup(inm);
554 	}
555 	splx(s);
556 	return (inm);
557 }
558 
559 /*
560  * Delete a multicast address record.
561  */
562 int
563 in_delmulti(inm)
564 	register struct in_multi *inm;
565 {
566 	register struct in_multi **p;
567 	struct ifreq ifr;
568 	int s = splnet();
569 
570 	if (--inm->inm_refcount == 0) {
571 		/*
572 		 * No remaining claims to this record; let IGMP know that
573 		 * we are leaving the multicast group.
574 		 */
575 		igmp_leavegroup(inm);
576 		/*
577 		 * Unlink from list.
578 		 */
579 		for (p = &inm->inm_ia->ia_multiaddrs;
580 		     *p != inm;
581 		     p = &(*p)->inm_next)
582 			 continue;
583 		*p = (*p)->inm_next;
584 		/*
585 		 * Notify the network driver to update its multicast reception
586 		 * filter.
587 		 */
588 		((struct sockaddr_in *)&(ifr.ifr_addr))->sin_family = AF_INET;
589 		((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr =
590 								inm->inm_addr;
591 		(*inm->inm_ifp->if_ioctl)(inm->inm_ifp, SIOCDELMULTI,
592 							     (caddr_t)&ifr);
593 		free(inm, M_IPMADDR);
594 	}
595 	splx(s);
596 }
597 #endif
598