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 #endif /* not lint */ 37 38 #ifndef lint 39 #if 0 40 static char sccsid[] = "@(#)ifconfig.c 8.2 (Berkeley) 2/16/94"; 41 #endif 42 static const char rcsid[] = 43 "$FreeBSD$"; 44 #endif /* not lint */ 45 46 #include <sys/param.h> 47 #include <sys/ioctl.h> 48 #include <sys/module.h> 49 #include <sys/linker.h> 50 #include <sys/queue.h> 51 #include <sys/socket.h> 52 #include <sys/time.h> 53 54 #include <net/ethernet.h> 55 #include <net/if.h> 56 #include <net/if_dl.h> 57 #include <net/if_types.h> 58 #include <net/route.h> 59 60 /* IP */ 61 #include <netinet/in.h> 62 #include <netinet/in_var.h> 63 #include <arpa/inet.h> 64 #include <netdb.h> 65 66 #include <ifaddrs.h> 67 #include <ctype.h> 68 #include <err.h> 69 #include <errno.h> 70 #include <fcntl.h> 71 #ifdef JAIL 72 #include <jail.h> 73 #endif 74 #include <stdio.h> 75 #include <stdlib.h> 76 #include <string.h> 77 #include <unistd.h> 78 79 #include "ifconfig.h" 80 81 /* 82 * Since "struct ifreq" is composed of various union members, callers 83 * should pay special attention to interpret the value. 84 * (.e.g. little/big endian difference in the structure.) 85 */ 86 struct ifreq ifr; 87 88 char name[IFNAMSIZ]; 89 char *descr = NULL; 90 size_t descrlen = 64; 91 int setaddr; 92 int setmask; 93 int doalias; 94 int clearaddr; 95 int newaddr = 1; 96 int verbose; 97 int noload; 98 int printifname = 0; 99 100 int supmedia = 0; 101 int printkeys = 0; /* Print keying material for interfaces. */ 102 int exit_code = 0; 103 104 /* Formatter Strings */ 105 char *f_inet, *f_inet6, *f_ether, *f_addr; 106 107 static int ifconfig(int argc, char *const *argv, int iscreate, 108 const struct afswtch *afp); 109 static void status(const struct afswtch *afp, const struct sockaddr_dl *sdl, 110 struct ifaddrs *ifa); 111 static void tunnel_status(int s); 112 static void usage(void) _Noreturn; 113 114 static struct afswtch *af_getbyname(const char *name); 115 static struct afswtch *af_getbyfamily(int af); 116 static void af_other_status(int); 117 118 void printifnamemaybe(void); 119 120 static struct option *opts = NULL; 121 122 struct ifa_order_elt { 123 int if_order; 124 int af_orders[255]; 125 struct ifaddrs *ifa; 126 TAILQ_ENTRY(ifa_order_elt) link; 127 }; 128 129 TAILQ_HEAD(ifa_queue, ifa_order_elt); 130 131 void 132 opt_register(struct option *p) 133 { 134 p->next = opts; 135 opts = p; 136 } 137 138 static void 139 usage(void) 140 { 141 char options[1024]; 142 struct option *p; 143 144 /* XXX not right but close enough for now */ 145 options[0] = '\0'; 146 for (p = opts; p != NULL; p = p->next) { 147 strlcat(options, p->opt_usage, sizeof(options)); 148 strlcat(options, " ", sizeof(options)); 149 } 150 151 fprintf(stderr, 152 "usage: ifconfig [-f type:format] %sinterface address_family\n" 153 " [address [dest_address]] [parameters]\n" 154 " ifconfig interface create\n" 155 " ifconfig -a %s[-d] [-m] [-u] [-v] [address_family]\n" 156 " ifconfig -l [-d] [-u] [address_family]\n" 157 " ifconfig %s[-d] [-m] [-u] [-v]\n", 158 options, options, options); 159 exit(1); 160 } 161 162 #define ORDERS_SIZE(x) sizeof(x) / sizeof(x[0]) 163 164 static int 165 calcorders(struct ifaddrs *ifa, struct ifa_queue *q) 166 { 167 struct ifaddrs *prev; 168 struct ifa_order_elt *cur; 169 unsigned int ord, af, ifa_ord; 170 171 prev = NULL; 172 cur = NULL; 173 ord = 0; 174 ifa_ord = 0; 175 176 while (ifa != NULL) { 177 if (prev == NULL || 178 strcmp(ifa->ifa_name, prev->ifa_name) != 0) { 179 cur = calloc(1, sizeof(*cur)); 180 181 if (cur == NULL) 182 return (-1); 183 184 TAILQ_INSERT_TAIL(q, cur, link); 185 cur->if_order = ifa_ord ++; 186 cur->ifa = ifa; 187 ord = 0; 188 } 189 190 if (ifa->ifa_addr) { 191 af = ifa->ifa_addr->sa_family; 192 193 if (af < ORDERS_SIZE(cur->af_orders) && 194 cur->af_orders[af] == 0) 195 cur->af_orders[af] = ++ord; 196 } 197 prev = ifa; 198 ifa = ifa->ifa_next; 199 } 200 201 return (0); 202 } 203 204 static int 205 cmpifaddrs(struct ifaddrs *a, struct ifaddrs *b, struct ifa_queue *q) 206 { 207 struct ifa_order_elt *cur, *e1, *e2; 208 unsigned int af1, af2; 209 int ret; 210 211 e1 = e2 = NULL; 212 213 ret = strcmp(a->ifa_name, b->ifa_name); 214 if (ret != 0) { 215 TAILQ_FOREACH(cur, q, link) { 216 if (e1 && e2) 217 break; 218 219 if (strcmp(cur->ifa->ifa_name, a->ifa_name) == 0) 220 e1 = cur; 221 else if (strcmp(cur->ifa->ifa_name, b->ifa_name) == 0) 222 e2 = cur; 223 } 224 225 if (!e1 || !e2) 226 return (0); 227 else 228 return (e1->if_order - e2->if_order); 229 230 } else if (a->ifa_addr != NULL && b->ifa_addr != NULL) { 231 TAILQ_FOREACH(cur, q, link) { 232 if (strcmp(cur->ifa->ifa_name, a->ifa_name) == 0) { 233 e1 = cur; 234 break; 235 } 236 } 237 238 if (!e1) 239 return (0); 240 241 af1 = a->ifa_addr->sa_family; 242 af2 = b->ifa_addr->sa_family; 243 244 if (af1 < ORDERS_SIZE(e1->af_orders) && 245 af2 < ORDERS_SIZE(e1->af_orders)) 246 return (e1->af_orders[af1] - e1->af_orders[af2]); 247 } 248 249 return (0); 250 } 251 252 static void freeformat(void) 253 { 254 255 if (f_inet != NULL) 256 free(f_inet); 257 if (f_inet6 != NULL) 258 free(f_inet6); 259 if (f_ether != NULL) 260 free(f_ether); 261 if (f_addr != NULL) 262 free(f_addr); 263 } 264 265 static void setformat(char *input) 266 { 267 char *formatstr, *category, *modifier; 268 269 formatstr = strdup(input); 270 while ((category = strsep(&formatstr, ",")) != NULL) { 271 modifier = strchr(category, ':'); 272 if (modifier == NULL || modifier[1] == '\0') { 273 warnx("Skipping invalid format specification: %s\n", 274 category); 275 continue; 276 } 277 278 /* Split the string on the separator, then seek past it */ 279 modifier[0] = '\0'; 280 modifier++; 281 282 if (strcmp(category, "addr") == 0) 283 f_addr = strdup(modifier); 284 else if (strcmp(category, "ether") == 0) 285 f_ether = strdup(modifier); 286 else if (strcmp(category, "inet") == 0) 287 f_inet = strdup(modifier); 288 else if (strcmp(category, "inet6") == 0) 289 f_inet6 = strdup(modifier); 290 } 291 free(formatstr); 292 } 293 294 #undef ORDERS_SIZE 295 296 static struct ifaddrs * 297 sortifaddrs(struct ifaddrs *list, 298 int (*compare)(struct ifaddrs *, struct ifaddrs *, struct ifa_queue *), 299 struct ifa_queue *q) 300 { 301 struct ifaddrs *right, *temp, *last, *result, *next, *tail; 302 303 right = list; 304 temp = list; 305 last = list; 306 result = NULL; 307 next = NULL; 308 tail = NULL; 309 310 if (!list || !list->ifa_next) 311 return (list); 312 313 while (temp && temp->ifa_next) { 314 last = right; 315 right = right->ifa_next; 316 temp = temp->ifa_next->ifa_next; 317 } 318 319 last->ifa_next = NULL; 320 321 list = sortifaddrs(list, compare, q); 322 right = sortifaddrs(right, compare, q); 323 324 while (list || right) { 325 326 if (!right) { 327 next = list; 328 list = list->ifa_next; 329 } else if (!list) { 330 next = right; 331 right = right->ifa_next; 332 } else if (compare(list, right, q) <= 0) { 333 next = list; 334 list = list->ifa_next; 335 } else { 336 next = right; 337 right = right->ifa_next; 338 } 339 340 if (!result) 341 result = next; 342 else 343 tail->ifa_next = next; 344 345 tail = next; 346 } 347 348 return (result); 349 } 350 351 void printifnamemaybe() 352 { 353 if (printifname) 354 printf("%s\n", name); 355 } 356 357 int 358 main(int argc, char *argv[]) 359 { 360 int c, all, namesonly, downonly, uponly; 361 const struct afswtch *afp = NULL; 362 int ifindex; 363 struct ifaddrs *ifap, *sifap, *ifa; 364 struct ifreq paifr; 365 const struct sockaddr_dl *sdl; 366 char options[1024], *cp, *envformat, *namecp = NULL; 367 struct ifa_queue q = TAILQ_HEAD_INITIALIZER(q); 368 struct ifa_order_elt *cur, *tmp; 369 const char *ifname; 370 struct option *p; 371 size_t iflen; 372 373 all = downonly = uponly = namesonly = noload = verbose = 0; 374 f_inet = f_inet6 = f_ether = f_addr = NULL; 375 376 envformat = getenv("IFCONFIG_FORMAT"); 377 if (envformat != NULL) 378 setformat(envformat); 379 380 /* 381 * Ensure we print interface name when expected to, 382 * even if we terminate early due to error. 383 */ 384 atexit(printifnamemaybe); 385 386 /* Parse leading line options */ 387 strlcpy(options, "f:adklmnuv", sizeof(options)); 388 for (p = opts; p != NULL; p = p->next) 389 strlcat(options, p->opt, sizeof(options)); 390 while ((c = getopt(argc, argv, options)) != -1) { 391 switch (c) { 392 case 'a': /* scan all interfaces */ 393 all++; 394 break; 395 case 'd': /* restrict scan to "down" interfaces */ 396 downonly++; 397 break; 398 case 'f': 399 if (optarg == NULL) 400 usage(); 401 setformat(optarg); 402 break; 403 case 'k': 404 printkeys++; 405 break; 406 case 'l': /* scan interface names only */ 407 namesonly++; 408 break; 409 case 'm': /* show media choices in status */ 410 supmedia = 1; 411 break; 412 case 'n': /* suppress module loading */ 413 noload++; 414 break; 415 case 'u': /* restrict scan to "up" interfaces */ 416 uponly++; 417 break; 418 case 'v': 419 verbose++; 420 break; 421 default: 422 for (p = opts; p != NULL; p = p->next) 423 if (p->opt[0] == c) { 424 p->cb(optarg); 425 break; 426 } 427 if (p == NULL) 428 usage(); 429 break; 430 } 431 } 432 argc -= optind; 433 argv += optind; 434 435 /* -l cannot be used with -a or -m */ 436 if (namesonly && (all || supmedia)) 437 usage(); 438 439 /* nonsense.. */ 440 if (uponly && downonly) 441 usage(); 442 443 /* no arguments is equivalent to '-a' */ 444 if (!namesonly && argc < 1) 445 all = 1; 446 447 /* -a and -l allow an address family arg to limit the output */ 448 if (all || namesonly) { 449 if (argc > 1) 450 usage(); 451 452 ifname = NULL; 453 ifindex = 0; 454 if (argc == 1) { 455 afp = af_getbyname(*argv); 456 if (afp == NULL) { 457 warnx("Address family '%s' unknown.", *argv); 458 usage(); 459 } 460 if (afp->af_name != NULL) 461 argc--, argv++; 462 /* leave with afp non-zero */ 463 } 464 } else { 465 /* not listing, need an argument */ 466 if (argc < 1) 467 usage(); 468 469 ifname = *argv; 470 argc--, argv++; 471 472 /* check and maybe load support for this interface */ 473 ifmaybeload(ifname); 474 475 ifindex = if_nametoindex(ifname); 476 if (ifindex == 0) { 477 /* 478 * NOTE: We must special-case the `create' command 479 * right here as we would otherwise fail when trying 480 * to find the interface. 481 */ 482 if (argc > 0 && (strcmp(argv[0], "create") == 0 || 483 strcmp(argv[0], "plumb") == 0)) { 484 iflen = strlcpy(name, ifname, sizeof(name)); 485 if (iflen >= sizeof(name)) 486 errx(1, "%s: cloning name too long", 487 ifname); 488 ifconfig(argc, argv, 1, NULL); 489 exit(exit_code); 490 } 491 #ifdef JAIL 492 /* 493 * NOTE: We have to special-case the `-vnet' command 494 * right here as we would otherwise fail when trying 495 * to find the interface as it lives in another vnet. 496 */ 497 if (argc > 0 && (strcmp(argv[0], "-vnet") == 0)) { 498 iflen = strlcpy(name, ifname, sizeof(name)); 499 if (iflen >= sizeof(name)) 500 errx(1, "%s: interface name too long", 501 ifname); 502 ifconfig(argc, argv, 0, NULL); 503 exit(exit_code); 504 } 505 #endif 506 errx(1, "interface %s does not exist", ifname); 507 } 508 } 509 510 /* Check for address family */ 511 if (argc > 0) { 512 afp = af_getbyname(*argv); 513 if (afp != NULL) 514 argc--, argv++; 515 } 516 517 if (getifaddrs(&ifap) != 0) 518 err(EXIT_FAILURE, "getifaddrs"); 519 520 cp = NULL; 521 522 if (calcorders(ifap, &q) != 0) 523 err(EXIT_FAILURE, "calcorders"); 524 525 sifap = sortifaddrs(ifap, cmpifaddrs, &q); 526 527 TAILQ_FOREACH_SAFE(cur, &q, link, tmp) 528 free(cur); 529 530 ifindex = 0; 531 for (ifa = sifap; ifa; ifa = ifa->ifa_next) { 532 memset(&paifr, 0, sizeof(paifr)); 533 strlcpy(paifr.ifr_name, ifa->ifa_name, sizeof(paifr.ifr_name)); 534 if (sizeof(paifr.ifr_addr) >= ifa->ifa_addr->sa_len) { 535 memcpy(&paifr.ifr_addr, ifa->ifa_addr, 536 ifa->ifa_addr->sa_len); 537 } 538 539 if (ifname != NULL && strcmp(ifname, ifa->ifa_name) != 0) 540 continue; 541 if (ifa->ifa_addr->sa_family == AF_LINK) 542 sdl = (const struct sockaddr_dl *) ifa->ifa_addr; 543 else 544 sdl = NULL; 545 if (cp != NULL && strcmp(cp, ifa->ifa_name) == 0 && !namesonly) 546 continue; 547 iflen = strlcpy(name, ifa->ifa_name, sizeof(name)); 548 if (iflen >= sizeof(name)) { 549 warnx("%s: interface name too long, skipping", 550 ifa->ifa_name); 551 continue; 552 } 553 cp = ifa->ifa_name; 554 555 if ((ifa->ifa_flags & IFF_CANTCONFIG) != 0) 556 continue; 557 if (downonly && (ifa->ifa_flags & IFF_UP) != 0) 558 continue; 559 if (uponly && (ifa->ifa_flags & IFF_UP) == 0) 560 continue; 561 /* 562 * Are we just listing the interfaces? 563 */ 564 if (namesonly) { 565 if (namecp == cp) 566 continue; 567 if (afp != NULL) { 568 /* special case for "ether" address family */ 569 if (!strcmp(afp->af_name, "ether")) { 570 if (sdl == NULL || 571 (sdl->sdl_type != IFT_ETHER && 572 sdl->sdl_type != IFT_L2VLAN && 573 sdl->sdl_type != IFT_BRIDGE) || 574 sdl->sdl_alen != ETHER_ADDR_LEN) 575 continue; 576 } else { 577 if (ifa->ifa_addr->sa_family 578 != afp->af_af) 579 continue; 580 } 581 } 582 namecp = cp; 583 ifindex++; 584 if (ifindex > 1) 585 printf(" "); 586 fputs(name, stdout); 587 continue; 588 } 589 ifindex++; 590 591 if (argc > 0) 592 ifconfig(argc, argv, 0, afp); 593 else 594 status(afp, sdl, ifa); 595 } 596 if (namesonly) 597 printf("\n"); 598 freeifaddrs(ifap); 599 600 freeformat(); 601 exit(exit_code); 602 } 603 604 static struct afswtch *afs = NULL; 605 606 void 607 af_register(struct afswtch *p) 608 { 609 p->af_next = afs; 610 afs = p; 611 } 612 613 static struct afswtch * 614 af_getbyname(const char *name) 615 { 616 struct afswtch *afp; 617 618 for (afp = afs; afp != NULL; afp = afp->af_next) 619 if (strcmp(afp->af_name, name) == 0) 620 return afp; 621 return NULL; 622 } 623 624 static struct afswtch * 625 af_getbyfamily(int af) 626 { 627 struct afswtch *afp; 628 629 for (afp = afs; afp != NULL; afp = afp->af_next) 630 if (afp->af_af == af) 631 return afp; 632 return NULL; 633 } 634 635 static void 636 af_other_status(int s) 637 { 638 struct afswtch *afp; 639 uint8_t afmask[howmany(AF_MAX, NBBY)]; 640 641 memset(afmask, 0, sizeof(afmask)); 642 for (afp = afs; afp != NULL; afp = afp->af_next) { 643 if (afp->af_other_status == NULL) 644 continue; 645 if (afp->af_af != AF_UNSPEC && isset(afmask, afp->af_af)) 646 continue; 647 afp->af_other_status(s); 648 setbit(afmask, afp->af_af); 649 } 650 } 651 652 static void 653 af_all_tunnel_status(int s) 654 { 655 struct afswtch *afp; 656 uint8_t afmask[howmany(AF_MAX, NBBY)]; 657 658 memset(afmask, 0, sizeof(afmask)); 659 for (afp = afs; afp != NULL; afp = afp->af_next) { 660 if (afp->af_status_tunnel == NULL) 661 continue; 662 if (afp->af_af != AF_UNSPEC && isset(afmask, afp->af_af)) 663 continue; 664 afp->af_status_tunnel(s); 665 setbit(afmask, afp->af_af); 666 } 667 } 668 669 static struct cmd *cmds = NULL; 670 671 void 672 cmd_register(struct cmd *p) 673 { 674 p->c_next = cmds; 675 cmds = p; 676 } 677 678 static const struct cmd * 679 cmd_lookup(const char *name, int iscreate) 680 { 681 const struct cmd *p; 682 683 for (p = cmds; p != NULL; p = p->c_next) 684 if (strcmp(name, p->c_name) == 0) { 685 if (iscreate) { 686 if (p->c_iscloneop) 687 return p; 688 } else { 689 if (!p->c_iscloneop) 690 return p; 691 } 692 } 693 return NULL; 694 } 695 696 struct callback { 697 callback_func *cb_func; 698 void *cb_arg; 699 struct callback *cb_next; 700 }; 701 static struct callback *callbacks = NULL; 702 703 void 704 callback_register(callback_func *func, void *arg) 705 { 706 struct callback *cb; 707 708 cb = malloc(sizeof(struct callback)); 709 if (cb == NULL) 710 errx(1, "unable to allocate memory for callback"); 711 cb->cb_func = func; 712 cb->cb_arg = arg; 713 cb->cb_next = callbacks; 714 callbacks = cb; 715 } 716 717 /* specially-handled commands */ 718 static void setifaddr(const char *, int, int, const struct afswtch *); 719 static const struct cmd setifaddr_cmd = DEF_CMD("ifaddr", 0, setifaddr); 720 721 static void setifdstaddr(const char *, int, int, const struct afswtch *); 722 static const struct cmd setifdstaddr_cmd = 723 DEF_CMD("ifdstaddr", 0, setifdstaddr); 724 725 static int 726 ifconfig(int argc, char *const *argv, int iscreate, const struct afswtch *uafp) 727 { 728 const struct afswtch *afp, *nafp; 729 const struct cmd *p; 730 struct callback *cb; 731 int s; 732 733 strlcpy(ifr.ifr_name, name, sizeof ifr.ifr_name); 734 afp = NULL; 735 if (uafp != NULL) 736 afp = uafp; 737 /* 738 * This is the historical "accident" allowing users to configure IPv4 739 * addresses without the "inet" keyword which while a nice feature has 740 * proven to complicate other things. We cannot remove this but only 741 * make sure we will never have a similar implicit default for IPv6 or 742 * any other address familiy. We need a fallback though for 743 * ifconfig IF up/down etc. to work without INET support as people 744 * never used ifconfig IF link up/down, etc. either. 745 */ 746 #ifndef RESCUE 747 #ifdef INET 748 if (afp == NULL && feature_present("inet")) 749 afp = af_getbyname("inet"); 750 #endif 751 #endif 752 if (afp == NULL) 753 afp = af_getbyname("link"); 754 if (afp == NULL) { 755 warnx("Please specify an address_family."); 756 usage(); 757 } 758 top: 759 ifr.ifr_addr.sa_family = 760 afp->af_af == AF_LINK || afp->af_af == AF_UNSPEC ? 761 AF_LOCAL : afp->af_af; 762 763 if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0 && 764 (uafp != NULL || errno != EAFNOSUPPORT || 765 (s = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0)) 766 err(1, "socket(family %u,SOCK_DGRAM)", ifr.ifr_addr.sa_family); 767 768 while (argc > 0) { 769 p = cmd_lookup(*argv, iscreate); 770 if (iscreate && p == NULL) { 771 /* 772 * Push the clone create callback so the new 773 * device is created and can be used for any 774 * remaining arguments. 775 */ 776 cb = callbacks; 777 if (cb == NULL) 778 errx(1, "internal error, no callback"); 779 callbacks = cb->cb_next; 780 cb->cb_func(s, cb->cb_arg); 781 iscreate = 0; 782 /* 783 * Handle any address family spec that 784 * immediately follows and potentially 785 * recreate the socket. 786 */ 787 nafp = af_getbyname(*argv); 788 if (nafp != NULL) { 789 argc--, argv++; 790 if (nafp != afp) { 791 close(s); 792 afp = nafp; 793 goto top; 794 } 795 } 796 /* 797 * Look for a normal parameter. 798 */ 799 continue; 800 } 801 if (p == NULL) { 802 /* 803 * Not a recognized command, choose between setting 804 * the interface address and the dst address. 805 */ 806 p = (setaddr ? &setifdstaddr_cmd : &setifaddr_cmd); 807 } 808 if (p->c_parameter == NEXTARG && p->c_u.c_func) { 809 if (argv[1] == NULL) 810 errx(1, "'%s' requires argument", 811 p->c_name); 812 p->c_u.c_func(argv[1], 0, s, afp); 813 argc--, argv++; 814 } else if (p->c_parameter == OPTARG && p->c_u.c_func) { 815 p->c_u.c_func(argv[1], 0, s, afp); 816 if (argv[1] != NULL) 817 argc--, argv++; 818 } else if (p->c_parameter == NEXTARG2 && p->c_u.c_func2) { 819 if (argc < 3) 820 errx(1, "'%s' requires 2 arguments", 821 p->c_name); 822 p->c_u.c_func2(argv[1], argv[2], s, afp); 823 argc -= 2, argv += 2; 824 } else if (p->c_u.c_func) 825 p->c_u.c_func(*argv, p->c_parameter, s, afp); 826 argc--, argv++; 827 } 828 829 /* 830 * Do any post argument processing required by the address family. 831 */ 832 if (afp->af_postproc != NULL) 833 afp->af_postproc(s, afp); 834 /* 835 * Do deferred callbacks registered while processing 836 * command-line arguments. 837 */ 838 for (cb = callbacks; cb != NULL; cb = cb->cb_next) 839 cb->cb_func(s, cb->cb_arg); 840 /* 841 * Do deferred operations. 842 */ 843 if (clearaddr) { 844 if (afp->af_ridreq == NULL || afp->af_difaddr == 0) { 845 warnx("interface %s cannot change %s addresses!", 846 name, afp->af_name); 847 clearaddr = 0; 848 } 849 } 850 if (clearaddr) { 851 int ret; 852 strlcpy(((struct ifreq *)afp->af_ridreq)->ifr_name, name, 853 sizeof ifr.ifr_name); 854 ret = ioctl(s, afp->af_difaddr, afp->af_ridreq); 855 if (ret < 0) { 856 if (errno == EADDRNOTAVAIL && (doalias >= 0)) { 857 /* means no previous address for interface */ 858 } else 859 Perror("ioctl (SIOCDIFADDR)"); 860 } 861 } 862 if (newaddr) { 863 if (afp->af_addreq == NULL || afp->af_aifaddr == 0) { 864 warnx("interface %s cannot change %s addresses!", 865 name, afp->af_name); 866 newaddr = 0; 867 } 868 } 869 if (newaddr && (setaddr || setmask)) { 870 strlcpy(((struct ifreq *)afp->af_addreq)->ifr_name, name, 871 sizeof ifr.ifr_name); 872 if (ioctl(s, afp->af_aifaddr, afp->af_addreq) < 0) 873 Perror("ioctl (SIOCAIFADDR)"); 874 } 875 876 close(s); 877 return(0); 878 } 879 880 /*ARGSUSED*/ 881 static void 882 setifaddr(const char *addr, int param, int s, const struct afswtch *afp) 883 { 884 if (afp->af_getaddr == NULL) 885 return; 886 /* 887 * Delay the ioctl to set the interface addr until flags are all set. 888 * The address interpretation may depend on the flags, 889 * and the flags may change when the address is set. 890 */ 891 setaddr++; 892 if (doalias == 0 && afp->af_af != AF_LINK) 893 clearaddr = 1; 894 afp->af_getaddr(addr, (doalias >= 0 ? ADDR : RIDADDR)); 895 } 896 897 static void 898 settunnel(const char *src, const char *dst, int s, const struct afswtch *afp) 899 { 900 struct addrinfo *srcres, *dstres; 901 int ecode; 902 903 if (afp->af_settunnel == NULL) { 904 warn("address family %s does not support tunnel setup", 905 afp->af_name); 906 return; 907 } 908 909 if ((ecode = getaddrinfo(src, NULL, NULL, &srcres)) != 0) 910 errx(1, "error in parsing address string: %s", 911 gai_strerror(ecode)); 912 913 if ((ecode = getaddrinfo(dst, NULL, NULL, &dstres)) != 0) 914 errx(1, "error in parsing address string: %s", 915 gai_strerror(ecode)); 916 917 if (srcres->ai_addr->sa_family != dstres->ai_addr->sa_family) 918 errx(1, 919 "source and destination address families do not match"); 920 921 afp->af_settunnel(s, srcres, dstres); 922 923 freeaddrinfo(srcres); 924 freeaddrinfo(dstres); 925 } 926 927 /* ARGSUSED */ 928 static void 929 deletetunnel(const char *vname, int param, int s, const struct afswtch *afp) 930 { 931 932 if (ioctl(s, SIOCDIFPHYADDR, &ifr) < 0) 933 err(1, "SIOCDIFPHYADDR"); 934 } 935 936 #ifdef JAIL 937 static void 938 setifvnet(const char *jname, int dummy __unused, int s, 939 const struct afswtch *afp) 940 { 941 struct ifreq my_ifr; 942 943 memcpy(&my_ifr, &ifr, sizeof(my_ifr)); 944 my_ifr.ifr_jid = jail_getid(jname); 945 if (my_ifr.ifr_jid < 0) 946 errx(1, "%s", jail_errmsg); 947 if (ioctl(s, SIOCSIFVNET, &my_ifr) < 0) 948 err(1, "SIOCSIFVNET"); 949 } 950 951 static void 952 setifrvnet(const char *jname, int dummy __unused, int s, 953 const struct afswtch *afp) 954 { 955 struct ifreq my_ifr; 956 957 memcpy(&my_ifr, &ifr, sizeof(my_ifr)); 958 my_ifr.ifr_jid = jail_getid(jname); 959 if (my_ifr.ifr_jid < 0) 960 errx(1, "%s", jail_errmsg); 961 if (ioctl(s, SIOCSIFRVNET, &my_ifr) < 0) 962 err(1, "SIOCSIFRVNET(%d, %s)", my_ifr.ifr_jid, my_ifr.ifr_name); 963 } 964 #endif 965 966 static void 967 setifnetmask(const char *addr, int dummy __unused, int s, 968 const struct afswtch *afp) 969 { 970 if (afp->af_getaddr != NULL) { 971 setmask++; 972 afp->af_getaddr(addr, MASK); 973 } 974 } 975 976 static void 977 setifbroadaddr(const char *addr, int dummy __unused, int s, 978 const struct afswtch *afp) 979 { 980 if (afp->af_getaddr != NULL) 981 afp->af_getaddr(addr, DSTADDR); 982 } 983 984 static void 985 notealias(const char *addr, int param, int s, const struct afswtch *afp) 986 { 987 #define rqtosa(x) (&(((struct ifreq *)(afp->x))->ifr_addr)) 988 if (setaddr && doalias == 0 && param < 0) 989 if (afp->af_addreq != NULL && afp->af_ridreq != NULL) 990 bcopy((caddr_t)rqtosa(af_addreq), 991 (caddr_t)rqtosa(af_ridreq), 992 rqtosa(af_addreq)->sa_len); 993 doalias = param; 994 if (param < 0) { 995 clearaddr = 1; 996 newaddr = 0; 997 } else 998 clearaddr = 0; 999 #undef rqtosa 1000 } 1001 1002 /*ARGSUSED*/ 1003 static void 1004 setifdstaddr(const char *addr, int param __unused, int s, 1005 const struct afswtch *afp) 1006 { 1007 if (afp->af_getaddr != NULL) 1008 afp->af_getaddr(addr, DSTADDR); 1009 } 1010 1011 /* 1012 * Note: doing an SIOCIGIFFLAGS scribbles on the union portion 1013 * of the ifreq structure, which may confuse other parts of ifconfig. 1014 * Make a private copy so we can avoid that. 1015 */ 1016 static void 1017 setifflags(const char *vname, int value, int s, const struct afswtch *afp) 1018 { 1019 struct ifreq my_ifr; 1020 int flags; 1021 1022 memset(&my_ifr, 0, sizeof(my_ifr)); 1023 (void) strlcpy(my_ifr.ifr_name, name, sizeof(my_ifr.ifr_name)); 1024 1025 if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&my_ifr) < 0) { 1026 Perror("ioctl (SIOCGIFFLAGS)"); 1027 exit(1); 1028 } 1029 flags = (my_ifr.ifr_flags & 0xffff) | (my_ifr.ifr_flagshigh << 16); 1030 1031 if (value < 0) { 1032 value = -value; 1033 flags &= ~value; 1034 } else 1035 flags |= value; 1036 my_ifr.ifr_flags = flags & 0xffff; 1037 my_ifr.ifr_flagshigh = flags >> 16; 1038 if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&my_ifr) < 0) 1039 Perror(vname); 1040 } 1041 1042 void 1043 setifcap(const char *vname, int value, int s, const struct afswtch *afp) 1044 { 1045 int flags; 1046 1047 if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) < 0) { 1048 Perror("ioctl (SIOCGIFCAP)"); 1049 exit(1); 1050 } 1051 flags = ifr.ifr_curcap; 1052 if (value < 0) { 1053 value = -value; 1054 flags &= ~value; 1055 } else 1056 flags |= value; 1057 flags &= ifr.ifr_reqcap; 1058 ifr.ifr_reqcap = flags; 1059 if (ioctl(s, SIOCSIFCAP, (caddr_t)&ifr) < 0) 1060 Perror(vname); 1061 } 1062 1063 static void 1064 setifmetric(const char *val, int dummy __unused, int s, 1065 const struct afswtch *afp) 1066 { 1067 strlcpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 1068 ifr.ifr_metric = atoi(val); 1069 if (ioctl(s, SIOCSIFMETRIC, (caddr_t)&ifr) < 0) 1070 err(1, "ioctl SIOCSIFMETRIC (set metric)"); 1071 } 1072 1073 static void 1074 setifmtu(const char *val, int dummy __unused, int s, 1075 const struct afswtch *afp) 1076 { 1077 strlcpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 1078 ifr.ifr_mtu = atoi(val); 1079 if (ioctl(s, SIOCSIFMTU, (caddr_t)&ifr) < 0) 1080 err(1, "ioctl SIOCSIFMTU (set mtu)"); 1081 } 1082 1083 static void 1084 setifpcp(const char *val, int arg __unused, int s, const struct afswtch *afp) 1085 { 1086 u_long ul; 1087 char *endp; 1088 1089 ul = strtoul(val, &endp, 0); 1090 if (*endp != '\0') 1091 errx(1, "invalid value for pcp"); 1092 if (ul > 7) 1093 errx(1, "value for pcp out of range"); 1094 ifr.ifr_lan_pcp = ul; 1095 if (ioctl(s, SIOCSLANPCP, (caddr_t)&ifr) == -1) 1096 err(1, "SIOCSLANPCP"); 1097 } 1098 1099 static void 1100 disableifpcp(const char *val, int arg __unused, int s, 1101 const struct afswtch *afp) 1102 { 1103 1104 ifr.ifr_lan_pcp = IFNET_PCP_NONE; 1105 if (ioctl(s, SIOCSLANPCP, (caddr_t)&ifr) == -1) 1106 err(1, "SIOCSLANPCP"); 1107 } 1108 1109 static void 1110 setifname(const char *val, int dummy __unused, int s, 1111 const struct afswtch *afp) 1112 { 1113 char *newname; 1114 1115 strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 1116 1117 newname = strdup(val); 1118 if (newname == NULL) 1119 err(1, "no memory to set ifname"); 1120 ifr.ifr_data = newname; 1121 if (ioctl(s, SIOCSIFNAME, (caddr_t)&ifr) < 0) { 1122 free(newname); 1123 err(1, "ioctl SIOCSIFNAME (set name)"); 1124 } 1125 printifname = 1; 1126 strlcpy(name, newname, sizeof(name)); 1127 free(newname); 1128 } 1129 1130 /* ARGSUSED */ 1131 static void 1132 setifdescr(const char *val, int dummy __unused, int s, 1133 const struct afswtch *afp) 1134 { 1135 char *newdescr; 1136 1137 strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 1138 1139 ifr.ifr_buffer.length = strlen(val) + 1; 1140 if (ifr.ifr_buffer.length == 1) { 1141 ifr.ifr_buffer.buffer = newdescr = NULL; 1142 ifr.ifr_buffer.length = 0; 1143 } else { 1144 newdescr = strdup(val); 1145 ifr.ifr_buffer.buffer = newdescr; 1146 if (newdescr == NULL) { 1147 warn("no memory to set ifdescr"); 1148 return; 1149 } 1150 } 1151 1152 if (ioctl(s, SIOCSIFDESCR, (caddr_t)&ifr) < 0) 1153 err(1, "ioctl SIOCSIFDESCR (set descr)"); 1154 1155 free(newdescr); 1156 } 1157 1158 /* ARGSUSED */ 1159 static void 1160 unsetifdescr(const char *val, int value, int s, const struct afswtch *afp) 1161 { 1162 1163 setifdescr("", 0, s, 0); 1164 } 1165 1166 #define IFFBITS \ 1167 "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\7RUNNING" \ 1168 "\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2" \ 1169 "\20MULTICAST\22PPROMISC\23MONITOR\24STATICARP" 1170 1171 #define IFCAPBITS \ 1172 "\020\1RXCSUM\2TXCSUM\3NETCONS\4VLAN_MTU\5VLAN_HWTAGGING\6JUMBO_MTU\7POLLING" \ 1173 "\10VLAN_HWCSUM\11TSO4\12TSO6\13LRO\14WOL_UCAST\15WOL_MCAST\16WOL_MAGIC" \ 1174 "\17TOE4\20TOE6\21VLAN_HWFILTER\23VLAN_HWTSO\24LINKSTATE\25NETMAP" \ 1175 "\26RXCSUM_IPV6\27TXCSUM_IPV6\31TXRTLMT\32HWRXTSTMP" 1176 1177 /* 1178 * Print the status of the interface. If an address family was 1179 * specified, show only it; otherwise, show them all. 1180 */ 1181 static void 1182 status(const struct afswtch *afp, const struct sockaddr_dl *sdl, 1183 struct ifaddrs *ifa) 1184 { 1185 struct ifaddrs *ift; 1186 int allfamilies, s; 1187 struct ifstat ifs; 1188 1189 if (afp == NULL) { 1190 allfamilies = 1; 1191 ifr.ifr_addr.sa_family = AF_LOCAL; 1192 } else { 1193 allfamilies = 0; 1194 ifr.ifr_addr.sa_family = 1195 afp->af_af == AF_LINK ? AF_LOCAL : afp->af_af; 1196 } 1197 strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 1198 1199 s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0); 1200 if (s < 0) 1201 err(1, "socket(family %u,SOCK_DGRAM)", ifr.ifr_addr.sa_family); 1202 1203 printf("%s: ", name); 1204 printb("flags", ifa->ifa_flags, IFFBITS); 1205 if (ioctl(s, SIOCGIFMETRIC, &ifr) != -1) 1206 printf(" metric %d", ifr.ifr_metric); 1207 if (ioctl(s, SIOCGIFMTU, &ifr) != -1) 1208 printf(" mtu %d", ifr.ifr_mtu); 1209 putchar('\n'); 1210 1211 for (;;) { 1212 if ((descr = reallocf(descr, descrlen)) != NULL) { 1213 ifr.ifr_buffer.buffer = descr; 1214 ifr.ifr_buffer.length = descrlen; 1215 if (ioctl(s, SIOCGIFDESCR, &ifr) == 0) { 1216 if (ifr.ifr_buffer.buffer == descr) { 1217 if (strlen(descr) > 0) 1218 printf("\tdescription: %s\n", 1219 descr); 1220 } else if (ifr.ifr_buffer.length > descrlen) { 1221 descrlen = ifr.ifr_buffer.length; 1222 continue; 1223 } 1224 } 1225 } else 1226 warn("unable to allocate memory for interface" 1227 "description"); 1228 break; 1229 } 1230 1231 if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) == 0) { 1232 if (ifr.ifr_curcap != 0) { 1233 printb("\toptions", ifr.ifr_curcap, IFCAPBITS); 1234 putchar('\n'); 1235 } 1236 if (supmedia && ifr.ifr_reqcap != 0) { 1237 printb("\tcapabilities", ifr.ifr_reqcap, IFCAPBITS); 1238 putchar('\n'); 1239 } 1240 } 1241 1242 tunnel_status(s); 1243 1244 for (ift = ifa; ift != NULL; ift = ift->ifa_next) { 1245 if (ift->ifa_addr == NULL) 1246 continue; 1247 if (strcmp(ifa->ifa_name, ift->ifa_name) != 0) 1248 continue; 1249 if (allfamilies) { 1250 const struct afswtch *p; 1251 p = af_getbyfamily(ift->ifa_addr->sa_family); 1252 if (p != NULL && p->af_status != NULL) 1253 p->af_status(s, ift); 1254 } else if (afp->af_af == ift->ifa_addr->sa_family) 1255 afp->af_status(s, ift); 1256 } 1257 #if 0 1258 if (allfamilies || afp->af_af == AF_LINK) { 1259 const struct afswtch *lafp; 1260 1261 /* 1262 * Hack; the link level address is received separately 1263 * from the routing information so any address is not 1264 * handled above. Cobble together an entry and invoke 1265 * the status method specially. 1266 */ 1267 lafp = af_getbyname("lladdr"); 1268 if (lafp != NULL) { 1269 info.rti_info[RTAX_IFA] = (struct sockaddr *)sdl; 1270 lafp->af_status(s, &info); 1271 } 1272 } 1273 #endif 1274 if (allfamilies) 1275 af_other_status(s); 1276 else if (afp->af_other_status != NULL) 1277 afp->af_other_status(s); 1278 1279 strlcpy(ifs.ifs_name, name, sizeof ifs.ifs_name); 1280 if (ioctl(s, SIOCGIFSTATUS, &ifs) == 0) 1281 printf("%s", ifs.ascii); 1282 1283 if (verbose > 0) 1284 sfp_status(s, &ifr, verbose); 1285 1286 close(s); 1287 return; 1288 } 1289 1290 static void 1291 tunnel_status(int s) 1292 { 1293 af_all_tunnel_status(s); 1294 } 1295 1296 void 1297 Perror(const char *cmd) 1298 { 1299 switch (errno) { 1300 1301 case ENXIO: 1302 errx(1, "%s: no such interface", cmd); 1303 break; 1304 1305 case EPERM: 1306 errx(1, "%s: permission denied", cmd); 1307 break; 1308 1309 default: 1310 err(1, "%s", cmd); 1311 } 1312 } 1313 1314 /* 1315 * Print a value a la the %b format of the kernel's printf 1316 */ 1317 void 1318 printb(const char *s, unsigned v, const char *bits) 1319 { 1320 int i, any = 0; 1321 char c; 1322 1323 if (bits && *bits == 8) 1324 printf("%s=%o", s, v); 1325 else 1326 printf("%s=%x", s, v); 1327 if (bits) { 1328 bits++; 1329 putchar('<'); 1330 while ((i = *bits++) != '\0') { 1331 if (v & (1 << (i-1))) { 1332 if (any) 1333 putchar(','); 1334 any = 1; 1335 for (; (c = *bits) > 32; bits++) 1336 putchar(c); 1337 } else 1338 for (; *bits > 32; bits++) 1339 ; 1340 } 1341 putchar('>'); 1342 } 1343 } 1344 1345 void 1346 print_vhid(const struct ifaddrs *ifa, const char *s) 1347 { 1348 struct if_data *ifd; 1349 1350 if (ifa->ifa_data == NULL) 1351 return; 1352 1353 ifd = ifa->ifa_data; 1354 if (ifd->ifi_vhid == 0) 1355 return; 1356 1357 printf("vhid %d ", ifd->ifi_vhid); 1358 } 1359 1360 void 1361 ifmaybeload(const char *name) 1362 { 1363 #define MOD_PREFIX_LEN 3 /* "if_" */ 1364 struct module_stat mstat; 1365 int fileid, modid; 1366 char ifkind[IFNAMSIZ + MOD_PREFIX_LEN], ifname[IFNAMSIZ], *dp; 1367 const char *cp; 1368 1369 /* loading suppressed by the user */ 1370 if (noload) 1371 return; 1372 1373 /* trim the interface number off the end */ 1374 strlcpy(ifname, name, sizeof(ifname)); 1375 for (dp = ifname; *dp != 0; dp++) 1376 if (isdigit(*dp)) { 1377 *dp = 0; 1378 break; 1379 } 1380 1381 /* turn interface and unit into module name */ 1382 strlcpy(ifkind, "if_", sizeof(ifkind)); 1383 strlcat(ifkind, ifname, sizeof(ifkind)); 1384 1385 /* scan files in kernel */ 1386 mstat.version = sizeof(struct module_stat); 1387 for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid)) { 1388 /* scan modules in file */ 1389 for (modid = kldfirstmod(fileid); modid > 0; 1390 modid = modfnext(modid)) { 1391 if (modstat(modid, &mstat) < 0) 1392 continue; 1393 /* strip bus name if present */ 1394 if ((cp = strchr(mstat.name, '/')) != NULL) { 1395 cp++; 1396 } else { 1397 cp = mstat.name; 1398 } 1399 /* already loaded? */ 1400 if (strcmp(ifname, cp) == 0 || 1401 strcmp(ifkind, cp) == 0) 1402 return; 1403 } 1404 } 1405 1406 /* 1407 * Try to load the module. But ignore failures, because ifconfig can't 1408 * infer the names of all drivers (eg mlx4en(4)). 1409 */ 1410 (void) kldload(ifkind); 1411 } 1412 1413 static struct cmd basic_cmds[] = { 1414 DEF_CMD("up", IFF_UP, setifflags), 1415 DEF_CMD("down", -IFF_UP, setifflags), 1416 DEF_CMD("arp", -IFF_NOARP, setifflags), 1417 DEF_CMD("-arp", IFF_NOARP, setifflags), 1418 DEF_CMD("debug", IFF_DEBUG, setifflags), 1419 DEF_CMD("-debug", -IFF_DEBUG, setifflags), 1420 DEF_CMD_ARG("description", setifdescr), 1421 DEF_CMD_ARG("descr", setifdescr), 1422 DEF_CMD("-description", 0, unsetifdescr), 1423 DEF_CMD("-descr", 0, unsetifdescr), 1424 DEF_CMD("promisc", IFF_PPROMISC, setifflags), 1425 DEF_CMD("-promisc", -IFF_PPROMISC, setifflags), 1426 DEF_CMD("add", IFF_UP, notealias), 1427 DEF_CMD("alias", IFF_UP, notealias), 1428 DEF_CMD("-alias", -IFF_UP, notealias), 1429 DEF_CMD("delete", -IFF_UP, notealias), 1430 DEF_CMD("remove", -IFF_UP, notealias), 1431 #ifdef notdef 1432 #define EN_SWABIPS 0x1000 1433 DEF_CMD("swabips", EN_SWABIPS, setifflags), 1434 DEF_CMD("-swabips", -EN_SWABIPS, setifflags), 1435 #endif 1436 DEF_CMD_ARG("netmask", setifnetmask), 1437 DEF_CMD_ARG("metric", setifmetric), 1438 DEF_CMD_ARG("broadcast", setifbroadaddr), 1439 DEF_CMD_ARG2("tunnel", settunnel), 1440 DEF_CMD("-tunnel", 0, deletetunnel), 1441 DEF_CMD("deletetunnel", 0, deletetunnel), 1442 #ifdef JAIL 1443 DEF_CMD_ARG("vnet", setifvnet), 1444 DEF_CMD_ARG("-vnet", setifrvnet), 1445 #endif 1446 DEF_CMD("link0", IFF_LINK0, setifflags), 1447 DEF_CMD("-link0", -IFF_LINK0, setifflags), 1448 DEF_CMD("link1", IFF_LINK1, setifflags), 1449 DEF_CMD("-link1", -IFF_LINK1, setifflags), 1450 DEF_CMD("link2", IFF_LINK2, setifflags), 1451 DEF_CMD("-link2", -IFF_LINK2, setifflags), 1452 DEF_CMD("monitor", IFF_MONITOR, setifflags), 1453 DEF_CMD("-monitor", -IFF_MONITOR, setifflags), 1454 DEF_CMD("staticarp", IFF_STATICARP, setifflags), 1455 DEF_CMD("-staticarp", -IFF_STATICARP, setifflags), 1456 DEF_CMD("rxcsum6", IFCAP_RXCSUM_IPV6, setifcap), 1457 DEF_CMD("-rxcsum6", -IFCAP_RXCSUM_IPV6, setifcap), 1458 DEF_CMD("txcsum6", IFCAP_TXCSUM_IPV6, setifcap), 1459 DEF_CMD("-txcsum6", -IFCAP_TXCSUM_IPV6, setifcap), 1460 DEF_CMD("rxcsum", IFCAP_RXCSUM, setifcap), 1461 DEF_CMD("-rxcsum", -IFCAP_RXCSUM, setifcap), 1462 DEF_CMD("txcsum", IFCAP_TXCSUM, setifcap), 1463 DEF_CMD("-txcsum", -IFCAP_TXCSUM, setifcap), 1464 DEF_CMD("netcons", IFCAP_NETCONS, setifcap), 1465 DEF_CMD("-netcons", -IFCAP_NETCONS, setifcap), 1466 DEF_CMD_ARG("pcp", setifpcp), 1467 DEF_CMD("-pcp", 0, disableifpcp), 1468 DEF_CMD("polling", IFCAP_POLLING, setifcap), 1469 DEF_CMD("-polling", -IFCAP_POLLING, setifcap), 1470 DEF_CMD("tso6", IFCAP_TSO6, setifcap), 1471 DEF_CMD("-tso6", -IFCAP_TSO6, setifcap), 1472 DEF_CMD("tso4", IFCAP_TSO4, setifcap), 1473 DEF_CMD("-tso4", -IFCAP_TSO4, setifcap), 1474 DEF_CMD("tso", IFCAP_TSO, setifcap), 1475 DEF_CMD("-tso", -IFCAP_TSO, setifcap), 1476 DEF_CMD("toe", IFCAP_TOE, setifcap), 1477 DEF_CMD("-toe", -IFCAP_TOE, setifcap), 1478 DEF_CMD("lro", IFCAP_LRO, setifcap), 1479 DEF_CMD("-lro", -IFCAP_LRO, setifcap), 1480 DEF_CMD("wol", IFCAP_WOL, setifcap), 1481 DEF_CMD("-wol", -IFCAP_WOL, setifcap), 1482 DEF_CMD("wol_ucast", IFCAP_WOL_UCAST, setifcap), 1483 DEF_CMD("-wol_ucast", -IFCAP_WOL_UCAST, setifcap), 1484 DEF_CMD("wol_mcast", IFCAP_WOL_MCAST, setifcap), 1485 DEF_CMD("-wol_mcast", -IFCAP_WOL_MCAST, setifcap), 1486 DEF_CMD("wol_magic", IFCAP_WOL_MAGIC, setifcap), 1487 DEF_CMD("-wol_magic", -IFCAP_WOL_MAGIC, setifcap), 1488 DEF_CMD("txrtlmt", IFCAP_TXRTLMT, setifcap), 1489 DEF_CMD("-txrtlmt", -IFCAP_TXRTLMT, setifcap), 1490 DEF_CMD("hwrxtstmp", IFCAP_HWRXTSTMP, setifcap), 1491 DEF_CMD("-hwrxtstmp", -IFCAP_HWRXTSTMP, setifcap), 1492 DEF_CMD("normal", -IFF_LINK0, setifflags), 1493 DEF_CMD("compress", IFF_LINK0, setifflags), 1494 DEF_CMD("noicmp", IFF_LINK1, setifflags), 1495 DEF_CMD_ARG("mtu", setifmtu), 1496 DEF_CMD_ARG("name", setifname), 1497 }; 1498 1499 static __constructor void 1500 ifconfig_ctor(void) 1501 { 1502 size_t i; 1503 1504 for (i = 0; i < nitems(basic_cmds); i++) 1505 cmd_register(&basic_cmds[i]); 1506 } 1507