1 /* $NetBSD: in.c,v 1.144 2013/06/29 21:06:58 rmind Exp $ */ 2 3 /* 4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the project nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 /*- 33 * Copyright (c) 1998 The NetBSD Foundation, Inc. 34 * All rights reserved. 35 * 36 * This code is derived from software contributed to The NetBSD Foundation 37 * by Public Access Networks Corporation ("Panix"). It was developed under 38 * contract to Panix by Eric Haszlakiewicz and Thor Lancelot Simon. 39 * 40 * Redistribution and use in source and binary forms, with or without 41 * modification, are permitted provided that the following conditions 42 * are met: 43 * 1. Redistributions of source code must retain the above copyright 44 * notice, this list of conditions and the following disclaimer. 45 * 2. Redistributions in binary form must reproduce the above copyright 46 * notice, this list of conditions and the following disclaimer in the 47 * documentation and/or other materials provided with the distribution. 48 * 49 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 50 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 51 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 52 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 53 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 54 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 55 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 56 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 57 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 58 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 59 * POSSIBILITY OF SUCH DAMAGE. 60 */ 61 62 /* 63 * Copyright (c) 1982, 1986, 1991, 1993 64 * The Regents of the University of California. All rights reserved. 65 * 66 * Redistribution and use in source and binary forms, with or without 67 * modification, are permitted provided that the following conditions 68 * are met: 69 * 1. Redistributions of source code must retain the above copyright 70 * notice, this list of conditions and the following disclaimer. 71 * 2. Redistributions in binary form must reproduce the above copyright 72 * notice, this list of conditions and the following disclaimer in the 73 * documentation and/or other materials provided with the distribution. 74 * 3. Neither the name of the University nor the names of its contributors 75 * may be used to endorse or promote products derived from this software 76 * without specific prior written permission. 77 * 78 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 79 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 80 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 81 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 82 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 83 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 84 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 85 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 86 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 87 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 88 * SUCH DAMAGE. 89 * 90 * @(#)in.c 8.4 (Berkeley) 1/9/95 91 */ 92 93 #include <sys/cdefs.h> 94 __KERNEL_RCSID(0, "$NetBSD: in.c,v 1.144 2013/06/29 21:06:58 rmind Exp $"); 95 96 #include "opt_inet.h" 97 #include "opt_inet_conf.h" 98 #include "opt_mrouting.h" 99 100 #include <sys/param.h> 101 #include <sys/ioctl.h> 102 #include <sys/errno.h> 103 #include <sys/malloc.h> 104 #include <sys/socket.h> 105 #include <sys/socketvar.h> 106 #include <sys/sysctl.h> 107 #include <sys/systm.h> 108 #include <sys/proc.h> 109 #include <sys/syslog.h> 110 #include <sys/kauth.h> 111 112 #include <sys/cprng.h> 113 114 #include <net/if.h> 115 #include <net/route.h> 116 #include <net/pfil.h> 117 118 #include <net/if_ether.h> 119 120 #include <netinet/in_systm.h> 121 #include <netinet/in.h> 122 #include <netinet/in_var.h> 123 #include <netinet/ip.h> 124 #include <netinet/ip_var.h> 125 #include <netinet/in_ifattach.h> 126 #include <netinet/in_pcb.h> 127 #include <netinet/if_inarp.h> 128 #include <netinet/ip_mroute.h> 129 #include <netinet/igmp_var.h> 130 131 #ifdef IPSELSRC 132 #include <netinet/in_selsrc.h> 133 #endif 134 135 static u_int in_mask2len(struct in_addr *); 136 static void in_len2mask(struct in_addr *, u_int); 137 static int in_lifaddr_ioctl(struct socket *, u_long, void *, 138 struct ifnet *, struct lwp *); 139 140 static int in_addprefix(struct in_ifaddr *, int); 141 static int in_scrubprefix(struct in_ifaddr *); 142 143 #ifndef SUBNETSARELOCAL 144 #define SUBNETSARELOCAL 1 145 #endif 146 147 #ifndef HOSTZEROBROADCAST 148 #define HOSTZEROBROADCAST 1 149 #endif 150 151 int subnetsarelocal = SUBNETSARELOCAL; 152 int hostzeroisbroadcast = HOSTZEROBROADCAST; 153 154 /* 155 * This list is used to keep track of in_multi chains which belong to 156 * deleted interface addresses. We use in_ifaddr so that a chain head 157 * won't be deallocated until all multicast address record are deleted. 158 */ 159 static TAILQ_HEAD(, in_ifaddr) in_mk = TAILQ_HEAD_INITIALIZER(in_mk); 160 161 /* 162 * Return 1 if an internet address is for a ``local'' host 163 * (one to which we have a connection). If subnetsarelocal 164 * is true, this includes other subnets of the local net. 165 * Otherwise, it includes only the directly-connected (sub)nets. 166 */ 167 int 168 in_localaddr(struct in_addr in) 169 { 170 struct in_ifaddr *ia; 171 172 if (subnetsarelocal) { 173 TAILQ_FOREACH(ia, &in_ifaddrhead, ia_list) 174 if ((in.s_addr & ia->ia_netmask) == ia->ia_net) 175 return (1); 176 } else { 177 TAILQ_FOREACH(ia, &in_ifaddrhead, ia_list) 178 if ((in.s_addr & ia->ia_subnetmask) == ia->ia_subnet) 179 return (1); 180 } 181 return (0); 182 } 183 184 /* 185 * Determine whether an IP address is in a reserved set of addresses 186 * that may not be forwarded, or whether datagrams to that destination 187 * may be forwarded. 188 */ 189 int 190 in_canforward(struct in_addr in) 191 { 192 u_int32_t net; 193 194 if (IN_EXPERIMENTAL(in.s_addr) || IN_MULTICAST(in.s_addr)) 195 return (0); 196 if (IN_CLASSA(in.s_addr)) { 197 net = in.s_addr & IN_CLASSA_NET; 198 if (net == 0 || net == htonl(IN_LOOPBACKNET << IN_CLASSA_NSHIFT)) 199 return (0); 200 } 201 return (1); 202 } 203 204 /* 205 * Trim a mask in a sockaddr 206 */ 207 void 208 in_socktrim(struct sockaddr_in *ap) 209 { 210 char *cplim = (char *) &ap->sin_addr; 211 char *cp = (char *) (&ap->sin_addr + 1); 212 213 ap->sin_len = 0; 214 while (--cp >= cplim) 215 if (*cp) { 216 (ap)->sin_len = cp - (char *) (ap) + 1; 217 break; 218 } 219 } 220 221 /* 222 * Routine to take an Internet address and convert into a 223 * "dotted quad" representation for printing. 224 */ 225 const char * 226 in_fmtaddr(struct in_addr addr) 227 { 228 static char buf[sizeof("123.456.789.123")]; 229 230 addr.s_addr = ntohl(addr.s_addr); 231 232 snprintf(buf, sizeof(buf), "%d.%d.%d.%d", 233 (addr.s_addr >> 24) & 0xFF, 234 (addr.s_addr >> 16) & 0xFF, 235 (addr.s_addr >> 8) & 0xFF, 236 (addr.s_addr >> 0) & 0xFF); 237 return buf; 238 } 239 240 /* 241 * Maintain the "in_maxmtu" variable, which is the largest 242 * mtu for non-local interfaces with AF_INET addresses assigned 243 * to them that are up. 244 */ 245 unsigned long in_maxmtu; 246 247 void 248 in_setmaxmtu(void) 249 { 250 struct in_ifaddr *ia; 251 struct ifnet *ifp; 252 unsigned long maxmtu = 0; 253 254 TAILQ_FOREACH(ia, &in_ifaddrhead, ia_list) { 255 if ((ifp = ia->ia_ifp) == 0) 256 continue; 257 if ((ifp->if_flags & (IFF_UP|IFF_LOOPBACK)) != IFF_UP) 258 continue; 259 if (ifp->if_mtu > maxmtu) 260 maxmtu = ifp->if_mtu; 261 } 262 if (maxmtu) 263 in_maxmtu = maxmtu; 264 } 265 266 static u_int 267 in_mask2len(struct in_addr *mask) 268 { 269 u_int x, y; 270 u_char *p; 271 272 p = (u_char *)mask; 273 for (x = 0; x < sizeof(*mask); x++) { 274 if (p[x] != 0xff) 275 break; 276 } 277 y = 0; 278 if (x < sizeof(*mask)) { 279 for (y = 0; y < NBBY; y++) { 280 if ((p[x] & (0x80 >> y)) == 0) 281 break; 282 } 283 } 284 return x * NBBY + y; 285 } 286 287 static void 288 in_len2mask(struct in_addr *mask, u_int len) 289 { 290 u_int i; 291 u_char *p; 292 293 p = (u_char *)mask; 294 memset(mask, 0, sizeof(*mask)); 295 for (i = 0; i < len / NBBY; i++) 296 p[i] = 0xff; 297 if (len % NBBY) 298 p[i] = (0xff00 >> (len % NBBY)) & 0xff; 299 } 300 301 /* 302 * Generic internet control operations (ioctl's). 303 * Ifp is 0 if not an interface-specific ioctl. 304 */ 305 /* ARGSUSED */ 306 int 307 in_control(struct socket *so, u_long cmd, void *data, struct ifnet *ifp, 308 struct lwp *l) 309 { 310 struct ifreq *ifr = (struct ifreq *)data; 311 struct in_ifaddr *ia = NULL; 312 struct in_aliasreq *ifra = (struct in_aliasreq *)data; 313 struct sockaddr_in oldaddr; 314 int error, hostIsNew, maskIsNew; 315 int newifaddr = 0; 316 317 switch (cmd) { 318 case SIOCALIFADDR: 319 case SIOCDLIFADDR: 320 case SIOCGLIFADDR: 321 if (ifp == NULL) 322 return EINVAL; 323 return in_lifaddr_ioctl(so, cmd, data, ifp, l); 324 case SIOCGIFADDRPREF: 325 case SIOCSIFADDRPREF: 326 if (ifp == NULL) 327 return EINVAL; 328 return ifaddrpref_ioctl(so, cmd, data, ifp, l); 329 } 330 331 /* 332 * Find address for this interface, if it exists. 333 */ 334 if (ifp != NULL) 335 IFP_TO_IA(ifp, ia); 336 337 switch (cmd) { 338 case SIOCAIFADDR: 339 case SIOCDIFADDR: 340 case SIOCGIFALIAS: 341 if (ifra->ifra_addr.sin_family == AF_INET) 342 LIST_FOREACH(ia, 343 &IN_IFADDR_HASH(ifra->ifra_addr.sin_addr.s_addr), 344 ia_hash) { 345 if (ia->ia_ifp == ifp && 346 in_hosteq(ia->ia_addr.sin_addr, 347 ifra->ifra_addr.sin_addr)) 348 break; 349 } 350 if ((cmd == SIOCDIFADDR || cmd == SIOCGIFALIAS) && ia == NULL) 351 return (EADDRNOTAVAIL); 352 353 if (cmd == SIOCDIFADDR && 354 ifra->ifra_addr.sin_family == AF_UNSPEC) { 355 ifra->ifra_addr.sin_family = AF_INET; 356 } 357 /* FALLTHROUGH */ 358 case SIOCSIFADDR: 359 case SIOCSIFDSTADDR: 360 if (ifra->ifra_addr.sin_family != AF_INET) 361 return (EAFNOSUPPORT); 362 /* FALLTHROUGH */ 363 case SIOCSIFNETMASK: 364 if (ifp == NULL) 365 panic("in_control"); 366 367 if (cmd == SIOCGIFALIAS) 368 break; 369 370 if (ia == NULL && 371 (cmd == SIOCSIFNETMASK || cmd == SIOCSIFDSTADDR)) 372 return (EADDRNOTAVAIL); 373 374 if (l == NULL) 375 return (EPERM); 376 if (kauth_authorize_network(l->l_cred, KAUTH_NETWORK_INTERFACE, 377 KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd, 378 NULL) != 0) 379 return (EPERM); 380 381 if (ia == NULL) { 382 ia = malloc(sizeof(*ia), M_IFADDR, M_WAITOK|M_ZERO); 383 if (ia == NULL) 384 return (ENOBUFS); 385 TAILQ_INSERT_TAIL(&in_ifaddrhead, ia, ia_list); 386 IFAREF(&ia->ia_ifa); 387 ifa_insert(ifp, &ia->ia_ifa); 388 ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr); 389 ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr); 390 ia->ia_ifa.ifa_netmask = sintosa(&ia->ia_sockmask); 391 #ifdef IPSELSRC 392 ia->ia_ifa.ifa_getifa = in_getifa; 393 #else /* IPSELSRC */ 394 ia->ia_ifa.ifa_getifa = NULL; 395 #endif /* IPSELSRC */ 396 ia->ia_sockmask.sin_len = 8; 397 if (ifp->if_flags & IFF_BROADCAST) { 398 ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr); 399 ia->ia_broadaddr.sin_family = AF_INET; 400 } 401 ia->ia_ifp = ifp; 402 ia->ia_idsalt = cprng_fast32() % 65535; 403 LIST_INIT(&ia->ia_multiaddrs); 404 newifaddr = 1; 405 } 406 break; 407 408 case SIOCSIFBRDADDR: 409 if (l == NULL) 410 return (EPERM); 411 if (kauth_authorize_network(l->l_cred, KAUTH_NETWORK_INTERFACE, 412 KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd, 413 NULL) != 0) 414 return (EPERM); 415 /* FALLTHROUGH */ 416 417 case SIOCGIFADDR: 418 case SIOCGIFNETMASK: 419 case SIOCGIFDSTADDR: 420 case SIOCGIFBRDADDR: 421 if (ia == NULL) 422 return (EADDRNOTAVAIL); 423 break; 424 } 425 error = 0; 426 switch (cmd) { 427 428 case SIOCGIFADDR: 429 ifreq_setaddr(cmd, ifr, sintocsa(&ia->ia_addr)); 430 break; 431 432 case SIOCGIFBRDADDR: 433 if ((ifp->if_flags & IFF_BROADCAST) == 0) 434 return (EINVAL); 435 ifreq_setdstaddr(cmd, ifr, sintocsa(&ia->ia_broadaddr)); 436 break; 437 438 case SIOCGIFDSTADDR: 439 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) 440 return (EINVAL); 441 ifreq_setdstaddr(cmd, ifr, sintocsa(&ia->ia_dstaddr)); 442 break; 443 444 case SIOCGIFNETMASK: 445 ifreq_setaddr(cmd, ifr, sintocsa(&ia->ia_sockmask)); 446 break; 447 448 case SIOCSIFDSTADDR: 449 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) 450 return (EINVAL); 451 oldaddr = ia->ia_dstaddr; 452 ia->ia_dstaddr = *satocsin(ifreq_getdstaddr(cmd, ifr)); 453 if ((error = if_addr_init(ifp, &ia->ia_ifa, false)) != 0) { 454 ia->ia_dstaddr = oldaddr; 455 return error; 456 } 457 if (ia->ia_flags & IFA_ROUTE) { 458 ia->ia_ifa.ifa_dstaddr = sintosa(&oldaddr); 459 rtinit(&ia->ia_ifa, RTM_DELETE, RTF_HOST); 460 ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr); 461 rtinit(&ia->ia_ifa, RTM_ADD, RTF_HOST|RTF_UP); 462 } 463 break; 464 465 case SIOCSIFBRDADDR: 466 if ((ifp->if_flags & IFF_BROADCAST) == 0) 467 return EINVAL; 468 ia->ia_broadaddr = *satocsin(ifreq_getbroadaddr(cmd, ifr)); 469 break; 470 471 case SIOCSIFADDR: 472 error = in_ifinit(ifp, ia, satocsin(ifreq_getaddr(cmd, ifr)), 473 1); 474 if (error == 0) { 475 (void)pfil_run_hooks(if_pfil, 476 (struct mbuf **)SIOCSIFADDR, ifp, PFIL_IFADDR); 477 } 478 break; 479 480 case SIOCSIFNETMASK: 481 in_ifscrub(ifp, ia); 482 ia->ia_sockmask = *satocsin(ifreq_getaddr(cmd, ifr)); 483 ia->ia_subnetmask = ia->ia_sockmask.sin_addr.s_addr; 484 error = in_ifinit(ifp, ia, NULL, 0); 485 break; 486 487 case SIOCAIFADDR: 488 maskIsNew = 0; 489 hostIsNew = 1; 490 if (ia->ia_addr.sin_family != AF_INET) 491 ; 492 else if (ifra->ifra_addr.sin_len == 0) { 493 ifra->ifra_addr = ia->ia_addr; 494 hostIsNew = 0; 495 } else if (in_hosteq(ia->ia_addr.sin_addr, 496 ifra->ifra_addr.sin_addr)) 497 hostIsNew = 0; 498 if (ifra->ifra_mask.sin_len) { 499 /* Only scrub if we control the prefix route, 500 * otherwise userland gets a bogus message */ 501 if ((ia->ia_flags & IFA_ROUTE)) 502 in_ifscrub(ifp, ia); 503 ia->ia_sockmask = ifra->ifra_mask; 504 ia->ia_subnetmask = ia->ia_sockmask.sin_addr.s_addr; 505 maskIsNew = 1; 506 } 507 if ((ifp->if_flags & IFF_POINTOPOINT) && 508 (ifra->ifra_dstaddr.sin_family == AF_INET)) { 509 /* Only scrub if we control the prefix route, 510 * otherwise userland gets a bogus message */ 511 if ((ia->ia_flags & IFA_ROUTE)) 512 in_ifscrub(ifp, ia); 513 ia->ia_dstaddr = ifra->ifra_dstaddr; 514 maskIsNew = 1; /* We lie; but the effect's the same */ 515 } 516 if (ifra->ifra_addr.sin_family == AF_INET && 517 (hostIsNew || maskIsNew)) { 518 error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0); 519 } 520 if ((ifp->if_flags & IFF_BROADCAST) && 521 (ifra->ifra_broadaddr.sin_family == AF_INET)) 522 ia->ia_broadaddr = ifra->ifra_broadaddr; 523 if (error == 0) 524 (void)pfil_run_hooks(if_pfil, 525 (struct mbuf **)SIOCAIFADDR, ifp, PFIL_IFADDR); 526 break; 527 528 case SIOCGIFALIAS: 529 ifra->ifra_mask = ia->ia_sockmask; 530 if ((ifp->if_flags & IFF_POINTOPOINT) && 531 (ia->ia_dstaddr.sin_family == AF_INET)) 532 ifra->ifra_dstaddr = ia->ia_dstaddr; 533 else if ((ifp->if_flags & IFF_BROADCAST) && 534 (ia->ia_broadaddr.sin_family == AF_INET)) 535 ifra->ifra_broadaddr = ia->ia_broadaddr; 536 else 537 memset(&ifra->ifra_broadaddr, 0, 538 sizeof(ifra->ifra_broadaddr)); 539 break; 540 541 case SIOCDIFADDR: 542 in_purgeaddr(&ia->ia_ifa); 543 (void)pfil_run_hooks(if_pfil, (struct mbuf **)SIOCDIFADDR, 544 ifp, PFIL_IFADDR); 545 break; 546 547 #ifdef MROUTING 548 case SIOCGETVIFCNT: 549 case SIOCGETSGCNT: 550 error = mrt_ioctl(so, cmd, data); 551 break; 552 #endif /* MROUTING */ 553 554 default: 555 return ENOTTY; 556 } 557 558 if (error != 0 && newifaddr) { 559 KASSERT(ia != NULL); 560 in_purgeaddr(&ia->ia_ifa); 561 } 562 563 return error; 564 } 565 566 void 567 in_purgeaddr(struct ifaddr *ifa) 568 { 569 struct ifnet *ifp = ifa->ifa_ifp; 570 struct in_ifaddr *ia = (void *) ifa; 571 572 in_ifscrub(ifp, ia); 573 LIST_REMOVE(ia, ia_hash); 574 ifa_remove(ifp, &ia->ia_ifa); 575 TAILQ_REMOVE(&in_ifaddrhead, ia, ia_list); 576 if (ia->ia_allhosts != NULL) 577 in_delmulti(ia->ia_allhosts); 578 IFAFREE(&ia->ia_ifa); 579 in_setmaxmtu(); 580 } 581 582 void 583 in_purgeif(struct ifnet *ifp) /* MUST be called at splsoftnet() */ 584 { 585 if_purgeaddrs(ifp, AF_INET, in_purgeaddr); 586 igmp_purgeif(ifp); /* manipulates pools */ 587 #ifdef MROUTING 588 ip_mrouter_detach(ifp); 589 #endif 590 } 591 592 /* 593 * SIOC[GAD]LIFADDR. 594 * SIOCGLIFADDR: get first address. (???) 595 * SIOCGLIFADDR with IFLR_PREFIX: 596 * get first address that matches the specified prefix. 597 * SIOCALIFADDR: add the specified address. 598 * SIOCALIFADDR with IFLR_PREFIX: 599 * EINVAL since we can't deduce hostid part of the address. 600 * SIOCDLIFADDR: delete the specified address. 601 * SIOCDLIFADDR with IFLR_PREFIX: 602 * delete the first address that matches the specified prefix. 603 * return values: 604 * EINVAL on invalid parameters 605 * EADDRNOTAVAIL on prefix match failed/specified address not found 606 * other values may be returned from in_ioctl() 607 */ 608 static int 609 in_lifaddr_ioctl(struct socket *so, u_long cmd, void *data, 610 struct ifnet *ifp, struct lwp *l) 611 { 612 struct if_laddrreq *iflr = (struct if_laddrreq *)data; 613 struct ifaddr *ifa; 614 struct sockaddr *sa; 615 616 /* sanity checks */ 617 if (data == NULL || ifp == NULL) { 618 panic("invalid argument to in_lifaddr_ioctl"); 619 /*NOTRECHED*/ 620 } 621 622 switch (cmd) { 623 case SIOCGLIFADDR: 624 /* address must be specified on GET with IFLR_PREFIX */ 625 if ((iflr->flags & IFLR_PREFIX) == 0) 626 break; 627 /*FALLTHROUGH*/ 628 case SIOCALIFADDR: 629 case SIOCDLIFADDR: 630 /* address must be specified on ADD and DELETE */ 631 sa = (struct sockaddr *)&iflr->addr; 632 if (sa->sa_family != AF_INET) 633 return EINVAL; 634 if (sa->sa_len != sizeof(struct sockaddr_in)) 635 return EINVAL; 636 /* XXX need improvement */ 637 sa = (struct sockaddr *)&iflr->dstaddr; 638 if (sa->sa_family != AF_UNSPEC && sa->sa_family != AF_INET) 639 return EINVAL; 640 if (sa->sa_len != 0 && sa->sa_len != sizeof(struct sockaddr_in)) 641 return EINVAL; 642 break; 643 default: /*shouldn't happen*/ 644 #if 0 645 panic("invalid cmd to in_lifaddr_ioctl"); 646 /*NOTREACHED*/ 647 #else 648 return EOPNOTSUPP; 649 #endif 650 } 651 if (sizeof(struct in_addr) * NBBY < iflr->prefixlen) 652 return EINVAL; 653 654 switch (cmd) { 655 case SIOCALIFADDR: 656 { 657 struct in_aliasreq ifra; 658 659 if (iflr->flags & IFLR_PREFIX) 660 return EINVAL; 661 662 /* copy args to in_aliasreq, perform ioctl(SIOCAIFADDR). */ 663 memset(&ifra, 0, sizeof(ifra)); 664 memcpy(ifra.ifra_name, iflr->iflr_name, 665 sizeof(ifra.ifra_name)); 666 667 memcpy(&ifra.ifra_addr, &iflr->addr, 668 ((struct sockaddr *)&iflr->addr)->sa_len); 669 670 if (((struct sockaddr *)&iflr->dstaddr)->sa_family) { /*XXX*/ 671 memcpy(&ifra.ifra_dstaddr, &iflr->dstaddr, 672 ((struct sockaddr *)&iflr->dstaddr)->sa_len); 673 } 674 675 ifra.ifra_mask.sin_family = AF_INET; 676 ifra.ifra_mask.sin_len = sizeof(struct sockaddr_in); 677 in_len2mask(&ifra.ifra_mask.sin_addr, iflr->prefixlen); 678 679 return in_control(so, SIOCAIFADDR, (void *)&ifra, ifp, l); 680 } 681 case SIOCGLIFADDR: 682 case SIOCDLIFADDR: 683 { 684 struct in_ifaddr *ia; 685 struct in_addr mask, candidate, match; 686 struct sockaddr_in *sin; 687 int cmp; 688 689 memset(&mask, 0, sizeof(mask)); 690 memset(&match, 0, sizeof(match)); /* XXX gcc */ 691 if (iflr->flags & IFLR_PREFIX) { 692 /* lookup a prefix rather than address. */ 693 in_len2mask(&mask, iflr->prefixlen); 694 695 sin = (struct sockaddr_in *)&iflr->addr; 696 match.s_addr = sin->sin_addr.s_addr; 697 match.s_addr &= mask.s_addr; 698 699 /* if you set extra bits, that's wrong */ 700 if (match.s_addr != sin->sin_addr.s_addr) 701 return EINVAL; 702 703 cmp = 1; 704 } else { 705 if (cmd == SIOCGLIFADDR) { 706 /* on getting an address, take the 1st match */ 707 cmp = 0; /*XXX*/ 708 } else { 709 /* on deleting an address, do exact match */ 710 in_len2mask(&mask, 32); 711 sin = (struct sockaddr_in *)&iflr->addr; 712 match.s_addr = sin->sin_addr.s_addr; 713 714 cmp = 1; 715 } 716 } 717 718 IFADDR_FOREACH(ifa, ifp) { 719 if (ifa->ifa_addr->sa_family != AF_INET) 720 continue; 721 if (cmp == 0) 722 break; 723 candidate.s_addr = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr; 724 candidate.s_addr &= mask.s_addr; 725 if (candidate.s_addr == match.s_addr) 726 break; 727 } 728 if (ifa == NULL) 729 return EADDRNOTAVAIL; 730 ia = (struct in_ifaddr *)ifa; 731 732 if (cmd == SIOCGLIFADDR) { 733 /* fill in the if_laddrreq structure */ 734 memcpy(&iflr->addr, &ia->ia_addr, ia->ia_addr.sin_len); 735 736 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) { 737 memcpy(&iflr->dstaddr, &ia->ia_dstaddr, 738 ia->ia_dstaddr.sin_len); 739 } else 740 memset(&iflr->dstaddr, 0, sizeof(iflr->dstaddr)); 741 742 iflr->prefixlen = 743 in_mask2len(&ia->ia_sockmask.sin_addr); 744 745 iflr->flags = 0; /*XXX*/ 746 747 return 0; 748 } else { 749 struct in_aliasreq ifra; 750 751 /* fill in_aliasreq and do ioctl(SIOCDIFADDR) */ 752 memset(&ifra, 0, sizeof(ifra)); 753 memcpy(ifra.ifra_name, iflr->iflr_name, 754 sizeof(ifra.ifra_name)); 755 756 memcpy(&ifra.ifra_addr, &ia->ia_addr, 757 ia->ia_addr.sin_len); 758 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) { 759 memcpy(&ifra.ifra_dstaddr, &ia->ia_dstaddr, 760 ia->ia_dstaddr.sin_len); 761 } 762 memcpy(&ifra.ifra_dstaddr, &ia->ia_sockmask, 763 ia->ia_sockmask.sin_len); 764 765 return in_control(so, SIOCDIFADDR, (void *)&ifra, 766 ifp, l); 767 } 768 } 769 } 770 771 return EOPNOTSUPP; /*just for safety*/ 772 } 773 774 /* 775 * Delete any existing route for an interface. 776 */ 777 void 778 in_ifscrub(struct ifnet *ifp, struct in_ifaddr *ia) 779 { 780 781 in_scrubprefix(ia); 782 } 783 784 /* 785 * Initialize an interface's internet address 786 * and routing table entry. 787 */ 788 int 789 in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, 790 const struct sockaddr_in *sin, int scrub) 791 { 792 u_int32_t i; 793 struct sockaddr_in oldaddr; 794 int s = splnet(), flags = RTF_UP, error; 795 796 if (sin == NULL) 797 sin = &ia->ia_addr; 798 799 /* 800 * Set up new addresses. 801 */ 802 oldaddr = ia->ia_addr; 803 if (ia->ia_addr.sin_family == AF_INET) 804 LIST_REMOVE(ia, ia_hash); 805 ia->ia_addr = *sin; 806 LIST_INSERT_HEAD(&IN_IFADDR_HASH(ia->ia_addr.sin_addr.s_addr), ia, ia_hash); 807 808 /* 809 * Give the interface a chance to initialize 810 * if this is its first address, 811 * and to validate the address if necessary. 812 */ 813 if ((error = if_addr_init(ifp, &ia->ia_ifa, true)) != 0) 814 goto bad; 815 splx(s); 816 if (scrub) { 817 ia->ia_ifa.ifa_addr = sintosa(&oldaddr); 818 in_ifscrub(ifp, ia); 819 ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr); 820 } 821 822 i = ia->ia_addr.sin_addr.s_addr; 823 if (IN_CLASSA(i)) 824 ia->ia_netmask = IN_CLASSA_NET; 825 else if (IN_CLASSB(i)) 826 ia->ia_netmask = IN_CLASSB_NET; 827 else 828 ia->ia_netmask = IN_CLASSC_NET; 829 /* 830 * The subnet mask usually includes at least the standard network part, 831 * but may may be smaller in the case of supernetting. 832 * If it is set, we believe it. 833 */ 834 if (ia->ia_subnetmask == 0) { 835 ia->ia_subnetmask = ia->ia_netmask; 836 ia->ia_sockmask.sin_addr.s_addr = ia->ia_subnetmask; 837 } else 838 ia->ia_netmask &= ia->ia_subnetmask; 839 840 ia->ia_net = i & ia->ia_netmask; 841 ia->ia_subnet = i & ia->ia_subnetmask; 842 in_socktrim(&ia->ia_sockmask); 843 /* re-calculate the "in_maxmtu" value */ 844 in_setmaxmtu(); 845 /* 846 * Add route for the network. 847 */ 848 ia->ia_ifa.ifa_metric = ifp->if_metric; 849 if (ifp->if_flags & IFF_BROADCAST) { 850 ia->ia_broadaddr.sin_addr.s_addr = 851 ia->ia_subnet | ~ia->ia_subnetmask; 852 ia->ia_netbroadcast.s_addr = 853 ia->ia_net | ~ia->ia_netmask; 854 } else if (ifp->if_flags & IFF_LOOPBACK) { 855 ia->ia_dstaddr = ia->ia_addr; 856 flags |= RTF_HOST; 857 } else if (ifp->if_flags & IFF_POINTOPOINT) { 858 if (ia->ia_dstaddr.sin_family != AF_INET) 859 return (0); 860 flags |= RTF_HOST; 861 } 862 error = in_addprefix(ia, flags); 863 /* 864 * If the interface supports multicast, join the "all hosts" 865 * multicast group on that interface. 866 */ 867 if ((ifp->if_flags & IFF_MULTICAST) != 0 && ia->ia_allhosts == NULL) { 868 struct in_addr addr; 869 870 addr.s_addr = INADDR_ALLHOSTS_GROUP; 871 ia->ia_allhosts = in_addmulti(&addr, ifp); 872 } 873 return (error); 874 bad: 875 splx(s); 876 LIST_REMOVE(ia, ia_hash); 877 ia->ia_addr = oldaddr; 878 if (ia->ia_addr.sin_family == AF_INET) 879 LIST_INSERT_HEAD(&IN_IFADDR_HASH(ia->ia_addr.sin_addr.s_addr), 880 ia, ia_hash); 881 return (error); 882 } 883 884 #define rtinitflags(x) \ 885 ((((x)->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) != 0) \ 886 ? RTF_HOST : 0) 887 888 /* 889 * add a route to prefix ("connected route" in cisco terminology). 890 * does nothing if there's some interface address with the same prefix already. 891 */ 892 static int 893 in_addprefix(struct in_ifaddr *target, int flags) 894 { 895 struct in_ifaddr *ia; 896 struct in_addr prefix, mask, p; 897 int error; 898 899 if ((flags & RTF_HOST) != 0) 900 prefix = target->ia_dstaddr.sin_addr; 901 else { 902 prefix = target->ia_addr.sin_addr; 903 mask = target->ia_sockmask.sin_addr; 904 prefix.s_addr &= mask.s_addr; 905 } 906 907 TAILQ_FOREACH(ia, &in_ifaddrhead, ia_list) { 908 if (rtinitflags(ia)) 909 p = ia->ia_dstaddr.sin_addr; 910 else { 911 p = ia->ia_addr.sin_addr; 912 p.s_addr &= ia->ia_sockmask.sin_addr.s_addr; 913 } 914 915 if (prefix.s_addr != p.s_addr) 916 continue; 917 918 /* 919 * if we got a matching prefix route inserted by other 920 * interface address, we don't need to bother 921 * 922 * XXX RADIX_MPATH implications here? -dyoung 923 * 924 * But we should still notify userland of the new address 925 */ 926 if (ia->ia_flags & IFA_ROUTE) { 927 rt_newaddrmsg(RTM_NEWADDR, &target->ia_ifa, 0, NULL); 928 return 0; 929 } 930 } 931 932 /* 933 * noone seem to have prefix route. insert it. 934 */ 935 error = rtinit(&target->ia_ifa, RTM_ADD, flags); 936 if (error == 0) 937 target->ia_flags |= IFA_ROUTE; 938 else if (error == EEXIST) { 939 /* 940 * the fact the route already exists is not an error. 941 */ 942 error = 0; 943 } 944 return error; 945 } 946 947 /* 948 * remove a route to prefix ("connected route" in cisco terminology). 949 * re-installs the route by using another interface address, if there's one 950 * with the same prefix (otherwise we lose the route mistakenly). 951 */ 952 static int 953 in_scrubprefix(struct in_ifaddr *target) 954 { 955 struct in_ifaddr *ia; 956 struct in_addr prefix, mask, p; 957 int error; 958 959 /* If we don't have IFA_ROUTE we should still inform userland */ 960 if ((target->ia_flags & IFA_ROUTE) == 0) { 961 rt_newaddrmsg(RTM_DELADDR, &target->ia_ifa, 0, NULL); 962 return 0; 963 } 964 965 if (rtinitflags(target)) 966 prefix = target->ia_dstaddr.sin_addr; 967 else { 968 prefix = target->ia_addr.sin_addr; 969 mask = target->ia_sockmask.sin_addr; 970 prefix.s_addr &= mask.s_addr; 971 } 972 973 TAILQ_FOREACH(ia, &in_ifaddrhead, ia_list) { 974 if (rtinitflags(ia)) 975 p = ia->ia_dstaddr.sin_addr; 976 else { 977 p = ia->ia_addr.sin_addr; 978 p.s_addr &= ia->ia_sockmask.sin_addr.s_addr; 979 } 980 981 if (prefix.s_addr != p.s_addr) 982 continue; 983 984 /* 985 * if we got a matching prefix route, move IFA_ROUTE to him 986 */ 987 if ((ia->ia_flags & IFA_ROUTE) == 0) { 988 rtinit(&target->ia_ifa, RTM_DELETE, 989 rtinitflags(target)); 990 target->ia_flags &= ~IFA_ROUTE; 991 992 error = rtinit(&ia->ia_ifa, RTM_ADD, 993 rtinitflags(ia) | RTF_UP); 994 if (error == 0) 995 ia->ia_flags |= IFA_ROUTE; 996 return error; 997 } 998 } 999 1000 /* 1001 * noone seem to have prefix route. remove it. 1002 */ 1003 rtinit(&target->ia_ifa, RTM_DELETE, rtinitflags(target)); 1004 target->ia_flags &= ~IFA_ROUTE; 1005 return 0; 1006 } 1007 1008 #undef rtinitflags 1009 1010 /* 1011 * Return 1 if the address might be a local broadcast address. 1012 */ 1013 int 1014 in_broadcast(struct in_addr in, struct ifnet *ifp) 1015 { 1016 struct ifaddr *ifa; 1017 1018 if (in.s_addr == INADDR_BROADCAST || 1019 in_nullhost(in)) 1020 return 1; 1021 if ((ifp->if_flags & IFF_BROADCAST) == 0) 1022 return 0; 1023 /* 1024 * Look through the list of addresses for a match 1025 * with a broadcast address. 1026 */ 1027 #define ia (ifatoia(ifa)) 1028 IFADDR_FOREACH(ifa, ifp) 1029 if (ifa->ifa_addr->sa_family == AF_INET && 1030 !in_hosteq(in, ia->ia_addr.sin_addr) && 1031 (in_hosteq(in, ia->ia_broadaddr.sin_addr) || 1032 in_hosteq(in, ia->ia_netbroadcast) || 1033 (hostzeroisbroadcast && 1034 /* 1035 * Check for old-style (host 0) broadcast. 1036 */ 1037 (in.s_addr == ia->ia_subnet || 1038 in.s_addr == ia->ia_net)))) 1039 return 1; 1040 return (0); 1041 #undef ia 1042 } 1043 1044 /* 1045 * Add an address to the list of IP multicast addresses for a given interface. 1046 */ 1047 struct in_multi * 1048 in_addmulti(struct in_addr *ap, struct ifnet *ifp) 1049 { 1050 struct sockaddr_in sin; 1051 struct in_multi *inm; 1052 int s = splsoftnet(); 1053 1054 /* 1055 * See if address already in list. 1056 */ 1057 IN_LOOKUP_MULTI(*ap, ifp, inm); 1058 if (inm != NULL) { 1059 /* 1060 * Found it; just increment the reference count. 1061 */ 1062 ++inm->inm_refcount; 1063 } else { 1064 /* 1065 * New address; allocate a new multicast record 1066 * and link it into the interface's multicast list. 1067 */ 1068 inm = pool_get(&inmulti_pool, PR_NOWAIT); 1069 if (inm == NULL) { 1070 splx(s); 1071 return (NULL); 1072 } 1073 inm->inm_addr = *ap; 1074 inm->inm_ifp = ifp; 1075 inm->inm_refcount = 1; 1076 LIST_INSERT_HEAD( 1077 &IN_MULTI_HASH(inm->inm_addr.s_addr, ifp), 1078 inm, inm_list); 1079 /* 1080 * Ask the network driver to update its multicast reception 1081 * filter appropriately for the new address. 1082 */ 1083 sockaddr_in_init(&sin, ap, 0); 1084 if (if_mcast_op(ifp, SIOCADDMULTI, sintosa(&sin)) != 0) { 1085 LIST_REMOVE(inm, inm_list); 1086 pool_put(&inmulti_pool, inm); 1087 splx(s); 1088 return (NULL); 1089 } 1090 /* 1091 * Let IGMP know that we have joined a new IP multicast group. 1092 */ 1093 if (igmp_joingroup(inm) != 0) { 1094 LIST_REMOVE(inm, inm_list); 1095 pool_put(&inmulti_pool, inm); 1096 splx(s); 1097 return (NULL); 1098 } 1099 in_multientries++; 1100 } 1101 splx(s); 1102 return (inm); 1103 } 1104 1105 /* 1106 * Delete a multicast address record. 1107 */ 1108 void 1109 in_delmulti(struct in_multi *inm) 1110 { 1111 struct sockaddr_in sin; 1112 int s = splsoftnet(); 1113 1114 if (--inm->inm_refcount == 0) { 1115 /* 1116 * No remaining claims to this record; let IGMP know that 1117 * we are leaving the multicast group. 1118 */ 1119 igmp_leavegroup(inm); 1120 /* 1121 * Unlink from list. 1122 */ 1123 LIST_REMOVE(inm, inm_list); 1124 in_multientries--; 1125 /* 1126 * Notify the network driver to update its multicast reception 1127 * filter. 1128 */ 1129 sockaddr_in_init(&sin, &inm->inm_addr, 0); 1130 if_mcast_op(inm->inm_ifp, SIOCDELMULTI, sintosa(&sin)); 1131 pool_put(&inmulti_pool, inm); 1132 } 1133 splx(s); 1134 } 1135