1 /* $NetBSD: if.c,v 1.96 2001/08/02 01:42:38 itojun Exp $ */ 2 3 /*- 4 * Copyright (c) 1999, 2000, 2001 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 #include "opt_pfil_hooks.h" 110 111 #include <sys/param.h> 112 #include <sys/mbuf.h> 113 #include <sys/systm.h> 114 #include <sys/callout.h> 115 #include <sys/proc.h> 116 #include <sys/socket.h> 117 #include <sys/socketvar.h> 118 #include <sys/domain.h> 119 #include <sys/protosw.h> 120 #include <sys/kernel.h> 121 #include <sys/ioctl.h> 122 123 #include <net/if.h> 124 #include <net/if_dl.h> 125 #include <net/if_ether.h> 126 #include <net/if_ieee80211.h> 127 #include <net/if_types.h> 128 #include <net/radix.h> 129 #include <net/route.h> 130 #include <net/netisr.h> 131 #ifdef NETATALK 132 #include <netatalk/at_extern.h> 133 #include <netatalk/at.h> 134 #endif 135 136 #ifdef INET6 137 /*XXX*/ 138 #include <netinet/in.h> 139 #include <netinet6/in6_var.h> 140 #endif 141 142 int ifqmaxlen = IFQ_MAXLEN; 143 struct callout if_slowtimo_ch; 144 145 #ifdef INET6 146 /* 147 * XXX: declare here to avoid to include many inet6 related files.. 148 * should be more generalized? 149 */ 150 extern void nd6_setmtu __P((struct ifnet *)); 151 #endif 152 153 int if_rt_walktree __P((struct radix_node *, void *)); 154 155 struct if_clone *if_clone_lookup __P((const char *, int *)); 156 int if_clone_list __P((struct if_clonereq *)); 157 158 LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners); 159 int if_cloners_count; 160 161 static void if_detach_queues __P((struct ifnet *, struct ifqueue *)); 162 163 /* 164 * Network interface utility routines. 165 * 166 * Routines with ifa_ifwith* names take sockaddr *'s as 167 * parameters. 168 */ 169 void 170 ifinit() 171 { 172 173 callout_init(&if_slowtimo_ch); 174 if_slowtimo(NULL); 175 } 176 177 /* 178 * Null routines used while an interface is going away. These routines 179 * just return an error. 180 */ 181 182 int 183 if_nulloutput(ifp, m, so, rt) 184 struct ifnet *ifp; 185 struct mbuf *m; 186 struct sockaddr *so; 187 struct rtentry *rt; 188 { 189 190 return (ENXIO); 191 } 192 193 void 194 if_nullinput(ifp, m) 195 struct ifnet *ifp; 196 struct mbuf *m; 197 { 198 199 /* Nothing. */ 200 } 201 202 void 203 if_nullstart(ifp) 204 struct ifnet *ifp; 205 { 206 207 /* Nothing. */ 208 } 209 210 int 211 if_nullioctl(ifp, cmd, data) 212 struct ifnet *ifp; 213 u_long cmd; 214 caddr_t data; 215 { 216 217 return (ENXIO); 218 } 219 220 int 221 if_nullinit(ifp) 222 struct ifnet *ifp; 223 { 224 225 return (ENXIO); 226 } 227 228 void 229 if_nullstop(ifp, disable) 230 struct ifnet *ifp; 231 int disable; 232 { 233 234 /* Nothing. */ 235 } 236 237 void 238 if_nullwatchdog(ifp) 239 struct ifnet *ifp; 240 { 241 242 /* Nothing. */ 243 } 244 245 void 246 if_nulldrain(ifp) 247 struct ifnet *ifp; 248 { 249 250 /* Nothing. */ 251 } 252 253 int if_index = 0; 254 struct ifaddr **ifnet_addrs = NULL; 255 struct ifnet **ifindex2ifnet = NULL; 256 257 /* 258 * Allocate the link level name for the specified interface. This 259 * is an attachment helper. It must be called after ifp->if_addrlen 260 * is initialized, which may not be the case when if_attach() is 261 * called. 262 */ 263 void 264 if_alloc_sadl(struct ifnet *ifp) 265 { 266 unsigned socksize, ifasize; 267 int namelen, masklen; 268 struct sockaddr_dl *sdl; 269 struct ifaddr *ifa; 270 271 /* 272 * If the interface already has a link name, release it 273 * now. This is useful for interfaces that can change 274 * link types, and thus switch link names often. 275 */ 276 if (ifp->if_sadl != NULL) 277 if_free_sadl(ifp); 278 279 namelen = strlen(ifp->if_xname); 280 masklen = offsetof(struct sockaddr_dl, sdl_data[0]) + namelen; 281 socksize = masklen + ifp->if_addrlen; 282 #define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1))) 283 if (socksize < sizeof(*sdl)) 284 socksize = sizeof(*sdl); 285 socksize = ROUNDUP(socksize); 286 ifasize = sizeof(*ifa) + 2 * socksize; 287 ifa = (struct ifaddr *)malloc(ifasize, M_IFADDR, M_WAITOK); 288 memset((caddr_t)ifa, 0, ifasize); 289 sdl = (struct sockaddr_dl *)(ifa + 1); 290 sdl->sdl_len = socksize; 291 sdl->sdl_family = AF_LINK; 292 bcopy(ifp->if_xname, sdl->sdl_data, namelen); 293 sdl->sdl_nlen = namelen; 294 sdl->sdl_alen = ifp->if_addrlen; 295 sdl->sdl_index = ifp->if_index; 296 sdl->sdl_type = ifp->if_type; 297 ifnet_addrs[ifp->if_index] = ifa; 298 IFAREF(ifa); 299 ifa->ifa_ifp = ifp; 300 ifa->ifa_rtrequest = link_rtrequest; 301 TAILQ_INSERT_HEAD(&ifp->if_addrlist, ifa, ifa_list); 302 IFAREF(ifa); 303 ifa->ifa_addr = (struct sockaddr *)sdl; 304 ifp->if_sadl = sdl; 305 sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl); 306 ifa->ifa_netmask = (struct sockaddr *)sdl; 307 sdl->sdl_len = masklen; 308 while (namelen != 0) 309 sdl->sdl_data[--namelen] = 0xff; 310 } 311 312 /* 313 * Free the link level name for the specified interface. This is 314 * a detach helper. This is called from if_detach() or from 315 * link layer type specific detach functions. 316 */ 317 void 318 if_free_sadl(struct ifnet *ifp) 319 { 320 struct ifaddr *ifa; 321 int s; 322 323 ifa = ifnet_addrs[ifp->if_index]; 324 if (ifa == NULL) { 325 KASSERT(ifp->if_sadl == NULL); 326 return; 327 } 328 329 KASSERT(ifp->if_sadl != NULL); 330 331 s = splnet(); 332 rtinit(ifa, RTM_DELETE, 0); 333 TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list); 334 IFAFREE(ifa); 335 336 ifp->if_sadl = NULL; 337 338 ifnet_addrs[ifp->if_index] = NULL; 339 IFAFREE(ifa); 340 splx(s); 341 } 342 343 /* 344 * Attach an interface to the 345 * list of "active" interfaces. 346 */ 347 void 348 if_attach(ifp) 349 struct ifnet *ifp; 350 { 351 static size_t if_indexlim = 8; 352 353 if (if_index == 0) 354 TAILQ_INIT(&ifnet); 355 TAILQ_INIT(&ifp->if_addrlist); 356 TAILQ_INSERT_TAIL(&ifnet, ifp, if_list); 357 ifp->if_index = ++if_index; 358 359 /* 360 * We have some arrays that should be indexed by if_index. 361 * since if_index will grow dynamically, they should grow too. 362 * struct ifadd **ifnet_addrs 363 * struct ifnet **ifindex2ifnet 364 */ 365 if (ifnet_addrs == 0 || ifindex2ifnet == 0 || 366 ifp->if_index >= if_indexlim) { 367 size_t n; 368 caddr_t q; 369 370 while (ifp->if_index >= if_indexlim) 371 if_indexlim <<= 1; 372 373 /* grow ifnet_addrs */ 374 n = if_indexlim * sizeof(struct ifaddr *); 375 q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK); 376 memset(q, 0, n); 377 if (ifnet_addrs) { 378 bcopy((caddr_t)ifnet_addrs, q, n/2); 379 free((caddr_t)ifnet_addrs, M_IFADDR); 380 } 381 ifnet_addrs = (struct ifaddr **)q; 382 383 /* grow ifindex2ifnet */ 384 n = if_indexlim * sizeof(struct ifnet *); 385 q = (caddr_t)malloc(n, M_IFADDR, M_WAITOK); 386 memset(q, 0, n); 387 if (ifindex2ifnet) { 388 bcopy((caddr_t)ifindex2ifnet, q, n/2); 389 free((caddr_t)ifindex2ifnet, M_IFADDR); 390 } 391 ifindex2ifnet = (struct ifnet **)q; 392 } 393 394 ifindex2ifnet[ifp->if_index] = ifp; 395 396 /* 397 * Link level name is allocated later by a separate call to 398 * if_alloc_sadl(). 399 */ 400 401 if (ifp->if_snd.ifq_maxlen == 0) 402 ifp->if_snd.ifq_maxlen = ifqmaxlen; 403 ifp->if_broadcastaddr = 0; /* reliably crash if used uninitialized */ 404 405 ifp->if_link_state = LINK_STATE_UNKNOWN; 406 407 ifp->if_capenable = 0; 408 ifp->if_csum_flags = 0; 409 410 #ifdef ALTQ 411 ifp->if_snd.altq_type = 0; 412 ifp->if_snd.altq_disc = NULL; 413 ifp->if_snd.altq_flags &= ALTQF_CANTCHANGE; 414 ifp->if_snd.altq_tbr = NULL; 415 ifp->if_snd.altq_ifp = ifp; 416 #endif 417 418 #ifdef PFIL_HOOKS 419 ifp->if_pfil.ph_type = PFIL_TYPE_IFNET; 420 ifp->if_pfil.ph_ifnet = ifp; 421 if (pfil_head_register(&ifp->if_pfil) != 0) 422 printf("%s: WARNING: unable to register pfil hook\n", 423 ifp->if_xname); 424 #endif 425 426 /* Announce the interface. */ 427 rt_ifannouncemsg(ifp, IFAN_ARRIVAL); 428 } 429 430 /* 431 * Deactivate an interface. This points all of the procedure 432 * handles at error stubs. May be called from interrupt context. 433 */ 434 void 435 if_deactivate(ifp) 436 struct ifnet *ifp; 437 { 438 int s; 439 440 s = splnet(); 441 442 ifp->if_output = if_nulloutput; 443 ifp->if_input = if_nullinput; 444 ifp->if_start = if_nullstart; 445 ifp->if_ioctl = if_nullioctl; 446 ifp->if_init = if_nullinit; 447 ifp->if_stop = if_nullstop; 448 ifp->if_watchdog = if_nullwatchdog; 449 ifp->if_drain = if_nulldrain; 450 451 /* No more packets may be enqueued. */ 452 ifp->if_snd.ifq_maxlen = 0; 453 454 splx(s); 455 } 456 457 /* 458 * Detach an interface from the list of "active" interfaces, 459 * freeing any resources as we go along. 460 * 461 * NOTE: This routine must be called with a valid thread context, 462 * as it may block. 463 */ 464 void 465 if_detach(ifp) 466 struct ifnet *ifp; 467 { 468 struct socket so; 469 struct ifaddr *ifa; 470 #ifdef IFAREF_DEBUG 471 struct ifaddr *last_ifa = NULL; 472 #endif 473 struct domain *dp; 474 struct protosw *pr; 475 struct radix_node_head *rnh; 476 int s, i, family, purged; 477 478 /* 479 * XXX It's kind of lame that we have to have the 480 * XXX socket structure... 481 */ 482 memset(&so, 0, sizeof(so)); 483 484 s = splnet(); 485 486 /* 487 * Do an if_down() to give protocols a chance to do something. 488 */ 489 if_down(ifp); 490 491 #ifdef ALTQ 492 if (ALTQ_IS_ENABLED(&ifp->if_snd)) 493 altq_disable(&ifp->if_snd); 494 if (ALTQ_IS_ATTACHED(&ifp->if_snd)) 495 altq_detach(&ifp->if_snd); 496 #endif 497 498 #ifdef PFIL_HOOKS 499 (void) pfil_head_unregister(&ifp->if_pfil); 500 #endif 501 502 if_free_sadl(ifp); 503 504 /* 505 * Rip all the addresses off the interface. This should make 506 * all of the routes go away. 507 */ 508 while ((ifa = TAILQ_FIRST(&ifp->if_addrlist)) != NULL) { 509 family = ifa->ifa_addr->sa_family; 510 #ifdef IFAREF_DEBUG 511 printf("if_detach: ifaddr %p, family %d, refcnt %d\n", 512 ifa, family, ifa->ifa_refcnt); 513 if (last_ifa != NULL && ifa == last_ifa) 514 panic("if_detach: loop detected"); 515 last_ifa = ifa; 516 #endif 517 if (family == AF_LINK) { 518 /* 519 * XXX This case may now be obsolete by 520 * XXX the call to if_free_sadl(). 521 */ 522 rtinit(ifa, RTM_DELETE, 0); 523 TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list); 524 IFAFREE(ifa); 525 } else { 526 dp = pffinddomain(family); 527 #ifdef DIAGNOSTIC 528 if (dp == NULL) 529 panic("if_detach: no domain for AF %d\n", 530 family); 531 #endif 532 purged = 0; 533 for (pr = dp->dom_protosw; 534 pr < dp->dom_protoswNPROTOSW; pr++) { 535 so.so_proto = pr; 536 if (pr->pr_usrreq != NULL) { 537 (void) (*pr->pr_usrreq)(&so, 538 PRU_PURGEIF, NULL, NULL, 539 (struct mbuf *) ifp, curproc); 540 purged = 1; 541 } 542 } 543 if (purged == 0) { 544 /* 545 * XXX What's really the best thing to do 546 * XXX here? --thorpej@netbsd.org 547 */ 548 printf("if_detach: WARNING: AF %d not purged\n", 549 family); 550 } 551 } 552 } 553 554 /* Walk the routing table looking for straglers. */ 555 for (i = 0; i <= AF_MAX; i++) { 556 if ((rnh = rt_tables[i]) != NULL) 557 (void) (*rnh->rnh_walktree)(rnh, if_rt_walktree, ifp); 558 } 559 560 /* Announce that the interface is gone. */ 561 rt_ifannouncemsg(ifp, IFAN_DEPARTURE); 562 563 ifindex2ifnet[ifp->if_index] = NULL; 564 565 TAILQ_REMOVE(&ifnet, ifp, if_list); 566 567 /* 568 * remove packets came from ifp, from software interrupt queues. 569 * net/netisr_dispatch.h is not usable, as some of them use 570 * strange queue names. 571 */ 572 #define IF_DETACH_QUEUES(x) \ 573 do { \ 574 extern struct ifqueue x; \ 575 if_detach_queues(ifp, & x); \ 576 } while (0) 577 #ifdef INET 578 #if NARP > 0 579 IF_DETACH_QUEUES(arpintrq); 580 #endif 581 IF_DETACH_QUEUES(ipintrq); 582 #endif 583 #ifdef INET6 584 IF_DETACH_QUEUES(ip6intrq); 585 #endif 586 #ifdef NETATALK 587 IF_DETACH_QUEUES(atintrq1); 588 IF_DETACH_QUEUES(atintrq2); 589 #endif 590 #ifdef NS 591 IF_DETACH_QUEUES(nsintrq); 592 #endif 593 #ifdef ISO 594 IF_DETACH_QUEUES(clnlintrq); 595 #endif 596 #ifdef CCITT 597 IF_DETACH_QUEUES(llcintrq); 598 IF_DETACH_QUEUES(hdintrq); 599 #endif 600 #ifdef NATM 601 IF_DETACH_QUEUES(natmintrq); 602 #endif 603 #undef IF_DETACH_QUEUES 604 605 splx(s); 606 } 607 608 static void 609 if_detach_queues(ifp, q) 610 struct ifnet *ifp; 611 struct ifqueue *q; 612 { 613 struct mbuf *m, *prev, *next; 614 615 prev = NULL; 616 for (m = q->ifq_head; m; m = next) { 617 next = m->m_nextpkt; 618 #ifdef DIAGNOSTIC 619 if ((m->m_flags & M_PKTHDR) == 0) { 620 prev = m; 621 continue; 622 } 623 #endif 624 if (m->m_pkthdr.rcvif != ifp) { 625 prev = m; 626 continue; 627 } 628 629 if (prev) 630 prev->m_nextpkt = m->m_nextpkt; 631 else 632 q->ifq_head = m->m_nextpkt; 633 if (q->ifq_tail == m) 634 q->ifq_tail = prev; 635 q->ifq_len--; 636 637 m->m_nextpkt = NULL; 638 m_freem(m); 639 IF_DROP(q); 640 } 641 } 642 643 /* 644 * Callback for a radix tree walk to delete all references to an 645 * ifnet. 646 */ 647 int 648 if_rt_walktree(rn, v) 649 struct radix_node *rn; 650 void *v; 651 { 652 struct ifnet *ifp = (struct ifnet *)v; 653 struct rtentry *rt = (struct rtentry *)rn; 654 int error; 655 656 if (rt->rt_ifp == ifp) { 657 /* Delete the entry. */ 658 error = rtrequest(RTM_DELETE, rt_key(rt), rt->rt_gateway, 659 rt_mask(rt), rt->rt_flags, NULL); 660 if (error) 661 printf("%s: warning: unable to delete rtentry @ %p, " 662 "error = %d\n", ifp->if_xname, rt, error); 663 } 664 return (0); 665 } 666 667 /* 668 * Create a clone network interface. 669 */ 670 int 671 if_clone_create(name) 672 const char *name; 673 { 674 struct if_clone *ifc; 675 int unit; 676 677 ifc = if_clone_lookup(name, &unit); 678 if (ifc == NULL) 679 return (EINVAL); 680 681 if (ifunit(name) != NULL) 682 return (EEXIST); 683 684 return ((*ifc->ifc_create)(ifc, unit)); 685 } 686 687 /* 688 * Destroy a clone network interface. 689 */ 690 int 691 if_clone_destroy(name) 692 const char *name; 693 { 694 struct if_clone *ifc; 695 struct ifnet *ifp; 696 697 ifc = if_clone_lookup(name, NULL); 698 if (ifc == NULL) 699 return (EINVAL); 700 701 ifp = ifunit(name); 702 if (ifp == NULL) 703 return (ENXIO); 704 705 if (ifc->ifc_destroy == NULL) 706 return (EOPNOTSUPP); 707 708 (*ifc->ifc_destroy)(ifp); 709 return (0); 710 } 711 712 /* 713 * Look up a network interface cloner. 714 */ 715 struct if_clone * 716 if_clone_lookup(name, unitp) 717 const char *name; 718 int *unitp; 719 { 720 struct if_clone *ifc; 721 const char *cp; 722 int i; 723 724 for (ifc = LIST_FIRST(&if_cloners); ifc != NULL;) { 725 for (cp = name, i = 0; i < ifc->ifc_namelen; i++, cp++) { 726 if (ifc->ifc_name[i] != *cp) 727 goto next_ifc; 728 } 729 goto found_name; 730 next_ifc: 731 ifc = LIST_NEXT(ifc, ifc_list); 732 } 733 734 /* No match. */ 735 return (NULL); 736 737 found_name: 738 for (i = 0; *cp != '\0'; cp++) { 739 if (*cp < '0' || *cp > '9') { 740 /* Bogus unit number. */ 741 return (NULL); 742 } 743 i = (i * 10) + (*cp - '0'); 744 } 745 746 if (unitp != NULL) 747 *unitp = i; 748 return (ifc); 749 } 750 751 /* 752 * Register a network interface cloner. 753 */ 754 void 755 if_clone_attach(ifc) 756 struct if_clone *ifc; 757 { 758 759 LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list); 760 if_cloners_count++; 761 } 762 763 /* 764 * Unregister a network interface cloner. 765 */ 766 void 767 if_clone_detach(ifc) 768 struct if_clone *ifc; 769 { 770 771 LIST_REMOVE(ifc, ifc_list); 772 if_cloners_count--; 773 } 774 775 /* 776 * Provide list of interface cloners to userspace. 777 */ 778 int 779 if_clone_list(ifcr) 780 struct if_clonereq *ifcr; 781 { 782 char outbuf[IFNAMSIZ], *dst; 783 struct if_clone *ifc; 784 int count, error = 0; 785 786 ifcr->ifcr_total = if_cloners_count; 787 if ((dst = ifcr->ifcr_buffer) == NULL) { 788 /* Just asking how many there are. */ 789 return (0); 790 } 791 792 if (ifcr->ifcr_count < 0) 793 return (EINVAL); 794 795 count = (if_cloners_count < ifcr->ifcr_count) ? 796 if_cloners_count : ifcr->ifcr_count; 797 798 for (ifc = LIST_FIRST(&if_cloners); ifc != NULL && count != 0; 799 ifc = LIST_NEXT(ifc, ifc_list), count--, dst += IFNAMSIZ) { 800 strncpy(outbuf, ifc->ifc_name, IFNAMSIZ); 801 outbuf[IFNAMSIZ - 1] = '\0'; /* sanity */ 802 error = copyout(outbuf, dst, IFNAMSIZ); 803 if (error) 804 break; 805 } 806 807 return (error); 808 } 809 810 /* 811 * Locate an interface based on a complete address. 812 */ 813 /*ARGSUSED*/ 814 struct ifaddr * 815 ifa_ifwithaddr(addr) 816 struct sockaddr *addr; 817 { 818 struct ifnet *ifp; 819 struct ifaddr *ifa; 820 821 #define equal(a1, a2) \ 822 (bcmp((caddr_t)(a1), (caddr_t)(a2), ((struct sockaddr *)(a1))->sa_len) == 0) 823 824 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL; 825 ifp = TAILQ_NEXT(ifp, if_list)) { 826 if (ifp->if_output == if_nulloutput) 827 continue; 828 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; 829 ifa = TAILQ_NEXT(ifa, ifa_list)) { 830 if (ifa->ifa_addr->sa_family != addr->sa_family) 831 continue; 832 if (equal(addr, ifa->ifa_addr)) 833 return (ifa); 834 if ((ifp->if_flags & IFF_BROADCAST) && 835 ifa->ifa_broadaddr && 836 /* IP6 doesn't have broadcast */ 837 ifa->ifa_broadaddr->sa_len != 0 && 838 equal(ifa->ifa_broadaddr, addr)) 839 return (ifa); 840 } 841 } 842 return (NULL); 843 } 844 845 /* 846 * Locate the point to point interface with a given destination address. 847 */ 848 /*ARGSUSED*/ 849 struct ifaddr * 850 ifa_ifwithdstaddr(addr) 851 struct sockaddr *addr; 852 { 853 struct ifnet *ifp; 854 struct ifaddr *ifa; 855 856 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL; 857 ifp = TAILQ_NEXT(ifp, if_list)) { 858 if (ifp->if_output == if_nulloutput) 859 continue; 860 if (ifp->if_flags & IFF_POINTOPOINT) { 861 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; 862 ifa = TAILQ_NEXT(ifa, ifa_list)) { 863 if (ifa->ifa_addr->sa_family != 864 addr->sa_family || 865 ifa->ifa_dstaddr == NULL) 866 continue; 867 if (equal(addr, ifa->ifa_dstaddr)) 868 return (ifa); 869 } 870 } 871 } 872 return (NULL); 873 } 874 875 /* 876 * Find an interface on a specific network. If many, choice 877 * is most specific found. 878 */ 879 struct ifaddr * 880 ifa_ifwithnet(addr) 881 struct sockaddr *addr; 882 { 883 struct ifnet *ifp; 884 struct ifaddr *ifa; 885 struct sockaddr_dl *sdl; 886 struct ifaddr *ifa_maybe = 0; 887 u_int af = addr->sa_family; 888 char *addr_data = addr->sa_data, *cplim; 889 890 if (af == AF_LINK) { 891 sdl = (struct sockaddr_dl *)addr; 892 if (sdl->sdl_index && sdl->sdl_index <= if_index && 893 ifindex2ifnet[sdl->sdl_index]->if_output != if_nulloutput) 894 return (ifnet_addrs[sdl->sdl_index]); 895 } 896 #ifdef NETATALK 897 if (af == AF_APPLETALK) { 898 struct sockaddr_at *sat, *sat2; 899 sat = (struct sockaddr_at *)addr; 900 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL; 901 ifp = TAILQ_NEXT(ifp, if_list)) { 902 if (ifp->if_output == if_nulloutput) 903 continue; 904 ifa = at_ifawithnet((struct sockaddr_at *)addr, ifp); 905 if (ifa == NULL) 906 continue; 907 sat2 = (struct sockaddr_at *)ifa->ifa_addr; 908 if (sat2->sat_addr.s_net == sat->sat_addr.s_net) 909 return (ifa); /* exact match */ 910 if (ifa_maybe == NULL) { 911 /* else keep the if with the rigth range */ 912 ifa_maybe = ifa; 913 } 914 } 915 return (ifa_maybe); 916 } 917 #endif 918 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL; 919 ifp = TAILQ_NEXT(ifp, if_list)) { 920 if (ifp->if_output == if_nulloutput) 921 continue; 922 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; 923 ifa = TAILQ_NEXT(ifa, ifa_list)) { 924 char *cp, *cp2, *cp3; 925 926 if (ifa->ifa_addr->sa_family != af || 927 ifa->ifa_netmask == 0) 928 next: continue; 929 cp = addr_data; 930 cp2 = ifa->ifa_addr->sa_data; 931 cp3 = ifa->ifa_netmask->sa_data; 932 cplim = (char *)ifa->ifa_netmask + 933 ifa->ifa_netmask->sa_len; 934 while (cp3 < cplim) { 935 if ((*cp++ ^ *cp2++) & *cp3++) { 936 /* want to continue for() loop */ 937 goto next; 938 } 939 } 940 if (ifa_maybe == 0 || 941 rn_refines((caddr_t)ifa->ifa_netmask, 942 (caddr_t)ifa_maybe->ifa_netmask)) 943 ifa_maybe = ifa; 944 } 945 } 946 return (ifa_maybe); 947 } 948 949 /* 950 * Find the interface of the addresss. 951 */ 952 struct ifaddr * 953 ifa_ifwithladdr(addr) 954 struct sockaddr *addr; 955 { 956 struct ifaddr *ia; 957 958 if ((ia = ifa_ifwithaddr(addr)) || (ia = ifa_ifwithdstaddr(addr)) || 959 (ia = ifa_ifwithnet(addr))) 960 return (ia); 961 return (NULL); 962 } 963 964 /* 965 * Find an interface using a specific address family 966 */ 967 struct ifaddr * 968 ifa_ifwithaf(af) 969 int af; 970 { 971 struct ifnet *ifp; 972 struct ifaddr *ifa; 973 974 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL; 975 ifp = TAILQ_NEXT(ifp, if_list)) { 976 if (ifp->if_output == if_nulloutput) 977 continue; 978 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; 979 ifa = TAILQ_NEXT(ifa, ifa_list)) { 980 if (ifa->ifa_addr->sa_family == af) 981 return (ifa); 982 } 983 } 984 return (NULL); 985 } 986 987 /* 988 * Find an interface address specific to an interface best matching 989 * a given address. 990 */ 991 struct ifaddr * 992 ifaof_ifpforaddr(addr, ifp) 993 struct sockaddr *addr; 994 struct ifnet *ifp; 995 { 996 struct ifaddr *ifa; 997 char *cp, *cp2, *cp3; 998 char *cplim; 999 struct ifaddr *ifa_maybe = 0; 1000 u_int af = addr->sa_family; 1001 1002 if (ifp->if_output == if_nulloutput) 1003 return (NULL); 1004 1005 if (af >= AF_MAX) 1006 return (NULL); 1007 1008 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; 1009 ifa = TAILQ_NEXT(ifa, ifa_list)) { 1010 if (ifa->ifa_addr->sa_family != af) 1011 continue; 1012 ifa_maybe = ifa; 1013 if (ifa->ifa_netmask == 0) { 1014 if (equal(addr, ifa->ifa_addr) || 1015 (ifa->ifa_dstaddr && 1016 equal(addr, ifa->ifa_dstaddr))) 1017 return (ifa); 1018 continue; 1019 } 1020 cp = addr->sa_data; 1021 cp2 = ifa->ifa_addr->sa_data; 1022 cp3 = ifa->ifa_netmask->sa_data; 1023 cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask; 1024 for (; cp3 < cplim; cp3++) { 1025 if ((*cp++ ^ *cp2++) & *cp3) 1026 break; 1027 } 1028 if (cp3 == cplim) 1029 return (ifa); 1030 } 1031 return (ifa_maybe); 1032 } 1033 1034 /* 1035 * Default action when installing a route with a Link Level gateway. 1036 * Lookup an appropriate real ifa to point to. 1037 * This should be moved to /sys/net/link.c eventually. 1038 */ 1039 void 1040 link_rtrequest(cmd, rt, info) 1041 int cmd; 1042 struct rtentry *rt; 1043 struct rt_addrinfo *info; 1044 { 1045 struct ifaddr *ifa; 1046 struct sockaddr *dst; 1047 struct ifnet *ifp; 1048 1049 if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) || 1050 ((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0)) 1051 return; 1052 if ((ifa = ifaof_ifpforaddr(dst, ifp)) != NULL) { 1053 IFAFREE(rt->rt_ifa); 1054 rt->rt_ifa = ifa; 1055 IFAREF(ifa); 1056 if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest) 1057 ifa->ifa_rtrequest(cmd, rt, info); 1058 } 1059 } 1060 1061 /* 1062 * Mark an interface down and notify protocols of 1063 * the transition. 1064 * NOTE: must be called at splsoftnet or equivalent. 1065 */ 1066 void 1067 if_down(ifp) 1068 struct ifnet *ifp; 1069 { 1070 struct ifaddr *ifa; 1071 1072 ifp->if_flags &= ~IFF_UP; 1073 microtime(&ifp->if_lastchange); 1074 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; 1075 ifa = TAILQ_NEXT(ifa, ifa_list)) 1076 pfctlinput(PRC_IFDOWN, ifa->ifa_addr); 1077 IFQ_PURGE(&ifp->if_snd); 1078 rt_ifmsg(ifp); 1079 } 1080 1081 /* 1082 * Mark an interface up and notify protocols of 1083 * the transition. 1084 * NOTE: must be called at splsoftnet or equivalent. 1085 */ 1086 void 1087 if_up(ifp) 1088 struct ifnet *ifp; 1089 { 1090 #ifdef notyet 1091 struct ifaddr *ifa; 1092 #endif 1093 1094 ifp->if_flags |= IFF_UP; 1095 microtime(&ifp->if_lastchange); 1096 #ifdef notyet 1097 /* this has no effect on IP, and will kill all ISO connections XXX */ 1098 for (ifa = TAILQ_FIRST(&ifp->if_addrlist); ifa != NULL; 1099 ifa = TAILQ_NEXT(ifa, ifa_list)) 1100 pfctlinput(PRC_IFUP, ifa->ifa_addr); 1101 #endif 1102 rt_ifmsg(ifp); 1103 #ifdef INET6 1104 in6_if_up(ifp); 1105 #endif 1106 } 1107 1108 /* 1109 * Handle interface watchdog timer routines. Called 1110 * from softclock, we decrement timers (if set) and 1111 * call the appropriate interface routine on expiration. 1112 */ 1113 void 1114 if_slowtimo(arg) 1115 void *arg; 1116 { 1117 struct ifnet *ifp; 1118 int s = splnet(); 1119 1120 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL; 1121 ifp = TAILQ_NEXT(ifp, if_list)) { 1122 if (ifp->if_timer == 0 || --ifp->if_timer) 1123 continue; 1124 if (ifp->if_watchdog) 1125 (*ifp->if_watchdog)(ifp); 1126 } 1127 splx(s); 1128 callout_reset(&if_slowtimo_ch, hz / IFNET_SLOWHZ, 1129 if_slowtimo, NULL); 1130 } 1131 1132 /* 1133 * Set/clear promiscuous mode on interface ifp based on the truth value 1134 * of pswitch. The calls are reference counted so that only the first 1135 * "on" request actually has an effect, as does the final "off" request. 1136 * Results are undefined if the "off" and "on" requests are not matched. 1137 */ 1138 int 1139 ifpromisc(ifp, pswitch) 1140 struct ifnet *ifp; 1141 int pswitch; 1142 { 1143 int pcount, ret; 1144 short flags; 1145 struct ifreq ifr; 1146 1147 pcount = ifp->if_pcount; 1148 flags = ifp->if_flags; 1149 if (pswitch) { 1150 /* 1151 * Allow the device to be "placed" into promiscuous 1152 * mode even if it is not configured up. It will 1153 * consult IFF_PROMISC when it is is brought up. 1154 */ 1155 if (ifp->if_pcount++ != 0) 1156 return (0); 1157 ifp->if_flags |= IFF_PROMISC; 1158 if ((ifp->if_flags & IFF_UP) == 0) 1159 return (0); 1160 } else { 1161 if (--ifp->if_pcount > 0) 1162 return (0); 1163 ifp->if_flags &= ~IFF_PROMISC; 1164 /* 1165 * If the device is not configured up, we should not need to 1166 * turn off promiscuous mode (device should have turned it 1167 * off when interface went down; and will look at IFF_PROMISC 1168 * again next time interface comes up). 1169 */ 1170 if ((ifp->if_flags & IFF_UP) == 0) 1171 return (0); 1172 } 1173 memset(&ifr, 0, sizeof(ifr)); 1174 ifr.ifr_flags = ifp->if_flags; 1175 ret = (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t) &ifr); 1176 /* Restore interface state if not successful. */ 1177 if (ret != 0) { 1178 ifp->if_pcount = pcount; 1179 ifp->if_flags = flags; 1180 } 1181 return (ret); 1182 } 1183 1184 /* 1185 * Map interface name to 1186 * interface structure pointer. 1187 */ 1188 struct ifnet * 1189 ifunit(name) 1190 const char *name; 1191 { 1192 struct ifnet *ifp; 1193 1194 for (ifp = TAILQ_FIRST(&ifnet); ifp != NULL; 1195 ifp = TAILQ_NEXT(ifp, if_list)) { 1196 if (ifp->if_output == if_nulloutput) 1197 continue; 1198 if (strcmp(ifp->if_xname, name) == 0) 1199 return (ifp); 1200 } 1201 return (NULL); 1202 } 1203 1204 /* 1205 * Interface ioctls. 1206 */ 1207 int 1208 ifioctl(so, cmd, data, p) 1209 struct socket *so; 1210 u_long cmd; 1211 caddr_t data; 1212 struct proc *p; 1213 { 1214 struct ifnet *ifp; 1215 struct ifreq *ifr; 1216 struct ifcapreq *ifcr; 1217 int s, error = 0; 1218 short oif_flags; 1219 1220 switch (cmd) { 1221 1222 case SIOCGIFCONF: 1223 case OSIOCGIFCONF: 1224 return (ifconf(cmd, data)); 1225 } 1226 ifr = (struct ifreq *)data; 1227 ifcr = (struct ifcapreq *)data; 1228 1229 switch (cmd) { 1230 case SIOCIFCREATE: 1231 case SIOCIFDESTROY: 1232 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 1233 return (error); 1234 return ((cmd == SIOCIFCREATE) ? 1235 if_clone_create(ifr->ifr_name) : 1236 if_clone_destroy(ifr->ifr_name)); 1237 1238 case SIOCIFGCLONERS: 1239 return (if_clone_list((struct if_clonereq *)data)); 1240 } 1241 1242 ifp = ifunit(ifr->ifr_name); 1243 if (ifp == 0) 1244 return (ENXIO); 1245 oif_flags = ifp->if_flags; 1246 switch (cmd) { 1247 1248 case SIOCGIFFLAGS: 1249 ifr->ifr_flags = ifp->if_flags; 1250 break; 1251 1252 case SIOCGIFMETRIC: 1253 ifr->ifr_metric = ifp->if_metric; 1254 break; 1255 1256 case SIOCGIFMTU: 1257 ifr->ifr_mtu = ifp->if_mtu; 1258 break; 1259 1260 case SIOCGIFDLT: 1261 ifr->ifr_dlt = ifp->if_dlt; 1262 break; 1263 1264 case SIOCSIFFLAGS: 1265 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 1266 return (error); 1267 if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) { 1268 s = splnet(); 1269 if_down(ifp); 1270 splx(s); 1271 } 1272 if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) { 1273 s = splnet(); 1274 if_up(ifp); 1275 splx(s); 1276 } 1277 ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) | 1278 (ifr->ifr_flags &~ IFF_CANTCHANGE); 1279 if (ifp->if_ioctl) 1280 (void) (*ifp->if_ioctl)(ifp, cmd, data); 1281 break; 1282 1283 case SIOCGIFCAP: 1284 ifcr->ifcr_capabilities = ifp->if_capabilities; 1285 ifcr->ifcr_capenable = ifp->if_capenable; 1286 break; 1287 1288 case SIOCSIFCAP: 1289 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 1290 return (error); 1291 if ((ifcr->ifcr_capenable & ~ifp->if_capabilities) != 0) 1292 return (EINVAL); 1293 if (ifp->if_ioctl == NULL) 1294 return (EOPNOTSUPP); 1295 1296 /* Must prevent race with packet reception here. */ 1297 s = splnet(); 1298 if (ifcr->ifcr_capenable != ifp->if_capenable) { 1299 struct ifreq ifrq; 1300 1301 ifrq.ifr_flags = ifp->if_flags; 1302 ifp->if_capenable = ifcr->ifcr_capenable; 1303 1304 /* Pre-compute the checksum flags mask. */ 1305 ifp->if_csum_flags = 0; 1306 if (ifp->if_capenable & IFCAP_CSUM_IPv4) 1307 ifp->if_csum_flags |= M_CSUM_IPv4; 1308 if (ifp->if_capenable & IFCAP_CSUM_TCPv4) 1309 ifp->if_csum_flags |= M_CSUM_TCPv4; 1310 if (ifp->if_capenable & IFCAP_CSUM_UDPv4) 1311 ifp->if_csum_flags |= M_CSUM_UDPv4; 1312 if (ifp->if_capenable & IFCAP_CSUM_TCPv6) 1313 ifp->if_csum_flags |= M_CSUM_TCPv6; 1314 if (ifp->if_capenable & IFCAP_CSUM_UDPv6) 1315 ifp->if_csum_flags |= M_CSUM_UDPv6; 1316 1317 /* 1318 * Only kick the interface if it's up. If it's 1319 * not up now, it will notice the cap enables 1320 * when it is brought up later. 1321 */ 1322 if (ifp->if_flags & IFF_UP) 1323 (void) (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, 1324 (caddr_t) &ifrq); 1325 } 1326 splx(s); 1327 break; 1328 1329 case SIOCSIFMETRIC: 1330 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 1331 return (error); 1332 ifp->if_metric = ifr->ifr_metric; 1333 break; 1334 1335 case SIOCSIFMTU: 1336 { 1337 u_long oldmtu = ifp->if_mtu; 1338 1339 error = suser(p->p_ucred, &p->p_acflag); 1340 if (error) 1341 return (error); 1342 if (ifp->if_ioctl == NULL) 1343 return (EOPNOTSUPP); 1344 error = (*ifp->if_ioctl)(ifp, cmd, data); 1345 1346 /* 1347 * If the link MTU changed, do network layer specific procedure. 1348 */ 1349 if (ifp->if_mtu != oldmtu) { 1350 #ifdef INET6 1351 nd6_setmtu(ifp); 1352 #endif 1353 } 1354 break; 1355 } 1356 case SIOCSIFPHYADDR: 1357 case SIOCDIFPHYADDR: 1358 #ifdef INET6 1359 case SIOCSIFPHYADDR_IN6: 1360 #endif 1361 case SIOCSLIFPHYADDR: 1362 case SIOCADDMULTI: 1363 case SIOCDELMULTI: 1364 case SIOCSIFMEDIA: 1365 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 1366 return (error); 1367 /* FALLTHROUGH */ 1368 case SIOCGIFPSRCADDR: 1369 case SIOCGIFPDSTADDR: 1370 case SIOCGLIFPHYADDR: 1371 case SIOCGIFMEDIA: 1372 if (ifp->if_ioctl == 0) 1373 return (EOPNOTSUPP); 1374 error = (*ifp->if_ioctl)(ifp, cmd, data); 1375 break; 1376 1377 case SIOCSDRVSPEC: 1378 case SIOCS80211NWID: 1379 case SIOCS80211NWKEY: 1380 case SIOCS80211POWER: 1381 /* XXX: need to pass proc pointer through to driver... */ 1382 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) 1383 return (error); 1384 /* FALLTHROUGH */ 1385 default: 1386 if (so->so_proto == 0) 1387 return (EOPNOTSUPP); 1388 #if !defined(COMPAT_43) && !defined(COMPAT_LINUX) && !defined(COMPAT_SVR4) && !defined(LKM) 1389 error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 1390 (struct mbuf *)cmd, (struct mbuf *)data, 1391 (struct mbuf *)ifp, p)); 1392 #else 1393 { 1394 int ocmd = cmd; 1395 1396 switch (cmd) { 1397 1398 case SIOCSIFADDR: 1399 case SIOCSIFDSTADDR: 1400 case SIOCSIFBRDADDR: 1401 case SIOCSIFNETMASK: 1402 #if BYTE_ORDER != BIG_ENDIAN 1403 if (ifr->ifr_addr.sa_family == 0 && 1404 ifr->ifr_addr.sa_len < 16) { 1405 ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len; 1406 ifr->ifr_addr.sa_len = 16; 1407 } 1408 #else 1409 if (ifr->ifr_addr.sa_len == 0) 1410 ifr->ifr_addr.sa_len = 16; 1411 #endif 1412 break; 1413 1414 case OSIOCGIFADDR: 1415 cmd = SIOCGIFADDR; 1416 break; 1417 1418 case OSIOCGIFDSTADDR: 1419 cmd = SIOCGIFDSTADDR; 1420 break; 1421 1422 case OSIOCGIFBRDADDR: 1423 cmd = SIOCGIFBRDADDR; 1424 break; 1425 1426 case OSIOCGIFNETMASK: 1427 cmd = SIOCGIFNETMASK; 1428 } 1429 1430 error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL, 1431 (struct mbuf *)cmd, (struct mbuf *)data, 1432 (struct mbuf *)ifp, p)); 1433 1434 switch (ocmd) { 1435 case OSIOCGIFADDR: 1436 case OSIOCGIFDSTADDR: 1437 case OSIOCGIFBRDADDR: 1438 case OSIOCGIFNETMASK: 1439 *(u_int16_t *)&ifr->ifr_addr = ifr->ifr_addr.sa_family; 1440 } 1441 } 1442 #endif /* COMPAT_43 */ 1443 break; 1444 } 1445 1446 if (((oif_flags ^ ifp->if_flags) & IFF_UP) != 0) { 1447 #ifdef INET6 1448 if ((ifp->if_flags & IFF_UP) != 0) { 1449 s = splnet(); 1450 in6_if_up(ifp); 1451 splx(s); 1452 } 1453 #endif 1454 } 1455 1456 return (error); 1457 } 1458 1459 /* 1460 * Return interface configuration 1461 * of system. List may be used 1462 * in later ioctl's (above) to get 1463 * other information. 1464 */ 1465 /*ARGSUSED*/ 1466 int 1467 ifconf(cmd, data) 1468 u_long cmd; 1469 caddr_t data; 1470 { 1471 struct ifconf *ifc = (struct ifconf *)data; 1472 struct ifnet *ifp; 1473 struct ifaddr *ifa; 1474 struct ifreq ifr, *ifrp; 1475 int space = ifc->ifc_len, error = 0; 1476 1477 ifrp = ifc->ifc_req; 1478 for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next) { 1479 bcopy(ifp->if_xname, ifr.ifr_name, IFNAMSIZ); 1480 if ((ifa = ifp->if_addrlist.tqh_first) == 0) { 1481 memset((caddr_t)&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr)); 1482 if (space >= (int)sizeof (ifr)) { 1483 error = copyout((caddr_t)&ifr, (caddr_t)ifrp, 1484 sizeof(ifr)); 1485 if (error) 1486 break; 1487 } 1488 space -= sizeof (ifr), ifrp++; 1489 } else 1490 for (; ifa != 0; ifa = ifa->ifa_list.tqe_next) { 1491 struct sockaddr *sa = ifa->ifa_addr; 1492 #if defined(COMPAT_43) || defined(COMPAT_LINUX) || defined(COMPAT_SVR4) 1493 if (cmd == OSIOCGIFCONF) { 1494 struct osockaddr *osa = 1495 (struct osockaddr *)&ifr.ifr_addr; 1496 ifr.ifr_addr = *sa; 1497 osa->sa_family = sa->sa_family; 1498 if (space >= (int)sizeof (ifr)) { 1499 error = copyout((caddr_t)&ifr, 1500 (caddr_t)ifrp, 1501 sizeof (ifr)); 1502 ifrp++; 1503 } 1504 } else 1505 #endif 1506 if (sa->sa_len <= sizeof(*sa)) { 1507 ifr.ifr_addr = *sa; 1508 if (space >= (int)sizeof (ifr)) { 1509 error = copyout((caddr_t)&ifr, 1510 (caddr_t)ifrp, 1511 sizeof (ifr)); 1512 ifrp++; 1513 } 1514 } else { 1515 space -= sa->sa_len - sizeof(*sa); 1516 if (space >= (int)sizeof (ifr)) { 1517 error = copyout((caddr_t)&ifr, 1518 (caddr_t)ifrp, 1519 sizeof (ifr.ifr_name)); 1520 if (error == 0) { 1521 error = copyout((caddr_t)sa, 1522 (caddr_t)&ifrp->ifr_addr, 1523 sa->sa_len); 1524 } 1525 ifrp = (struct ifreq *) 1526 (sa->sa_len + 1527 (caddr_t)&ifrp->ifr_addr); 1528 } 1529 } 1530 if (error) 1531 break; 1532 space -= sizeof (ifr); 1533 } 1534 } 1535 ifc->ifc_len -= space; 1536 return (error); 1537 } 1538