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