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