1 /* $NetBSD: if.c,v 1.80 2000/12/18 21:05:04 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by William Studnemund and Jason R. Thorpe. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 /* 40 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 41 * All rights reserved. 42 * 43 * Redistribution and use in source and binary forms, with or without 44 * modification, are permitted provided that the following conditions 45 * are met: 46 * 1. Redistributions of source code must retain the above copyright 47 * notice, this list of conditions and the following disclaimer. 48 * 2. Redistributions in binary form must reproduce the above copyright 49 * notice, this list of conditions and the following disclaimer in the 50 * documentation and/or other materials provided with the distribution. 51 * 3. Neither the name of the project nor the names of its contributors 52 * may be used to endorse or promote products derived from this software 53 * without specific prior written permission. 54 * 55 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 56 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 57 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 58 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 59 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 60 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 61 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 62 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 63 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 64 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 65 * SUCH DAMAGE. 66 */ 67 68 /* 69 * Copyright (c) 1980, 1986, 1993 70 * The Regents of the University of California. All rights reserved. 71 * 72 * Redistribution and use in source and binary forms, with or without 73 * modification, are permitted provided that the following conditions 74 * are met: 75 * 1. Redistributions of source code must retain the above copyright 76 * notice, this list of conditions and the following disclaimer. 77 * 2. Redistributions in binary form must reproduce the above copyright 78 * notice, this list of conditions and the following disclaimer in the 79 * documentation and/or other materials provided with the distribution. 80 * 3. All advertising materials mentioning features or use of this software 81 * must display the following acknowledgement: 82 * This product includes software developed by the University of 83 * California, Berkeley and its contributors. 84 * 4. Neither the name of the University nor the names of its contributors 85 * may be used to endorse or promote products derived from this software 86 * without specific prior written permission. 87 * 88 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 89 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 90 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 91 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 92 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 93 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 94 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 95 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 96 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 97 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 98 * SUCH DAMAGE. 99 * 100 * @(#)if.c 8.5 (Berkeley) 1/9/95 101 */ 102 103 #include "opt_inet.h" 104 105 #include "opt_compat_linux.h" 106 #include "opt_compat_svr4.h" 107 #include "opt_compat_43.h" 108 #include "opt_atalk.h" 109 110 #include <sys/param.h> 111 #include <sys/mbuf.h> 112 #include <sys/systm.h> 113 #include <sys/callout.h> 114 #include <sys/proc.h> 115 #include <sys/socket.h> 116 #include <sys/socketvar.h> 117 #include <sys/domain.h> 118 #include <sys/protosw.h> 119 #include <sys/kernel.h> 120 #include <sys/ioctl.h> 121 122 #include <net/if.h> 123 #include <net/if_dl.h> 124 #include <net/if_ether.h> 125 #include <net/if_ieee80211.h> 126 #include <net/if_types.h> 127 #include <net/radix.h> 128 #include <net/route.h> 129 #ifdef NETATALK 130 #include <netatalk/at_extern.h> 131 #include <netatalk/at.h> 132 #endif 133 134 #ifdef INET6 135 /*XXX*/ 136 #include <netinet/in.h> 137 #include <netinet6/in6_var.h> 138 #endif 139 140 int ifqmaxlen = IFQ_MAXLEN; 141 struct callout if_slowtimo_ch; 142 143 #ifdef INET6 144 /* 145 * XXX: declare here to avoid to include many inet6 related files.. 146 * should be more generalized? 147 */ 148 extern void nd6_setmtu __P((struct ifnet *)); 149 #endif 150 151 int if_rt_walktree __P((struct radix_node *, void *)); 152 153 struct if_clone *if_clone_lookup __P((const char *, int *)); 154 int if_clone_list __P((struct if_clonereq *)); 155 156 LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners); 157 int if_cloners_count; 158 159 /* 160 * Network interface utility routines. 161 * 162 * Routines with ifa_ifwith* names take sockaddr *'s as 163 * parameters. 164 */ 165 void 166 ifinit() 167 { 168 169 callout_init(&if_slowtimo_ch); 170 if_slowtimo(NULL); 171 } 172 173 /* 174 * Null routines used while an interface is going away. These routines 175 * just return an error. 176 */ 177 178 int 179 if_nulloutput(ifp, m, so, rt) 180 struct ifnet *ifp; 181 struct mbuf *m; 182 struct sockaddr *so; 183 struct rtentry *rt; 184 { 185 186 return (ENXIO); 187 } 188 189 void 190 if_nullinput(ifp, m) 191 struct ifnet *ifp; 192 struct mbuf *m; 193 { 194 195 /* Nothing. */ 196 } 197 198 void 199 if_nullstart(ifp) 200 struct ifnet *ifp; 201 { 202 203 /* Nothing. */ 204 } 205 206 int 207 if_nullioctl(ifp, cmd, data) 208 struct ifnet *ifp; 209 u_long cmd; 210 caddr_t data; 211 { 212 213 return (ENXIO); 214 } 215 216 int 217 if_nullinit(ifp) 218 struct ifnet *ifp; 219 { 220 221 return (ENXIO); 222 } 223 224 void 225 if_nullstop(ifp, disable) 226 struct ifnet *ifp; 227 int disable; 228 { 229 230 /* Nothing. */ 231 } 232 233 void 234 if_nullwatchdog(ifp) 235 struct ifnet *ifp; 236 { 237 238 /* Nothing. */ 239 } 240 241 void 242 if_nulldrain(ifp) 243 struct ifnet *ifp; 244 { 245 246 /* Nothing. */ 247 } 248 249 int if_index = 0; 250 struct ifaddr **ifnet_addrs = NULL; 251 struct ifnet **ifindex2ifnet = NULL; 252 253 /* 254 * Attach an interface to the 255 * list of "active" interfaces. 256 */ 257 void 258 if_attach(ifp) 259 struct ifnet *ifp; 260 { 261 unsigned socksize, ifasize; 262 int namelen, masklen; 263 struct sockaddr_dl *sdl; 264 struct ifaddr *ifa; 265 static size_t if_indexlim = 8; 266 267 if (if_index == 0) 268 TAILQ_INIT(&ifnet); 269 TAILQ_INIT(&ifp->if_addrlist); 270 TAILQ_INSERT_TAIL(&ifnet, ifp, if_list); 271 ifp->if_index = ++if_index; 272 273 /* 274 * We have some arrays that should be indexed by if_index. 275 * since if_index will grow dynamically, they should grow too. 276 * struct ifadd **ifnet_addrs 277 * struct ifnet **ifindex2ifnet 278 */ 279 if (ifnet_addrs == 0 || ifindex2ifnet == 0 || 280 ifp->if_index >= if_indexlim) { 281 size_t n; 282 caddr_t q; 283 284 while (ifp->if_index >= if_indexlim) 285 if_indexlim <<= 1; 286 287 /* grow ifnet_addrs */ 288 n = if_indexlim * sizeof(ifa); 289 q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK); 290 bzero(q, n); 291 if (ifnet_addrs) { 292 bcopy((caddr_t)ifnet_addrs, q, n/2); 293 free((caddr_t)ifnet_addrs, M_IFADDR); 294 } 295 ifnet_addrs = (struct ifaddr **)q; 296 297 /* grow ifindex2ifnet */ 298 n = if_indexlim * sizeof(struct ifnet *); 299 q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK); 300 bzero(q, n); 301 if (ifindex2ifnet) { 302 bcopy((caddr_t)ifindex2ifnet, q, n/2); 303 free((caddr_t)ifindex2ifnet, M_IFADDR); 304 } 305 ifindex2ifnet = (struct ifnet **)q; 306 } 307 308 ifindex2ifnet[ifp->if_index] = ifp; 309 310 /* 311 * create a Link Level name for this device 312 */ 313 namelen = strlen(ifp->if_xname); 314 masklen = offsetof(struct sockaddr_dl, sdl_data[0]) + namelen; 315 socksize = masklen + ifp->if_addrlen; 316 #define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1))) 317 if (socksize < sizeof(*sdl)) 318 socksize = sizeof(*sdl); 319 socksize = ROUNDUP(socksize); 320 ifasize = sizeof(*ifa) + 2 * socksize; 321 ifa = (struct ifaddr *)malloc(ifasize, M_IFADDR, M_WAITOK); 322 bzero((caddr_t)ifa, ifasize); 323 sdl = (struct sockaddr_dl *)(ifa + 1); 324 sdl->sdl_len = socksize; 325 sdl->sdl_family = AF_LINK; 326 bcopy(ifp->if_xname, sdl->sdl_data, namelen); 327 sdl->sdl_nlen = namelen; 328 sdl->sdl_index = ifp->if_index; 329 sdl->sdl_type = ifp->if_type; 330 ifnet_addrs[ifp->if_index] = ifa; 331 IFAREF(ifa); 332 ifa->ifa_ifp = ifp; 333 ifa->ifa_rtrequest = link_rtrequest; 334 TAILQ_INSERT_HEAD(&ifp->if_addrlist, ifa, ifa_list); 335 IFAREF(ifa); 336 ifa->ifa_addr = (struct sockaddr *)sdl; 337 ifp->if_sadl = sdl; 338 sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl); 339 ifa->ifa_netmask = (struct sockaddr *)sdl; 340 sdl->sdl_len = masklen; 341 while (namelen != 0) 342 sdl->sdl_data[--namelen] = 0xff; 343 if (ifp->if_snd.ifq_maxlen == 0) 344 ifp->if_snd.ifq_maxlen = ifqmaxlen; 345 ifp->if_broadcastaddr = 0; /* reliably crash if used uninitialized */ 346 347 ifp->if_link_state = LINK_STATE_UNKNOWN; 348 349 /* Announce the interface. */ 350 rt_ifannouncemsg(ifp, IFAN_ARRIVAL); 351 } 352 353 /* 354 * Deactivate an interface. This points all of the procedure 355 * handles at error stubs. May be called from interrupt context. 356 */ 357 void 358 if_deactivate(ifp) 359 struct ifnet *ifp; 360 { 361 int s; 362 363 s = splimp(); 364 365 ifp->if_output = if_nulloutput; 366 ifp->if_input = if_nullinput; 367 ifp->if_start = if_nullstart; 368 ifp->if_ioctl = if_nullioctl; 369 ifp->if_init = if_nullinit; 370 ifp->if_stop = if_nullstop; 371 ifp->if_watchdog = if_nullwatchdog; 372 ifp->if_drain = if_nulldrain; 373 374 /* No more packets may be enqueued. */ 375 ifp->if_snd.ifq_maxlen = 0; 376 377 splx(s); 378 } 379 380 /* 381 * Detach an interface from the list of "active" interfaces, 382 * freeing any resources as we go along. 383 * 384 * NOTE: This routine must be called with a valid thread context, 385 * as it may block. 386 */ 387 void 388 if_detach(ifp) 389 struct ifnet *ifp; 390 { 391 struct socket so; 392 struct ifaddr *ifa; 393 #ifdef IFAREF_DEBUG 394 struct ifaddr *last_ifa = NULL; 395 #endif 396 struct domain *dp; 397 struct protosw *pr; 398 struct radix_node_head *rnh; 399 int s, i, family, purged; 400 401 /* 402 * XXX It's kind of lame that we have to have the 403 * XXX socket structure... 404 */ 405 memset(&so, 0, sizeof(so)); 406 407 s = splimp(); 408 409 /* 410 * Do an if_down() to give protocols a chance to do something. 411 */ 412 if_down(ifp); 413 414 /* 415 * Rip all the addresses off the interface. This should make 416 * all of the routes go away. 417 */ 418 while ((ifa = TAILQ_FIRST(&ifp->if_addrlist)) != NULL) { 419 family = ifa->ifa_addr->sa_family; 420 #ifdef IFAREF_DEBUG 421 printf("if_detach: ifaddr %p, family %d, refcnt %d\n", 422 ifa, family, ifa->ifa_refcnt); 423 if (last_ifa != NULL && ifa == last_ifa) 424 panic("if_detach: loop detected"); 425 last_ifa = ifa; 426 #endif 427 if (family == AF_LINK) { 428 rtinit(ifa, RTM_DELETE, 0); 429 TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list); 430 IFAFREE(ifa); 431 } else { 432 dp = pffinddomain(family); 433 #ifdef DIAGNOSTIC 434 if (dp == NULL) 435 panic("if_detach: no domain for AF %d\n", 436 family); 437 #endif 438 purged = 0; 439 for (pr = dp->dom_protosw; 440 pr < dp->dom_protoswNPROTOSW; pr++) { 441 so.so_proto = pr; 442 if (pr->pr_usrreq != NULL) { 443 (void) (*pr->pr_usrreq)(&so, 444 PRU_PURGEIF, NULL, NULL, 445 (struct mbuf *) ifp, curproc); 446 purged = 1; 447 } 448 } 449 if (purged == 0) { 450 /* 451 * XXX What's really the best thing to do 452 * XXX here? --thorpej@netbsd.org 453 */ 454 printf("if_detach: WARNING: AF %d not purged\n", 455 family); 456 } 457 } 458 } 459 460 /* Walk the routing table looking for straglers. */ 461 for (i = 0; i <= AF_MAX; i++) { 462 if ((rnh = rt_tables[i]) != NULL) 463 (void) (*rnh->rnh_walktree)(rnh, if_rt_walktree, ifp); 464 } 465 466 IFAFREE(ifnet_addrs[ifp->if_index]); 467 ifnet_addrs[ifp->if_index] = NULL; 468 469 /* Announce that the interface is gone. */ 470 rt_ifannouncemsg(ifp, IFAN_DEPARTURE); 471 472 TAILQ_REMOVE(&ifnet, ifp, if_list); 473 474 splx(s); 475 } 476 477 /* 478 * Callback for a radix tree walk to delete all references to an 479 * ifnet. 480 */ 481 int 482 if_rt_walktree(rn, v) 483 struct radix_node *rn; 484 void *v; 485 { 486 struct ifnet *ifp = (struct ifnet *)v; 487 struct rtentry *rt = (struct rtentry *)rn; 488 int error; 489 490 if (rt->rt_ifp == ifp) { 491 /* Delete the entry. */ 492 error = rtrequest(RTM_DELETE, rt_key(rt), rt->rt_gateway, 493 rt_mask(rt), rt->rt_flags, NULL); 494 if (error) 495 printf("%s: warning: unable to delete rtentry @ %p, " 496 "error = %d\n", ifp->if_xname, rt, error); 497 } 498 return (0); 499 } 500 501 /* 502 * Create a clone network interface. 503 */ 504 int 505 if_clone_create(name) 506 const char *name; 507 { 508 struct if_clone *ifc; 509 int unit; 510 511 ifc = if_clone_lookup(name, &unit); 512 if (ifc == NULL) 513 return (EINVAL); 514 515 if (ifunit(name) != NULL) 516 return (EEXIST); 517 518 return ((*ifc->ifc_create)(ifc, unit)); 519 } 520 521 /* 522 * Destroy a clone network interface. 523 */ 524 int 525 if_clone_destroy(name) 526 const char *name; 527 { 528 struct if_clone *ifc; 529 struct ifnet *ifp; 530 531 ifc = if_clone_lookup(name, NULL); 532 if (ifc == NULL) 533 return (EINVAL); 534 535 ifp = ifunit(name); 536 if (ifp == NULL) 537 return (ENXIO); 538 539 if (ifc->ifc_destroy == NULL) 540 return (EOPNOTSUPP); 541 542 (*ifc->ifc_destroy)(ifp); 543 return (0); 544 } 545 546 /* 547 * Look up a network interface cloner. 548 */ 549 struct if_clone * 550 if_clone_lookup(name, unitp) 551 const char *name; 552 int *unitp; 553 { 554 struct if_clone *ifc; 555 const char *cp; 556 int i; 557 558 for (ifc = LIST_FIRST(&if_cloners); ifc != NULL;) { 559 for (cp = name, i = 0; i < ifc->ifc_namelen; i++, cp++) { 560 if (ifc->ifc_name[i] != *cp) 561 goto next_ifc; 562 } 563 goto found_name; 564 next_ifc: 565 ifc = LIST_NEXT(ifc, ifc_list); 566 } 567 568 /* No match. */ 569 return (NULL); 570 571 found_name: 572 for (i = 0; *cp != '\0'; cp++) { 573 if (*cp < '0' || *cp > '9') { 574 /* Bogus unit number. */ 575 return (NULL); 576 } 577 i = (i * 10) + (*cp - '0'); 578 } 579 580 if (unitp != NULL) 581 *unitp = i; 582 return (ifc); 583 } 584 585 /* 586 * Register a network interface cloner. 587 */ 588 void 589 if_clone_attach(ifc) 590 struct if_clone *ifc; 591 { 592 593 LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list); 594 if_cloners_count++; 595 } 596 597 /* 598 * Unregister a network interface cloner. 599 */ 600 void 601 if_clone_detach(ifc) 602 struct if_clone *ifc; 603 { 604 605 LIST_REMOVE(ifc, ifc_list); 606 if_cloners_count--; 607 } 608 609 /* 610 * Provide list of interface cloners to userspace. 611 */ 612 int 613 if_clone_list(ifcr) 614 struct if_clonereq *ifcr; 615 { 616 char outbuf[IFNAMSIZ], *dst; 617 struct if_clone *ifc; 618 int count, error = 0; 619 620 ifcr->ifcr_total = if_cloners_count; 621 if ((dst = ifcr->ifcr_buffer) == NULL) { 622 /* Just asking how many there are. */ 623 return (0); 624 } 625 626 if (ifcr->ifcr_count < 0) 627 return (EINVAL); 628 629 count = (if_cloners_count < ifcr->ifcr_count) ? 630 if_cloners_count : ifcr->ifcr_count; 631 632 for (ifc = LIST_FIRST(&if_cloners); ifc != NULL && count != 0; 633 ifc = LIST_NEXT(ifc, ifc_list), count--, dst += IFNAMSIZ) { 634 strncpy(outbuf, ifc->ifc_name, IFNAMSIZ); 635 outbuf[IFNAMSIZ - 1] = '\0'; /* sanity */ 636 error = copyout(outbuf, dst, IFNAMSIZ); 637 if (error) 638 break; 639 } 640 641 return (error); 642 } 643 644 /* 645 * Locate an interface based on a complete address. 646 */ 647 /*ARGSUSED*/ 648 struct ifaddr * 649 ifa_ifwithaddr(addr) 650 struct sockaddr *addr; 651 { 652 struct ifnet *ifp; 653 struct ifaddr *ifa; 654 655 #define equal(a1, a2) \ 656 (bcmp((caddr_t)(a1), (caddr_t)(a2), ((struct sockaddr *)(a1))->sa_len) == 0) 657 658 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL; 659 ifp = TAILQ_NEXT(ifp, if_list)) { 660 if (ifp->if_output == if_nulloutput) 661 continue; 662 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; 663 ifa = TAILQ_NEXT(ifa, ifa_list)) { 664 if (ifa->ifa_addr->sa_family != addr->sa_family) 665 continue; 666 if (equal(addr, ifa->ifa_addr)) 667 return (ifa); 668 if ((ifp->if_flags & IFF_BROADCAST) && 669 ifa->ifa_broadaddr && 670 /* IP6 doesn't have broadcast */ 671 ifa->ifa_broadaddr->sa_len != 0 && 672 equal(ifa->ifa_broadaddr, addr)) 673 return (ifa); 674 } 675 } 676 return (NULL); 677 } 678 679 /* 680 * Locate the point to point interface with a given destination address. 681 */ 682 /*ARGSUSED*/ 683 struct ifaddr * 684 ifa_ifwithdstaddr(addr) 685 struct sockaddr *addr; 686 { 687 struct ifnet *ifp; 688 struct ifaddr *ifa; 689 690 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL; 691 ifp = TAILQ_NEXT(ifp, if_list)) { 692 if (ifp->if_output == if_nulloutput) 693 continue; 694 if (ifp->if_flags & IFF_POINTOPOINT) { 695 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; 696 ifa = TAILQ_NEXT(ifa, ifa_list)) { 697 if (ifa->ifa_addr->sa_family != 698 addr->sa_family || 699 ifa->ifa_dstaddr == NULL) 700 continue; 701 if (equal(addr, ifa->ifa_dstaddr)) 702 return (ifa); 703 } 704 } 705 } 706 return (NULL); 707 } 708 709 /* 710 * Find an interface on a specific network. If many, choice 711 * is most specific found. 712 */ 713 struct ifaddr * 714 ifa_ifwithnet(addr) 715 struct sockaddr *addr; 716 { 717 struct ifnet *ifp; 718 struct ifaddr *ifa; 719 struct sockaddr_dl *sdl; 720 struct ifaddr *ifa_maybe = 0; 721 u_int af = addr->sa_family; 722 char *addr_data = addr->sa_data, *cplim; 723 724 if (af == AF_LINK) { 725 sdl = (struct sockaddr_dl *)addr; 726 if (sdl->sdl_index && sdl->sdl_index <= if_index && 727 ifindex2ifnet[sdl->sdl_index]->if_output != if_nulloutput) 728 return (ifnet_addrs[sdl->sdl_index]); 729 } 730 #ifdef NETATALK 731 if (af == AF_APPLETALK) { 732 struct sockaddr_at *sat, *sat2; 733 sat = (struct sockaddr_at *)addr; 734 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL; 735 ifp = TAILQ_NEXT(ifp, if_list)) { 736 if (ifp->if_output == if_nulloutput) 737 continue; 738 ifa = at_ifawithnet((struct sockaddr_at *)addr, ifp); 739 if (ifa == NULL) 740 continue; 741 sat2 = (struct sockaddr_at *)ifa->ifa_addr; 742 if (sat2->sat_addr.s_net == sat->sat_addr.s_net) 743 return (ifa); /* exact match */ 744 if (ifa_maybe == NULL) { 745 /* else keep the if with the rigth range */ 746 ifa_maybe = ifa; 747 } 748 } 749 return (ifa_maybe); 750 } 751 #endif 752 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL; 753 ifp = TAILQ_NEXT(ifp, if_list)) { 754 if (ifp->if_output == if_nulloutput) 755 continue; 756 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; 757 ifa = TAILQ_NEXT(ifa, ifa_list)) { 758 char *cp, *cp2, *cp3; 759 760 if (ifa->ifa_addr->sa_family != af || 761 ifa->ifa_netmask == 0) 762 next: continue; 763 cp = addr_data; 764 cp2 = ifa->ifa_addr->sa_data; 765 cp3 = ifa->ifa_netmask->sa_data; 766 cplim = (char *)ifa->ifa_netmask + 767 ifa->ifa_netmask->sa_len; 768 while (cp3 < cplim) { 769 if ((*cp++ ^ *cp2++) & *cp3++) { 770 /* want to continue for() loop */ 771 goto next; 772 } 773 } 774 if (ifa_maybe == 0 || 775 rn_refines((caddr_t)ifa->ifa_netmask, 776 (caddr_t)ifa_maybe->ifa_netmask)) 777 ifa_maybe = ifa; 778 } 779 } 780 return (ifa_maybe); 781 } 782 783 /* 784 * Find the interface of the addresss. 785 */ 786 struct ifaddr * 787 ifa_ifwithladdr(addr) 788 struct sockaddr *addr; 789 { 790 struct ifaddr *ia; 791 792 if ((ia = ifa_ifwithaddr(addr)) || (ia = ifa_ifwithdstaddr(addr)) || 793 (ia = ifa_ifwithnet(addr))) 794 return (ia); 795 return (NULL); 796 } 797 798 /* 799 * Find an interface using a specific address family 800 */ 801 struct ifaddr * 802 ifa_ifwithaf(af) 803 int af; 804 { 805 struct ifnet *ifp; 806 struct ifaddr *ifa; 807 808 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL; 809 ifp = TAILQ_NEXT(ifp, if_list)) { 810 if (ifp->if_output == if_nulloutput) 811 continue; 812 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; 813 ifa = TAILQ_NEXT(ifa, ifa_list)) { 814 if (ifa->ifa_addr->sa_family == af) 815 return (ifa); 816 } 817 } 818 return (NULL); 819 } 820 821 /* 822 * Find an interface address specific to an interface best matching 823 * a given address. 824 */ 825 struct ifaddr * 826 ifaof_ifpforaddr(addr, ifp) 827 struct sockaddr *addr; 828 struct ifnet *ifp; 829 { 830 struct ifaddr *ifa; 831 char *cp, *cp2, *cp3; 832 char *cplim; 833 struct ifaddr *ifa_maybe = 0; 834 u_int af = addr->sa_family; 835 836 if (ifp->if_output == if_nulloutput) 837 return (NULL); 838 839 if (af >= AF_MAX) 840 return (NULL); 841 842 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; 843 ifa = TAILQ_NEXT(ifa, ifa_list)) { 844 if (ifa->ifa_addr->sa_family != af) 845 continue; 846 ifa_maybe = ifa; 847 if (ifa->ifa_netmask == 0) { 848 if (equal(addr, ifa->ifa_addr) || 849 (ifa->ifa_dstaddr && 850 equal(addr, ifa->ifa_dstaddr))) 851 return (ifa); 852 continue; 853 } 854 cp = addr->sa_data; 855 cp2 = ifa->ifa_addr->sa_data; 856 cp3 = ifa->ifa_netmask->sa_data; 857 cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask; 858 for (; cp3 < cplim; cp3++) { 859 if ((*cp++ ^ *cp2++) & *cp3) 860 break; 861 } 862 if (cp3 == cplim) 863 return (ifa); 864 } 865 return (ifa_maybe); 866 } 867 868 /* 869 * Default action when installing a route with a Link Level gateway. 870 * Lookup an appropriate real ifa to point to. 871 * This should be moved to /sys/net/link.c eventually. 872 */ 873 void 874 link_rtrequest(cmd, rt, sa) 875 int cmd; 876 struct rtentry *rt; 877 struct sockaddr *sa; 878 { 879 struct ifaddr *ifa; 880 struct sockaddr *dst; 881 struct ifnet *ifp; 882 883 if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) || 884 ((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0)) 885 return; 886 if ((ifa = ifaof_ifpforaddr(dst, ifp)) != NULL) { 887 IFAFREE(rt->rt_ifa); 888 rt->rt_ifa = ifa; 889 IFAREF(ifa); 890 if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest) 891 ifa->ifa_rtrequest(cmd, rt, sa); 892 } 893 } 894 895 /* 896 * Mark an interface down and notify protocols of 897 * the transition. 898 * NOTE: must be called at splsoftnet or equivalent. 899 */ 900 void 901 if_down(ifp) 902 struct ifnet *ifp; 903 { 904 struct ifaddr *ifa; 905 906 ifp->if_flags &= ~IFF_UP; 907 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; 908 ifa = TAILQ_NEXT(ifa, ifa_list)) 909 pfctlinput(PRC_IFDOWN, ifa->ifa_addr); 910 IFQ_PURGE(&ifp->if_snd); 911 rt_ifmsg(ifp); 912 } 913 914 /* 915 * Mark an interface up and notify protocols of 916 * the transition. 917 * NOTE: must be called at splsoftnet or equivalent. 918 */ 919 void 920 if_up(ifp) 921 struct ifnet *ifp; 922 { 923 #ifdef notyet 924 struct ifaddr *ifa; 925 #endif 926 927 ifp->if_flags |= IFF_UP; 928 #ifdef notyet 929 /* this has no effect on IP, and will kill all ISO connections XXX */ 930 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; 931 ifa = TAILQ_NEXT(ifa, ifa_list)) 932 pfctlinput(PRC_IFUP, ifa->ifa_addr); 933 #endif 934 rt_ifmsg(ifp); 935 #ifdef INET6 936 in6_if_up(ifp); 937 #endif 938 } 939 940 /* 941 * Handle interface watchdog timer routines. Called 942 * from softclock, we decrement timers (if set) and 943 * call the appropriate interface routine on expiration. 944 */ 945 void 946 if_slowtimo(arg) 947 void *arg; 948 { 949 struct ifnet *ifp; 950 int s = splimp(); 951 952 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL; 953 ifp = TAILQ_NEXT(ifp, if_list)) { 954 if (ifp->if_timer == 0 || --ifp->if_timer) 955 continue; 956 if (ifp->if_watchdog) 957 (*ifp->if_watchdog)(ifp); 958 } 959 splx(s); 960 callout_reset(&if_slowtimo_ch, hz / IFNET_SLOWHZ, 961 if_slowtimo, NULL); 962 } 963 964 /* 965 * Set/clear promiscuous mode on interface ifp based on the truth value 966 * of pswitch. The calls are reference counted so that only the first 967 * "on" request actually has an effect, as does the final "off" request. 968 * Results are undefined if the "off" and "on" requests are not matched. 969 */ 970 int 971 ifpromisc(ifp, pswitch) 972 struct ifnet *ifp; 973 int pswitch; 974 { 975 int pcount, ret; 976 short flags; 977 struct ifreq ifr; 978 979 pcount = ifp->if_pcount; 980 flags = ifp->if_flags; 981 if (pswitch) { 982 /* 983 * Allow the device to be "placed" into promiscuous 984 * mode even if it is not configured up. It will 985 * consult IFF_PROMISC when it is is brought up. 986 */ 987 if (ifp->if_pcount++ != 0) 988 return (0); 989 ifp->if_flags |= IFF_PROMISC; 990 if ((ifp->if_flags & IFF_UP) == 0) 991 return (0); 992 } else { 993 if (--ifp->if_pcount > 0) 994 return (0); 995 ifp->if_flags &= ~IFF_PROMISC; 996 /* 997 * If the device is not configured up, we should not need to 998 * turn off promiscuous mode (device should have turned it 999 * off when interface went down; and will look at IFF_PROMISC 1000 * again next time interface comes up). 1001 */ 1002 if ((ifp->if_flags & IFF_UP) == 0) 1003 return (0); 1004 } 1005 memset(&ifr, 0, sizeof(ifr)); 1006 ifr.ifr_flags = ifp->if_flags; 1007 ret = (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t) &ifr); 1008 /* Restore interface state if not successful. */ 1009 if (ret != 0) { 1010 ifp->if_pcount = pcount; 1011 ifp->if_flags = flags; 1012 } 1013 return (ret); 1014 } 1015 1016 /* 1017 * Map interface name to 1018 * interface structure pointer. 1019 */ 1020 struct ifnet * 1021 ifunit(name) 1022 const char *name; 1023 { 1024 struct ifnet *ifp; 1025 1026 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL; 1027 ifp = TAILQ_NEXT(ifp, if_list)) { 1028 if (ifp->if_output == if_nulloutput) 1029 continue; 1030 if (strcmp(ifp->if_xname, name) == 0) 1031 return (ifp); 1032 } 1033 return (NULL); 1034 } 1035 1036 /* 1037 * Interface ioctls. 1038 */ 1039 int 1040 ifioctl(so, cmd, data, p) 1041 struct socket *so; 1042 u_long cmd; 1043 caddr_t data; 1044 struct proc *p; 1045 { 1046 struct ifnet *ifp; 1047 struct ifreq *ifr; 1048 int error = 0; 1049 short oif_flags; 1050 1051 switch (cmd) { 1052 1053 case SIOCGIFCONF: 1054 case OSIOCGIFCONF: 1055 return (ifconf(cmd, data)); 1056 } 1057 ifr = (struct ifreq *)data; 1058 1059 switch (cmd) { 1060 case SIOCIFCREATE: 1061 case SIOCIFDESTROY: 1062 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 1063 return (error); 1064 return ((cmd == SIOCIFCREATE) ? 1065 if_clone_create(ifr->ifr_name) : 1066 if_clone_destroy(ifr->ifr_name)); 1067 1068 case SIOCIFGCLONERS: 1069 return (if_clone_list((struct if_clonereq *)data)); 1070 } 1071 1072 ifp = ifunit(ifr->ifr_name); 1073 if (ifp == 0) 1074 return (ENXIO); 1075 oif_flags = ifp->if_flags; 1076 switch (cmd) { 1077 1078 case SIOCGIFFLAGS: 1079 ifr->ifr_flags = ifp->if_flags; 1080 break; 1081 1082 case SIOCGIFMETRIC: 1083 ifr->ifr_metric = ifp->if_metric; 1084 break; 1085 1086 case SIOCGIFMTU: 1087 ifr->ifr_mtu = ifp->if_mtu; 1088 break; 1089 1090 case SIOCGIFDLT: 1091 ifr->ifr_dlt = ifp->if_dlt; 1092 break; 1093 1094 case SIOCSIFFLAGS: 1095 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 1096 return (error); 1097 if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) { 1098 int s = splimp(); 1099 if_down(ifp); 1100 splx(s); 1101 } 1102 if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) { 1103 int s = splimp(); 1104 if_up(ifp); 1105 splx(s); 1106 } 1107 ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) | 1108 (ifr->ifr_flags &~ IFF_CANTCHANGE); 1109 if (ifp->if_ioctl) 1110 (void) (*ifp->if_ioctl)(ifp, cmd, data); 1111 break; 1112 1113 case SIOCSIFMETRIC: 1114 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 1115 return (error); 1116 ifp->if_metric = ifr->ifr_metric; 1117 break; 1118 1119 case SIOCSIFMTU: 1120 { 1121 u_long oldmtu = ifp->if_mtu; 1122 1123 error = suser(p->p_ucred, &p->p_acflag); 1124 if (error) 1125 return (error); 1126 if (ifp->if_ioctl == NULL) 1127 return (EOPNOTSUPP); 1128 error = (*ifp->if_ioctl)(ifp, cmd, data); 1129 1130 /* 1131 * If the link MTU changed, do network layer specific procedure. 1132 */ 1133 if (ifp->if_mtu != oldmtu) { 1134 #ifdef INET6 1135 nd6_setmtu(ifp); 1136 #endif 1137 } 1138 break; 1139 } 1140 case SIOCSIFPHYADDR: 1141 case SIOCDIFPHYADDR: 1142 #ifdef INET6 1143 case SIOCSIFPHYADDR_IN6: 1144 #endif 1145 case SIOCADDMULTI: 1146 case SIOCDELMULTI: 1147 case SIOCSIFMEDIA: 1148 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 1149 return (error); 1150 /* FALLTHROUGH */ 1151 case SIOCGIFPSRCADDR: 1152 case SIOCGIFPDSTADDR: 1153 case SIOCGIFMEDIA: 1154 if (ifp->if_ioctl == 0) 1155 return (EOPNOTSUPP); 1156 error = (*ifp->if_ioctl)(ifp, cmd, data); 1157 break; 1158 1159 case SIOCSDRVSPEC: 1160 case SIOCS80211NWID: 1161 case SIOCS80211NWKEY: 1162 case SIOCS80211POWER: 1163 /* XXX: need to pass proc pointer through to driver... */ 1164 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 1165 return (error); 1166 /* FALLTHROUGH */ 1167 default: 1168 if (so->so_proto == 0) 1169 return (EOPNOTSUPP); 1170 #if !defined(COMPAT_43) && !defined(COMPAT_LINUX) && !defined(COMPAT_SVR4) 1171 error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 1172 (struct mbuf *)cmd, (struct mbuf *)data, 1173 (struct mbuf *)ifp, p)); 1174 #else 1175 { 1176 int ocmd = cmd; 1177 1178 switch (cmd) { 1179 1180 case SIOCSIFADDR: 1181 case SIOCSIFDSTADDR: 1182 case SIOCSIFBRDADDR: 1183 case SIOCSIFNETMASK: 1184 #if BYTE_ORDER != BIG_ENDIAN 1185 if (ifr->ifr_addr.sa_family == 0 && 1186 ifr->ifr_addr.sa_len < 16) { 1187 ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len; 1188 ifr->ifr_addr.sa_len = 16; 1189 } 1190 #else 1191 if (ifr->ifr_addr.sa_len == 0) 1192 ifr->ifr_addr.sa_len = 16; 1193 #endif 1194 break; 1195 1196 case OSIOCGIFADDR: 1197 cmd = SIOCGIFADDR; 1198 break; 1199 1200 case OSIOCGIFDSTADDR: 1201 cmd = SIOCGIFDSTADDR; 1202 break; 1203 1204 case OSIOCGIFBRDADDR: 1205 cmd = SIOCGIFBRDADDR; 1206 break; 1207 1208 case OSIOCGIFNETMASK: 1209 cmd = SIOCGIFNETMASK; 1210 } 1211 1212 error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 1213 (struct mbuf *)cmd, (struct mbuf *)data, 1214 (struct mbuf *)ifp, p)); 1215 1216 switch (ocmd) { 1217 case OSIOCGIFADDR: 1218 case OSIOCGIFDSTADDR: 1219 case OSIOCGIFBRDADDR: 1220 case OSIOCGIFNETMASK: 1221 *(u_int16_t *)&ifr->ifr_addr = ifr->ifr_addr.sa_family; 1222 } 1223 } 1224 #endif /* COMPAT_43 */ 1225 break; 1226 } 1227 1228 if (((oif_flags ^ ifp->if_flags) & IFF_UP) != 0) { 1229 #ifdef INET6 1230 if ((ifp->if_flags & IFF_UP) != 0) { 1231 int s = splimp(); 1232 in6_if_up(ifp); 1233 splx(s); 1234 } 1235 #endif 1236 } 1237 1238 return (error); 1239 } 1240 1241 /* 1242 * Return interface configuration 1243 * of system. List may be used 1244 * in later ioctl's (above) to get 1245 * other information. 1246 */ 1247 /*ARGSUSED*/ 1248 int 1249 ifconf(cmd, data) 1250 u_long cmd; 1251 caddr_t data; 1252 { 1253 struct ifconf *ifc = (struct ifconf *)data; 1254 struct ifnet *ifp; 1255 struct ifaddr *ifa; 1256 struct ifreq ifr, *ifrp; 1257 int space = ifc->ifc_len, error = 0; 1258 1259 ifrp = ifc->ifc_req; 1260 for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next) { 1261 bcopy(ifp->if_xname, ifr.ifr_name, IFNAMSIZ); 1262 if ((ifa = ifp->if_addrlist.tqh_first) == 0) { 1263 bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr)); 1264 if (space >= (int)sizeof (ifr)) { 1265 error = copyout((caddr_t)&ifr, (caddr_t)ifrp, 1266 sizeof(ifr)); 1267 if (error) 1268 break; 1269 } 1270 space -= sizeof (ifr), ifrp++; 1271 } else 1272 for (; ifa != 0; ifa = ifa->ifa_list.tqe_next) { 1273 struct sockaddr *sa = ifa->ifa_addr; 1274 #if defined(COMPAT_43) || defined(COMPAT_LINUX) || defined(COMPAT_SVR4) 1275 if (cmd == OSIOCGIFCONF) { 1276 struct osockaddr *osa = 1277 (struct osockaddr *)&ifr.ifr_addr; 1278 ifr.ifr_addr = *sa; 1279 osa->sa_family = sa->sa_family; 1280 if (space >= (int)sizeof (ifr)) { 1281 error = copyout((caddr_t)&ifr, 1282 (caddr_t)ifrp, 1283 sizeof (ifr)); 1284 ifrp++; 1285 } 1286 } else 1287 #endif 1288 if (sa->sa_len <= sizeof(*sa)) { 1289 ifr.ifr_addr = *sa; 1290 if (space >= (int)sizeof (ifr)) { 1291 error = copyout((caddr_t)&ifr, 1292 (caddr_t)ifrp, 1293 sizeof (ifr)); 1294 ifrp++; 1295 } 1296 } else { 1297 space -= sa->sa_len - sizeof(*sa); 1298 if (space >= (int)sizeof (ifr)) { 1299 error = copyout((caddr_t)&ifr, 1300 (caddr_t)ifrp, 1301 sizeof (ifr.ifr_name)); 1302 if (error == 0) { 1303 error = copyout((caddr_t)sa, 1304 (caddr_t)&ifrp->ifr_addr, 1305 sa->sa_len); 1306 } 1307 ifrp = (struct ifreq *) 1308 (sa->sa_len + 1309 (caddr_t)&ifrp->ifr_addr); 1310 } 1311 } 1312 if (error) 1313 break; 1314 space -= sizeof (ifr); 1315 } 1316 } 1317 ifc->ifc_len -= space; 1318 return (error); 1319 } 1320