xref: /original-bsd/sys/netinet/in.c (revision 2598cae2)
1 /*
2  * Copyright (c) 1982, 1986, 1991 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)in.c	7.33 (Berkeley) 06/04/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 	ia->ia_net = i & ia->ia_netmask;
413 	/*
414 	 * The subnet mask includes at least the standard network part,
415 	 * but may already have been set to a larger value.
416 	 */
417 	ia->ia_subnetmask |= ia->ia_netmask;
418 	ia->ia_subnet = i & ia->ia_subnetmask;
419 	ia->ia_sockmask.sin_addr.s_addr = htonl(ia->ia_subnetmask);
420 	in_socktrim(&ia->ia_sockmask);
421 	/*
422 	 * Add route for the network.
423 	 */
424 	ia->ia_ifa.ifa_metric = ifp->if_metric;
425 	if (ifp->if_flags & IFF_BROADCAST) {
426 		ia->ia_broadaddr.sin_addr.s_addr =
427 			htonl(ia->ia_subnet | ~ia->ia_subnetmask);
428 		ia->ia_netbroadcast.s_addr =
429 			htonl(ia->ia_net | ~ ia->ia_netmask);
430 	} else if (ifp->if_flags & IFF_LOOPBACK) {
431 		ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
432 		flags |= RTF_HOST;
433 	} else if (ifp->if_flags & IFF_POINTOPOINT) {
434 		if (ia->ia_dstaddr.sin_family != AF_INET)
435 			return (0);
436 		flags |= RTF_HOST;
437 	}
438 	if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, flags)) == 0)
439 		ia->ia_flags |= IFA_ROUTE;
440 	/*
441 	 * If the interface supports multicast, join the "all hosts"
442 	 * multicast group on that interface.
443 	 */
444 	if (ifp->if_flags & IFF_MULTICAST) {
445 		struct in_addr addr;
446 
447 		addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP);
448 		in_addmulti(&addr, ifp);
449 	}
450 	return (error);
451 }
452 
453 
454 /*
455  * Return 1 if the address might be a local broadcast address.
456  */
457 in_broadcast(in, ifp)
458 	struct in_addr in;
459         struct ifnet *ifp;
460 {
461 	register struct ifaddr *ifa;
462 	u_long t;
463 
464 	if (in.s_addr == INADDR_BROADCAST ||
465 	    in.s_addr == INADDR_ANY)
466 		return 1;
467 	if ((ifp->if_flags & IFF_BROADCAST) == 0)
468 		return 0;
469 	t = ntohl(in.s_addr);
470 	/*
471 	 * Look through the list of addresses for a match
472 	 * with a broadcast address.
473 	 */
474 #define ia ((struct in_ifaddr *)ifa)
475 	for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
476 		if (ifa->ifa_addr->sa_family == AF_INET &&
477 		    (in.s_addr == ia->ia_broadaddr.sin_addr.s_addr ||
478 		     in.s_addr == ia->ia_netbroadcast.s_addr ||
479 		     /*
480 		      * Check for old-style (host 0) broadcast.
481 		      */
482 		     t == ia->ia_subnet || t == ia->ia_net))
483 			    return 1;
484 	return (0);
485 #undef ia
486 }
487 /*
488  * Add an address to the list of IP multicast addresses for a given interface.
489  */
490 struct in_multi *
491 in_addmulti(ap, ifp)
492 	register struct in_addr *ap;
493 	register struct ifnet *ifp;
494 {
495 	register struct in_multi *inm;
496 	struct ifreq ifr;
497 	struct in_ifaddr *ia;
498 	int s = splnet();
499 
500 	/*
501 	 * See if address already in list.
502 	 */
503 	IN_LOOKUP_MULTI(*ap, ifp, inm);
504 	if (inm != NULL) {
505 		/*
506 		 * Found it; just increment the reference count.
507 		 */
508 		++inm->inm_refcount;
509 	}
510 	else {
511 		/*
512 		 * New address; allocate a new multicast record
513 		 * and link it into the interface's multicast list.
514 		 */
515 		inm = (struct in_multi *)malloc(sizeof(*inm),
516 		    M_IPMADDR, M_NOWAIT);
517 		if (inm == NULL) {
518 			splx(s);
519 			return (NULL);
520 		}
521 		inm->inm_addr = *ap;
522 		inm->inm_ifp = ifp;
523 		inm->inm_refcount = 1;
524 		IFP_TO_IA(ifp, ia);
525 		if (ia == NULL) {
526 			free(inm, M_IPMADDR);
527 			splx(s);
528 			return (NULL);
529 		}
530 		inm->inm_ia = ia;
531 		inm->inm_next = ia->ia_multiaddrs;
532 		ia->ia_multiaddrs = inm;
533 		/*
534 		 * Ask the network driver to update its multicast reception
535 		 * filter appropriately for the new address.
536 		 */
537 		((struct sockaddr_in *)&ifr.ifr_addr)->sin_family = AF_INET;
538 		((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr = *ap;
539 		if ((ifp->if_ioctl == NULL) ||
540 		    (*ifp->if_ioctl)(ifp, SIOCADDMULTI,(caddr_t)&ifr) != 0) {
541 			ia->ia_multiaddrs = inm->inm_next;
542 			free(inm, M_IPMADDR);
543 			splx(s);
544 			return (NULL);
545 		}
546 		/*
547 		 * Let IGMP know that we have joined a new IP multicast group.
548 		 */
549 		igmp_joingroup(inm);
550 	}
551 	splx(s);
552 	return (inm);
553 }
554 
555 /*
556  * Delete a multicast address record.
557  */
558 int
559 in_delmulti(inm)
560 	register struct in_multi *inm;
561 {
562 	register struct in_multi **p;
563 	struct ifreq ifr;
564 	int s = splnet();
565 
566 	if (--inm->inm_refcount == 0) {
567 		/*
568 		 * No remaining claims to this record; let IGMP know that
569 		 * we are leaving the multicast group.
570 		 */
571 		igmp_leavegroup(inm);
572 		/*
573 		 * Unlink from list.
574 		 */
575 		for (p = &inm->inm_ia->ia_multiaddrs;
576 		     *p != inm;
577 		     p = &(*p)->inm_next)
578 			 continue;
579 		*p = (*p)->inm_next;
580 		/*
581 		 * Notify the network driver to update its multicast reception
582 		 * filter.
583 		 */
584 		((struct sockaddr_in *)&(ifr.ifr_addr))->sin_family = AF_INET;
585 		((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr =
586 								inm->inm_addr;
587 		(*inm->inm_ifp->if_ioctl)(inm->inm_ifp, SIOCDELMULTI,
588 							     (caddr_t)&ifr);
589 		free(inm, M_IPMADDR);
590 	}
591 	splx(s);
592 }
593 #endif
594