Home | History | Annotate | Line # | Download | only in netinet
in.c revision 1.7
      1 /*
      2  * Copyright (c) 1982, 1986, 1991 Regents of the University of California.
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  * 3. All advertising materials mentioning features or use of this software
     14  *    must display the following acknowledgement:
     15  *	This product includes software developed by the University of
     16  *	California, Berkeley and its contributors.
     17  * 4. Neither the name of the University nor the names of its contributors
     18  *    may be used to endorse or promote products derived from this software
     19  *    without specific prior written permission.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     31  * SUCH DAMAGE.
     32  *
     33  *	from: @(#)in.c	7.17 (Berkeley) 4/20/91
     34  *	$Id: in.c,v 1.7 1994/01/08 21:21:36 mycroft Exp $
     35  */
     36 
     37 #include <sys/param.h>
     38 #include <sys/ioctl.h>
     39 #include <sys/mbuf.h>
     40 #include <sys/socket.h>
     41 #include <sys/socketvar.h>
     42 
     43 #include <net/if.h>
     44 #include <net/route.h>
     45 #include <net/af.h>
     46 
     47 #include <netinet/in.h>
     48 #include <netinet/in_var.h>
     49 #include <netinet/in_systm.h>
     50 
     51 #ifdef INET
     52 /*
     53  * Formulate an Internet address from network + host.
     54  */
     55 struct in_addr
     56 in_makeaddr(net, host)
     57 	u_long net, host;
     58 {
     59 	register struct in_ifaddr *ia;
     60 	register u_long mask;
     61 	u_long addr;
     62 
     63 	if (IN_CLASSA(net))
     64 		mask = IN_CLASSA_HOST;
     65 	else if (IN_CLASSB(net))
     66 		mask = IN_CLASSB_HOST;
     67 	else
     68 		mask = IN_CLASSC_HOST;
     69 	for (ia = in_ifaddr; ia; ia = ia->ia_next)
     70 		if ((ia->ia_netmask & net) == ia->ia_net) {
     71 			mask = ~ia->ia_subnetmask;
     72 			break;
     73 		}
     74 	addr = htonl(net | (host & mask));
     75 	return (*(struct in_addr *)&addr);
     76 }
     77 
     78 /*
     79  * Return the network number from an internet address.
     80  */
     81 u_long
     82 in_netof(in)
     83 	struct in_addr in;
     84 {
     85 	register u_long i = ntohl(in.s_addr);
     86 	register u_long net;
     87 	register struct in_ifaddr *ia;
     88 
     89 	if (IN_CLASSA(i))
     90 		net = i & IN_CLASSA_NET;
     91 	else if (IN_CLASSB(i))
     92 		net = i & IN_CLASSB_NET;
     93 #ifdef MULTICAST
     94 	else if (IN_CLASSD(i))
     95 		net = i & IN_CLASSD_NET;
     96 #endif
     97 	else if (IN_CLASSC(i))
     98 		net = i & IN_CLASSC_NET;
     99 	else
    100 		return (0);
    101 
    102 	/*
    103 	 * Check whether network is a subnet;
    104 	 * if so, return subnet number.
    105 	 */
    106 	for (ia = in_ifaddr; ia; ia = ia->ia_next)
    107 		if (net == ia->ia_net)
    108 			return (i & ia->ia_subnetmask);
    109 	return (net);
    110 }
    111 
    112 /*
    113  * Compute and save network mask as sockaddr from an internet address.
    114  */
    115 in_sockmaskof(in, sockmask)
    116 	struct in_addr in;
    117 	register struct sockaddr_in *sockmask;
    118 {
    119 	register u_long net;
    120 	register u_long mask;
    121     {
    122 	register u_long i = ntohl(in.s_addr);
    123 
    124 	if (i == 0)
    125 		net = 0, mask = 0;
    126 	else if (IN_CLASSA(i))
    127 		net = i & IN_CLASSA_NET, mask = IN_CLASSA_NET;
    128 	else if (IN_CLASSB(i))
    129 		net = i & IN_CLASSB_NET, mask = IN_CLASSB_NET;
    130 	else if (IN_CLASSC(i))
    131 		net = i & IN_CLASSC_NET, mask = IN_CLASSC_NET;
    132 	else
    133 		net = i, mask = -1;
    134     }
    135     {
    136 	register struct in_ifaddr *ia;
    137 	/*
    138 	 * Check whether network is a subnet;
    139 	 * if so, return subnet number.
    140 	 */
    141 	for (ia = in_ifaddr; ia; ia = ia->ia_next)
    142 		if (net == ia->ia_net)
    143 			mask =  ia->ia_subnetmask;
    144     }
    145     {
    146 	register char *cpbase = (char *)&(sockmask->sin_addr);
    147 	register char *cp = (char *)(1 + &(sockmask->sin_addr));
    148 
    149 	sockmask->sin_addr.s_addr = htonl(mask);
    150 	sockmask->sin_len = 0;
    151 	while (--cp >= cpbase)
    152 		if (*cp) {
    153 			sockmask->sin_len = 1 + cp - (caddr_t)sockmask;
    154 			break;
    155 		}
    156     }
    157 }
    158 
    159 /*
    160  * Return the host portion of an internet address.
    161  */
    162 u_long
    163 in_lnaof(in)
    164 	struct in_addr in;
    165 {
    166 	register u_long i = ntohl(in.s_addr);
    167 	register u_long net, host;
    168 	register struct in_ifaddr *ia;
    169 
    170 	if (IN_CLASSA(i)) {
    171 		net = i & IN_CLASSA_NET;
    172 		host = i & IN_CLASSA_HOST;
    173 	} else if (IN_CLASSB(i)) {
    174 		net = i & IN_CLASSB_NET;
    175 		host = i & IN_CLASSB_HOST;
    176 	} else if (IN_CLASSC(i)) {
    177 		net = i & IN_CLASSC_NET;
    178 		host = i & IN_CLASSC_HOST;
    179 #ifdef MULTICAST
    180 	} else if (IN_CLASSD(i)) {
    181 		net = i & IN_CLASSD_NET;
    182 		host = i & IN_CLASSD_HOST;
    183 #endif
    184 	} else
    185 		return (i);
    186 
    187 	/*
    188 	 * Check whether network is a subnet;
    189 	 * if so, use the modified interpretation of `host'.
    190 	 */
    191 	for (ia = in_ifaddr; ia; ia = ia->ia_next)
    192 		if (net == ia->ia_net)
    193 			return (host &~ ia->ia_subnetmask);
    194 	return (host);
    195 }
    196 
    197 #ifndef SUBNETSARELOCAL
    198 #define	SUBNETSARELOCAL	1
    199 #endif
    200 int subnetsarelocal = SUBNETSARELOCAL;
    201 /*
    202  * Return 1 if an internet address is for a ``local'' host
    203  * (one to which we have a connection).  If subnetsarelocal
    204  * is true, this includes other subnets of the local net.
    205  * Otherwise, it includes only the directly-connected (sub)nets.
    206  */
    207 in_localaddr(in)
    208 	struct in_addr in;
    209 {
    210 	register u_long i = ntohl(in.s_addr);
    211 	register struct in_ifaddr *ia;
    212 
    213 	if (subnetsarelocal) {
    214 		for (ia = in_ifaddr; ia; ia = ia->ia_next)
    215 			if ((i & ia->ia_netmask) == ia->ia_net)
    216 				return (1);
    217 	} else {
    218 		for (ia = in_ifaddr; ia; ia = ia->ia_next)
    219 			if ((i & ia->ia_subnetmask) == ia->ia_subnet)
    220 				return (1);
    221 	}
    222 	return (0);
    223 }
    224 
    225 /*
    226  * Determine whether an IP address is in a reserved set of addresses
    227  * that may not be forwarded, or whether datagrams to that destination
    228  * may be forwarded.
    229  */
    230 in_canforward(in)
    231 	struct in_addr in;
    232 {
    233 	register u_long i = ntohl(in.s_addr);
    234 	register u_long net;
    235 
    236 	if (IN_EXPERIMENTAL(i))
    237 		return (0);
    238 	if (IN_CLASSA(i)) {
    239 		net = i & IN_CLASSA_NET;
    240 		if (net == 0 || net == (IN_LOOPBACKNET << IN_CLASSA_NSHIFT))
    241 			return (0);
    242 	}
    243 	return (1);
    244 }
    245 
    246 int	in_interfaces;		/* number of external internet interfaces */
    247 extern	struct ifnet loif;
    248 
    249 /*
    250  * Generic internet control operations (ioctl's).
    251  * Ifp is 0 if not an interface-specific ioctl.
    252  */
    253 /* ARGSUSED */
    254 in_control(so, cmd, data, ifp)
    255 	struct socket *so;
    256 	int cmd;
    257 	caddr_t data;
    258 	register struct ifnet *ifp;
    259 {
    260 	register struct ifreq *ifr = (struct ifreq *)data;
    261 	register struct in_ifaddr *ia = 0;
    262 	register struct ifaddr *ifa;
    263 	struct in_ifaddr *oia;
    264 	struct in_aliasreq *ifra = (struct in_aliasreq *)data;
    265 	struct mbuf *m;
    266 	struct sockaddr_in oldaddr;
    267 	int error, hostIsNew, maskIsNew;
    268 	u_long i;
    269 
    270 	/*
    271 	 * Find address for this interface, if it exists.
    272 	 */
    273 	if (ifp)
    274 		for (ia = in_ifaddr; ia; ia = ia->ia_next)
    275 			if (ia->ia_ifp == ifp)
    276 				break;
    277 
    278 	switch (cmd) {
    279 
    280 	case SIOCAIFADDR:
    281 	case SIOCDIFADDR:
    282 		if (ifra->ifra_addr.sin_family == AF_INET)
    283 		    for (oia = ia; ia; ia = ia->ia_next) {
    284 			if (ia->ia_ifp == ifp  &&
    285 			    ia->ia_addr.sin_addr.s_addr ==
    286 				ifra->ifra_addr.sin_addr.s_addr)
    287 			    break;
    288 		}
    289 		if (cmd == SIOCDIFADDR && ia == 0)
    290 			return (EADDRNOTAVAIL);
    291 		/* FALLTHROUGH */
    292 	case SIOCSIFADDR:
    293 	case SIOCSIFNETMASK:
    294 	case SIOCSIFDSTADDR:
    295 		if ((so->so_state & SS_PRIV) == 0)
    296 			return (EPERM);
    297 
    298 		if (ifp == 0)
    299 			panic("in_control");
    300 		if (ia == (struct in_ifaddr *)0) {
    301 			m = m_getclr(M_WAIT, MT_IFADDR);
    302 			if (m == (struct mbuf *)NULL)
    303 				return (ENOBUFS);
    304 			if (ia = in_ifaddr) {
    305 				for ( ; ia->ia_next; ia = ia->ia_next)
    306 					;
    307 				ia->ia_next = mtod(m, struct in_ifaddr *);
    308 			} else
    309 				in_ifaddr = mtod(m, struct in_ifaddr *);
    310 			ia = mtod(m, struct in_ifaddr *);
    311 			if (ifa = ifp->if_addrlist) {
    312 				for ( ; ifa->ifa_next; ifa = ifa->ifa_next)
    313 					;
    314 				ifa->ifa_next = (struct ifaddr *) ia;
    315 			} else
    316 				ifp->if_addrlist = (struct ifaddr *) ia;
    317 			ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
    318 			ia->ia_ifa.ifa_dstaddr
    319 					= (struct sockaddr *)&ia->ia_dstaddr;
    320 			ia->ia_ifa.ifa_netmask
    321 					= (struct sockaddr *)&ia->ia_sockmask;
    322 			ia->ia_sockmask.sin_len = 8;
    323 			if (ifp->if_flags & IFF_BROADCAST) {
    324 				ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr);
    325 				ia->ia_broadaddr.sin_family = AF_INET;
    326 			}
    327 			ia->ia_ifp = ifp;
    328 			if (ifp != &loif)
    329 				in_interfaces++;
    330 		}
    331 		break;
    332 
    333 	case SIOCSIFBRDADDR:
    334 		if ((so->so_state & SS_PRIV) == 0)
    335 			return (EPERM);
    336 		/* FALLTHROUGH */
    337 
    338 	case SIOCGIFADDR:
    339 	case SIOCGIFNETMASK:
    340 	case SIOCGIFDSTADDR:
    341 	case SIOCGIFBRDADDR:
    342 		if (ia == (struct in_ifaddr *)0)
    343 			return (EADDRNOTAVAIL);
    344 		break;
    345 
    346 	default:
    347 		return (EOPNOTSUPP);
    348 		break;
    349 	}
    350 	switch (cmd) {
    351 
    352 	case SIOCGIFADDR:
    353 		*((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_addr;
    354 		break;
    355 
    356 	case SIOCGIFBRDADDR:
    357 		if ((ifp->if_flags & IFF_BROADCAST) == 0)
    358 			return (EINVAL);
    359 		*((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_broadaddr;
    360 		break;
    361 
    362 	case SIOCGIFDSTADDR:
    363 		if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
    364 			return (EINVAL);
    365 		*((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_dstaddr;
    366 		break;
    367 
    368 	case SIOCGIFNETMASK:
    369 		*((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_sockmask;
    370 		break;
    371 
    372 	case SIOCSIFDSTADDR:
    373 		if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
    374 			return (EINVAL);
    375 		oldaddr = ia->ia_dstaddr;
    376 		ia->ia_dstaddr = *(struct sockaddr_in *)&ifr->ifr_dstaddr;
    377 		if (ifp->if_ioctl &&
    378 		    (error = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR, ia))) {
    379 			ia->ia_dstaddr = oldaddr;
    380 			return (error);
    381 		}
    382 		if (ia->ia_flags & IFA_ROUTE) {
    383 			ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&oldaddr;
    384 			rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
    385 			ia->ia_ifa.ifa_dstaddr =
    386 					(struct sockaddr *)&ia->ia_dstaddr;
    387 			rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP);
    388 		}
    389 		break;
    390 
    391 	case SIOCSIFBRDADDR:
    392 		if ((ifp->if_flags & IFF_BROADCAST) == 0)
    393 			return (EINVAL);
    394 		ia->ia_broadaddr = *(struct sockaddr_in *)&ifr->ifr_broadaddr;
    395 		break;
    396 
    397 	case SIOCSIFADDR:
    398 		return (in_ifinit(ifp, ia,
    399 		    (struct sockaddr_in *) &ifr->ifr_addr, 1));
    400 
    401 	case SIOCSIFNETMASK:
    402 		i = ifra->ifra_addr.sin_addr.s_addr;
    403 		ia->ia_subnetmask = ntohl(ia->ia_sockmask.sin_addr.s_addr = i);
    404 		break;
    405 
    406 	case SIOCAIFADDR:
    407 		maskIsNew = 0;
    408 		hostIsNew = 1;
    409 		error = 0;
    410 		if (ia->ia_addr.sin_family == AF_INET) {
    411 			if (ifra->ifra_addr.sin_len == 0) {
    412 				ifra->ifra_addr = ia->ia_addr;
    413 				hostIsNew = 0;
    414 			} else if (ifra->ifra_addr.sin_addr.s_addr ==
    415 					       ia->ia_addr.sin_addr.s_addr)
    416 				hostIsNew = 0;
    417 		}
    418 		if (ifra->ifra_mask.sin_len) {
    419 			in_ifscrub(ifp, ia);
    420 			ia->ia_sockmask = ifra->ifra_mask;
    421 			ia->ia_subnetmask =
    422 			     ntohl(ia->ia_sockmask.sin_addr.s_addr);
    423 			maskIsNew = 1;
    424 		}
    425 		if ((ifp->if_flags & IFF_POINTOPOINT) &&
    426 		    (ifra->ifra_dstaddr.sin_family == AF_INET)) {
    427 			in_ifscrub(ifp, ia);
    428 			ia->ia_dstaddr = ifra->ifra_dstaddr;
    429 			maskIsNew  = 1; /* We lie; but the effect's the same */
    430 		}
    431 		if (ifra->ifra_addr.sin_family == AF_INET &&
    432 		    (hostIsNew || maskIsNew))
    433 			error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0);
    434 		if ((ifp->if_flags & IFF_BROADCAST) &&
    435 		    (ifra->ifra_broadaddr.sin_family == AF_INET))
    436 			ia->ia_broadaddr = ifra->ifra_broadaddr;
    437 		return (error);
    438 
    439 	case SIOCDIFADDR:
    440 		in_ifscrub(ifp, ia);
    441 		if ((ifa = ifp->if_addrlist) == (struct ifaddr *)ia)
    442 			ifp->if_addrlist = ifa->ifa_next;
    443 		else {
    444 			while (ifa->ifa_next &&
    445 			       (ifa->ifa_next != (struct ifaddr *)ia))
    446 				    ifa = ifa->ifa_next;
    447 			if (ifa->ifa_next)
    448 				ifa->ifa_next = ((struct ifaddr *)ia)->ifa_next;
    449 			else
    450 				printf("Couldn't unlink inifaddr from ifp\n");
    451 		}
    452 		oia = ia;
    453 		if (oia == (ia = in_ifaddr))
    454 			in_ifaddr = ia->ia_next;
    455 		else {
    456 			while (ia->ia_next && (ia->ia_next != oia))
    457 				ia = ia->ia_next;
    458 			if (ia->ia_next)
    459 				ia->ia_next = oia->ia_next;
    460 			else
    461 				printf("Didn't unlink inifadr from list\n");
    462 		}
    463 		(void) m_free(dtom(oia));
    464 		break;
    465 
    466 	default:
    467 		if (ifp == 0 || ifp->if_ioctl == 0)
    468 			return (EOPNOTSUPP);
    469 		return ((*ifp->if_ioctl)(ifp, cmd, data));
    470 	}
    471 	return (0);
    472 }
    473 
    474 /*
    475  * Delete any existing route for an interface.
    476  */
    477 in_ifscrub(ifp, ia)
    478 	register struct ifnet *ifp;
    479 	register struct in_ifaddr *ia;
    480 {
    481 
    482 	if ((ia->ia_flags & IFA_ROUTE) == 0)
    483 		return;
    484 	if (ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT))
    485 		rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST);
    486 	else
    487 		rtinit(&(ia->ia_ifa), (int)RTM_DELETE, 0);
    488 	ia->ia_flags &= ~IFA_ROUTE;
    489 }
    490 
    491 /*
    492  * Initialize an interface's internet address
    493  * and routing table entry.
    494  */
    495 in_ifinit(ifp, ia, sin, scrub)
    496 	register struct ifnet *ifp;
    497 	register struct in_ifaddr *ia;
    498 	struct sockaddr_in *sin;
    499 {
    500 	register u_long i = ntohl(sin->sin_addr.s_addr);
    501 	struct sockaddr_in oldaddr;
    502 	int s = splimp(), error, flags = RTF_UP;
    503 
    504 	oldaddr = ia->ia_addr;
    505 	ia->ia_addr = *sin;
    506 	/*
    507 	 * Give the interface a chance to initialize
    508 	 * if this is its first address,
    509 	 * and to validate the address if necessary.
    510 	 */
    511 	if (ifp->if_ioctl && (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) {
    512 		splx(s);
    513 		ia->ia_addr = oldaddr;
    514 		return (error);
    515 	}
    516 	splx(s);
    517 	if (scrub) {
    518 		ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr;
    519 		in_ifscrub(ifp, ia);
    520 		ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr;
    521 	}
    522 	if (IN_CLASSA(i))
    523 		ia->ia_netmask = IN_CLASSA_NET;
    524 	else if (IN_CLASSB(i))
    525 		ia->ia_netmask = IN_CLASSB_NET;
    526 	else
    527 		ia->ia_netmask = IN_CLASSC_NET;
    528 	ia->ia_net = i & ia->ia_netmask;
    529 	/*
    530 	 * The subnet mask includes at least the standard network part,
    531 	 * but may already have been set to a larger value.
    532 	 */
    533 	ia->ia_subnetmask |= ia->ia_netmask;
    534 	ia->ia_subnet = i & ia->ia_subnetmask;
    535 	ia->ia_sockmask.sin_addr.s_addr = htonl(ia->ia_subnetmask);
    536 	{
    537 		register char *cp = (char *) (1 + &(ia->ia_sockmask.sin_addr));
    538 		register char *cpbase = (char *) &(ia->ia_sockmask.sin_addr);
    539 		while (--cp >= cpbase)
    540 			if (*cp) {
    541 				ia->ia_sockmask.sin_len =
    542 					1 + cp - (char *) &(ia->ia_sockmask);
    543 				break;
    544 			}
    545 	}
    546 	/*
    547 	 * Add route for the network.
    548 	 */
    549 	if (ifp->if_flags & IFF_BROADCAST) {
    550 		ia->ia_broadaddr.sin_addr =
    551 			in_makeaddr(ia->ia_subnet, INADDR_BROADCAST);
    552 		ia->ia_netbroadcast.s_addr =
    553 		    htonl(ia->ia_net | (INADDR_BROADCAST &~ ia->ia_netmask));
    554 	} else if (ifp->if_flags & IFF_LOOPBACK) {
    555 		ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr;
    556 		flags |= RTF_HOST;
    557 	} else if (ifp->if_flags & IFF_POINTOPOINT) {
    558 		if (ia->ia_dstaddr.sin_family != AF_INET)
    559 			return (0);
    560 		flags |= RTF_HOST;
    561 	}
    562 	if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, flags)) == 0)
    563 		ia->ia_flags |= IFA_ROUTE;
    564 #ifdef MULTICAST
    565 	/*
    566 	 * If the interface supports multicast, join the "all hosts"
    567 	 * multicast group on that interface.
    568 	 */
    569 	if (ifp->if_flags & IFF_MULTICAST) {
    570 		struct in_addr addr;
    571 
    572 		addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP);
    573 		in_addmulti(&addr, ifp);
    574 	}
    575 #endif
    576 	return (error);
    577 }
    578 
    579 /*
    580  * Return address info for specified internet network.
    581  */
    582 struct in_ifaddr *
    583 in_iaonnetof(net)
    584 	u_long net;
    585 {
    586 	register struct in_ifaddr *ia;
    587 
    588 	for (ia = in_ifaddr; ia; ia = ia->ia_next)
    589 		if (ia->ia_subnet == net)
    590 			return (ia);
    591 	return ((struct in_ifaddr *)0);
    592 }
    593 
    594 /*
    595  * Return 1 if the address might be a local broadcast address.
    596  */
    597 in_broadcast(in)
    598 	struct in_addr in;
    599 {
    600 	register struct in_ifaddr *ia;
    601 	u_long t;
    602 
    603 	/*
    604 	 * Look through the list of addresses for a match
    605 	 * with a broadcast address.
    606 	 */
    607 	for (ia = in_ifaddr; ia; ia = ia->ia_next)
    608 	    if (ia->ia_ifp->if_flags & IFF_BROADCAST) {
    609 		if (ia->ia_broadaddr.sin_addr.s_addr == in.s_addr)
    610 		     return (1);
    611 		/*
    612 		 * Check for old-style (host 0) broadcast.
    613 		 */
    614 		if ((t = ntohl(in.s_addr)) == ia->ia_subnet || t == ia->ia_net)
    615 		    return (1);
    616 	}
    617 	if (in.s_addr == INADDR_BROADCAST || in.s_addr == INADDR_ANY)
    618 		return (1);
    619 	return (0);
    620 }
    621 
    622 #ifdef MULTICAST
    623 /*
    624  * Add an address to the list of IP multicast addresses for a given interface.
    625  */
    626 struct in_multi *
    627 in_addmulti(ap, ifp)
    628 	register struct in_addr *ap;
    629 	register struct ifnet *ifp;
    630 {
    631 	register struct in_multi *inm;
    632 	struct ifreq ifr;
    633 	struct in_ifaddr *ia;
    634 	int s = splnet();
    635 
    636 	/*
    637 	 * See if address already in list.
    638 	 */
    639 	IN_LOOKUP_MULTI(*ap, ifp, inm);
    640 	if (inm != NULL) {
    641 		/*
    642 		 * Found it; just increment the reference count.
    643 		 */
    644 		++inm->inm_refcount;
    645 	}
    646 	else {
    647 		/*
    648 		 * New address; allocate a new multicast record
    649 		 * and link it into the interface's multicast list.
    650 		 */
    651 		inm = (struct in_multi *)malloc(sizeof(*inm),
    652 		    M_IPMADDR, M_NOWAIT);
    653 		if (inm == NULL) {
    654 			splx(s);
    655 			return (NULL);
    656 		}
    657 		inm->inm_addr = *ap;
    658 		inm->inm_ifp = ifp;
    659 		inm->inm_refcount = 1;
    660 		IFP_TO_IA(ifp, ia);
    661 		if (ia == NULL) {
    662 			free(inm, M_IPMADDR);
    663 			splx(s);
    664 			return (NULL);
    665 		}
    666 		inm->inm_ia = ia;
    667 		inm->inm_next = ia->ia_multiaddrs;
    668 		ia->ia_multiaddrs = inm;
    669 		/*
    670 		 * Ask the network driver to update its multicast reception
    671 		 * filter appropriately for the new address.
    672 		 */
    673 		((struct sockaddr_in *)&ifr.ifr_addr)->sin_family = AF_INET;
    674 		((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr = *ap;
    675 		if (ifp->if_ioctl == NULL ||
    676 		    (*ifp->if_ioctl)(ifp, SIOCADDMULTI,(caddr_t)&ifr) != 0) {
    677 			ia->ia_multiaddrs = inm->inm_next;
    678 			free(inm, M_IPMADDR);
    679 			splx(s);
    680 			return (NULL);
    681 		}
    682 		/*
    683 		 * Let IGMP know that we have joined a new IP multicast group.
    684 		 */
    685 		igmp_joingroup(inm);
    686 	}
    687 	splx(s);
    688 	return (inm);
    689 }
    690 
    691 /*
    692  * Delete a multicast address record.
    693  */
    694 int
    695 in_delmulti(inm)
    696 	register struct in_multi *inm;
    697 {
    698 	register struct in_multi **p;
    699 	struct ifreq ifr;
    700 	int s = splnet();
    701 
    702 	if (--inm->inm_refcount == 0) {
    703 		/*
    704 		 * No remaining claims to this record; let IGMP know that
    705 		 * we are leaving the multicast group.
    706 		 */
    707 		igmp_leavegroup(inm);
    708 		/*
    709 		 * Unlink from list.
    710 		 */
    711 		for (p = &inm->inm_ia->ia_multiaddrs;
    712 		     *p != inm;
    713 		     p = &(*p)->inm_next)
    714 			 continue;
    715 		*p = (*p)->inm_next;
    716 		/*
    717 		 * Notify the network driver to update its multicast reception
    718 		 * filter.
    719 		 */
    720 		((struct sockaddr_in *)&(ifr.ifr_addr))->sin_family = AF_INET;
    721 		((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr =
    722 								inm->inm_addr;
    723 		(*inm->inm_ifp->if_ioctl)(inm->inm_ifp, SIOCDELMULTI,
    724 							     (caddr_t)&ifr);
    725 		free(inm, M_IPMADDR);
    726 	}
    727 	splx(s);
    728 }
    729 #endif
    730 #endif
    731