1 /* 2 * Copyright (c) 1982, 1986, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)in.c 8.4 (Berkeley) 1/9/95 34 * $FreeBSD: src/sys/netinet/in.c,v 1.44.2.14 2002/11/08 00:45:50 suz Exp $ 35 * $DragonFly: src/sys/netinet/in.c,v 1.41 2008/08/17 05:20:10 sephe Exp $ 36 */ 37 38 #include "opt_bootp.h" 39 40 #include <sys/param.h> 41 #include <sys/systm.h> 42 #include <sys/sockio.h> 43 #include <sys/malloc.h> 44 #include <sys/proc.h> 45 #include <sys/priv.h> 46 #include <sys/msgport.h> 47 #include <sys/socket.h> 48 49 #include <sys/kernel.h> 50 #include <sys/sysctl.h> 51 #include <sys/thread2.h> 52 53 #include <net/if.h> 54 #include <net/if_types.h> 55 #include <net/route.h> 56 #include <net/netmsg2.h> 57 58 #include <netinet/in.h> 59 #include <netinet/in_var.h> 60 #include <netinet/in_pcb.h> 61 62 #include <netinet/igmp_var.h> 63 64 MALLOC_DEFINE(M_IPMADDR, "in_multi", "internet multicast address"); 65 66 static int in_mask2len (struct in_addr *); 67 static void in_len2mask (struct in_addr *, int); 68 static int in_lifaddr_ioctl (struct socket *, u_long, caddr_t, 69 struct ifnet *, struct thread *); 70 71 static void in_socktrim (struct sockaddr_in *); 72 static int in_ifinit(struct ifnet *, struct in_ifaddr *, 73 const struct sockaddr_in *, int); 74 75 static void in_control_dispatch(struct netmsg *); 76 static int in_control_internal(u_long, caddr_t, struct ifnet *, 77 struct thread *); 78 79 static int in_addprefix(struct in_ifaddr *, int); 80 static void in_scrubprefix(struct in_ifaddr *); 81 82 static int subnetsarelocal = 0; 83 SYSCTL_INT(_net_inet_ip, OID_AUTO, subnets_are_local, CTLFLAG_RW, 84 &subnetsarelocal, 0, ""); 85 86 struct in_multihead in_multihead; /* XXX BSS initialization */ 87 88 extern struct inpcbinfo ripcbinfo; 89 extern struct inpcbinfo udbinfo; 90 91 /* 92 * Return 1 if an internet address is for a ``local'' host 93 * (one to which we have a connection). If subnetsarelocal 94 * is true, this includes other subnets of the local net. 95 * Otherwise, it includes only the directly-connected (sub)nets. 96 */ 97 int 98 in_localaddr(struct in_addr in) 99 { 100 u_long i = ntohl(in.s_addr); 101 struct in_ifaddr_container *iac; 102 struct in_ifaddr *ia; 103 104 if (subnetsarelocal) { 105 TAILQ_FOREACH(iac, &in_ifaddrheads[mycpuid], ia_link) { 106 ia = iac->ia; 107 108 if ((i & ia->ia_netmask) == ia->ia_net) 109 return (1); 110 } 111 } else { 112 TAILQ_FOREACH(iac, &in_ifaddrheads[mycpuid], ia_link) { 113 ia = iac->ia; 114 115 if ((i & ia->ia_subnetmask) == ia->ia_subnet) 116 return (1); 117 } 118 } 119 return (0); 120 } 121 122 /* 123 * Determine whether an IP address is in a reserved set of addresses 124 * that may not be forwarded, or whether datagrams to that destination 125 * may be forwarded. 126 */ 127 int 128 in_canforward(struct in_addr in) 129 { 130 u_long i = ntohl(in.s_addr); 131 u_long net; 132 133 if (IN_EXPERIMENTAL(i) || IN_MULTICAST(i)) 134 return (0); 135 if (IN_CLASSA(i)) { 136 net = i & IN_CLASSA_NET; 137 if (net == 0 || net == (IN_LOOPBACKNET << IN_CLASSA_NSHIFT)) 138 return (0); 139 } 140 return (1); 141 } 142 143 /* 144 * Trim a mask in a sockaddr 145 */ 146 static void 147 in_socktrim(struct sockaddr_in *ap) 148 { 149 char *cplim = (char *) &ap->sin_addr; 150 char *cp = (char *) (&ap->sin_addr + 1); 151 152 ap->sin_len = 0; 153 while (--cp >= cplim) 154 if (*cp) { 155 (ap)->sin_len = cp - (char *) (ap) + 1; 156 break; 157 } 158 } 159 160 static int 161 in_mask2len(struct in_addr *mask) 162 { 163 int x, y; 164 u_char *p; 165 166 p = (u_char *)mask; 167 for (x = 0; x < sizeof *mask; x++) { 168 if (p[x] != 0xff) 169 break; 170 } 171 y = 0; 172 if (x < sizeof *mask) { 173 for (y = 0; y < 8; y++) { 174 if ((p[x] & (0x80 >> y)) == 0) 175 break; 176 } 177 } 178 return x * 8 + y; 179 } 180 181 static void 182 in_len2mask(struct in_addr *mask, int len) 183 { 184 int i; 185 u_char *p; 186 187 p = (u_char *)mask; 188 bzero(mask, sizeof *mask); 189 for (i = 0; i < len / 8; i++) 190 p[i] = 0xff; 191 if (len % 8) 192 p[i] = (0xff00 >> (len % 8)) & 0xff; 193 } 194 195 static int in_interfaces; /* number of external internet interfaces */ 196 197 struct in_control_arg { 198 u_long cmd; 199 caddr_t data; 200 struct ifnet *ifp; 201 struct thread *td; 202 }; 203 204 static void 205 in_control_dispatch(struct netmsg *nmsg) 206 { 207 struct lwkt_msg *msg = &nmsg->nm_lmsg; 208 const struct in_control_arg *arg = msg->u.ms_resultp; 209 int error; 210 211 error = in_control_internal(arg->cmd, arg->data, arg->ifp, arg->td); 212 lwkt_replymsg(msg, error); 213 } 214 215 /* 216 * Generic internet control operations (ioctl's). 217 * Ifp is 0 if not an interface-specific ioctl. 218 * 219 * NOTE! td might be NULL. 220 */ 221 /* ARGSUSED */ 222 int 223 in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp, 224 struct thread *td) 225 { 226 struct netmsg nmsg; 227 struct in_control_arg arg; 228 struct lwkt_msg *msg; 229 int error; 230 231 switch (cmd) { 232 case SIOCALIFADDR: 233 case SIOCDLIFADDR: 234 if (td && (error = priv_check(td, PRIV_ROOT)) != 0) 235 return error; 236 /* FALLTHROUGH */ 237 case SIOCGLIFADDR: 238 if (!ifp) 239 return EINVAL; 240 return in_lifaddr_ioctl(so, cmd, data, ifp, td); 241 } 242 243 KASSERT(cmd != SIOCALIFADDR && cmd != SIOCDLIFADDR, 244 ("recursive SIOC%cLIFADDR!\n", 245 cmd == SIOCDLIFADDR ? 'D' : 'A')); 246 247 /* 248 * IFADDR alterations are serialized by netisr0 249 */ 250 switch (cmd) { 251 case SIOCSIFDSTADDR: 252 case SIOCSIFBRDADDR: 253 case SIOCSIFADDR: 254 case SIOCSIFNETMASK: 255 case SIOCAIFADDR: 256 case SIOCDIFADDR: 257 bzero(&arg, sizeof(arg)); 258 arg.cmd = cmd; 259 arg.data = data; 260 arg.ifp = ifp; 261 arg.td = td; 262 263 netmsg_init(&nmsg, NULL, &curthread->td_msgport, 264 0, in_control_dispatch); 265 msg = &nmsg.nm_lmsg; 266 msg->u.ms_resultp = &arg; 267 268 lwkt_domsg(cpu_portfn(0), msg, 0); 269 return msg->ms_error; 270 default: 271 return in_control_internal(cmd, data, ifp, td); 272 } 273 } 274 275 static void 276 in_ialink_dispatch(struct netmsg *nmsg) 277 { 278 struct lwkt_msg *lmsg = &nmsg->nm_lmsg; 279 struct in_ifaddr *ia = lmsg->u.ms_resultp; 280 struct ifaddr_container *ifac; 281 struct in_ifaddr_container *iac; 282 int cpu = mycpuid; 283 284 crit_enter(); 285 286 ifac = &ia->ia_ifa.ifa_containers[cpu]; 287 ASSERT_IFAC_VALID(ifac); 288 KASSERT((ifac->ifa_listmask & IFA_LIST_IN_IFADDRHEAD) == 0, 289 ("ia is on in_ifaddrheads\n")); 290 291 ifac->ifa_listmask |= IFA_LIST_IN_IFADDRHEAD; 292 iac = &ifac->ifa_proto_u.u_in_ifac; 293 TAILQ_INSERT_TAIL(&in_ifaddrheads[cpu], iac, ia_link); 294 295 crit_exit(); 296 297 ifa_forwardmsg(lmsg, cpu + 1); 298 } 299 300 static void 301 in_iaunlink_dispatch(struct netmsg *nmsg) 302 { 303 struct lwkt_msg *lmsg = &nmsg->nm_lmsg; 304 struct in_ifaddr *ia = lmsg->u.ms_resultp; 305 struct ifaddr_container *ifac; 306 struct in_ifaddr_container *iac; 307 int cpu = mycpuid; 308 309 crit_enter(); 310 311 ifac = &ia->ia_ifa.ifa_containers[cpu]; 312 ASSERT_IFAC_VALID(ifac); 313 KASSERT(ifac->ifa_listmask & IFA_LIST_IN_IFADDRHEAD, 314 ("ia is not on in_ifaddrheads\n")); 315 316 iac = &ifac->ifa_proto_u.u_in_ifac; 317 TAILQ_REMOVE(&in_ifaddrheads[cpu], iac, ia_link); 318 ifac->ifa_listmask &= ~IFA_LIST_IN_IFADDRHEAD; 319 320 crit_exit(); 321 322 ifa_forwardmsg(lmsg, cpu + 1); 323 } 324 325 static void 326 in_iahashins_dispatch(struct netmsg *nmsg) 327 { 328 struct lwkt_msg *lmsg = &nmsg->nm_lmsg; 329 struct in_ifaddr *ia = lmsg->u.ms_resultp; 330 struct ifaddr_container *ifac; 331 struct in_ifaddr_container *iac; 332 int cpu = mycpuid; 333 334 crit_enter(); 335 336 ifac = &ia->ia_ifa.ifa_containers[cpu]; 337 ASSERT_IFAC_VALID(ifac); 338 KASSERT((ifac->ifa_listmask & IFA_LIST_IN_IFADDRHASH) == 0, 339 ("ia is on in_ifaddrhashtbls\n")); 340 341 ifac->ifa_listmask |= IFA_LIST_IN_IFADDRHASH; 342 iac = &ifac->ifa_proto_u.u_in_ifac; 343 LIST_INSERT_HEAD(INADDR_HASH(ia->ia_addr.sin_addr.s_addr), 344 iac, ia_hash); 345 346 crit_exit(); 347 348 ifa_forwardmsg(lmsg, cpu + 1); 349 } 350 351 static void 352 in_iahashrem_dispatch(struct netmsg *nmsg) 353 { 354 struct lwkt_msg *lmsg = &nmsg->nm_lmsg; 355 struct in_ifaddr *ia = lmsg->u.ms_resultp; 356 struct ifaddr_container *ifac; 357 struct in_ifaddr_container *iac; 358 int cpu = mycpuid; 359 360 crit_enter(); 361 362 ifac = &ia->ia_ifa.ifa_containers[cpu]; 363 ASSERT_IFAC_VALID(ifac); 364 KASSERT(ifac->ifa_listmask & IFA_LIST_IN_IFADDRHASH, 365 ("ia is not on in_ifaddrhashtbls\n")); 366 367 iac = &ifac->ifa_proto_u.u_in_ifac; 368 LIST_REMOVE(iac, ia_hash); 369 ifac->ifa_listmask &= ~IFA_LIST_IN_IFADDRHASH; 370 371 crit_exit(); 372 373 ifa_forwardmsg(lmsg, cpu + 1); 374 } 375 376 static void 377 in_ialink(struct in_ifaddr *ia) 378 { 379 struct netmsg nmsg; 380 struct lwkt_msg *lmsg; 381 382 netmsg_init(&nmsg, NULL, &curthread->td_msgport, 383 0, in_ialink_dispatch); 384 lmsg = &nmsg.nm_lmsg; 385 lmsg->u.ms_resultp = ia; 386 387 ifa_domsg(lmsg, 0); 388 } 389 390 void 391 in_iaunlink(struct in_ifaddr *ia) 392 { 393 struct netmsg nmsg; 394 struct lwkt_msg *lmsg; 395 396 netmsg_init(&nmsg, NULL, &curthread->td_msgport, 397 0, in_iaunlink_dispatch); 398 lmsg = &nmsg.nm_lmsg; 399 lmsg->u.ms_resultp = ia; 400 401 ifa_domsg(lmsg, 0); 402 } 403 404 void 405 in_iahash_insert(struct in_ifaddr *ia) 406 { 407 struct netmsg nmsg; 408 struct lwkt_msg *lmsg; 409 410 netmsg_init(&nmsg, NULL, &curthread->td_msgport, 411 0, in_iahashins_dispatch); 412 lmsg = &nmsg.nm_lmsg; 413 lmsg->u.ms_resultp = ia; 414 415 ifa_domsg(lmsg, 0); 416 } 417 418 void 419 in_iahash_remove(struct in_ifaddr *ia) 420 { 421 struct netmsg nmsg; 422 struct lwkt_msg *lmsg; 423 424 netmsg_init(&nmsg, NULL, &curthread->td_msgport, 425 0, in_iahashrem_dispatch); 426 lmsg = &nmsg.nm_lmsg; 427 lmsg->u.ms_resultp = ia; 428 429 ifa_domsg(lmsg, 0); 430 } 431 432 static __inline struct in_ifaddr * 433 in_ianext(struct in_ifaddr *oia) 434 { 435 struct ifaddr_container *ifac; 436 struct in_ifaddr_container *iac; 437 438 ifac = &oia->ia_ifa.ifa_containers[mycpuid]; 439 ASSERT_IFAC_VALID(ifac); 440 KASSERT(ifac->ifa_listmask & IFA_LIST_IN_IFADDRHEAD, 441 ("ia is not on in_ifaddrheads\n")); 442 443 iac = &ifac->ifa_proto_u.u_in_ifac; 444 iac = TAILQ_NEXT(iac, ia_link); 445 if (iac != NULL) 446 return iac->ia; 447 else 448 return NULL; 449 } 450 451 static int 452 in_control_internal(u_long cmd, caddr_t data, struct ifnet *ifp, 453 struct thread *td) 454 { 455 struct ifreq *ifr = (struct ifreq *)data; 456 struct in_ifaddr *ia = NULL; 457 struct in_addr dst; 458 struct in_aliasreq *ifra = (struct in_aliasreq *)data; 459 struct ifaddr_container *ifac; 460 struct in_ifaddr_container *iac; 461 struct sockaddr_in oldaddr; 462 int hostIsNew, iaIsNew, maskIsNew, ifpWasUp; 463 int error = 0; 464 465 iaIsNew = 0; 466 ifpWasUp = 0; 467 468 /* 469 * Find address for this interface, if it exists. 470 * 471 * If an alias address was specified, find that one instead of 472 * the first one on the interface, if possible 473 */ 474 if (ifp) { 475 struct in_ifaddr *iap; 476 477 dst = ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr; 478 LIST_FOREACH(iac, INADDR_HASH(dst.s_addr), ia_hash) { 479 iap = iac->ia; 480 if (iap->ia_ifp == ifp && 481 iap->ia_addr.sin_addr.s_addr == dst.s_addr) { 482 ia = iap; 483 break; 484 } 485 } 486 if (ia == NULL) { 487 TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], 488 ifa_link) { 489 iap = ifatoia(ifac->ifa); 490 if (iap->ia_addr.sin_family == AF_INET) { 491 ia = iap; 492 break; 493 } 494 } 495 } 496 497 if (ifp->if_flags & IFF_UP) 498 ifpWasUp = 1; 499 } 500 501 switch (cmd) { 502 case SIOCAIFADDR: 503 case SIOCDIFADDR: 504 if (ifp == NULL) 505 return (EADDRNOTAVAIL); 506 if (ifra->ifra_addr.sin_family == AF_INET) { 507 while (ia != NULL) { 508 if (ia->ia_ifp == ifp && 509 ia->ia_addr.sin_addr.s_addr == 510 ifra->ifra_addr.sin_addr.s_addr) 511 break; 512 ia = in_ianext(ia); 513 } 514 if ((ifp->if_flags & IFF_POINTOPOINT) && 515 cmd == SIOCAIFADDR && 516 ifra->ifra_dstaddr.sin_addr.s_addr == INADDR_ANY) { 517 return EDESTADDRREQ; 518 } 519 } 520 if (cmd == SIOCDIFADDR && ia == NULL) 521 return (EADDRNOTAVAIL); 522 /* FALLTHROUGH */ 523 case SIOCSIFADDR: 524 case SIOCSIFNETMASK: 525 case SIOCSIFDSTADDR: 526 if (td && (error = priv_check(td, PRIV_ROOT)) != 0) 527 return error; 528 529 if (ifp == NULL) 530 return (EADDRNOTAVAIL); 531 532 if (cmd == SIOCSIFDSTADDR && 533 (ifp->if_flags & IFF_POINTOPOINT) == 0) 534 return (EINVAL); 535 536 if (ia == NULL) { 537 struct ifaddr *ifa; 538 int i; 539 540 ia = ifa_create(sizeof(*ia), M_WAITOK); 541 ifa = &ia->ia_ifa; 542 543 /* 544 * Setup per-CPU information 545 */ 546 for (i = 0; i < ncpus; ++i) { 547 ifac = &ifa->ifa_containers[i]; 548 iac = &ifac->ifa_proto_u.u_in_ifac; 549 iac->ia = ia; 550 iac->ia_ifac = ifac; 551 } 552 553 /* 554 * Protect from NETISR_IP traversing address list 555 * while we're modifying it. 556 */ 557 crit_enter(); 558 559 in_ialink(ia); 560 ifa_iflink(ifa, ifp, 1); 561 562 ifa->ifa_addr = (struct sockaddr *)&ia->ia_addr; 563 ifa->ifa_dstaddr = (struct sockaddr *)&ia->ia_dstaddr; 564 ifa->ifa_netmask = (struct sockaddr *)&ia->ia_sockmask; 565 ia->ia_sockmask.sin_len = 8; 566 ia->ia_sockmask.sin_family = AF_INET; 567 if (ifp->if_flags & IFF_BROADCAST) { 568 ia->ia_broadaddr.sin_len = sizeof ia->ia_addr; 569 ia->ia_broadaddr.sin_family = AF_INET; 570 } 571 ia->ia_ifp = ifp; 572 if (!(ifp->if_flags & IFF_LOOPBACK)) 573 in_interfaces++; 574 iaIsNew = 1; 575 576 crit_exit(); 577 } 578 break; 579 580 case SIOCSIFBRDADDR: 581 if (td && (error = priv_check(td, PRIV_ROOT)) != 0) 582 return error; 583 /* FALLTHROUGH */ 584 585 case SIOCGIFADDR: 586 case SIOCGIFNETMASK: 587 case SIOCGIFDSTADDR: 588 case SIOCGIFBRDADDR: 589 if (ia == NULL) 590 return (EADDRNOTAVAIL); 591 break; 592 } 593 594 switch (cmd) { 595 case SIOCGIFADDR: 596 *((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_addr; 597 return (0); 598 599 case SIOCGIFBRDADDR: 600 if ((ifp->if_flags & IFF_BROADCAST) == 0) 601 return (EINVAL); 602 *((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_broadaddr; 603 return (0); 604 605 case SIOCGIFDSTADDR: 606 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) 607 return (EINVAL); 608 *((struct sockaddr_in *)&ifr->ifr_dstaddr) = ia->ia_dstaddr; 609 return (0); 610 611 case SIOCGIFNETMASK: 612 *((struct sockaddr_in *)&ifr->ifr_addr) = ia->ia_sockmask; 613 return (0); 614 615 case SIOCSIFDSTADDR: 616 KKASSERT(ifp->if_flags & IFF_POINTOPOINT); 617 618 oldaddr = ia->ia_dstaddr; 619 ia->ia_dstaddr = *(struct sockaddr_in *)&ifr->ifr_dstaddr; 620 if (ifp->if_ioctl != NULL) { 621 ifnet_serialize_all(ifp); 622 error = ifp->if_ioctl(ifp, SIOCSIFDSTADDR, (caddr_t)ia, 623 td->td_proc->p_ucred); 624 ifnet_deserialize_all(ifp); 625 if (error) { 626 ia->ia_dstaddr = oldaddr; 627 return (error); 628 } 629 } 630 if (ia->ia_flags & IFA_ROUTE) { 631 ia->ia_ifa.ifa_dstaddr = (struct sockaddr *)&oldaddr; 632 rtinit(&ia->ia_ifa, RTM_DELETE, RTF_HOST); 633 ia->ia_ifa.ifa_dstaddr = 634 (struct sockaddr *)&ia->ia_dstaddr; 635 rtinit(&ia->ia_ifa, RTM_ADD, RTF_HOST | RTF_UP); 636 } 637 return (0); 638 639 case SIOCSIFBRDADDR: 640 if ((ifp->if_flags & IFF_BROADCAST) == 0) 641 return (EINVAL); 642 ia->ia_broadaddr = *(struct sockaddr_in *)&ifr->ifr_broadaddr; 643 return (0); 644 645 case SIOCSIFADDR: 646 error = in_ifinit(ifp, ia, 647 (const struct sockaddr_in *)&ifr->ifr_addr, 1); 648 if (error != 0 && iaIsNew) 649 break; 650 if (error == 0) { 651 EVENTHANDLER_INVOKE(ifaddr_event, ifp, 652 iaIsNew ? IFADDR_EVENT_ADD : IFADDR_EVENT_CHANGE, 653 &ia->ia_ifa); 654 } 655 if (!ifpWasUp && (ifp->if_flags & IFF_UP)) { 656 /* 657 * Interface is brought up by in_ifinit() 658 * (via ifp->if_ioctl). We act as if the 659 * interface got IFF_UP flag turned on. 660 */ 661 if_up(ifp); 662 } 663 return (0); 664 665 case SIOCSIFNETMASK: 666 ia->ia_sockmask.sin_addr = ifra->ifra_addr.sin_addr; 667 ia->ia_subnetmask = ntohl(ia->ia_sockmask.sin_addr.s_addr); 668 return (0); 669 670 case SIOCAIFADDR: 671 maskIsNew = 0; 672 hostIsNew = 1; 673 error = 0; 674 if (ia->ia_addr.sin_family == AF_INET) { 675 if (ifra->ifra_addr.sin_len == 0) { 676 ifra->ifra_addr = ia->ia_addr; 677 hostIsNew = 0; 678 } else if (ifra->ifra_addr.sin_addr.s_addr == 679 ia->ia_addr.sin_addr.s_addr) { 680 hostIsNew = 0; 681 } 682 } 683 if (ifra->ifra_mask.sin_len) { 684 in_ifscrub(ifp, ia); 685 ia->ia_sockmask = ifra->ifra_mask; 686 ia->ia_sockmask.sin_family = AF_INET; 687 ia->ia_subnetmask = 688 ntohl(ia->ia_sockmask.sin_addr.s_addr); 689 maskIsNew = 1; 690 } 691 if ((ifp->if_flags & IFF_POINTOPOINT) && 692 ifra->ifra_dstaddr.sin_family == AF_INET) { 693 in_ifscrub(ifp, ia); 694 ia->ia_dstaddr = ifra->ifra_dstaddr; 695 maskIsNew = 1; /* We lie; but the effect's the same */ 696 } 697 if (ifra->ifra_addr.sin_family == AF_INET && 698 (hostIsNew || maskIsNew)) 699 error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0); 700 701 if (error != 0 && iaIsNew) 702 break; 703 704 if ((ifp->if_flags & IFF_BROADCAST) && 705 ifra->ifra_broadaddr.sin_family == AF_INET) 706 ia->ia_broadaddr = ifra->ifra_broadaddr; 707 if (error == 0) { 708 EVENTHANDLER_INVOKE(ifaddr_event, ifp, 709 iaIsNew ? IFADDR_EVENT_ADD : IFADDR_EVENT_CHANGE, 710 &ia->ia_ifa); 711 } 712 if (!ifpWasUp && (ifp->if_flags & IFF_UP)) { 713 /* See the comment in SIOCSIFADDR */ 714 if_up(ifp); 715 } 716 return (error); 717 718 case SIOCDIFADDR: 719 /* 720 * in_ifscrub kills the interface route. 721 */ 722 in_ifscrub(ifp, ia); 723 /* 724 * in_ifadown gets rid of all the rest of 725 * the routes. This is not quite the right 726 * thing to do, but at least if we are running 727 * a routing process they will come back. 728 */ 729 in_ifadown(&ia->ia_ifa, 1); 730 EVENTHANDLER_INVOKE(ifaddr_event, ifp, IFADDR_EVENT_DELETE, 731 &ia->ia_ifa); 732 error = 0; 733 break; 734 735 default: 736 if (ifp == NULL || ifp->if_ioctl == NULL) 737 return (EOPNOTSUPP); 738 ifnet_serialize_all(ifp); 739 error = ifp->if_ioctl(ifp, cmd, data, td->td_proc->p_ucred); 740 ifnet_deserialize_all(ifp); 741 return (error); 742 } 743 744 KKASSERT(cmd == SIOCDIFADDR || 745 ((cmd == SIOCAIFADDR || cmd == SIOCSIFADDR) && iaIsNew)); 746 747 ifa_ifunlink(&ia->ia_ifa, ifp); 748 in_iaunlink(ia); 749 750 if (cmd == SIOCDIFADDR) { 751 ifac = &ia->ia_ifa.ifa_containers[mycpuid]; 752 if (ifac->ifa_listmask & IFA_LIST_IN_IFADDRHASH) 753 in_iahash_remove(ia); 754 } 755 #ifdef INVARIANTS 756 else { 757 /* 758 * If cmd is SIOCSIFADDR or SIOCAIFADDR, in_ifinit() has 759 * already taken care of the deletion from hash table 760 */ 761 ifac = &ia->ia_ifa.ifa_containers[mycpuid]; 762 KASSERT((ifac->ifa_listmask & IFA_LIST_IN_IFADDRHASH) == 0, 763 ("SIOC%cIFADDR failed on new ia, " 764 "but the new ia is still in hash table\n", 765 cmd == SIOCSIFADDR ? 'S' : 'A')); 766 } 767 #endif 768 769 ifa_destroy(&ia->ia_ifa); 770 771 if ((cmd == SIOCAIFADDR || cmd == SIOCSIFADDR) && 772 !ifpWasUp && (ifp->if_flags & IFF_UP)) { 773 /* 774 * Though the address assignment failed, the 775 * interface is brought up by in_ifinit() 776 * (via ifp->if_ioctl). With the hope that 777 * the interface has some valid addresses, we 778 * act as if IFF_UP flag was just set on the 779 * interface. 780 * 781 * NOTE: 782 * This could only be done after the failed 783 * address is unlinked from the global address 784 * list. 785 */ 786 if_up(ifp); 787 } 788 789 return (error); 790 } 791 792 /* 793 * SIOC[GAD]LIFADDR. 794 * SIOCGLIFADDR: get first address. (?!?) 795 * SIOCGLIFADDR with IFLR_PREFIX: 796 * get first address that matches the specified prefix. 797 * SIOCALIFADDR: add the specified address. 798 * SIOCALIFADDR with IFLR_PREFIX: 799 * EINVAL since we can't deduce hostid part of the address. 800 * SIOCDLIFADDR: delete the specified address. 801 * SIOCDLIFADDR with IFLR_PREFIX: 802 * delete the first address that matches the specified prefix. 803 * return values: 804 * EINVAL on invalid parameters 805 * EADDRNOTAVAIL on prefix match failed/specified address not found 806 * other values may be returned from in_ioctl() 807 * 808 * NOTE! td might be NULL. 809 */ 810 static int 811 in_lifaddr_ioctl(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp, 812 struct thread *td) 813 { 814 struct if_laddrreq *iflr = (struct if_laddrreq *)data; 815 816 /* sanity checks */ 817 if (!data || !ifp) { 818 panic("invalid argument to in_lifaddr_ioctl"); 819 /*NOTRECHED*/ 820 } 821 822 switch (cmd) { 823 case SIOCGLIFADDR: 824 /* address must be specified on GET with IFLR_PREFIX */ 825 if ((iflr->flags & IFLR_PREFIX) == 0) 826 break; 827 /*FALLTHROUGH*/ 828 case SIOCALIFADDR: 829 case SIOCDLIFADDR: 830 /* address must be specified on ADD and DELETE */ 831 if (iflr->addr.ss_family != AF_INET) 832 return EINVAL; 833 if (iflr->addr.ss_len != sizeof(struct sockaddr_in)) 834 return EINVAL; 835 /* XXX need improvement */ 836 if (iflr->dstaddr.ss_family 837 && iflr->dstaddr.ss_family != AF_INET) 838 return EINVAL; 839 if (iflr->dstaddr.ss_family 840 && iflr->dstaddr.ss_len != sizeof(struct sockaddr_in)) 841 return EINVAL; 842 break; 843 default: /*shouldn't happen*/ 844 return EOPNOTSUPP; 845 } 846 if (sizeof(struct in_addr) * 8 < iflr->prefixlen) 847 return EINVAL; 848 849 switch (cmd) { 850 case SIOCALIFADDR: 851 { 852 struct in_aliasreq ifra; 853 854 if (iflr->flags & IFLR_PREFIX) 855 return EINVAL; 856 857 /* copy args to in_aliasreq, perform ioctl(SIOCAIFADDR_IN6). */ 858 bzero(&ifra, sizeof ifra); 859 bcopy(iflr->iflr_name, ifra.ifra_name, sizeof ifra.ifra_name); 860 861 bcopy(&iflr->addr, &ifra.ifra_addr, iflr->addr.ss_len); 862 863 if (iflr->dstaddr.ss_family) { /*XXX*/ 864 bcopy(&iflr->dstaddr, &ifra.ifra_dstaddr, 865 iflr->dstaddr.ss_len); 866 } 867 868 ifra.ifra_mask.sin_family = AF_INET; 869 ifra.ifra_mask.sin_len = sizeof(struct sockaddr_in); 870 in_len2mask(&ifra.ifra_mask.sin_addr, iflr->prefixlen); 871 872 return in_control(so, SIOCAIFADDR, (caddr_t)&ifra, ifp, td); 873 } 874 case SIOCGLIFADDR: 875 case SIOCDLIFADDR: 876 { 877 struct ifaddr_container *ifac; 878 struct in_ifaddr *ia; 879 struct in_addr mask, candidate, match; 880 struct sockaddr_in *sin; 881 int cmp; 882 883 bzero(&mask, sizeof mask); 884 if (iflr->flags & IFLR_PREFIX) { 885 /* lookup a prefix rather than address. */ 886 in_len2mask(&mask, iflr->prefixlen); 887 888 sin = (struct sockaddr_in *)&iflr->addr; 889 match.s_addr = sin->sin_addr.s_addr; 890 match.s_addr &= mask.s_addr; 891 892 /* if you set extra bits, that's wrong */ 893 if (match.s_addr != sin->sin_addr.s_addr) 894 return EINVAL; 895 896 cmp = 1; 897 } else { 898 if (cmd == SIOCGLIFADDR) { 899 /* on getting an address, take the 1st match */ 900 match.s_addr = 0; /* gcc4 warning */ 901 cmp = 0; /*XXX*/ 902 } else { 903 /* on deleting an address, do exact match */ 904 in_len2mask(&mask, 32); 905 sin = (struct sockaddr_in *)&iflr->addr; 906 match.s_addr = sin->sin_addr.s_addr; 907 908 cmp = 1; 909 } 910 } 911 912 TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) { 913 struct ifaddr *ifa = ifac->ifa; 914 915 if (ifa->ifa_addr->sa_family != AF_INET6) 916 continue; 917 if (!cmp) 918 break; 919 candidate.s_addr = 920 ((struct sockaddr_in *)&ifa->ifa_addr)->sin_addr.s_addr; 921 candidate.s_addr &= mask.s_addr; 922 if (candidate.s_addr == match.s_addr) 923 break; 924 } 925 if (ifac == NULL) 926 return EADDRNOTAVAIL; 927 ia = (struct in_ifaddr *)(ifac->ifa); 928 929 if (cmd == SIOCGLIFADDR) { 930 /* fill in the if_laddrreq structure */ 931 bcopy(&ia->ia_addr, &iflr->addr, ia->ia_addr.sin_len); 932 933 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) { 934 bcopy(&ia->ia_dstaddr, &iflr->dstaddr, 935 ia->ia_dstaddr.sin_len); 936 } else 937 bzero(&iflr->dstaddr, sizeof iflr->dstaddr); 938 939 iflr->prefixlen = 940 in_mask2len(&ia->ia_sockmask.sin_addr); 941 942 iflr->flags = 0; /*XXX*/ 943 944 return 0; 945 } else { 946 struct in_aliasreq ifra; 947 948 /* fill in_aliasreq and do ioctl(SIOCDIFADDR_IN6) */ 949 bzero(&ifra, sizeof ifra); 950 bcopy(iflr->iflr_name, ifra.ifra_name, 951 sizeof ifra.ifra_name); 952 953 bcopy(&ia->ia_addr, &ifra.ifra_addr, 954 ia->ia_addr.sin_len); 955 if ((ifp->if_flags & IFF_POINTOPOINT) != 0) { 956 bcopy(&ia->ia_dstaddr, &ifra.ifra_dstaddr, 957 ia->ia_dstaddr.sin_len); 958 } 959 bcopy(&ia->ia_sockmask, &ifra.ifra_dstaddr, 960 ia->ia_sockmask.sin_len); 961 962 return in_control(so, SIOCDIFADDR, (caddr_t)&ifra, 963 ifp, td); 964 } 965 } 966 } 967 968 return EOPNOTSUPP; /*just for safety*/ 969 } 970 971 /* 972 * Delete any existing route for an interface. 973 */ 974 void 975 in_ifscrub(struct ifnet *ifp __unused, struct in_ifaddr *ia) 976 { 977 in_scrubprefix(ia); 978 } 979 980 /* 981 * Initialize an interface's internet address 982 * and routing table entry. 983 */ 984 static int 985 in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, 986 const struct sockaddr_in *sin, int scrub) 987 { 988 u_long i = ntohl(sin->sin_addr.s_addr); 989 struct sockaddr_in oldaddr; 990 struct ifaddr_container *ifac; 991 int flags = RTF_UP, error = 0; 992 int was_hash = 0; 993 994 ifac = &ia->ia_ifa.ifa_containers[mycpuid]; 995 oldaddr = ia->ia_addr; 996 997 if (ifac->ifa_listmask & IFA_LIST_IN_IFADDRHASH) { 998 was_hash = 1; 999 in_iahash_remove(ia); 1000 } 1001 1002 ia->ia_addr = *sin; 1003 if (ia->ia_addr.sin_family == AF_INET) 1004 in_iahash_insert(ia); 1005 1006 /* 1007 * Give the interface a chance to initialize 1008 * if this is its first address, 1009 * and to validate the address if necessary. 1010 */ 1011 if (ifp->if_ioctl != NULL) { 1012 ifnet_serialize_all(ifp); 1013 error = ifp->if_ioctl(ifp, SIOCSIFADDR, (caddr_t)ia, NULL); 1014 ifnet_deserialize_all(ifp); 1015 if (error) 1016 goto fail; 1017 } 1018 1019 /* 1020 * Delete old route, if requested. 1021 */ 1022 if (scrub) { 1023 ia->ia_ifa.ifa_addr = (struct sockaddr *)&oldaddr; 1024 in_ifscrub(ifp, ia); 1025 ia->ia_ifa.ifa_addr = (struct sockaddr *)&ia->ia_addr; 1026 } 1027 1028 /* 1029 * Calculate netmask/subnetmask. 1030 */ 1031 if (IN_CLASSA(i)) 1032 ia->ia_netmask = IN_CLASSA_NET; 1033 else if (IN_CLASSB(i)) 1034 ia->ia_netmask = IN_CLASSB_NET; 1035 else 1036 ia->ia_netmask = IN_CLASSC_NET; 1037 /* 1038 * The subnet mask usually includes at least the standard network part, 1039 * but may may be smaller in the case of supernetting. 1040 * If it is set, we believe it. 1041 */ 1042 if (ia->ia_subnetmask == 0) { 1043 ia->ia_subnetmask = ia->ia_netmask; 1044 ia->ia_sockmask.sin_addr.s_addr = htonl(ia->ia_subnetmask); 1045 } else { 1046 ia->ia_netmask &= ia->ia_subnetmask; 1047 } 1048 ia->ia_net = i & ia->ia_netmask; 1049 ia->ia_subnet = i & ia->ia_subnetmask; 1050 in_socktrim(&ia->ia_sockmask); 1051 1052 /* 1053 * Add route for the network. 1054 */ 1055 ia->ia_ifa.ifa_metric = ifp->if_metric; 1056 if (ifp->if_flags & IFF_BROADCAST) { 1057 ia->ia_broadaddr.sin_addr.s_addr = 1058 htonl(ia->ia_subnet | ~ia->ia_subnetmask); 1059 ia->ia_netbroadcast.s_addr = 1060 htonl(ia->ia_net | ~ ia->ia_netmask); 1061 } else if (ifp->if_flags & IFF_LOOPBACK) { 1062 ia->ia_dstaddr = ia->ia_addr; 1063 flags |= RTF_HOST; 1064 } else if (ifp->if_flags & IFF_POINTOPOINT) { 1065 if (ia->ia_dstaddr.sin_family != AF_INET) 1066 return (0); 1067 flags |= RTF_HOST; 1068 } 1069 1070 /*- 1071 * Don't add host routes for interface addresses of 1072 * 0.0.0.0 --> 0.255.255.255 netmask 255.0.0.0. This makes it 1073 * possible to assign several such address pairs with consistent 1074 * results (no host route) and is required by BOOTP. 1075 * 1076 * XXX: This is ugly ! There should be a way for the caller to 1077 * say that they don't want a host route. 1078 */ 1079 if (ia->ia_addr.sin_addr.s_addr != INADDR_ANY || 1080 ia->ia_netmask != IN_CLASSA_NET || 1081 ia->ia_dstaddr.sin_addr.s_addr != htonl(IN_CLASSA_HOST)) { 1082 error = in_addprefix(ia, flags); 1083 if (error) 1084 goto fail; 1085 } 1086 1087 /* 1088 * If the interface supports multicast, join the "all hosts" 1089 * multicast group on that interface. 1090 */ 1091 if (ifp->if_flags & IFF_MULTICAST) { 1092 struct in_addr addr; 1093 1094 addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP); 1095 in_addmulti(&addr, ifp); 1096 } 1097 return (0); 1098 fail: 1099 if (ifac->ifa_listmask & IFA_LIST_IN_IFADDRHASH) 1100 in_iahash_remove(ia); 1101 1102 ia->ia_addr = oldaddr; 1103 if (was_hash) 1104 in_iahash_insert(ia); 1105 return (error); 1106 } 1107 1108 #define rtinitflags(x) \ 1109 (((x)->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) \ 1110 ? RTF_HOST : 0) 1111 1112 /* 1113 * Add a route to prefix ("connected route" in cisco terminology). 1114 * Do nothing, if there are some interface addresses with the same 1115 * prefix already. This function assumes that the 'target' parent 1116 * interface is UP. 1117 */ 1118 static int 1119 in_addprefix(struct in_ifaddr *target, int flags) 1120 { 1121 struct in_ifaddr_container *iac; 1122 struct in_addr prefix, mask; 1123 int error; 1124 1125 mask = target->ia_sockmask.sin_addr; 1126 if (flags & RTF_HOST) { 1127 prefix = target->ia_dstaddr.sin_addr; 1128 } else { 1129 prefix = target->ia_addr.sin_addr; 1130 prefix.s_addr &= mask.s_addr; 1131 } 1132 1133 TAILQ_FOREACH(iac, &in_ifaddrheads[mycpuid], ia_link) { 1134 struct in_ifaddr *ia = iac->ia; 1135 struct in_addr p; 1136 1137 /* Don't test against self */ 1138 if (ia == target) 1139 continue; 1140 1141 /* The tested address does not own a route entry */ 1142 if ((ia->ia_flags & IFA_ROUTE) == 0) 1143 continue; 1144 1145 /* Prefix test */ 1146 if (rtinitflags(ia)) { 1147 p = ia->ia_dstaddr.sin_addr; 1148 } else { 1149 p = ia->ia_addr.sin_addr; 1150 p.s_addr &= ia->ia_sockmask.sin_addr.s_addr; 1151 } 1152 if (prefix.s_addr != p.s_addr) 1153 continue; 1154 1155 /* 1156 * If the to-be-added address and the curretly being 1157 * tested address are not host addresses, we need to 1158 * take subnetmask into consideration. 1159 */ 1160 if (!(flags & RTF_HOST) && !rtinitflags(ia) && 1161 mask.s_addr != ia->ia_sockmask.sin_addr.s_addr) 1162 continue; 1163 1164 /* 1165 * If we got a matching prefix route inserted by other 1166 * interface address, we don't need to bother. 1167 */ 1168 return 0; 1169 } 1170 1171 /* 1172 * No one seem to have prefix route; insert it. 1173 */ 1174 error = rtinit(&target->ia_ifa, RTM_ADD, flags); 1175 if (!error) 1176 target->ia_flags |= IFA_ROUTE; 1177 return error; 1178 } 1179 1180 /* 1181 * Remove a route to prefix ("connected route" in cisco terminology). 1182 * Re-installs the route by using another interface address, if there's 1183 * one with the same prefix (otherwise we lose the route mistakenly). 1184 */ 1185 static void 1186 in_scrubprefix(struct in_ifaddr *target) 1187 { 1188 struct in_ifaddr_container *iac; 1189 struct in_addr prefix, mask; 1190 int error; 1191 1192 if ((target->ia_flags & IFA_ROUTE) == 0) 1193 return; 1194 1195 mask = target->ia_sockmask.sin_addr; 1196 if (rtinitflags(target)) { 1197 prefix = target->ia_dstaddr.sin_addr; 1198 } else { 1199 prefix = target->ia_addr.sin_addr; 1200 prefix.s_addr &= mask.s_addr; 1201 } 1202 1203 TAILQ_FOREACH(iac, &in_ifaddrheads[mycpuid], ia_link) { 1204 struct in_ifaddr *ia = iac->ia; 1205 struct in_addr p; 1206 1207 /* Don't test against self */ 1208 if (ia == target) 1209 continue; 1210 1211 /* The tested address already owns a route entry */ 1212 if (ia->ia_flags & IFA_ROUTE) 1213 continue; 1214 1215 /* 1216 * The prefix route of the tested address should 1217 * never be installed if its parent interface is 1218 * not UP yet. 1219 */ 1220 if ((ia->ia_ifp->if_flags & IFF_UP) == 0) 1221 continue; 1222 1223 /* Prefix test */ 1224 if (rtinitflags(ia)) { 1225 p = ia->ia_dstaddr.sin_addr; 1226 } else { 1227 p = ia->ia_addr.sin_addr; 1228 p.s_addr &= ia->ia_sockmask.sin_addr.s_addr; 1229 } 1230 if (prefix.s_addr != p.s_addr) 1231 continue; 1232 1233 /* 1234 * We don't need to test subnetmask here, as what we do 1235 * in in_addprefix(), since if the the tested address's 1236 * parent interface is UP, the tested address should own 1237 * a prefix route entry and we would never reach here. 1238 */ 1239 1240 /* 1241 * If we got a matching prefix route, move IFA_ROUTE to him 1242 */ 1243 rtinit(&target->ia_ifa, RTM_DELETE, rtinitflags(target)); 1244 target->ia_flags &= ~IFA_ROUTE; 1245 1246 error = rtinit(&ia->ia_ifa, RTM_ADD, rtinitflags(ia) | RTF_UP); 1247 if (!error) 1248 ia->ia_flags |= IFA_ROUTE; 1249 return; 1250 } 1251 1252 /* 1253 * No candidates for this prefix route; just remove it. 1254 */ 1255 rtinit(&target->ia_ifa, RTM_DELETE, rtinitflags(target)); 1256 target->ia_flags &= ~IFA_ROUTE; 1257 } 1258 1259 #undef rtinitflags 1260 1261 /* 1262 * Return 1 if the address might be a local broadcast address. 1263 */ 1264 int 1265 in_broadcast(struct in_addr in, struct ifnet *ifp) 1266 { 1267 struct ifaddr_container *ifac; 1268 u_long t; 1269 1270 if (in.s_addr == INADDR_BROADCAST || 1271 in.s_addr == INADDR_ANY) 1272 return 1; 1273 if ((ifp->if_flags & IFF_BROADCAST) == 0) 1274 return 0; 1275 t = ntohl(in.s_addr); 1276 /* 1277 * Look through the list of addresses for a match 1278 * with a broadcast address. 1279 */ 1280 #define ia ((struct in_ifaddr *)ifa) 1281 TAILQ_FOREACH(ifac, &ifp->if_addrheads[mycpuid], ifa_link) { 1282 struct ifaddr *ifa = ifac->ifa; 1283 1284 if (ifa->ifa_addr->sa_family == AF_INET && 1285 (in.s_addr == ia->ia_broadaddr.sin_addr.s_addr || 1286 in.s_addr == ia->ia_netbroadcast.s_addr || 1287 /* 1288 * Check for old-style (host 0) broadcast. 1289 */ 1290 t == ia->ia_subnet || t == ia->ia_net) && 1291 /* 1292 * Check for an all one subnetmask. These 1293 * only exist when an interface gets a secondary 1294 * address. 1295 */ 1296 ia->ia_subnetmask != (u_long)0xffffffff) 1297 return 1; 1298 } 1299 return (0); 1300 #undef ia 1301 } 1302 /* 1303 * Add an address to the list of IP multicast addresses for a given interface. 1304 */ 1305 struct in_multi * 1306 in_addmulti(struct in_addr *ap, struct ifnet *ifp) 1307 { 1308 struct in_multi *inm; 1309 int error; 1310 struct sockaddr_in sin; 1311 struct ifmultiaddr *ifma; 1312 1313 /* 1314 * Call generic routine to add membership or increment 1315 * refcount. It wants addresses in the form of a sockaddr, 1316 * so we build one here (being careful to zero the unused bytes). 1317 */ 1318 bzero(&sin, sizeof sin); 1319 sin.sin_family = AF_INET; 1320 sin.sin_len = sizeof sin; 1321 sin.sin_addr = *ap; 1322 crit_enter(); 1323 error = if_addmulti(ifp, (struct sockaddr *)&sin, &ifma); 1324 if (error) { 1325 crit_exit(); 1326 return 0; 1327 } 1328 1329 /* 1330 * If ifma->ifma_protospec is null, then if_addmulti() created 1331 * a new record. Otherwise, we are done. 1332 */ 1333 if (ifma->ifma_protospec != 0) { 1334 crit_exit(); 1335 return ifma->ifma_protospec; 1336 } 1337 1338 /* XXX - if_addmulti uses M_WAITOK. Can this really be called 1339 at interrupt time? If so, need to fix if_addmulti. XXX */ 1340 inm = kmalloc(sizeof *inm, M_IPMADDR, M_WAITOK | M_ZERO); 1341 inm->inm_addr = *ap; 1342 inm->inm_ifp = ifp; 1343 inm->inm_ifma = ifma; 1344 ifma->ifma_protospec = inm; 1345 LIST_INSERT_HEAD(&in_multihead, inm, inm_link); 1346 1347 /* 1348 * Let IGMP know that we have joined a new IP multicast group. 1349 */ 1350 igmp_joingroup(inm); 1351 crit_exit(); 1352 return (inm); 1353 } 1354 1355 /* 1356 * Delete a multicast address record. 1357 */ 1358 void 1359 in_delmulti(struct in_multi *inm) 1360 { 1361 struct ifmultiaddr *ifma; 1362 struct in_multi my_inm; 1363 1364 crit_enter(); 1365 ifma = inm->inm_ifma; 1366 my_inm.inm_ifp = NULL ; /* don't send the leave msg */ 1367 if (ifma->ifma_refcount == 1) { 1368 /* 1369 * No remaining claims to this record; let IGMP know that 1370 * we are leaving the multicast group. 1371 * But do it after the if_delmulti() which might reset 1372 * the interface and nuke the packet. 1373 */ 1374 my_inm = *inm ; 1375 ifma->ifma_protospec = 0; 1376 LIST_REMOVE(inm, inm_link); 1377 kfree(inm, M_IPMADDR); 1378 } 1379 /* XXX - should be separate API for when we have an ifma? */ 1380 if_delmulti(ifma->ifma_ifp, ifma->ifma_addr); 1381 if (my_inm.inm_ifp != NULL) 1382 igmp_leavegroup(&my_inm); 1383 crit_exit(); 1384 } 1385 1386 void 1387 in_ifdetach(struct ifnet *ifp) 1388 { 1389 in_pcbpurgeif0(LIST_FIRST(&ripcbinfo.pcblisthead), ifp); 1390 in_pcbpurgeif0(LIST_FIRST(&udbinfo.pcblisthead), ifp); 1391 } 1392