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