1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 1983, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #ifndef lint 33 static const char copyright[] = 34 "@(#) Copyright (c) 1983, 1993\n\ 35 The Regents of the University of California. All rights reserved.\n"; 36 #if 0 37 static char sccsid[] = "@(#)ifconfig.c 8.2 (Berkeley) 2/16/94"; 38 #endif 39 static const char rcsid[] = 40 "$FreeBSD$"; 41 #endif /* not lint */ 42 43 #include <sys/param.h> 44 #include <sys/ioctl.h> 45 #ifdef JAIL 46 #include <sys/jail.h> 47 #endif 48 #include <sys/module.h> 49 #include <sys/linker.h> 50 #include <sys/nv.h> 51 #include <sys/queue.h> 52 #include <sys/socket.h> 53 #include <sys/time.h> 54 55 #include <net/ethernet.h> 56 #include <net/if.h> 57 #include <net/if_dl.h> 58 #include <net/if_types.h> 59 #include <net/route.h> 60 61 /* IP */ 62 #include <netinet/in.h> 63 #include <netinet/in_var.h> 64 #include <arpa/inet.h> 65 #include <netdb.h> 66 67 #include <fnmatch.h> 68 #include <ifaddrs.h> 69 #include <ctype.h> 70 #include <err.h> 71 #include <errno.h> 72 #include <fcntl.h> 73 #ifdef JAIL 74 #include <jail.h> 75 #endif 76 #include <stdbool.h> 77 #include <stdio.h> 78 #include <stdlib.h> 79 #include <string.h> 80 #include <unistd.h> 81 82 #include <libifconfig.h> 83 84 #include "ifconfig.h" 85 86 ifconfig_handle_t *lifh; 87 88 /* 89 * Since "struct ifreq" is composed of various union members, callers 90 * should pay special attention to interpret the value. 91 * (.e.g. little/big endian difference in the structure.) 92 */ 93 struct ifreq ifr; 94 95 char name[IFNAMSIZ]; 96 #ifdef WITHOUT_NETLINK 97 static char *descr = NULL; 98 static size_t descrlen = 64; 99 #endif 100 static int setaddr; 101 static int setmask; 102 static int doalias; 103 static int clearaddr; 104 int newaddr = 1; 105 int verbose; 106 int printifname = 0; 107 108 struct ifconfig_args global_args; 109 110 int printkeys = 0; /* Print keying material for interfaces. */ 111 int exit_code = 0; 112 113 /* Formatter Strings */ 114 char *f_inet, *f_inet6, *f_ether, *f_addr; 115 116 #ifdef WITHOUT_NETLINK 117 static void list_interfaces_ioctl(struct ifconfig_args *args); 118 static void status(struct ifconfig_args *args, const struct sockaddr_dl *sdl, 119 struct ifaddrs *ifa); 120 #endif 121 static _Noreturn void usage(void); 122 static void Perrorc(const char *cmd, int error); 123 124 static int getifflags(const char *ifname, int us, bool err_ok); 125 126 static struct afswtch *af_getbyname(const char *name); 127 128 static struct option *opts = NULL; 129 130 struct ifa_order_elt { 131 int if_order; 132 int af_orders[255]; 133 struct ifaddrs *ifa; 134 TAILQ_ENTRY(ifa_order_elt) link; 135 }; 136 137 TAILQ_HEAD(ifa_queue, ifa_order_elt); 138 139 static struct module_map_entry { 140 const char *ifname; 141 const char *kldname; 142 } module_map[] = { 143 { 144 .ifname = "tun", 145 .kldname = "if_tuntap", 146 }, 147 { 148 .ifname = "tap", 149 .kldname = "if_tuntap", 150 }, 151 { 152 .ifname = "vmnet", 153 .kldname = "if_tuntap", 154 }, 155 { 156 .ifname = "ipsec", 157 .kldname = "ipsec", 158 }, 159 { 160 /* 161 * This mapping exists because there is a conflicting enc module 162 * in CAM. ifconfig's guessing behavior will attempt to match 163 * the ifname to a module as well as if_${ifname} and clash with 164 * CAM enc. This is an assertion of the correct module to load. 165 */ 166 .ifname = "enc", 167 .kldname = "if_enc", 168 }, 169 }; 170 171 172 void 173 opt_register(struct option *p) 174 { 175 p->next = opts; 176 opts = p; 177 } 178 179 static void 180 usage(void) 181 { 182 char options[1024]; 183 struct option *p; 184 185 /* XXX not right but close enough for now */ 186 options[0] = '\0'; 187 for (p = opts; p != NULL; p = p->next) { 188 strlcat(options, p->opt_usage, sizeof(options)); 189 strlcat(options, " ", sizeof(options)); 190 } 191 192 fprintf(stderr, 193 "usage: ifconfig [-j jail] [-f type:format] %sinterface address_family\n" 194 " [address [dest_address]] [parameters]\n" 195 " ifconfig [-j jail] interface create\n" 196 " ifconfig [-j jail] -a %s[-d] [-m] [-u] [-v] [address_family]\n" 197 " ifconfig [-j jail] -l [-d] [-u] [address_family]\n" 198 " ifconfig [-j jail] %s[-d] [-m] [-u] [-v]\n", 199 options, options, options); 200 exit(1); 201 } 202 203 void 204 ioctl_ifcreate(int s, struct ifreq *ifr) 205 { 206 if (ioctl(s, SIOCIFCREATE2, ifr) < 0) { 207 switch (errno) { 208 case EEXIST: 209 errx(1, "interface %s already exists", ifr->ifr_name); 210 default: 211 err(1, "SIOCIFCREATE2 (%s)", ifr->ifr_name); 212 } 213 } 214 } 215 216 #ifdef WITHOUT_NETLINK 217 static int 218 calcorders(struct ifaddrs *ifa, struct ifa_queue *q) 219 { 220 struct ifaddrs *prev; 221 struct ifa_order_elt *cur; 222 unsigned int ord, af, ifa_ord; 223 224 prev = NULL; 225 cur = NULL; 226 ord = 0; 227 ifa_ord = 0; 228 229 while (ifa != NULL) { 230 if (prev == NULL || 231 strcmp(ifa->ifa_name, prev->ifa_name) != 0) { 232 cur = calloc(1, sizeof(*cur)); 233 234 if (cur == NULL) 235 return (-1); 236 237 TAILQ_INSERT_TAIL(q, cur, link); 238 cur->if_order = ifa_ord ++; 239 cur->ifa = ifa; 240 ord = 0; 241 } 242 243 if (ifa->ifa_addr) { 244 af = ifa->ifa_addr->sa_family; 245 246 if (af < nitems(cur->af_orders) && 247 cur->af_orders[af] == 0) 248 cur->af_orders[af] = ++ord; 249 } 250 prev = ifa; 251 ifa = ifa->ifa_next; 252 } 253 254 return (0); 255 } 256 257 static int 258 cmpifaddrs(struct ifaddrs *a, struct ifaddrs *b, struct ifa_queue *q) 259 { 260 struct ifa_order_elt *cur, *e1, *e2; 261 unsigned int af1, af2; 262 int ret; 263 264 e1 = e2 = NULL; 265 266 ret = strcmp(a->ifa_name, b->ifa_name); 267 if (ret != 0) { 268 TAILQ_FOREACH(cur, q, link) { 269 if (e1 && e2) 270 break; 271 272 if (strcmp(cur->ifa->ifa_name, a->ifa_name) == 0) 273 e1 = cur; 274 else if (strcmp(cur->ifa->ifa_name, b->ifa_name) == 0) 275 e2 = cur; 276 } 277 278 if (!e1 || !e2) 279 return (0); 280 else 281 return (e1->if_order - e2->if_order); 282 283 } else if (a->ifa_addr != NULL && b->ifa_addr != NULL) { 284 TAILQ_FOREACH(cur, q, link) { 285 if (strcmp(cur->ifa->ifa_name, a->ifa_name) == 0) { 286 e1 = cur; 287 break; 288 } 289 } 290 291 if (!e1) 292 return (0); 293 294 af1 = a->ifa_addr->sa_family; 295 af2 = b->ifa_addr->sa_family; 296 297 if (af1 < nitems(e1->af_orders) && af2 < nitems(e1->af_orders)) 298 return (e1->af_orders[af1] - e1->af_orders[af2]); 299 } 300 301 return (0); 302 } 303 #endif 304 305 static void freeformat(void) 306 { 307 308 if (f_inet != NULL) 309 free(f_inet); 310 if (f_inet6 != NULL) 311 free(f_inet6); 312 if (f_ether != NULL) 313 free(f_ether); 314 if (f_addr != NULL) 315 free(f_addr); 316 } 317 318 static void setformat(char *input) 319 { 320 char *formatstr, *category, *modifier; 321 322 formatstr = strdup(input); 323 while ((category = strsep(&formatstr, ",")) != NULL) { 324 modifier = strchr(category, ':'); 325 if (modifier == NULL || modifier[1] == '\0') { 326 warnx("Skipping invalid format specification: %s\n", 327 category); 328 continue; 329 } 330 331 /* Split the string on the separator, then seek past it */ 332 modifier[0] = '\0'; 333 modifier++; 334 335 if (strcmp(category, "addr") == 0) 336 f_addr = strdup(modifier); 337 else if (strcmp(category, "ether") == 0) 338 f_ether = strdup(modifier); 339 else if (strcmp(category, "inet") == 0) 340 f_inet = strdup(modifier); 341 else if (strcmp(category, "inet6") == 0) 342 f_inet6 = strdup(modifier); 343 } 344 free(formatstr); 345 } 346 347 #ifdef WITHOUT_NETLINK 348 static struct ifaddrs * 349 sortifaddrs(struct ifaddrs *list, 350 int (*compare)(struct ifaddrs *, struct ifaddrs *, struct ifa_queue *), 351 struct ifa_queue *q) 352 { 353 struct ifaddrs *right, *temp, *last, *result, *next, *tail; 354 355 right = list; 356 temp = list; 357 last = list; 358 result = NULL; 359 next = NULL; 360 tail = NULL; 361 362 if (!list || !list->ifa_next) 363 return (list); 364 365 while (temp && temp->ifa_next) { 366 last = right; 367 right = right->ifa_next; 368 temp = temp->ifa_next->ifa_next; 369 } 370 371 last->ifa_next = NULL; 372 373 list = sortifaddrs(list, compare, q); 374 right = sortifaddrs(right, compare, q); 375 376 while (list || right) { 377 378 if (!right) { 379 next = list; 380 list = list->ifa_next; 381 } else if (!list) { 382 next = right; 383 right = right->ifa_next; 384 } else if (compare(list, right, q) <= 0) { 385 next = list; 386 list = list->ifa_next; 387 } else { 388 next = right; 389 right = right->ifa_next; 390 } 391 392 if (!result) 393 result = next; 394 else 395 tail->ifa_next = next; 396 397 tail = next; 398 } 399 400 return (result); 401 } 402 #endif 403 404 static void 405 printifnamemaybe(void) 406 { 407 if (printifname) 408 printf("%s\n", name); 409 } 410 411 static void 412 list_interfaces(struct ifconfig_args *args) 413 { 414 #ifdef WITHOUT_NETLINK 415 list_interfaces_ioctl(args); 416 #else 417 list_interfaces_nl(args); 418 #endif 419 } 420 421 static char * 422 args_peek(struct ifconfig_args *args) 423 { 424 if (args->argc > 0) 425 return (args->argv[0]); 426 return (NULL); 427 } 428 429 static char * 430 args_pop(struct ifconfig_args *args) 431 { 432 if (args->argc == 0) 433 return (NULL); 434 435 char *arg = args->argv[0]; 436 437 args->argc--; 438 args->argv++; 439 440 return (arg); 441 } 442 443 static void 444 args_parse(struct ifconfig_args *args, int argc, char *argv[]) 445 { 446 char options[1024]; 447 struct option *p; 448 int c; 449 450 /* Parse leading line options */ 451 strlcpy(options, "G:adf:j:klmnuv", sizeof(options)); 452 for (p = opts; p != NULL; p = p->next) 453 strlcat(options, p->opt, sizeof(options)); 454 while ((c = getopt(argc, argv, options)) != -1) { 455 switch (c) { 456 case 'a': /* scan all interfaces */ 457 args->all = true; 458 break; 459 case 'd': /* restrict scan to "down" interfaces */ 460 args->downonly = true; 461 break; 462 case 'f': 463 if (optarg == NULL) 464 usage(); 465 setformat(optarg); 466 break; 467 case 'G': 468 if (optarg == NULL || args->all == 0) 469 usage(); 470 args->nogroup = optarg; 471 break; 472 case 'j': 473 #ifdef JAIL 474 if (optarg == NULL) 475 usage(); 476 args->jail_name = optarg; 477 #else 478 Perror("not built with jail support"); 479 #endif 480 break; 481 case 'k': 482 args->printkeys = true; 483 break; 484 case 'l': /* scan interface names only */ 485 args->namesonly++; 486 break; 487 case 'm': /* show media choices in status */ 488 args->supmedia = true; 489 break; 490 case 'n': /* suppress module loading */ 491 args->noload = true; 492 break; 493 case 'u': /* restrict scan to "up" interfaces */ 494 args->uponly = true; 495 break; 496 case 'v': 497 args->verbose++; 498 break; 499 case 'g': 500 if (args->all) { 501 if (optarg == NULL) 502 usage(); 503 args->matchgroup = optarg; 504 break; 505 } 506 /* FALLTHROUGH */ 507 default: 508 for (p = opts; p != NULL; p = p->next) 509 if (p->opt[0] == c) { 510 p->cb(optarg); 511 break; 512 } 513 if (p == NULL) 514 usage(); 515 break; 516 } 517 } 518 argc -= optind; 519 argv += optind; 520 521 /* -l cannot be used with -a or -m */ 522 if (args->namesonly && (args->all || args->supmedia)) 523 usage(); 524 525 /* nonsense.. */ 526 if (args->uponly && args->downonly) 527 usage(); 528 529 /* no arguments is equivalent to '-a' */ 530 if (!args->namesonly && argc < 1) 531 args->all = 1; 532 533 /* -a and -l allow an address family arg to limit the output */ 534 if (args->all || args->namesonly) { 535 if (argc > 1) 536 usage(); 537 538 if (argc == 1) { 539 const struct afswtch *afp = af_getbyname(*argv); 540 541 if (afp == NULL) { 542 warnx("Address family '%s' unknown.", *argv); 543 usage(); 544 } 545 if (afp->af_name != NULL) 546 argc--, argv++; 547 /* leave with afp non-zero */ 548 args->afp = afp; 549 } 550 } else { 551 /* not listing, need an argument */ 552 if (argc < 1) 553 usage(); 554 } 555 556 args->argc = argc; 557 args->argv = argv; 558 559 /* Sync global variables */ 560 printkeys = args->printkeys; 561 verbose = args->verbose; 562 } 563 564 static int 565 ifconfig_wrapper(struct ifconfig_args *args, int iscreate, 566 const struct afswtch *uafp) 567 { 568 #ifdef WITHOUT_NETLINK 569 struct ifconfig_context ctx = { 570 .args = args, 571 .io_s = -1, 572 }; 573 574 return (ifconfig(&ctx, iscreate, uafp)); 575 #else 576 return (ifconfig_wrapper_nl(args, iscreate, uafp)); 577 #endif 578 } 579 580 static bool 581 isargcreate(const char *arg) 582 { 583 if (arg == NULL) 584 return (false); 585 586 if (strcmp(arg, "create") == 0 || strcmp(arg, "plumb") == 0) 587 return (true); 588 589 return (false); 590 } 591 592 int 593 main(int ac, char *av[]) 594 { 595 char *envformat; 596 size_t iflen; 597 int flags; 598 #ifdef JAIL 599 int jid; 600 #endif 601 struct ifconfig_args *args = &global_args; 602 603 f_inet = f_inet6 = f_ether = f_addr = NULL; 604 605 lifh = ifconfig_open(); 606 if (lifh == NULL) 607 err(EXIT_FAILURE, "ifconfig_open"); 608 609 envformat = getenv("IFCONFIG_FORMAT"); 610 if (envformat != NULL) 611 setformat(envformat); 612 613 /* 614 * Ensure we print interface name when expected to, 615 * even if we terminate early due to error. 616 */ 617 atexit(printifnamemaybe); 618 619 args_parse(args, ac, av); 620 621 #ifdef JAIL 622 if (args->jail_name) { 623 jid = jail_getid(args->jail_name); 624 if (jid == -1) 625 Perror("jail not found"); 626 if (jail_attach(jid) != 0) 627 Perror("cannot attach to jail"); 628 } 629 #endif 630 631 if (!args->all && !args->namesonly) { 632 /* not listing, need an argument */ 633 args->ifname = args_pop(args); 634 635 /* check and maybe load support for this interface */ 636 ifmaybeload(args, args->ifname); 637 638 char *arg = args_peek(args); 639 if (if_nametoindex(args->ifname) == 0) { 640 /* 641 * NOTE: We must special-case the `create' command 642 * right here as we would otherwise fail when trying 643 * to find the interface. 644 */ 645 if (isargcreate(arg)) { 646 iflen = strlcpy(name, args->ifname, sizeof(name)); 647 if (iflen >= sizeof(name)) 648 errx(1, "%s: cloning name too long", 649 args->ifname); 650 ifconfig_wrapper(args, 1, NULL); 651 exit(exit_code); 652 } 653 #ifdef JAIL 654 /* 655 * NOTE: We have to special-case the `-vnet' command 656 * right here as we would otherwise fail when trying 657 * to find the interface as it lives in another vnet. 658 */ 659 if (arg != NULL && (strcmp(arg, "-vnet") == 0)) { 660 iflen = strlcpy(name, args->ifname, sizeof(name)); 661 if (iflen >= sizeof(name)) 662 errx(1, "%s: interface name too long", 663 args->ifname); 664 ifconfig_wrapper(args, 0, NULL); 665 exit(exit_code); 666 } 667 #endif 668 errx(1, "interface %s does not exist", args->ifname); 669 } else { 670 /* 671 * Do not allow use `create` command as hostname if 672 * address family is not specified. 673 */ 674 if (isargcreate(arg)) { 675 if (args->argc == 1) 676 errx(1, "interface %s already exists", 677 args->ifname); 678 args_pop(args); 679 } 680 } 681 } 682 683 /* Check for address family */ 684 if (args->argc > 0) { 685 args->afp = af_getbyname(args_peek(args)); 686 if (args->afp != NULL) 687 args_pop(args); 688 } 689 690 /* 691 * Check for a requested configuration action on a single interface, 692 * which doesn't require building, sorting, and searching the entire 693 * system address list 694 */ 695 if ((args->argc > 0) && (args->ifname != NULL)) { 696 iflen = strlcpy(name, args->ifname, sizeof(name)); 697 if (iflen >= sizeof(name)) { 698 warnx("%s: interface name too long, skipping", args->ifname); 699 } else { 700 flags = getifflags(name, -1, false); 701 if (!(((flags & IFF_CANTCONFIG) != 0) || 702 (args->downonly && (flags & IFF_UP) != 0) || 703 (args->uponly && (flags & IFF_UP) == 0))) 704 ifconfig_wrapper(args, 0, args->afp); 705 } 706 goto done; 707 } 708 709 args->allfamilies = args->afp == NULL; 710 711 list_interfaces(args); 712 713 done: 714 freeformat(); 715 ifconfig_close(lifh); 716 exit(exit_code); 717 } 718 719 bool 720 match_ether(const struct sockaddr_dl *sdl) 721 { 722 switch (sdl->sdl_type) { 723 case IFT_ETHER: 724 case IFT_L2VLAN: 725 case IFT_BRIDGE: 726 if (sdl->sdl_alen == ETHER_ADDR_LEN) 727 return (true); 728 default: 729 return (false); 730 } 731 } 732 733 bool 734 match_if_flags(struct ifconfig_args *args, int if_flags) 735 { 736 if ((if_flags & IFF_CANTCONFIG) != 0) 737 return (false); 738 if (args->downonly && (if_flags & IFF_UP) != 0) 739 return (false); 740 if (args->uponly && (if_flags & IFF_UP) == 0) 741 return (false); 742 return (true); 743 } 744 745 #ifdef WITHOUT_NETLINK 746 static bool 747 match_afp(const struct afswtch *afp, int sa_family, const struct sockaddr_dl *sdl) 748 { 749 if (afp == NULL) 750 return (true); 751 /* special case for "ether" address family */ 752 if (!strcmp(afp->af_name, "ether")) { 753 if (sdl == NULL && !match_ether(sdl)) 754 return (false); 755 return (true); 756 } 757 return (afp->af_af == sa_family); 758 } 759 760 static void 761 list_interfaces_ioctl(struct ifconfig_args *args) 762 { 763 struct ifa_queue q = TAILQ_HEAD_INITIALIZER(q); 764 struct ifaddrs *ifap, *sifap, *ifa; 765 struct ifa_order_elt *cur, *tmp; 766 char *namecp = NULL; 767 int ifindex; 768 size_t iflen; 769 770 if (getifaddrs(&ifap) != 0) 771 err(EXIT_FAILURE, "getifaddrs"); 772 773 char *cp = NULL; 774 775 if (calcorders(ifap, &q) != 0) 776 err(EXIT_FAILURE, "calcorders"); 777 778 sifap = sortifaddrs(ifap, cmpifaddrs, &q); 779 780 TAILQ_FOREACH_SAFE(cur, &q, link, tmp) 781 free(cur); 782 783 ifindex = 0; 784 for (ifa = sifap; ifa; ifa = ifa->ifa_next) { 785 struct ifreq paifr = {}; 786 const struct sockaddr_dl *sdl; 787 788 strlcpy(paifr.ifr_name, ifa->ifa_name, sizeof(paifr.ifr_name)); 789 if (sizeof(paifr.ifr_addr) >= ifa->ifa_addr->sa_len) { 790 memcpy(&paifr.ifr_addr, ifa->ifa_addr, 791 ifa->ifa_addr->sa_len); 792 } 793 794 if (args->ifname != NULL && strcmp(args->ifname, ifa->ifa_name) != 0) 795 continue; 796 if (ifa->ifa_addr->sa_family == AF_LINK) 797 sdl = (const struct sockaddr_dl *) ifa->ifa_addr; 798 else 799 sdl = NULL; 800 if (cp != NULL && strcmp(cp, ifa->ifa_name) == 0 && !args->namesonly) 801 continue; 802 iflen = strlcpy(name, ifa->ifa_name, sizeof(name)); 803 if (iflen >= sizeof(name)) { 804 warnx("%s: interface name too long, skipping", 805 ifa->ifa_name); 806 continue; 807 } 808 cp = ifa->ifa_name; 809 810 if (!match_if_flags(args, ifa->ifa_flags)) 811 continue; 812 if (!group_member(ifa->ifa_name, args->matchgroup, args->nogroup)) 813 continue; 814 /* 815 * Are we just listing the interfaces? 816 */ 817 if (args->namesonly) { 818 if (namecp == cp) 819 continue; 820 if (!match_afp(args->afp, ifa->ifa_addr->sa_family, sdl)) 821 continue; 822 namecp = cp; 823 ifindex++; 824 if (ifindex > 1) 825 printf(" "); 826 fputs(name, stdout); 827 continue; 828 } 829 ifindex++; 830 831 if (args->argc > 0) 832 ifconfig_wrapper(args, 0, args->afp); 833 else 834 status(args, sdl, ifa); 835 } 836 if (args->namesonly) 837 printf("\n"); 838 freeifaddrs(ifap); 839 } 840 #endif 841 842 /* 843 * Returns true if an interface should be listed because any its groups 844 * matches shell pattern "match" and none of groups matches pattern "nomatch". 845 * If any pattern is NULL, corresponding condition is skipped. 846 */ 847 bool 848 group_member(const char *ifname, const char *match, const char *nomatch) 849 { 850 static int sock = -1; 851 852 struct ifgroupreq ifgr; 853 struct ifg_req *ifg; 854 unsigned int len; 855 bool matched, nomatched; 856 857 /* Sanity checks. */ 858 if (match == NULL && nomatch == NULL) 859 return (true); 860 if (ifname == NULL) 861 return (false); 862 863 memset(&ifgr, 0, sizeof(ifgr)); 864 strlcpy(ifgr.ifgr_name, ifname, IFNAMSIZ); 865 866 /* The socket is opened once. Let _exit() close it. */ 867 if (sock == -1) { 868 sock = socket(AF_LOCAL, SOCK_DGRAM, 0); 869 if (sock == -1) 870 errx(1, "%s: socket(AF_LOCAL,SOCK_DGRAM)", __func__); 871 } 872 873 /* Determine amount of memory for the list of groups. */ 874 if (ioctl(sock, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) { 875 if (errno == EINVAL || errno == ENOTTY) 876 return (false); 877 else 878 errx(1, "%s: SIOCGIFGROUP", __func__); 879 } 880 881 /* Obtain the list of groups. */ 882 len = ifgr.ifgr_len; 883 ifgr.ifgr_groups = 884 (struct ifg_req *)calloc(len / sizeof(*ifg), sizeof(*ifg)); 885 886 if (ifgr.ifgr_groups == NULL) 887 errx(1, "%s: no memory", __func__); 888 if (ioctl(sock, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) 889 errx(1, "%s: SIOCGIFGROUP", __func__); 890 891 /* Perform matching. */ 892 matched = false; 893 nomatched = true; 894 for (ifg = ifgr.ifgr_groups; ifg && len >= sizeof(*ifg); ifg++) { 895 len -= sizeof(struct ifg_req); 896 if (match) 897 matched |= !fnmatch(match, ifg->ifgrq_group, 0); 898 if (nomatch) 899 nomatched &= fnmatch(nomatch, ifg->ifgrq_group, 0); 900 } 901 free(ifgr.ifgr_groups); 902 903 if (match && !nomatch) 904 return (matched); 905 if (!match && nomatch) 906 return (nomatched); 907 return (matched && nomatched); 908 } 909 910 static struct afswtch *afs = NULL; 911 912 void 913 af_register(struct afswtch *p) 914 { 915 p->af_next = afs; 916 afs = p; 917 } 918 919 static struct afswtch * 920 af_getbyname(const char *name) 921 { 922 struct afswtch *afp; 923 924 for (afp = afs; afp != NULL; afp = afp->af_next) 925 if (strcmp(afp->af_name, name) == 0) 926 return afp; 927 return NULL; 928 } 929 930 struct afswtch * 931 af_getbyfamily(int af) 932 { 933 struct afswtch *afp; 934 935 for (afp = afs; afp != NULL; afp = afp->af_next) 936 if (afp->af_af == af) 937 return afp; 938 return NULL; 939 } 940 941 void 942 af_other_status(if_ctx *ctx) 943 { 944 struct afswtch *afp; 945 uint8_t afmask[howmany(AF_MAX, NBBY)]; 946 947 memset(afmask, 0, sizeof(afmask)); 948 for (afp = afs; afp != NULL; afp = afp->af_next) { 949 if (afp->af_other_status == NULL) 950 continue; 951 if (afp->af_af != AF_UNSPEC && isset(afmask, afp->af_af)) 952 continue; 953 afp->af_other_status(ctx); 954 setbit(afmask, afp->af_af); 955 } 956 } 957 958 static void 959 af_all_tunnel_status(int s) 960 { 961 struct afswtch *afp; 962 uint8_t afmask[howmany(AF_MAX, NBBY)]; 963 964 memset(afmask, 0, sizeof(afmask)); 965 for (afp = afs; afp != NULL; afp = afp->af_next) { 966 if (afp->af_status_tunnel == NULL) 967 continue; 968 if (afp->af_af != AF_UNSPEC && isset(afmask, afp->af_af)) 969 continue; 970 afp->af_status_tunnel(s); 971 setbit(afmask, afp->af_af); 972 } 973 } 974 975 static struct cmd *cmds = NULL; 976 977 void 978 cmd_register(struct cmd *p) 979 { 980 p->c_next = cmds; 981 cmds = p; 982 } 983 984 static const struct cmd * 985 cmd_lookup(const char *name, int iscreate) 986 { 987 const struct cmd *p; 988 989 for (p = cmds; p != NULL; p = p->c_next) 990 if (strcmp(name, p->c_name) == 0) { 991 if (iscreate) { 992 if (p->c_iscloneop) 993 return p; 994 } else { 995 if (!p->c_iscloneop) 996 return p; 997 } 998 } 999 return NULL; 1000 } 1001 1002 struct callback { 1003 callback_func *cb_func; 1004 void *cb_arg; 1005 struct callback *cb_next; 1006 }; 1007 static struct callback *callbacks = NULL; 1008 1009 void 1010 callback_register(callback_func *func, void *arg) 1011 { 1012 struct callback *cb; 1013 1014 cb = malloc(sizeof(struct callback)); 1015 if (cb == NULL) 1016 errx(1, "unable to allocate memory for callback"); 1017 cb->cb_func = func; 1018 cb->cb_arg = arg; 1019 cb->cb_next = callbacks; 1020 callbacks = cb; 1021 } 1022 1023 /* specially-handled commands */ 1024 static void setifaddr(if_ctx *ctx, const char *addr, int param); 1025 static const struct cmd setifaddr_cmd = DEF_CMD("ifaddr", 0, setifaddr); 1026 1027 static void setifdstaddr(if_ctx *ctx, const char *addr, int param __unused); 1028 static const struct cmd setifdstaddr_cmd = 1029 DEF_CMD("ifdstaddr", 0, setifdstaddr); 1030 1031 int 1032 af_exec_ioctl(if_ctx *ctx, unsigned long action, void *data) 1033 { 1034 struct ifreq *req = (struct ifreq *)data; 1035 1036 strlcpy(req->ifr_name, name, sizeof(req->ifr_name)); 1037 if (ioctl_ctx(ctx, action, req) == 0) 1038 return (0); 1039 return (errno); 1040 } 1041 1042 static void 1043 delifaddr(if_ctx *ctx, const struct afswtch *afp) 1044 { 1045 int error; 1046 1047 if (afp->af_exec == NULL) { 1048 warnx("interface %s cannot change %s addresses!", 1049 name, afp->af_name); 1050 clearaddr = 0; 1051 return; 1052 } 1053 1054 error = afp->af_exec(ctx, afp->af_difaddr, afp->af_ridreq); 1055 if (error != 0) { 1056 if (error == EADDRNOTAVAIL && (doalias >= 0)) { 1057 /* means no previous address for interface */ 1058 } else 1059 Perrorc("ioctl (SIOCDIFADDR)", error); 1060 } 1061 } 1062 1063 static void 1064 addifaddr(if_ctx *ctx, const struct afswtch *afp) 1065 { 1066 if (afp->af_exec == NULL) { 1067 warnx("interface %s cannot change %s addresses!", 1068 name, afp->af_name); 1069 newaddr = 0; 1070 return; 1071 } 1072 1073 if (setaddr || setmask) { 1074 int error = afp->af_exec(ctx, afp->af_aifaddr, afp->af_addreq); 1075 if (error != 0) 1076 Perrorc("ioctl (SIOCAIFADDR)", error); 1077 } 1078 } 1079 1080 int 1081 ifconfig(if_ctx *orig_ctx, int iscreate, const struct afswtch *uafp) 1082 { 1083 const struct afswtch *afp, *nafp; 1084 const struct cmd *p; 1085 struct callback *cb; 1086 int s; 1087 int argc = orig_ctx->args->argc; 1088 char *const *argv = orig_ctx->args->argv; 1089 struct ifconfig_context _ctx = { 1090 .args = orig_ctx->args, 1091 .io_ss = orig_ctx->io_ss, 1092 }; 1093 struct ifconfig_context *ctx = &_ctx; 1094 1095 strlcpy(ifr.ifr_name, name, sizeof ifr.ifr_name); 1096 afp = NULL; 1097 if (uafp != NULL) 1098 afp = uafp; 1099 /* 1100 * This is the historical "accident" allowing users to configure IPv4 1101 * addresses without the "inet" keyword which while a nice feature has 1102 * proven to complicate other things. We cannot remove this but only 1103 * make sure we will never have a similar implicit default for IPv6 or 1104 * any other address familiy. We need a fallback though for 1105 * ifconfig IF up/down etc. to work without INET support as people 1106 * never used ifconfig IF link up/down, etc. either. 1107 */ 1108 #ifndef RESCUE 1109 #ifdef INET 1110 if (afp == NULL && feature_present("inet")) 1111 afp = af_getbyname("inet"); 1112 #endif 1113 #endif 1114 if (afp == NULL) 1115 afp = af_getbyname("link"); 1116 if (afp == NULL) { 1117 warnx("Please specify an address_family."); 1118 usage(); 1119 } 1120 1121 top: 1122 ifr.ifr_addr.sa_family = 1123 afp->af_af == AF_LINK || afp->af_af == AF_UNSPEC ? 1124 AF_LOCAL : afp->af_af; 1125 1126 if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0 && 1127 (uafp != NULL || errno != EAFNOSUPPORT || 1128 (s = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0)) 1129 err(1, "socket(family %u,SOCK_DGRAM)", ifr.ifr_addr.sa_family); 1130 1131 ctx->io_s = s; 1132 ctx->afp = afp; 1133 1134 while (argc > 0) { 1135 p = cmd_lookup(*argv, iscreate); 1136 if (iscreate && p == NULL) { 1137 /* 1138 * Push the clone create callback so the new 1139 * device is created and can be used for any 1140 * remaining arguments. 1141 */ 1142 cb = callbacks; 1143 if (cb == NULL) 1144 errx(1, "internal error, no callback"); 1145 callbacks = cb->cb_next; 1146 cb->cb_func(s, cb->cb_arg); 1147 iscreate = 0; 1148 /* 1149 * Handle any address family spec that 1150 * immediately follows and potentially 1151 * recreate the socket. 1152 */ 1153 nafp = af_getbyname(*argv); 1154 if (nafp != NULL) { 1155 argc--, argv++; 1156 if (nafp != afp) { 1157 close(s); 1158 afp = nafp; 1159 goto top; 1160 } 1161 } 1162 /* 1163 * Look for a normal parameter. 1164 */ 1165 continue; 1166 } 1167 if (p == NULL) { 1168 /* 1169 * Not a recognized command, choose between setting 1170 * the interface address and the dst address. 1171 */ 1172 p = (setaddr ? &setifdstaddr_cmd : &setifaddr_cmd); 1173 } 1174 if (p->c_parameter == NEXTARG && p->c_u.c_func) { 1175 if (argv[1] == NULL) 1176 errx(1, "'%s' requires argument", 1177 p->c_name); 1178 p->c_u.c_func(ctx, argv[1], 0); 1179 argc--, argv++; 1180 } else if (p->c_parameter == OPTARG && p->c_u.c_func) { 1181 p->c_u.c_func(ctx, argv[1], 0); 1182 if (argv[1] != NULL) 1183 argc--, argv++; 1184 } else if (p->c_parameter == NEXTARG2 && p->c_u.c_func2) { 1185 if (argc < 3) 1186 errx(1, "'%s' requires 2 arguments", 1187 p->c_name); 1188 p->c_u.c_func2(ctx, argv[1], argv[2]); 1189 argc -= 2, argv += 2; 1190 } else if (p->c_parameter == SPARAM && p->c_u.c_func3) { 1191 p->c_u.c_func3(ctx, *argv, p->c_sparameter); 1192 } else if (p->c_u.c_func) 1193 p->c_u.c_func(ctx, *argv, p->c_parameter); 1194 argc--, argv++; 1195 } 1196 1197 /* 1198 * Do any post argument processing required by the address family. 1199 */ 1200 if (afp->af_postproc != NULL) 1201 afp->af_postproc(ctx, newaddr, getifflags(name, s, true)); 1202 /* 1203 * Do deferred callbacks registered while processing 1204 * command-line arguments. 1205 */ 1206 for (cb = callbacks; cb != NULL; cb = cb->cb_next) 1207 cb->cb_func(s, cb->cb_arg); 1208 /* 1209 * Do deferred operations. 1210 */ 1211 if (clearaddr) 1212 delifaddr(ctx, afp); 1213 if (newaddr) 1214 addifaddr(ctx, afp); 1215 1216 close(s); 1217 return(0); 1218 } 1219 1220 static void 1221 setifaddr(if_ctx *ctx, const char *addr, int param) 1222 { 1223 const struct afswtch *afp = ctx->afp; 1224 1225 if (afp->af_getaddr == NULL) 1226 return; 1227 /* 1228 * Delay the ioctl to set the interface addr until flags are all set. 1229 * The address interpretation may depend on the flags, 1230 * and the flags may change when the address is set. 1231 */ 1232 setaddr++; 1233 if (doalias == 0 && afp->af_af != AF_LINK) 1234 clearaddr = 1; 1235 afp->af_getaddr(addr, (doalias >= 0 ? ADDR : RIDADDR)); 1236 } 1237 1238 static void 1239 settunnel(if_ctx *ctx, const char *src, const char *dst) 1240 { 1241 const struct afswtch *afp = ctx->afp; 1242 struct addrinfo *srcres, *dstres; 1243 int ecode; 1244 1245 if (afp->af_settunnel == NULL) { 1246 warn("address family %s does not support tunnel setup", 1247 afp->af_name); 1248 return; 1249 } 1250 1251 if ((ecode = getaddrinfo(src, NULL, NULL, &srcres)) != 0) 1252 errx(1, "error in parsing address string: %s", 1253 gai_strerror(ecode)); 1254 1255 if ((ecode = getaddrinfo(dst, NULL, NULL, &dstres)) != 0) 1256 errx(1, "error in parsing address string: %s", 1257 gai_strerror(ecode)); 1258 1259 if (srcres->ai_addr->sa_family != dstres->ai_addr->sa_family) 1260 errx(1, 1261 "source and destination address families do not match"); 1262 1263 afp->af_settunnel(ctx->io_s, srcres, dstres); 1264 1265 freeaddrinfo(srcres); 1266 freeaddrinfo(dstres); 1267 } 1268 1269 static void 1270 deletetunnel(if_ctx *ctx, const char *vname, int param) 1271 { 1272 1273 if (ioctl(ctx->io_s, SIOCDIFPHYADDR, &ifr) < 0) 1274 err(1, "SIOCDIFPHYADDR"); 1275 } 1276 1277 #ifdef JAIL 1278 static void 1279 setifvnet(if_ctx *ctx, const char *jname, int dummy __unused) 1280 { 1281 struct ifreq my_ifr; 1282 1283 memcpy(&my_ifr, &ifr, sizeof(my_ifr)); 1284 my_ifr.ifr_jid = jail_getid(jname); 1285 if (my_ifr.ifr_jid < 0) 1286 errx(1, "%s", jail_errmsg); 1287 if (ioctl(ctx->io_s, SIOCSIFVNET, &my_ifr) < 0) 1288 err(1, "SIOCSIFVNET"); 1289 } 1290 1291 static void 1292 setifrvnet(if_ctx *ctx, const char *jname, int dummy __unused) 1293 { 1294 struct ifreq my_ifr; 1295 1296 memcpy(&my_ifr, &ifr, sizeof(my_ifr)); 1297 my_ifr.ifr_jid = jail_getid(jname); 1298 if (my_ifr.ifr_jid < 0) 1299 errx(1, "%s", jail_errmsg); 1300 if (ioctl(ctx->io_s, SIOCSIFRVNET, &my_ifr) < 0) 1301 err(1, "SIOCSIFRVNET(%d, %s)", my_ifr.ifr_jid, my_ifr.ifr_name); 1302 } 1303 #endif 1304 1305 static void 1306 setifnetmask(if_ctx *ctx, const char *addr, int dummy __unused) 1307 { 1308 const struct afswtch *afp = ctx->afp; 1309 1310 if (afp->af_getaddr != NULL) { 1311 setmask++; 1312 afp->af_getaddr(addr, MASK); 1313 } 1314 } 1315 1316 static void 1317 setifbroadaddr(if_ctx *ctx, const char *addr, int dummy __unused) 1318 { 1319 const struct afswtch *afp = ctx->afp; 1320 1321 if (afp->af_getaddr != NULL) 1322 afp->af_getaddr(addr, BRDADDR); 1323 } 1324 1325 static void 1326 notealias(if_ctx *ctx, const char *addr, int param) 1327 { 1328 const struct afswtch *afp = ctx->afp; 1329 1330 if (setaddr && doalias == 0 && param < 0) { 1331 if (afp->af_copyaddr != NULL) 1332 afp->af_copyaddr(ctx, RIDADDR, ADDR); 1333 } 1334 doalias = param; 1335 if (param < 0) { 1336 clearaddr = 1; 1337 newaddr = 0; 1338 } else 1339 clearaddr = 0; 1340 } 1341 1342 static void 1343 setifdstaddr(if_ctx *ctx, const char *addr, int param __unused) 1344 { 1345 const struct afswtch *afp = ctx->afp; 1346 1347 if (afp->af_getaddr != NULL) 1348 afp->af_getaddr(addr, DSTADDR); 1349 } 1350 1351 static int 1352 getifflags(const char *ifname, int us, bool err_ok) 1353 { 1354 struct ifreq my_ifr; 1355 int s; 1356 1357 memset(&my_ifr, 0, sizeof(my_ifr)); 1358 (void) strlcpy(my_ifr.ifr_name, ifname, sizeof(my_ifr.ifr_name)); 1359 if (us < 0) { 1360 if ((s = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0) 1361 err(1, "socket(family AF_LOCAL,SOCK_DGRAM"); 1362 } else 1363 s = us; 1364 if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&my_ifr) < 0) { 1365 if (!err_ok) { 1366 Perror("ioctl (SIOCGIFFLAGS)"); 1367 exit(1); 1368 } 1369 } 1370 if (us < 0) 1371 close(s); 1372 return ((my_ifr.ifr_flags & 0xffff) | (my_ifr.ifr_flagshigh << 16)); 1373 } 1374 1375 /* 1376 * Note: doing an SIOCIGIFFLAGS scribbles on the union portion 1377 * of the ifreq structure, which may confuse other parts of ifconfig. 1378 * Make a private copy so we can avoid that. 1379 */ 1380 static void 1381 setifflags(if_ctx *ctx, const char *vname, int value) 1382 { 1383 struct ifreq my_ifr; 1384 int flags; 1385 1386 flags = getifflags(name, ctx->io_s, false); 1387 if (value < 0) { 1388 value = -value; 1389 flags &= ~value; 1390 } else 1391 flags |= value; 1392 memset(&my_ifr, 0, sizeof(my_ifr)); 1393 (void) strlcpy(my_ifr.ifr_name, name, sizeof(my_ifr.ifr_name)); 1394 my_ifr.ifr_flags = flags & 0xffff; 1395 my_ifr.ifr_flagshigh = flags >> 16; 1396 if (ioctl(ctx->io_s, SIOCSIFFLAGS, (caddr_t)&my_ifr) < 0) 1397 Perror(vname); 1398 } 1399 1400 void 1401 setifcap(if_ctx *ctx, const char *vname, int value) 1402 { 1403 int flags; 1404 1405 if (ioctl(ctx->io_s, SIOCGIFCAP, (caddr_t)&ifr) < 0) { 1406 Perror("ioctl (SIOCGIFCAP)"); 1407 exit(1); 1408 } 1409 flags = ifr.ifr_curcap; 1410 if (value < 0) { 1411 value = -value; 1412 flags &= ~value; 1413 } else 1414 flags |= value; 1415 flags &= ifr.ifr_reqcap; 1416 /* Check for no change in capabilities. */ 1417 if (ifr.ifr_curcap == flags) 1418 return; 1419 ifr.ifr_reqcap = flags; 1420 if (ioctl(ctx->io_s, SIOCSIFCAP, (caddr_t)&ifr) < 0) 1421 Perror(vname); 1422 } 1423 1424 void 1425 setifcapnv(if_ctx *ctx, const char *vname, const char *arg) 1426 { 1427 nvlist_t *nvcap; 1428 void *buf; 1429 char *marg, *mopt; 1430 size_t nvbuflen; 1431 bool neg; 1432 1433 if (ioctl(ctx->io_s, SIOCGIFCAP, (caddr_t)&ifr) < 0) 1434 Perror("ioctl (SIOCGIFCAP)"); 1435 if ((ifr.ifr_curcap & IFCAP_NV) == 0) { 1436 warnx("IFCAP_NV not supported"); 1437 return; /* Not exit() */ 1438 } 1439 1440 marg = strdup(arg); 1441 if (marg == NULL) 1442 Perror("strdup"); 1443 nvcap = nvlist_create(0); 1444 if (nvcap == NULL) 1445 Perror("nvlist_create"); 1446 while ((mopt = strsep(&marg, ",")) != NULL) { 1447 neg = *mopt == '-'; 1448 if (neg) 1449 mopt++; 1450 if (strcmp(mopt, "rxtls") == 0) { 1451 nvlist_add_bool(nvcap, "rxtls4", !neg); 1452 nvlist_add_bool(nvcap, "rxtls6", !neg); 1453 } else { 1454 nvlist_add_bool(nvcap, mopt, !neg); 1455 } 1456 } 1457 buf = nvlist_pack(nvcap, &nvbuflen); 1458 if (buf == NULL) { 1459 errx(1, "nvlist_pack error"); 1460 exit(1); 1461 } 1462 ifr.ifr_cap_nv.buf_length = ifr.ifr_cap_nv.length = nvbuflen; 1463 ifr.ifr_cap_nv.buffer = buf; 1464 if (ioctl(ctx->io_s, SIOCSIFCAPNV, (caddr_t)&ifr) < 0) 1465 Perror(vname); 1466 free(buf); 1467 nvlist_destroy(nvcap); 1468 free(marg); 1469 } 1470 1471 static void 1472 setifmetric(if_ctx *ctx, const char *val, int dummy __unused) 1473 { 1474 strlcpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 1475 ifr.ifr_metric = atoi(val); 1476 if (ioctl(ctx->io_s, SIOCSIFMETRIC, (caddr_t)&ifr) < 0) 1477 err(1, "ioctl SIOCSIFMETRIC (set metric)"); 1478 } 1479 1480 static void 1481 setifmtu(if_ctx *ctx, const char *val, int dummy __unused) 1482 { 1483 strlcpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 1484 ifr.ifr_mtu = atoi(val); 1485 if (ioctl(ctx->io_s, SIOCSIFMTU, (caddr_t)&ifr) < 0) 1486 err(1, "ioctl SIOCSIFMTU (set mtu)"); 1487 } 1488 1489 static void 1490 setifpcp(if_ctx *ctx, const char *val, int arg __unused) 1491 { 1492 u_long ul; 1493 char *endp; 1494 1495 ul = strtoul(val, &endp, 0); 1496 if (*endp != '\0') 1497 errx(1, "invalid value for pcp"); 1498 if (ul > 7) 1499 errx(1, "value for pcp out of range"); 1500 ifr.ifr_lan_pcp = ul; 1501 if (ioctl(ctx->io_s, SIOCSLANPCP, (caddr_t)&ifr) == -1) 1502 err(1, "SIOCSLANPCP"); 1503 } 1504 1505 static void 1506 disableifpcp(if_ctx *ctx, const char *val, int arg __unused) 1507 { 1508 1509 ifr.ifr_lan_pcp = IFNET_PCP_NONE; 1510 if (ioctl(ctx->io_s, SIOCSLANPCP, (caddr_t)&ifr) == -1) 1511 err(1, "SIOCSLANPCP"); 1512 } 1513 1514 static void 1515 setifname(if_ctx *ctx, const char *val, int dummy __unused) 1516 { 1517 char *newname; 1518 1519 strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 1520 1521 newname = strdup(val); 1522 if (newname == NULL) 1523 err(1, "no memory to set ifname"); 1524 ifr.ifr_data = newname; 1525 if (ioctl(ctx->io_s, SIOCSIFNAME, (caddr_t)&ifr) < 0) { 1526 free(newname); 1527 err(1, "ioctl SIOCSIFNAME (set name)"); 1528 } 1529 printifname = 1; 1530 strlcpy(name, newname, sizeof(name)); 1531 free(newname); 1532 } 1533 1534 static void 1535 setifdescr(if_ctx *ctx, const char *val, int dummy __unused) 1536 { 1537 char *newdescr; 1538 1539 strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 1540 1541 ifr.ifr_buffer.length = strlen(val) + 1; 1542 if (ifr.ifr_buffer.length == 1) { 1543 ifr.ifr_buffer.buffer = newdescr = NULL; 1544 ifr.ifr_buffer.length = 0; 1545 } else { 1546 newdescr = strdup(val); 1547 ifr.ifr_buffer.buffer = newdescr; 1548 if (newdescr == NULL) { 1549 warn("no memory to set ifdescr"); 1550 return; 1551 } 1552 } 1553 1554 if (ioctl(ctx->io_s, SIOCSIFDESCR, (caddr_t)&ifr) < 0) 1555 err(1, "ioctl SIOCSIFDESCR (set descr)"); 1556 1557 free(newdescr); 1558 } 1559 1560 static void 1561 unsetifdescr(if_ctx *ctx, const char *val, int value) 1562 { 1563 setifdescr(ctx, "", 0); 1564 } 1565 1566 #define IFFBITS \ 1567 "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\7RUNNING" \ 1568 "\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2" \ 1569 "\20MULTICAST\22PPROMISC\23MONITOR\24STATICARP\25STICKYARP" 1570 1571 #define IFCAPBITS \ 1572 "\020\1RXCSUM\2TXCSUM\3NETCONS\4VLAN_MTU\5VLAN_HWTAGGING\6JUMBO_MTU\7POLLING" \ 1573 "\10VLAN_HWCSUM\11TSO4\12TSO6\13LRO\14WOL_UCAST\15WOL_MCAST\16WOL_MAGIC" \ 1574 "\17TOE4\20TOE6\21VLAN_HWFILTER\23VLAN_HWTSO\24LINKSTATE\25NETMAP" \ 1575 "\26RXCSUM_IPV6\27TXCSUM_IPV6\31TXRTLMT\32HWRXTSTMP\33NOMAP\34TXTLS4\35TXTLS6" \ 1576 "\36VXLAN_HWCSUM\37VXLAN_HWTSO\40TXTLS_RTLMT" 1577 1578 static void 1579 print_ifcap_nv(struct ifconfig_args *args, int s) 1580 { 1581 nvlist_t *nvcap; 1582 const char *nvname; 1583 void *buf, *cookie; 1584 bool first, val; 1585 int type; 1586 1587 buf = malloc(IFR_CAP_NV_MAXBUFSIZE); 1588 if (buf == NULL) 1589 Perror("malloc"); 1590 ifr.ifr_cap_nv.buffer = buf; 1591 ifr.ifr_cap_nv.buf_length = IFR_CAP_NV_MAXBUFSIZE; 1592 if (ioctl(s, SIOCGIFCAPNV, (caddr_t)&ifr) != 0) 1593 Perror("ioctl (SIOCGIFCAPNV)"); 1594 nvcap = nvlist_unpack(ifr.ifr_cap_nv.buffer, 1595 ifr.ifr_cap_nv.length, 0); 1596 if (nvcap == NULL) 1597 Perror("nvlist_unpack"); 1598 printf("\toptions"); 1599 cookie = NULL; 1600 for (first = true;; first = false) { 1601 nvname = nvlist_next(nvcap, &type, &cookie); 1602 if (nvname == NULL) { 1603 printf("\n"); 1604 break; 1605 } 1606 if (type == NV_TYPE_BOOL) { 1607 val = nvlist_get_bool(nvcap, nvname); 1608 if (val) { 1609 printf("%c%s", 1610 first ? ' ' : ',', nvname); 1611 } 1612 } 1613 } 1614 if (args->supmedia) { 1615 printf("\tcapabilities"); 1616 cookie = NULL; 1617 for (first = true;; first = false) { 1618 nvname = nvlist_next(nvcap, &type, 1619 &cookie); 1620 if (nvname == NULL) { 1621 printf("\n"); 1622 break; 1623 } 1624 if (type == NV_TYPE_BOOL) 1625 printf("%c%s", first ? ' ' : 1626 ',', nvname); 1627 } 1628 } 1629 nvlist_destroy(nvcap); 1630 free(buf); 1631 1632 if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) != 0) 1633 Perror("ioctl (SIOCGIFCAP)"); 1634 } 1635 1636 void 1637 print_ifcap(struct ifconfig_args *args, int s) 1638 { 1639 if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) != 0) 1640 return; 1641 1642 if ((ifr.ifr_curcap & IFCAP_NV) != 0) 1643 print_ifcap_nv(args, s); 1644 else { 1645 printb("\toptions", ifr.ifr_curcap, IFCAPBITS); 1646 putchar('\n'); 1647 if (args->supmedia && ifr.ifr_reqcap != 0) { 1648 printb("\tcapabilities", ifr.ifr_reqcap, 1649 IFCAPBITS); 1650 putchar('\n'); 1651 } 1652 } 1653 } 1654 1655 void 1656 print_ifstatus(int s) 1657 { 1658 struct ifstat ifs; 1659 1660 strlcpy(ifs.ifs_name, name, sizeof ifs.ifs_name); 1661 if (ioctl(s, SIOCGIFSTATUS, &ifs) == 0) 1662 printf("%s", ifs.ascii); 1663 } 1664 1665 void 1666 print_metric(int s) 1667 { 1668 if (ioctl(s, SIOCGIFMETRIC, &ifr) != -1) 1669 printf(" metric %d", ifr.ifr_metric); 1670 } 1671 1672 #ifdef WITHOUT_NETLINK 1673 static void 1674 print_mtu(int s) 1675 { 1676 if (ioctl(s, SIOCGIFMTU, &ifr) != -1) 1677 printf(" mtu %d", ifr.ifr_mtu); 1678 } 1679 1680 static void 1681 print_description(int s) 1682 { 1683 for (;;) { 1684 if ((descr = reallocf(descr, descrlen)) != NULL) { 1685 ifr.ifr_buffer.buffer = descr; 1686 ifr.ifr_buffer.length = descrlen; 1687 if (ioctl(s, SIOCGIFDESCR, &ifr) == 0) { 1688 if (ifr.ifr_buffer.buffer == descr) { 1689 if (strlen(descr) > 0) 1690 printf("\tdescription: %s\n", 1691 descr); 1692 } else if (ifr.ifr_buffer.length > descrlen) { 1693 descrlen = ifr.ifr_buffer.length; 1694 continue; 1695 } 1696 } 1697 } else 1698 warn("unable to allocate memory for interface" 1699 "description"); 1700 break; 1701 } 1702 } 1703 1704 /* 1705 * Print the status of the interface. If an address family was 1706 * specified, show only it; otherwise, show them all. 1707 */ 1708 static void 1709 status(struct ifconfig_args *args, const struct sockaddr_dl *sdl, 1710 struct ifaddrs *ifa) 1711 { 1712 struct ifaddrs *ift; 1713 int s; 1714 bool allfamilies = args->afp == NULL; 1715 1716 if (args->afp == NULL) 1717 ifr.ifr_addr.sa_family = AF_LOCAL; 1718 else 1719 ifr.ifr_addr.sa_family = 1720 args->afp->af_af == AF_LINK ? AF_LOCAL : args->afp->af_af; 1721 strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 1722 1723 s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0); 1724 if (s < 0) 1725 err(1, "socket(family %u,SOCK_DGRAM)", ifr.ifr_addr.sa_family); 1726 1727 struct ifconfig_context _ctx = { .io_s = s }, *ctx; 1728 ctx = &_ctx; 1729 1730 printf("%s: ", name); 1731 printb("flags", ifa->ifa_flags, IFFBITS); 1732 print_metric(s); 1733 print_mtu(s); 1734 putchar('\n'); 1735 1736 print_description(s); 1737 1738 print_ifcap(args, s); 1739 1740 tunnel_status(s); 1741 1742 for (ift = ifa; ift != NULL; ift = ift->ifa_next) { 1743 if (ift->ifa_addr == NULL) 1744 continue; 1745 if (strcmp(ifa->ifa_name, ift->ifa_name) != 0) 1746 continue; 1747 if (allfamilies) { 1748 const struct afswtch *p; 1749 p = af_getbyfamily(ift->ifa_addr->sa_family); 1750 if (p != NULL && p->af_status != NULL) 1751 p->af_status(ctx, ift); 1752 } else if (args->afp->af_af == ift->ifa_addr->sa_family) 1753 args->afp->af_status(ctx, ift); 1754 } 1755 #if 0 1756 if (allfamilies || afp->af_af == AF_LINK) { 1757 const struct afswtch *lafp; 1758 1759 /* 1760 * Hack; the link level address is received separately 1761 * from the routing information so any address is not 1762 * handled above. Cobble together an entry and invoke 1763 * the status method specially. 1764 */ 1765 lafp = af_getbyname("lladdr"); 1766 if (lafp != NULL) { 1767 info.rti_info[RTAX_IFA] = (struct sockaddr *)sdl; 1768 lafp->af_status(s, &info); 1769 } 1770 } 1771 #endif 1772 if (allfamilies) 1773 af_other_status(ctx); 1774 else if (args->afp->af_other_status != NULL) 1775 args->afp->af_other_status(ctx); 1776 1777 print_ifstatus(s); 1778 if (args->verbose > 0) 1779 sfp_status(ctx); 1780 1781 close(s); 1782 return; 1783 } 1784 #endif 1785 1786 void 1787 tunnel_status(int s) 1788 { 1789 af_all_tunnel_status(s); 1790 } 1791 1792 static void 1793 Perrorc(const char *cmd, int error) 1794 { 1795 switch (errno) { 1796 1797 case ENXIO: 1798 errx(1, "%s: no such interface", cmd); 1799 break; 1800 1801 case EPERM: 1802 errx(1, "%s: permission denied", cmd); 1803 break; 1804 1805 default: 1806 errc(1, error, "%s", cmd); 1807 } 1808 } 1809 1810 void 1811 Perror(const char *cmd) 1812 { 1813 Perrorc(cmd, errno); 1814 } 1815 1816 /* 1817 * Print a value a la the %b format of the kernel's printf 1818 */ 1819 void 1820 printb(const char *s, unsigned v, const char *bits) 1821 { 1822 int i, any = 0; 1823 char c; 1824 1825 if (bits && *bits == 8) 1826 printf("%s=%o", s, v); 1827 else 1828 printf("%s=%x", s, v); 1829 if (bits) { 1830 bits++; 1831 putchar('<'); 1832 while ((i = *bits++) != '\0') { 1833 if (v & (1u << (i-1))) { 1834 if (any) 1835 putchar(','); 1836 any = 1; 1837 for (; (c = *bits) > 32; bits++) 1838 putchar(c); 1839 } else 1840 for (; *bits > 32; bits++) 1841 ; 1842 } 1843 putchar('>'); 1844 } 1845 } 1846 1847 void 1848 print_vhid(const struct ifaddrs *ifa, const char *s) 1849 { 1850 struct if_data *ifd; 1851 1852 if (ifa->ifa_data == NULL) 1853 return; 1854 1855 ifd = ifa->ifa_data; 1856 if (ifd->ifi_vhid == 0) 1857 return; 1858 1859 printf(" vhid %d", ifd->ifi_vhid); 1860 } 1861 1862 void 1863 ifmaybeload(struct ifconfig_args *args, const char *name) 1864 { 1865 #define MOD_PREFIX_LEN 3 /* "if_" */ 1866 struct module_stat mstat; 1867 int fileid, modid; 1868 char ifkind[IFNAMSIZ + MOD_PREFIX_LEN], ifname[IFNAMSIZ], *dp; 1869 const char *cp; 1870 struct module_map_entry *mme; 1871 bool found; 1872 1873 /* loading suppressed by the user */ 1874 if (args->noload) 1875 return; 1876 1877 /* trim the interface number off the end */ 1878 strlcpy(ifname, name, sizeof(ifname)); 1879 dp = ifname + strlen(ifname) - 1; 1880 for (; dp > ifname; dp--) { 1881 if (isdigit(*dp)) 1882 *dp = '\0'; 1883 else 1884 break; 1885 } 1886 1887 /* Either derive it from the map or guess otherwise */ 1888 *ifkind = '\0'; 1889 found = false; 1890 for (unsigned i = 0; i < nitems(module_map); ++i) { 1891 mme = &module_map[i]; 1892 if (strcmp(mme->ifname, ifname) == 0) { 1893 strlcpy(ifkind, mme->kldname, sizeof(ifkind)); 1894 found = true; 1895 break; 1896 } 1897 } 1898 1899 /* We didn't have an alias for it... we'll guess. */ 1900 if (!found) { 1901 /* turn interface and unit into module name */ 1902 strlcpy(ifkind, "if_", sizeof(ifkind)); 1903 strlcat(ifkind, ifname, sizeof(ifkind)); 1904 } 1905 1906 /* scan files in kernel */ 1907 mstat.version = sizeof(struct module_stat); 1908 for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid)) { 1909 /* scan modules in file */ 1910 for (modid = kldfirstmod(fileid); modid > 0; 1911 modid = modfnext(modid)) { 1912 if (modstat(modid, &mstat) < 0) 1913 continue; 1914 /* strip bus name if present */ 1915 if ((cp = strchr(mstat.name, '/')) != NULL) { 1916 cp++; 1917 } else { 1918 cp = mstat.name; 1919 } 1920 /* 1921 * Is it already loaded? Don't compare with ifname if 1922 * we were specifically told which kld to use. Doing 1923 * so could lead to conflicts not trivially solved. 1924 */ 1925 if ((!found && strcmp(ifname, cp) == 0) || 1926 strcmp(ifkind, cp) == 0) 1927 return; 1928 } 1929 } 1930 1931 /* 1932 * Try to load the module. But ignore failures, because ifconfig can't 1933 * infer the names of all drivers (eg mlx4en(4)). 1934 */ 1935 (void) kldload(ifkind); 1936 } 1937 1938 static struct cmd basic_cmds[] = { 1939 DEF_CMD("up", IFF_UP, setifflags), 1940 DEF_CMD("down", -IFF_UP, setifflags), 1941 DEF_CMD("arp", -IFF_NOARP, setifflags), 1942 DEF_CMD("-arp", IFF_NOARP, setifflags), 1943 DEF_CMD("debug", IFF_DEBUG, setifflags), 1944 DEF_CMD("-debug", -IFF_DEBUG, setifflags), 1945 DEF_CMD_ARG("description", setifdescr), 1946 DEF_CMD_ARG("descr", setifdescr), 1947 DEF_CMD("-description", 0, unsetifdescr), 1948 DEF_CMD("-descr", 0, unsetifdescr), 1949 DEF_CMD("promisc", IFF_PPROMISC, setifflags), 1950 DEF_CMD("-promisc", -IFF_PPROMISC, setifflags), 1951 DEF_CMD("add", IFF_UP, notealias), 1952 DEF_CMD("alias", IFF_UP, notealias), 1953 DEF_CMD("-alias", -IFF_UP, notealias), 1954 DEF_CMD("delete", -IFF_UP, notealias), 1955 DEF_CMD("remove", -IFF_UP, notealias), 1956 #ifdef notdef 1957 #define EN_SWABIPS 0x1000 1958 DEF_CMD("swabips", EN_SWABIPS, setifflags), 1959 DEF_CMD("-swabips", -EN_SWABIPS, setifflags), 1960 #endif 1961 DEF_CMD_ARG("netmask", setifnetmask), 1962 DEF_CMD_ARG("metric", setifmetric), 1963 DEF_CMD_ARG("broadcast", setifbroadaddr), 1964 DEF_CMD_ARG2("tunnel", settunnel), 1965 DEF_CMD("-tunnel", 0, deletetunnel), 1966 DEF_CMD("deletetunnel", 0, deletetunnel), 1967 #ifdef JAIL 1968 DEF_CMD_ARG("vnet", setifvnet), 1969 DEF_CMD_ARG("-vnet", setifrvnet), 1970 #endif 1971 DEF_CMD("link0", IFF_LINK0, setifflags), 1972 DEF_CMD("-link0", -IFF_LINK0, setifflags), 1973 DEF_CMD("link1", IFF_LINK1, setifflags), 1974 DEF_CMD("-link1", -IFF_LINK1, setifflags), 1975 DEF_CMD("link2", IFF_LINK2, setifflags), 1976 DEF_CMD("-link2", -IFF_LINK2, setifflags), 1977 DEF_CMD("monitor", IFF_MONITOR, setifflags), 1978 DEF_CMD("-monitor", -IFF_MONITOR, setifflags), 1979 DEF_CMD("mextpg", IFCAP_MEXTPG, setifcap), 1980 DEF_CMD("-mextpg", -IFCAP_MEXTPG, setifcap), 1981 DEF_CMD("staticarp", IFF_STATICARP, setifflags), 1982 DEF_CMD("-staticarp", -IFF_STATICARP, setifflags), 1983 DEF_CMD("stickyarp", IFF_STICKYARP, setifflags), 1984 DEF_CMD("-stickyarp", -IFF_STICKYARP, setifflags), 1985 DEF_CMD("rxcsum6", IFCAP_RXCSUM_IPV6, setifcap), 1986 DEF_CMD("-rxcsum6", -IFCAP_RXCSUM_IPV6, setifcap), 1987 DEF_CMD("txcsum6", IFCAP_TXCSUM_IPV6, setifcap), 1988 DEF_CMD("-txcsum6", -IFCAP_TXCSUM_IPV6, setifcap), 1989 DEF_CMD("rxcsum", IFCAP_RXCSUM, setifcap), 1990 DEF_CMD("-rxcsum", -IFCAP_RXCSUM, setifcap), 1991 DEF_CMD("txcsum", IFCAP_TXCSUM, setifcap), 1992 DEF_CMD("-txcsum", -IFCAP_TXCSUM, setifcap), 1993 DEF_CMD("netcons", IFCAP_NETCONS, setifcap), 1994 DEF_CMD("-netcons", -IFCAP_NETCONS, setifcap), 1995 DEF_CMD_ARG("pcp", setifpcp), 1996 DEF_CMD("-pcp", 0, disableifpcp), 1997 DEF_CMD("polling", IFCAP_POLLING, setifcap), 1998 DEF_CMD("-polling", -IFCAP_POLLING, setifcap), 1999 DEF_CMD("tso6", IFCAP_TSO6, setifcap), 2000 DEF_CMD("-tso6", -IFCAP_TSO6, setifcap), 2001 DEF_CMD("tso4", IFCAP_TSO4, setifcap), 2002 DEF_CMD("-tso4", -IFCAP_TSO4, setifcap), 2003 DEF_CMD("tso", IFCAP_TSO, setifcap), 2004 DEF_CMD("-tso", -IFCAP_TSO, setifcap), 2005 DEF_CMD("toe", IFCAP_TOE, setifcap), 2006 DEF_CMD("-toe", -IFCAP_TOE, setifcap), 2007 DEF_CMD("lro", IFCAP_LRO, setifcap), 2008 DEF_CMD("-lro", -IFCAP_LRO, setifcap), 2009 DEF_CMD("txtls", IFCAP_TXTLS, setifcap), 2010 DEF_CMD("-txtls", -IFCAP_TXTLS, setifcap), 2011 DEF_CMD_SARG("rxtls", IFCAP2_RXTLS4_NAME "," IFCAP2_RXTLS6_NAME, 2012 setifcapnv), 2013 DEF_CMD_SARG("-rxtls", "-"IFCAP2_RXTLS4_NAME ",-" IFCAP2_RXTLS6_NAME, 2014 setifcapnv), 2015 DEF_CMD("wol", IFCAP_WOL, setifcap), 2016 DEF_CMD("-wol", -IFCAP_WOL, setifcap), 2017 DEF_CMD("wol_ucast", IFCAP_WOL_UCAST, setifcap), 2018 DEF_CMD("-wol_ucast", -IFCAP_WOL_UCAST, setifcap), 2019 DEF_CMD("wol_mcast", IFCAP_WOL_MCAST, setifcap), 2020 DEF_CMD("-wol_mcast", -IFCAP_WOL_MCAST, setifcap), 2021 DEF_CMD("wol_magic", IFCAP_WOL_MAGIC, setifcap), 2022 DEF_CMD("-wol_magic", -IFCAP_WOL_MAGIC, setifcap), 2023 DEF_CMD("txrtlmt", IFCAP_TXRTLMT, setifcap), 2024 DEF_CMD("-txrtlmt", -IFCAP_TXRTLMT, setifcap), 2025 DEF_CMD("txtlsrtlmt", IFCAP_TXTLS_RTLMT, setifcap), 2026 DEF_CMD("-txtlsrtlmt", -IFCAP_TXTLS_RTLMT, setifcap), 2027 DEF_CMD("hwrxtstmp", IFCAP_HWRXTSTMP, setifcap), 2028 DEF_CMD("-hwrxtstmp", -IFCAP_HWRXTSTMP, setifcap), 2029 DEF_CMD("normal", -IFF_LINK0, setifflags), 2030 DEF_CMD("compress", IFF_LINK0, setifflags), 2031 DEF_CMD("noicmp", IFF_LINK1, setifflags), 2032 DEF_CMD_ARG("mtu", setifmtu), 2033 DEF_CMD_ARG("name", setifname), 2034 }; 2035 2036 static __constructor void 2037 ifconfig_ctor(void) 2038 { 2039 size_t i; 2040 2041 for (i = 0; i < nitems(basic_cmds); i++) 2042 cmd_register(&basic_cmds[i]); 2043 } 2044