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