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