1/* 2 * Copyright (c) 2000-2008 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28/* 29 * Copyright (c) 1982, 1986, 1991, 1993 30 * The Regents of the University of California. All rights reserved. 31 * 32 * Redistribution and use in source and binary forms, with or without 33 * modification, are permitted provided that the following conditions 34 * are met: 35 * 1. Redistributions of source code must retain the above copyright 36 * notice, this list of conditions and the following disclaimer. 37 * 2. Redistributions in binary form must reproduce the above copyright 38 * notice, this list of conditions and the following disclaimer in the 39 * documentation and/or other materials provided with the distribution. 40 * 3. All advertising materials mentioning features or use of this software 41 * must display the following acknowledgement: 42 * This product includes software developed by the University of 43 * California, Berkeley and its contributors. 44 * 4. Neither the name of the University nor the names of its contributors 45 * may be used to endorse or promote products derived from this software 46 * without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * SUCH DAMAGE. 59 * 60 * @(#)in.c 8.4 (Berkeley) 1/9/95 61 * $FreeBSD: src/sys/netinet/in.c,v 1.44.2.5 2001/08/13 16:26:17 ume Exp $ 62 */ 63 64#include <sys/param.h> 65#include <sys/systm.h> 66#include <sys/sockio.h> 67#include <sys/socketvar.h> 68#include <sys/malloc.h> 69#include <sys/proc.h> 70#include <sys/socket.h> 71#include <sys/kernel.h> 72#include <sys/sysctl.h> 73#include <sys/kern_event.h> 74#include <sys/syslog.h> 75 76#include <pexpert/pexpert.h> 77 78#include <net/if.h> 79#include <net/if_types.h> 80#include <net/route.h> 81#include <net/kpi_protocol.h> 82 83#include <netinet/in.h> 84#include <netinet/in_var.h> 85#include <netinet/in_pcb.h> 86 87#include <netinet/igmp_var.h> 88#include <net/dlil.h> 89 90#include <netinet/ip_var.h> 91 92#include <netinet/tcp.h> 93#include <netinet/tcp_timer.h> 94#include <netinet/tcp_var.h> 95 96#include <sys/file.h> 97 98 99static int in_mask2len(struct in_addr *); 100static void in_len2mask(struct in_addr *, int); 101static int in_lifaddr_ioctl(struct socket *, u_long, caddr_t, 102 struct ifnet *, struct proc *); 103 104static void in_socktrim(struct sockaddr_in *); 105static int in_ifinit(struct ifnet *, 106 struct in_ifaddr *, struct sockaddr_in *, int); 107 108static int subnetsarelocal = 0; 109SYSCTL_INT(_net_inet_ip, OID_AUTO, subnets_are_local, CTLFLAG_RW, 110 &subnetsarelocal, 0, ""); 111 112struct in_multihead in_multihead; /* XXX BSS initialization */ 113 114/* Track whether or not the SIOCARPIPLL ioctl has been called */ 115__private_extern__ u_int32_t ipv4_ll_arp_aware = 0; 116 117int 118inaddr_local(struct in_addr in) 119{ 120 struct rtentry *rt; 121 struct sockaddr_in sin; 122 int local = 0; 123 124 sin.sin_family = AF_INET; 125 sin.sin_len = sizeof (sin); 126 sin.sin_addr = in; 127 rt = rtalloc1((struct sockaddr *)&sin, 0, 0UL); 128 129 if (rt != NULL) { 130 if (rt->rt_gateway->sa_family == AF_LINK || 131 (rt->rt_ifp->if_flags & IFF_LOOPBACK)) 132 local = 1; 133 rtfree(rt); 134 } else { 135 local = in_localaddr(in); 136 } 137 return (local); 138} 139 140/* 141 * Return 1 if an internet address is for a ``local'' host 142 * (one to which we have a connection). If subnetsarelocal 143 * is true, this includes other subnets of the local net. 144 * Otherwise, it includes only the directly-connected (sub)nets. 145 */ 146int 147in_localaddr(struct in_addr in) 148{ 149 u_long i = ntohl(in.s_addr); 150 struct in_ifaddr *ia; 151 152 if (subnetsarelocal) { 153 lck_mtx_lock(rt_mtx); 154 for (ia = in_ifaddrhead.tqh_first; ia; 155 ia = ia->ia_link.tqe_next) 156 if ((i & ia->ia_netmask) == ia->ia_net) { 157 lck_mtx_unlock(rt_mtx); 158 return (1); 159 } 160 lck_mtx_unlock(rt_mtx); 161 } else { 162 lck_mtx_lock(rt_mtx); 163 for (ia = in_ifaddrhead.tqh_first; ia; 164 ia = ia->ia_link.tqe_next) 165 if ((i & ia->ia_subnetmask) == ia->ia_subnet) { 166 lck_mtx_unlock(rt_mtx); 167 return (1); 168 } 169 lck_mtx_unlock(rt_mtx); 170 } 171 return (0); 172} 173 174/* 175 * Determine whether an IP address is in a reserved set of addresses 176 * that may not be forwarded, or whether datagrams to that destination 177 * may be forwarded. 178 */ 179int 180in_canforward(struct in_addr in) 181{ 182 u_long i = ntohl(in.s_addr); 183 u_long net; 184 185 if (IN_EXPERIMENTAL(i) || IN_MULTICAST(i)) 186 return (0); 187 if (IN_CLASSA(i)) { 188 net = i & IN_CLASSA_NET; 189 if (net == 0 || net == (IN_LOOPBACKNET << IN_CLASSA_NSHIFT)) 190 return (0); 191 } 192 return (1); 193} 194 195/* 196 * Trim a mask in a sockaddr 197 */ 198static void 199in_socktrim(struct sockaddr_in *ap) 200{ 201 char *cplim = (char *) &ap->sin_addr; 202 char *cp = (char *) (&ap->sin_addr + 1); 203 204 ap->sin_len = 0; 205 while (--cp >= cplim) 206 if (*cp) { 207 (ap)->sin_len = cp - (char *) (ap) + 1; 208 break; 209 } 210} 211 212static int 213in_mask2len(struct in_addr *mask) 214{ 215 size_t x, y; 216 u_char *p; 217 218 p = (u_char *)mask; 219 for (x = 0; x < sizeof(*mask); x++) { 220 if (p[x] != 0xff) 221 break; 222 } 223 y = 0; 224 if (x < sizeof(*mask)) { 225 for (y = 0; y < 8; y++) { 226 if ((p[x] & (0x80 >> y)) == 0) 227 break; 228 } 229 } 230 return x * 8 + y; 231} 232 233static void 234in_len2mask(struct in_addr *mask, int len) 235{ 236 int i; 237 u_char *p; 238 239 p = (u_char *)mask; 240 bzero(mask, sizeof(*mask)); 241 for (i = 0; i < len / 8; i++) 242 p[i] = 0xff; 243 if (len % 8) 244 p[i] = (0xff00 >> (len % 8)) & 0xff; 245} 246 247static int in_interfaces; /* number of external internet interfaces */ 248 249/* 250 * Generic internet control operations (ioctl's). 251 * Ifp is 0 if not an interface-specific ioctl. 252 * 253 * Returns: 0 Success 254 * EINVAL 255 * EADDRNOTAVAIL 256 * EDESTADDRREQ 257 * EPERM 258 * ENOBUFS 259 * EBUSY 260 * EOPNOTSUPP 261 * proc_suser:EPERM 262 * suser:EPERM 263 * in_lifaddr_ioctl:??? 264 * dlil_ioctl:??? 265 * in_ifinit:??? 266 * dlil_plumb_protocol:??? 267 * dlil_unplumb_protocol:??? 268 */ 269/* ARGSUSED */ 270int 271in_control( 272 struct socket *so, 273 u_long cmd, 274 caddr_t data, 275 struct ifnet *ifp, 276 struct proc *p) 277{ 278 struct ifreq *ifr = (struct ifreq *)data; 279 struct in_ifaddr *ia = NULL, *iap; 280 struct ifaddr *ifa; 281 struct in_aliasreq *ifra = (struct in_aliasreq *)data; 282 struct sockaddr_in oldaddr; 283 int error = 0; 284 int hostIsNew, maskIsNew; 285 struct kev_msg ev_msg; 286 struct kev_in_data in_event_data; 287 288 289 switch (cmd) { 290 case SIOCALIFADDR: 291 case SIOCDLIFADDR: 292 if (p && (error = proc_suser(p)) != 0) 293 return error; 294 /*fall through*/ 295 case SIOCGLIFADDR: 296 if (!ifp) 297 return EINVAL; 298 return in_lifaddr_ioctl(so, cmd, data, ifp, p); 299 } 300 301 /* 302 * Find address for this interface, if it exists. 303 * 304 * If an alias address was specified, find that one instead of 305 * the first one on the interface. 306 */ 307 if (ifp) { 308 lck_mtx_lock(rt_mtx); 309 for (iap = in_ifaddrhead.tqh_first; iap; 310 iap = iap->ia_link.tqe_next) 311 if (iap->ia_ifp == ifp) { 312 if (((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr.s_addr == 313 iap->ia_addr.sin_addr.s_addr) { 314 ia = iap; 315 break; 316 } else if (ia == NULL) { 317 ia = iap; 318 if (ifr->ifr_addr.sa_family != AF_INET) 319 break; 320 } 321 } 322 /* take a reference on ia before releasing mutex */ 323 if (ia != NULL) { 324 ifaref(&ia->ia_ifa); 325 } 326 lck_mtx_unlock(rt_mtx); 327 } 328 switch (cmd) { 329 case SIOCAUTOADDR: 330 case SIOCARPIPLL: 331 if (p && (error = proc_suser(p)) != 0) { 332 goto done; 333 } 334 if (ifp == 0) { 335 error = EADDRNOTAVAIL; 336 goto done; 337 } 338 break; 339 340 case SIOCAIFADDR: 341 case SIOCDIFADDR: 342 if (ifp == 0) { 343 error = EADDRNOTAVAIL; 344 goto done; 345 } 346 if (ifra->ifra_addr.sin_family == AF_INET) { 347 struct in_ifaddr *oia; 348 349 lck_mtx_lock(rt_mtx); 350 for (oia = ia; ia; ia = ia->ia_link.tqe_next) { 351 if (ia->ia_ifp == ifp && 352 ia->ia_addr.sin_addr.s_addr == 353 ifra->ifra_addr.sin_addr.s_addr) 354 break; 355 } 356 /* take a reference on ia before releasing mutex */ 357 if (ia != NULL && ia != oia) { 358 ifaref(&ia->ia_ifa); 359 } 360 lck_mtx_unlock(rt_mtx); 361 if (oia != NULL && oia != ia) { 362 ifafree(&oia->ia_ifa); 363 } 364 if ((ifp->if_flags & IFF_POINTOPOINT) 365 && (cmd == SIOCAIFADDR) 366 && (ifra->ifra_dstaddr.sin_addr.s_addr 367 == INADDR_ANY)) { 368 error = EDESTADDRREQ; 369 goto done; 370 } 371 } 372 else if (cmd == SIOCAIFADDR) { 373 error = EINVAL; 374 goto done; 375 } 376 if (cmd == SIOCDIFADDR && ia == 0) { 377 error = EADDRNOTAVAIL; 378 goto done; 379 } 380 /* FALLTHROUGH */ 381 case SIOCSIFADDR: 382 case SIOCSIFNETMASK: 383 case SIOCSIFDSTADDR: 384 if ((so->so_state & SS_PRIV) == 0) { 385 error = EPERM; 386 goto done; 387 } 388 if (ifp == 0) { 389 error = EADDRNOTAVAIL; 390 goto done; 391 } 392 if (ifra->ifra_addr.sin_family != AF_INET 393 && cmd == SIOCSIFADDR) { 394 error = EINVAL; 395 goto done; 396 } 397 if (ia == (struct in_ifaddr *)0) { 398 ia = (struct in_ifaddr *) 399 _MALLOC(sizeof *ia, M_IFADDR, M_WAITOK); 400 if (ia == (struct in_ifaddr *)NULL) { 401 error = ENOBUFS; 402 goto done; 403 } 404 bzero((caddr_t)ia, sizeof *ia); 405 /* 406 * Protect from ipintr() traversing address list 407 * while we're modifying it. 408 */ 409 410 ifa = &ia->ia_ifa; 411 412 ia->ia_addr.sin_family = AF_INET; 413 ia->ia_addr.sin_len = sizeof (ia->ia_addr); 414 ifa->ifa_addr = (struct sockaddr *)&ia->ia_addr; 415 ifa->ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr; 416 ifa->ifa_netmask = (struct sockaddr *)&ia->ia_sockmask; 417 ia->ia_sockmask.sin_len = 8; 418 ifnet_lock_exclusive(ifp); 419 if (ifp->if_flags & IFF_BROADCAST) { 420 ia->ia_broadaddr.sin_len = sizeof(ia->ia_addr); 421 ia->ia_broadaddr.sin_family = AF_INET; 422 } 423 ia->ia_ifp = ifp; 424 if (!(ifp->if_flags & IFF_LOOPBACK)) 425 in_interfaces++; 426 if_attach_ifa(ifp, ifa); 427 ifnet_lock_done(ifp); 428 429 lck_mtx_lock(rt_mtx); 430 ifaref(&ia->ia_ifa); 431 TAILQ_INSERT_TAIL(&in_ifaddrhead, ia, ia_link); 432 lck_mtx_unlock(rt_mtx); 433 434 /* Generic protocol plumbing */ 435 436 if ((error = proto_plumb(PF_INET, ifp))) { 437 if (error != EEXIST) { 438 kprintf("in.c: warning can't plumb proto if=%s%d type %d error=%d\n", 439 ifp->if_name, ifp->if_unit, ifp->if_type, error); 440 } 441 error = 0; /*discard error, can be cold with unsupported interfaces */ 442 } 443 444 } 445 break; 446 447 case SIOCPROTOATTACH: 448 case SIOCPROTODETACH: 449 if (p && (error = proc_suser(p)) != 0) { 450 goto done; 451 } 452 if (ifp == 0) { 453 error = EADDRNOTAVAIL; 454 goto done; 455 } 456 break; 457 458 case SIOCSIFBRDADDR: 459#ifdef __APPLE__ 460 if ((so->so_state & SS_PRIV) == 0) { 461 error = EPERM; 462 goto done; 463 } 464#else 465 if (p && (error = suser(p)) != 0) { 466 goto done; 467 } 468#endif 469 /* FALLTHROUGH */ 470 471 case SIOCGIFADDR: 472 case SIOCGIFNETMASK: 473 case SIOCGIFDSTADDR: 474 case SIOCGIFBRDADDR: 475 if (ia == (struct in_ifaddr *)0) { 476 error = EADDRNOTAVAIL; 477 goto done; 478 } 479 break; 480 } 481 switch (cmd) { 482 case SIOCAUTOADDR: 483 ifnet_lock_exclusive(ifp); 484 if (ifr->ifr_intval) 485 ifp->if_eflags |= IFEF_AUTOCONFIGURING; 486 else 487 ifp->if_eflags &= ~IFEF_AUTOCONFIGURING; 488 ifnet_lock_done(ifp); 489 break; 490 491 case SIOCARPIPLL: 492 ipv4_ll_arp_aware = 1; 493 ifnet_lock_exclusive(ifp); 494 if (ifr->ifr_data) 495 ifp->if_eflags |= IFEF_ARPLL; 496 else 497 ifp->if_eflags &= ~IFEF_ARPLL; 498 ifnet_lock_done(ifp); 499 break; 500 501 case SIOCGIFADDR: 502 *((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_addr; 503 break; 504 505 case SIOCGIFBRDADDR: 506 if ((ifp->if_flags & IFF_BROADCAST) == 0) { 507 error = EINVAL; 508 break; 509 } 510 *((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_broadaddr; 511 break; 512 513 case SIOCGIFDSTADDR: 514 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) { 515 error = EINVAL; 516 break; 517 } 518 *((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_dstaddr; 519 break; 520 521 case SIOCGIFNETMASK: 522 *((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_sockmask; 523 break; 524 525 case SIOCSIFDSTADDR: 526 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) { 527 error = EINVAL; 528 break; 529 } 530 oldaddr = ia->ia_dstaddr; 531 ia->ia_dstaddr = *(struct sockaddr_in *)&ifr->ifr_dstaddr; 532 error = ifnet_ioctl(ifp, PF_INET, SIOCSIFDSTADDR, ia); 533 if (error == EOPNOTSUPP) { 534 error = 0; 535 } 536 if (error) { 537 ia->ia_dstaddr = oldaddr; 538 break; 539 } 540 541 ev_msg.vendor_code = KEV_VENDOR_APPLE; 542 ev_msg.kev_class = KEV_NETWORK_CLASS; 543 ev_msg.kev_subclass = KEV_INET_SUBCLASS; 544 545 ev_msg.event_code = KEV_INET_SIFDSTADDR; 546 547 if (ia->ia_ifa.ifa_dstaddr) 548 in_event_data.ia_dstaddr = 549 ((struct sockaddr_in *)ia->ia_ifa.ifa_dstaddr)->sin_addr; 550 else 551 in_event_data.ia_dstaddr.s_addr = 0; 552 553 in_event_data.ia_addr = ia->ia_addr.sin_addr; 554 in_event_data.ia_net = ia->ia_net; 555 in_event_data.ia_netmask = ia->ia_netmask; 556 in_event_data.ia_subnet = ia->ia_subnet; 557 in_event_data.ia_subnetmask = ia->ia_subnetmask; 558 in_event_data.ia_netbroadcast = ia->ia_netbroadcast; 559 strncpy(&in_event_data.link_data.if_name[0], ifp->if_name, IFNAMSIZ); 560 in_event_data.link_data.if_family = ifp->if_family; 561 in_event_data.link_data.if_unit = (unsigned long) ifp->if_unit; 562 563 ev_msg.dv[0].data_ptr = &in_event_data; 564 ev_msg.dv[0].data_length = sizeof(struct kev_in_data); 565 ev_msg.dv[1].data_length = 0; 566 567 kev_post_msg(&ev_msg); 568 569 570 if (ia->ia_flags & IFA_ROUTE) { 571 ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&oldaddr; 572 rtinit(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST); 573 ia->ia_ifa.ifa_dstaddr = 574 (struct sockaddr *)&ia->ia_dstaddr; 575 rtinit(&(ia->ia_ifa), (int)RTM_ADD, RTF_HOST|RTF_UP); 576 } 577 break; 578 579 case SIOCSIFBRDADDR: 580 if ((ifp->if_flags & IFF_BROADCAST) == 0) { 581 error = EINVAL; 582 break; 583 } 584 ia->ia_broadaddr = *(struct sockaddr_in *)&ifr->ifr_broadaddr; 585 586 ev_msg.vendor_code = KEV_VENDOR_APPLE; 587 ev_msg.kev_class = KEV_NETWORK_CLASS; 588 ev_msg.kev_subclass = KEV_INET_SUBCLASS; 589 590 ev_msg.event_code = KEV_INET_SIFBRDADDR; 591 592 if (ia->ia_ifa.ifa_dstaddr) 593 in_event_data.ia_dstaddr = 594 ((struct sockaddr_in *)ia->ia_ifa.ifa_dstaddr)->sin_addr; 595 else 596 in_event_data.ia_dstaddr.s_addr = 0; 597 598 in_event_data.ia_addr = ia->ia_addr.sin_addr; 599 in_event_data.ia_net = ia->ia_net; 600 in_event_data.ia_netmask = ia->ia_netmask; 601 in_event_data.ia_subnet = ia->ia_subnet; 602 in_event_data.ia_subnetmask = ia->ia_subnetmask; 603 in_event_data.ia_netbroadcast = ia->ia_netbroadcast; 604 strncpy(&in_event_data.link_data.if_name[0], ifp->if_name, IFNAMSIZ); 605 in_event_data.link_data.if_family = ifp->if_family; 606 in_event_data.link_data.if_unit = (unsigned long) ifp->if_unit; 607 608 ev_msg.dv[0].data_ptr = &in_event_data; 609 ev_msg.dv[0].data_length = sizeof(struct kev_in_data); 610 ev_msg.dv[1].data_length = 0; 611 612 kev_post_msg(&ev_msg); 613 614 break; 615 616 case SIOCSIFADDR: 617 error = in_ifinit(ifp, ia, (struct sockaddr_in *) &ifr->ifr_addr, 1); 618 break; 619 620 case SIOCPROTOATTACH: 621 error = proto_plumb(PF_INET, ifp); 622 break; 623 624 case SIOCPROTODETACH: 625 // if an ip address is still present, refuse to detach 626 ifnet_lock_shared(ifp); 627 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) 628 if (ifa->ifa_addr->sa_family == AF_INET) 629 break; 630 ifnet_lock_done(ifp); 631 if (ifa != 0) { 632 error = EBUSY; 633 break; 634 } 635 636 error = proto_unplumb(PF_INET, ifp); 637 break; 638 639 640 case SIOCSIFNETMASK: { 641 u_long i; 642 643 i = ifra->ifra_addr.sin_addr.s_addr; 644 ia->ia_subnetmask = ntohl(ia->ia_sockmask.sin_addr.s_addr = i); 645 ev_msg.vendor_code = KEV_VENDOR_APPLE; 646 ev_msg.kev_class = KEV_NETWORK_CLASS; 647 ev_msg.kev_subclass = KEV_INET_SUBCLASS; 648 649 ev_msg.event_code = KEV_INET_SIFNETMASK; 650 651 if (ia->ia_ifa.ifa_dstaddr) 652 in_event_data.ia_dstaddr = 653 ((struct sockaddr_in *)ia->ia_ifa.ifa_dstaddr)->sin_addr; 654 else 655 in_event_data.ia_dstaddr.s_addr = 0; 656 657 in_event_data.ia_addr = ia->ia_addr.sin_addr; 658 in_event_data.ia_net = ia->ia_net; 659 in_event_data.ia_netmask = ia->ia_netmask; 660 in_event_data.ia_subnet = ia->ia_subnet; 661 in_event_data.ia_subnetmask = ia->ia_subnetmask; 662 in_event_data.ia_netbroadcast = ia->ia_netbroadcast; 663 strncpy(&in_event_data.link_data.if_name[0], ifp->if_name, IFNAMSIZ); 664 in_event_data.link_data.if_family = ifp->if_family; 665 in_event_data.link_data.if_unit = (unsigned long) ifp->if_unit; 666 667 ev_msg.dv[0].data_ptr = &in_event_data; 668 ev_msg.dv[0].data_length = sizeof(struct kev_in_data); 669 ev_msg.dv[1].data_length = 0; 670 671 kev_post_msg(&ev_msg); 672 673 break; 674 } 675 case SIOCAIFADDR: 676 maskIsNew = 0; 677 hostIsNew = 1; 678 error = 0; 679 if (ia->ia_addr.sin_family == AF_INET) { 680 if (ifra->ifra_addr.sin_len == 0) { 681 ifra->ifra_addr = ia->ia_addr; 682 hostIsNew = 0; 683 } else if (ifra->ifra_addr.sin_addr.s_addr == 684 ia->ia_addr.sin_addr.s_addr) 685 hostIsNew = 0; 686 } 687 if (ifra->ifra_mask.sin_len) { 688 in_ifscrub(ifp, ia, 0); 689 ia->ia_sockmask = ifra->ifra_mask; 690 ia->ia_subnetmask = 691 ntohl(ia->ia_sockmask.sin_addr.s_addr); 692 maskIsNew = 1; 693 } 694 if ((ifp->if_flags & IFF_POINTOPOINT) && 695 (ifra->ifra_dstaddr.sin_family == AF_INET)) { 696 in_ifscrub(ifp, ia, 0); 697 ia->ia_dstaddr = ifra->ifra_dstaddr; 698 maskIsNew = 1; /* We lie; but the effect's the same */ 699 } 700 if (ifra->ifra_addr.sin_family == AF_INET && 701 (hostIsNew || maskIsNew)) { 702 error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0); 703 } 704 if ((ifp->if_flags & IFF_BROADCAST) && 705 (ifra->ifra_broadaddr.sin_family == AF_INET)) 706 ia->ia_broadaddr = ifra->ifra_broadaddr; 707 708 /* 709 * Report event. 710 */ 711 712 if ((error == 0) || (error == EEXIST)) { 713 ev_msg.vendor_code = KEV_VENDOR_APPLE; 714 ev_msg.kev_class = KEV_NETWORK_CLASS; 715 ev_msg.kev_subclass = KEV_INET_SUBCLASS; 716 717 if (hostIsNew) 718 ev_msg.event_code = KEV_INET_NEW_ADDR; 719 else 720 ev_msg.event_code = KEV_INET_CHANGED_ADDR; 721 722 if (ia->ia_ifa.ifa_dstaddr) 723 in_event_data.ia_dstaddr = 724 ((struct sockaddr_in *)ia->ia_ifa.ifa_dstaddr)->sin_addr; 725 else 726 in_event_data.ia_dstaddr.s_addr = 0; 727 728 in_event_data.ia_addr = ia->ia_addr.sin_addr; 729 in_event_data.ia_net = ia->ia_net; 730 in_event_data.ia_netmask = ia->ia_netmask; 731 in_event_data.ia_subnet = ia->ia_subnet; 732 in_event_data.ia_subnetmask = ia->ia_subnetmask; 733 in_event_data.ia_netbroadcast = ia->ia_netbroadcast; 734 strncpy(&in_event_data.link_data.if_name[0], ifp->if_name, IFNAMSIZ); 735 in_event_data.link_data.if_family = ifp->if_family; 736 in_event_data.link_data.if_unit = (unsigned long) ifp->if_unit; 737 738 ev_msg.dv[0].data_ptr = &in_event_data; 739 ev_msg.dv[0].data_length = sizeof(struct kev_in_data); 740 ev_msg.dv[1].data_length = 0; 741 742 kev_post_msg(&ev_msg); 743 } 744 break; 745 746 case SIOCDIFADDR: 747 error = ifnet_ioctl(ifp, PF_INET, SIOCDIFADDR, ia); 748 if (error == EOPNOTSUPP) 749 error = 0; 750 if (error != 0) { 751 break; 752 } 753 754 /* Fill out the kernel event information */ 755 ev_msg.vendor_code = KEV_VENDOR_APPLE; 756 ev_msg.kev_class = KEV_NETWORK_CLASS; 757 ev_msg.kev_subclass = KEV_INET_SUBCLASS; 758 759 ev_msg.event_code = KEV_INET_ADDR_DELETED; 760 761 if (ia->ia_ifa.ifa_dstaddr) 762 in_event_data.ia_dstaddr = 763 ((struct sockaddr_in *)ia->ia_ifa.ifa_dstaddr)->sin_addr; 764 else 765 in_event_data.ia_dstaddr.s_addr = 0; 766 767 in_event_data.ia_addr = ia->ia_addr.sin_addr; 768 in_event_data.ia_net = ia->ia_net; 769 in_event_data.ia_netmask = ia->ia_netmask; 770 in_event_data.ia_subnet = ia->ia_subnet; 771 in_event_data.ia_subnetmask = ia->ia_subnetmask; 772 in_event_data.ia_netbroadcast = ia->ia_netbroadcast; 773 strncpy(&in_event_data.link_data.if_name[0], ifp->if_name, IFNAMSIZ); 774 in_event_data.link_data.if_family = ifp->if_family; 775 in_event_data.link_data.if_unit = (unsigned long) ifp->if_unit; 776 777 ev_msg.dv[0].data_ptr = &in_event_data; 778 ev_msg.dv[0].data_length = sizeof(struct kev_in_data); 779 ev_msg.dv[1].data_length = 0; 780 781 lck_mtx_lock(rt_mtx); 782 TAILQ_REMOVE(&in_ifaddrhead, ia, ia_link); 783 /* 784 * in_ifscrub kills the interface route. 785 */ 786 in_ifscrub(ifp, ia, 1); 787 ifa = &ia->ia_ifa; 788 lck_mtx_unlock(rt_mtx); 789 ifnet_lock_exclusive(ifp); 790 if_detach_ifa(ifp, ifa); 791 792#ifdef __APPLE__ 793 /* 794 * If the interface supports multicast, and no address is left, 795 * remove the "all hosts" multicast group from that interface. 796 */ 797 if (ifp->if_flags & IFF_MULTICAST) { 798 struct in_addr addr; 799 struct in_multi *inm = NULL; 800 801 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) 802 if (ifa->ifa_addr->sa_family == AF_INET) 803 break; 804 805 if (ifa == 0) { 806 addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP); 807 IN_LOOKUP_MULTI(addr, ifp, inm); 808 } 809 ifnet_lock_done(ifp); 810 if (inm) 811 in_delmulti(&inm); 812 } else 813 ifnet_lock_done(ifp); 814#endif 815 816 /* Post the kernel event */ 817 kev_post_msg(&ev_msg); 818 819 /* 820 * See if there is any IPV4 address left and if so, 821 * reconfigure KDP to use current primary address. 822 */ 823 ifa = ifa_ifpgetprimary(ifp, AF_INET); 824 if (ifa != NULL) { 825 error = ifnet_ioctl(ifp, PF_INET, SIOCSIFADDR, ifa); 826 if (error == EOPNOTSUPP) 827 error = 0; 828 829 /* Release reference from ifa_ifpgetprimary() */ 830 ifafree(ifa); 831 } 832 break; 833 834#ifdef __APPLE__ 835 case SIOCSETOT: { 836 /* 837 * Inspiration from tcp_ctloutput() and ip_ctloutput() 838 * Special ioctl for OpenTransport sockets 839 */ 840 struct inpcb *inp, *cloned_inp; 841 int error2 = 0; 842 int cloned_fd = *(int *)data; 843 844 inp = sotoinpcb(so); 845 if (inp == NULL) { 846 break; 847 } 848 849 /* let's make sure it's either -1 or a valid file descriptor */ 850 if (cloned_fd != -1) { 851 struct socket *cloned_so; 852 error2 = file_socket(cloned_fd, &cloned_so); 853 if (error2){ 854 break; 855 } 856 cloned_inp = sotoinpcb(cloned_so); 857 file_drop(cloned_fd); 858 } else { 859 cloned_inp = NULL; 860 } 861 862 if (cloned_inp == NULL) { 863 /* OT always uses IP_PORTRANGE_HIGH */ 864 inp->inp_flags &= ~(INP_LOWPORT); 865 inp->inp_flags |= INP_HIGHPORT; 866 /* For UDP, OT allows broadcast by default */ 867 if (so->so_type == SOCK_DGRAM) 868 so->so_options |= SO_BROADCAST; 869 /* For TCP we want to see MSG_OOB when receive urgent data */ 870 else if (so->so_type == SOCK_STREAM) 871 so->so_options |= SO_WANTOOBFLAG; 872 } else { 873 inp->inp_ip_tos = cloned_inp->inp_ip_tos; 874 inp->inp_ip_ttl = cloned_inp->inp_ip_ttl; 875 inp->inp_flags = cloned_inp->inp_flags; 876 877 /* Multicast options */ 878 if (cloned_inp->inp_moptions != NULL) { 879 int i; 880 struct ip_moptions *cloned_imo = cloned_inp->inp_moptions; 881 struct ip_moptions *imo = inp->inp_moptions; 882 883 if (imo == NULL) { 884 /* 885 * No multicast option buffer attached to the pcb; 886 * allocate one. 887 */ 888 imo = (struct ip_moptions*) 889 _MALLOC(sizeof(*imo), M_IPMOPTS, M_WAITOK); 890 if (imo == NULL) { 891 error2 = ENOBUFS; 892 break; 893 } 894 inp->inp_moptions = imo; 895 } 896 imo->imo_multicast_ifp = cloned_imo->imo_multicast_ifp; 897 imo->imo_multicast_vif = cloned_imo->imo_multicast_vif; 898 imo->imo_multicast_ttl = cloned_imo->imo_multicast_ttl; 899 imo->imo_multicast_loop = cloned_imo->imo_multicast_loop; 900 imo->imo_num_memberships = cloned_imo->imo_num_memberships; 901 for (i = 0; i < cloned_imo->imo_num_memberships; i++) { 902 imo->imo_membership[i] = 903 in_addmulti(&cloned_imo->imo_membership[i]->inm_addr, 904 cloned_imo->imo_membership[i]->inm_ifp); 905 if (imo->imo_membership[i] == NULL) { 906 error2 = ENOBUFS; 907 break; 908 } 909 } 910 if (i < cloned_imo->imo_num_memberships) { 911 /* Failed, perform cleanup */ 912 for (i--; i >= 0; i--) 913 in_delmulti(&imo->imo_membership[i]); 914 imo->imo_num_memberships = 0; 915 break; 916 } 917 } 918 } 919 break; 920 } 921#endif /* __APPLE__ */ 922 923 default: 924 error = EOPNOTSUPP; 925 } 926 done: 927 if (ia != NULL) { 928 ifafree(&ia->ia_ifa); 929 } 930 return (error); 931} 932 933/* 934 * SIOC[GAD]LIFADDR. 935 * SIOCGLIFADDR: get first address. (?!?) 936 * SIOCGLIFADDR with IFLR_PREFIX: 937 * get first address that matches the specified prefix. 938 * SIOCALIFADDR: add the specified address. 939 * SIOCALIFADDR with IFLR_PREFIX: 940 * EINVAL since we can't deduce hostid part of the address. 941 * SIOCDLIFADDR: delete the specified address. 942 * SIOCDLIFADDR with IFLR_PREFIX: 943 * delete the first address that matches the specified prefix. 944 * return values: 945 * EINVAL on invalid parameters 946 * EADDRNOTAVAIL on prefix match failed/specified address not found 947 * other values may be returned from in_ioctl() 948 */ 949static int 950in_lifaddr_ioctl( 951 struct socket *so, 952 u_long cmd, 953 caddr_t data, 954 struct ifnet *ifp, 955 struct proc *p) 956{ 957 struct if_laddrreq *iflr = (struct if_laddrreq *)data; 958 struct ifaddr *ifa; 959 960 /* sanity checks */ 961 if (!data || !ifp) { 962 panic("invalid argument to in_lifaddr_ioctl"); 963 /*NOTRECHED*/ 964 } 965 966 switch (cmd) { 967 case SIOCGLIFADDR: 968 /* address must be specified on GET with IFLR_PREFIX */ 969 if ((iflr->flags & IFLR_PREFIX) == 0) 970 break; 971 /*FALLTHROUGH*/ 972 case SIOCALIFADDR: 973 case SIOCDLIFADDR: 974 /* address must be specified on ADD and DELETE */ 975 if (iflr->addr.ss_family != AF_INET) 976 return EINVAL; 977 if (iflr->addr.ss_len != sizeof(struct sockaddr_in)) 978 return EINVAL; 979 /* XXX need improvement */ 980 if (iflr->dstaddr.ss_family 981 && iflr->dstaddr.ss_family != AF_INET) 982 return EINVAL; 983 if (iflr->dstaddr.ss_family 984 && iflr->dstaddr.ss_len != sizeof(struct sockaddr_in)) 985 return EINVAL; 986 break; 987 default: /*shouldn't happen*/ 988 return EOPNOTSUPP; 989 } 990 if (sizeof(struct in_addr) * 8 < iflr->prefixlen) 991 return EINVAL; 992 993 switch (cmd) { 994 case SIOCALIFADDR: 995 { 996 struct in_aliasreq ifra; 997 998 if (iflr->flags & IFLR_PREFIX) 999 return EINVAL; 1000 1001 /* copy args to in_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */ 1002 bzero(&ifra, sizeof(ifra)); 1003 bcopy(iflr->iflr_name, ifra.ifra_name, 1004 sizeof(ifra.ifra_name)); 1005 1006 bcopy(&iflr->addr, &ifra.ifra_addr, iflr->addr.ss_len); 1007 1008 if (iflr->dstaddr.ss_family) { /*XXX*/ 1009 bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr, 1010 iflr->dstaddr.ss_len); 1011 } 1012 1013 ifra.ifra_mask.sin_family = AF_INET; 1014 ifra.ifra_mask.sin_len = sizeof(struct sockaddr_in); 1015 in_len2mask(&ifra.ifra_mask.sin_addr, iflr->prefixlen); 1016 1017 return in_control(so, SIOCAIFADDR, (caddr_t)&ifra, ifp, p); 1018 } 1019 case SIOCGLIFADDR: 1020 case SIOCDLIFADDR: 1021 { 1022 struct in_ifaddr *ia; 1023 struct in_addr mask, candidate; 1024 struct in_addr match = { 0 }; 1025 struct sockaddr_in *sin; 1026 int cmp; 1027 1028 bzero(&mask, sizeof(mask)); 1029 if (iflr->flags & IFLR_PREFIX) { 1030 /* lookup a prefix rather than address. */ 1031 in_len2mask(&mask, iflr->prefixlen); 1032 1033 sin = (struct sockaddr_in *)&iflr->addr; 1034 match.s_addr = sin->sin_addr.s_addr; 1035 match.s_addr &= mask.s_addr; 1036 1037 /* if you set extra bits, that's wrong */ 1038 if (match.s_addr != sin->sin_addr.s_addr) 1039 return EINVAL; 1040 1041 cmp = 1; 1042 } else { 1043 if (cmd == SIOCGLIFADDR) { 1044 /* on getting an address, take the 1st match */ 1045 cmp = 0; /*XXX*/ 1046 } else { 1047 /* on deleting an address, do exact match */ 1048 in_len2mask(&mask, 32); 1049 sin = (struct sockaddr_in *)&iflr->addr; 1050 match.s_addr = sin->sin_addr.s_addr; 1051 1052 cmp = 1; 1053 } 1054 } 1055 1056 ifnet_lock_shared(ifp); 1057 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 1058 if (ifa->ifa_addr->sa_family != AF_INET6) 1059 continue; 1060 if (!cmp) 1061 break; 1062 candidate.s_addr = ((struct sockaddr_in *)&ifa->ifa_addr)->sin_addr.s_addr; 1063 candidate.s_addr &= mask.s_addr; 1064 if (candidate.s_addr == match.s_addr) 1065 break; 1066 } 1067 ifnet_lock_done(ifp); 1068 if (!ifa) 1069 return EADDRNOTAVAIL; 1070 ia = (struct in_ifaddr *)ifa; 1071 1072 if (cmd == SIOCGLIFADDR) { 1073 /* fill in the if_laddrreq structure */ 1074 bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin_len); 1075 1076 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) { 1077 bcopy(&ia->ia_dstaddr, &iflr->dstaddr, 1078 ia->ia_dstaddr.sin_len); 1079 } else 1080 bzero(&iflr->dstaddr, sizeof(iflr->dstaddr)); 1081 1082 iflr->prefixlen = 1083 in_mask2len(&ia->ia_sockmask.sin_addr); 1084 1085 iflr->flags = 0; /*XXX*/ 1086 1087 return 0; 1088 } else { 1089 struct in_aliasreq ifra; 1090 1091 /* fill in_aliasreq and do ioctl(SIOCDIFADDR_IN6) */ 1092 bzero(&ifra, sizeof(ifra)); 1093 bcopy(iflr->iflr_name, ifra.ifra_name, 1094 sizeof(ifra.ifra_name)); 1095 1096 bcopy(&ia->ia_addr, &ifra.ifra_addr, 1097 ia->ia_addr.sin_len); 1098 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) { 1099 bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr, 1100 ia->ia_dstaddr.sin_len); 1101 } 1102 bcopy(&ia->ia_sockmask, &ifra.ifra_dstaddr, 1103 ia->ia_sockmask.sin_len); 1104 1105 return in_control(so, SIOCDIFADDR, (caddr_t)&ifra, 1106 ifp, p); 1107 } 1108 } 1109 } 1110 1111 return EOPNOTSUPP; /*just for safety*/ 1112} 1113 1114/* 1115 * Delete any existing route for an interface. 1116 */ 1117void 1118in_ifscrub( 1119 struct ifnet *ifp, 1120 struct in_ifaddr *ia, 1121 int locked) 1122{ 1123 1124 if ((ia->ia_flags & IFA_ROUTE) == 0) 1125 return; 1126 if (!locked) 1127 lck_mtx_lock(rt_mtx); 1128 if (ifp->if_flags & (IFF_LOOPBACK|IFF_POINTOPOINT)) 1129 rtinit_locked(&(ia->ia_ifa), (int)RTM_DELETE, RTF_HOST); 1130 else 1131 rtinit_locked(&(ia->ia_ifa), (int)RTM_DELETE, 0); 1132 ia->ia_flags &= ~IFA_ROUTE; 1133 if (!locked) 1134 lck_mtx_unlock(rt_mtx); 1135} 1136 1137/* 1138 * Initialize an interface's internet address 1139 * and routing table entry. 1140 */ 1141static int 1142in_ifinit( 1143 struct ifnet *ifp, 1144 struct in_ifaddr *ia, 1145 struct sockaddr_in *sin, 1146 int scrub) 1147{ 1148 u_long i = ntohl(sin->sin_addr.s_addr); 1149 struct sockaddr_in oldaddr; 1150 int flags = RTF_UP, error; 1151 struct ifaddr *ifa0; 1152 unsigned int cmd; 1153 1154 oldaddr = ia->ia_addr; 1155 ia->ia_addr = *sin; 1156 1157 /* 1158 * Give the interface a chance to initialize if this is its first 1159 * address, and to validate the address if necessary. Send down 1160 * SIOCSIFADDR for first address, and SIOCAIFADDR for alias(es). 1161 * We find the first IPV4 address assigned to it and check if this 1162 * is the same as the one passed into this routine. 1163 */ 1164 ifa0 = ifa_ifpgetprimary(ifp, AF_INET); 1165 cmd = (&ia->ia_ifa == ifa0) ? SIOCSIFADDR : SIOCAIFADDR; 1166 error = ifnet_ioctl(ifp, PF_INET, cmd, ia); 1167 if (error == EOPNOTSUPP) 1168 error = 0; 1169 /* 1170 * If we've just sent down SIOCAIFADDR, send another ioctl down 1171 * for SIOCSIFADDR for the first IPV4 address of the interface, 1172 * because an address change on one of the addresses will result 1173 * in the removal of the previous first IPV4 address. KDP needs 1174 * be reconfigured with the current primary IPV4 address. 1175 */ 1176 if (error == 0 && cmd == SIOCAIFADDR) { 1177 error = ifnet_ioctl(ifp, PF_INET, SIOCSIFADDR, ifa0); 1178 if (error == EOPNOTSUPP) 1179 error = 0; 1180 } 1181 1182 /* Release reference from ifa_ifpgetprimary() */ 1183 ifafree(ifa0); 1184 1185 if (error) { 1186 ia->ia_addr = oldaddr; 1187 return (error); 1188 } 1189 if (scrub) { 1190 ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr; 1191 in_ifscrub(ifp, ia, 0); 1192 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; 1193 } 1194 if (IN_CLASSA(i)) 1195 ia->ia_netmask = IN_CLASSA_NET; 1196 else if (IN_CLASSB(i)) 1197 ia->ia_netmask = IN_CLASSB_NET; 1198 else 1199 ia->ia_netmask = IN_CLASSC_NET; 1200 /* 1201 * The subnet mask usually includes at least the standard network part, 1202 * but may may be smaller in the case of supernetting. 1203 * If it is set, we believe it. 1204 */ 1205 if (ia->ia_subnetmask == 0) { 1206 ia->ia_subnetmask = ia->ia_netmask; 1207 ia->ia_sockmask.sin_addr.s_addr = htonl(ia->ia_subnetmask); 1208 } else 1209 ia->ia_netmask &= ia->ia_subnetmask; 1210 ia->ia_net = i & ia->ia_netmask; 1211 ia->ia_subnet = i & ia->ia_subnetmask; 1212 in_socktrim(&ia->ia_sockmask); 1213 /* 1214 * Add route for the network. 1215 */ 1216 ia->ia_ifa.ifa_metric = ifp->if_metric; 1217 if (ifp->if_flags & IFF_BROADCAST) { 1218 ia->ia_broadaddr.sin_addr.s_addr = 1219 htonl(ia->ia_subnet | ~ia->ia_subnetmask); 1220 ia->ia_netbroadcast.s_addr = 1221 htonl(ia->ia_net | ~ ia->ia_netmask); 1222 } else if (ifp->if_flags & IFF_LOOPBACK) { 1223 ia->ia_ifa.ifa_dstaddr = ia->ia_ifa.ifa_addr; 1224 flags |= RTF_HOST; 1225 } else if (ifp->if_flags & IFF_POINTOPOINT) { 1226 if (ia->ia_dstaddr.sin_family != AF_INET) 1227 return (0); 1228 flags |= RTF_HOST; 1229 } 1230 if ((error = rtinit(&(ia->ia_ifa), (int)RTM_ADD, flags)) == 0) 1231 ia->ia_flags |= IFA_ROUTE; 1232 /* XXX check if the subnet route points to the same interface */ 1233 if (error == EEXIST) 1234 error = 0; 1235 1236 /* 1237 * If the interface supports multicast, join the "all hosts" 1238 * multicast group on that interface. 1239 */ 1240 if (ifp->if_flags & IFF_MULTICAST) { 1241 struct in_multi *inm; 1242 struct in_addr addr; 1243 1244 addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP); 1245 ifnet_lock_shared(ifp); 1246 IN_LOOKUP_MULTI(addr, ifp, inm); 1247 ifnet_lock_done(ifp); 1248 if (inm == 0) 1249 in_addmulti(&addr, ifp); 1250 } 1251 return (error); 1252} 1253 1254 1255/* 1256 * Return 1 if the address might be a local broadcast address. 1257 */ 1258int 1259in_broadcast( 1260 struct in_addr in, 1261 struct ifnet *ifp) 1262{ 1263 struct ifaddr *ifa; 1264 u_long t; 1265 1266 if (in.s_addr == INADDR_BROADCAST || 1267 in.s_addr == INADDR_ANY) 1268 return 1; 1269 if ((ifp->if_flags & IFF_BROADCAST) == 0) 1270 return 0; 1271 t = ntohl(in.s_addr); 1272 /* 1273 * Look through the list of addresses for a match 1274 * with a broadcast address. 1275 */ 1276#define ia ((struct in_ifaddr *)ifa) 1277 ifnet_lock_shared(ifp); 1278 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 1279 if (ifa->ifa_addr == NULL) { 1280 ifnet_lock_done(ifp); 1281 return (0); 1282 } 1283 if (ifa->ifa_addr->sa_family == AF_INET && 1284 (in.s_addr == ia->ia_broadaddr.sin_addr.s_addr || 1285 in.s_addr == ia->ia_netbroadcast.s_addr || 1286 /* 1287 * Check for old-style (host 0) broadcast. 1288 */ 1289 t == ia->ia_subnet || t == ia->ia_net) && 1290 /* 1291 * Check for an all one subnetmask. These 1292 * only exist when an interface gets a secondary 1293 * address. 1294 */ 1295 ia->ia_subnetmask != (u_long)0xffffffff) { 1296 ifnet_lock_done(ifp); 1297 return 1; 1298 } 1299 } 1300 ifnet_lock_done(ifp); 1301 return (0); 1302#undef ia 1303} 1304 1305static void 1306in_free_inm( 1307 void* ifma_protospec) 1308{ 1309 struct in_multi *inm = ifma_protospec; 1310 1311 /* 1312 * No remaining claims to this record; let IGMP know that 1313 * we are leaving the multicast group. 1314 */ 1315 igmp_leavegroup(inm); 1316 lck_mtx_lock(rt_mtx); 1317 LIST_REMOVE(inm, inm_link); 1318 lck_mtx_unlock(rt_mtx); 1319 FREE(inm, M_IPMADDR); 1320} 1321 1322/* 1323 * Add an address to the list of IP multicast addresses for a given interface. 1324 */ 1325struct in_multi * 1326in_addmulti( 1327 struct in_addr *ap, 1328 struct ifnet *ifp) 1329{ 1330 struct in_multi *inm; 1331 int error; 1332 struct sockaddr_in sin; 1333 struct ifmultiaddr *ifma; 1334 1335 /* 1336 * Call generic routine to add membership or increment 1337 * refcount. It wants addresses in the form of a sockaddr, 1338 * so we build one here (being careful to zero the unused bytes). 1339 */ 1340 bzero(&sin, sizeof sin); 1341 sin.sin_family = AF_INET; 1342 sin.sin_len = sizeof sin; 1343 sin.sin_addr = *ap; 1344 error = if_addmulti(ifp, (struct sockaddr *)&sin, &ifma); 1345 if (error) { 1346 return 0; 1347 } 1348 1349 /* 1350 * If ifma->ifma_protospec is null, then if_addmulti() created 1351 * a new record. Otherwise, we are done. 1352 */ 1353 if (ifma->ifma_protospec != 0) { 1354 return ifma->ifma_protospec; 1355 } 1356 1357 inm = (struct in_multi *) _MALLOC(sizeof(*inm), M_IPMADDR, M_WAITOK); 1358 if (inm == NULL) { 1359 return (NULL); 1360 } 1361 1362 bzero(inm, sizeof *inm); 1363 inm->inm_addr = *ap; 1364 inm->inm_ifp = ifp; 1365 inm->inm_ifma = ifma; 1366 lck_mtx_lock(rt_mtx); 1367 if (ifma->ifma_protospec == NULL) { 1368 ifma->ifma_protospec = inm; 1369 ifma->ifma_free = in_free_inm; 1370 LIST_INSERT_HEAD(&in_multihead, inm, inm_link); 1371 } 1372 lck_mtx_unlock(rt_mtx); 1373 1374 if (ifma->ifma_protospec != inm) { 1375 _FREE(inm, M_IPMADDR); 1376 return ifma->ifma_protospec; 1377 } 1378 1379 /* 1380 * Let IGMP know that we have joined a new IP multicast group. 1381 */ 1382 error = igmp_joingroup(inm); 1383 if (error) { 1384 char addrbuf[16]; 1385 1386 /* 1387 * We can't free the inm because someone else may already be 1388 * using it. Once we put it in to ifma->ifma_protospec, it 1389 * must exist as long as the ifma does. Might be nice to flag 1390 * the error so we can try igmp_joingroup the next time through. 1391 */ 1392 log(LOG_ERR, "igmp_joingroup error %d joining multicast %s on %s%d\n", 1393 error, inet_ntop(AF_INET, &sin.sin_addr, addrbuf, sizeof(addrbuf)), 1394 ifp->if_name, ifp->if_unit); 1395 } 1396 1397 return (inm); 1398} 1399 1400/* 1401 * Delete a multicast address record. 1402 */ 1403void 1404in_delmulti( 1405 struct in_multi **inm) 1406{ 1407 struct in_multi *inm2; 1408 1409 lck_mtx_lock(rt_mtx); 1410 LIST_FOREACH(inm2, &in_multihead, inm_link) { 1411 if (inm2 == *inm) 1412 break; 1413 } 1414 if (inm2 != *inm) { 1415 lck_mtx_unlock(rt_mtx); 1416 printf("in_delmulti - ignoring invalid inm (%p)\n", *inm); 1417 return; 1418 } 1419 lck_mtx_unlock(rt_mtx); 1420 1421 /* We intentionally do this a bit differently than BSD */ 1422 if ((*inm)->inm_ifma) { 1423 if_delmultiaddr((*inm)->inm_ifma, 0); 1424 ifma_release((*inm)->inm_ifma); 1425 } 1426 *inm = NULL; 1427} 1428 1429#if !NFSCLIENT 1430int inet_aton(char *cp, struct in_addr *pin); 1431int 1432inet_aton(char * cp, struct in_addr * pin) 1433{ 1434 u_char * b = (unsigned char *)pin; 1435 int i; 1436 char * p; 1437 1438 for (p = cp, i = 0; i < 4; i++) { 1439 u_long l = strtoul(p, 0, 0); 1440 if (l > 255) 1441 return (FALSE); 1442 b[i] = l; 1443 p = strchr(p, '.'); 1444 if (i < 3 && p == NULL) 1445 return (FALSE); 1446 p++; 1447 } 1448 return (TRUE); 1449} 1450#endif 1451