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 _Noreturn void usage(void); 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 } else { 508 /* 509 * Do not allow use `create` command as hostname if 510 * address family is not specified. 511 */ 512 if (argc > 0 && (strcmp(argv[0], "create") == 0 || 513 strcmp(argv[0], "plumb") == 0)) { 514 if (argc == 1) 515 errx(1, "interface %s already exists", 516 ifname); 517 argc--, argv++; 518 } 519 } 520 } 521 522 /* Check for address family */ 523 if (argc > 0) { 524 afp = af_getbyname(*argv); 525 if (afp != NULL) 526 argc--, argv++; 527 } 528 529 if (getifaddrs(&ifap) != 0) 530 err(EXIT_FAILURE, "getifaddrs"); 531 532 cp = NULL; 533 534 if (calcorders(ifap, &q) != 0) 535 err(EXIT_FAILURE, "calcorders"); 536 537 sifap = sortifaddrs(ifap, cmpifaddrs, &q); 538 539 TAILQ_FOREACH_SAFE(cur, &q, link, tmp) 540 free(cur); 541 542 ifindex = 0; 543 for (ifa = sifap; ifa; ifa = ifa->ifa_next) { 544 memset(&paifr, 0, sizeof(paifr)); 545 strlcpy(paifr.ifr_name, ifa->ifa_name, sizeof(paifr.ifr_name)); 546 if (sizeof(paifr.ifr_addr) >= ifa->ifa_addr->sa_len) { 547 memcpy(&paifr.ifr_addr, ifa->ifa_addr, 548 ifa->ifa_addr->sa_len); 549 } 550 551 if (ifname != NULL && strcmp(ifname, ifa->ifa_name) != 0) 552 continue; 553 if (ifa->ifa_addr->sa_family == AF_LINK) 554 sdl = (const struct sockaddr_dl *) ifa->ifa_addr; 555 else 556 sdl = NULL; 557 if (cp != NULL && strcmp(cp, ifa->ifa_name) == 0 && !namesonly) 558 continue; 559 iflen = strlcpy(name, ifa->ifa_name, sizeof(name)); 560 if (iflen >= sizeof(name)) { 561 warnx("%s: interface name too long, skipping", 562 ifa->ifa_name); 563 continue; 564 } 565 cp = ifa->ifa_name; 566 567 if ((ifa->ifa_flags & IFF_CANTCONFIG) != 0) 568 continue; 569 if (downonly && (ifa->ifa_flags & IFF_UP) != 0) 570 continue; 571 if (uponly && (ifa->ifa_flags & IFF_UP) == 0) 572 continue; 573 /* 574 * Are we just listing the interfaces? 575 */ 576 if (namesonly) { 577 if (namecp == cp) 578 continue; 579 if (afp != NULL) { 580 /* special case for "ether" address family */ 581 if (!strcmp(afp->af_name, "ether")) { 582 if (sdl == NULL || 583 (sdl->sdl_type != IFT_ETHER && 584 sdl->sdl_type != IFT_L2VLAN && 585 sdl->sdl_type != IFT_BRIDGE) || 586 sdl->sdl_alen != ETHER_ADDR_LEN) 587 continue; 588 } else { 589 if (ifa->ifa_addr->sa_family 590 != afp->af_af) 591 continue; 592 } 593 } 594 namecp = cp; 595 ifindex++; 596 if (ifindex > 1) 597 printf(" "); 598 fputs(name, stdout); 599 continue; 600 } 601 ifindex++; 602 603 if (argc > 0) 604 ifconfig(argc, argv, 0, afp); 605 else 606 status(afp, sdl, ifa); 607 } 608 if (namesonly) 609 printf("\n"); 610 freeifaddrs(ifap); 611 612 freeformat(); 613 exit(exit_code); 614 } 615 616 static struct afswtch *afs = NULL; 617 618 void 619 af_register(struct afswtch *p) 620 { 621 p->af_next = afs; 622 afs = p; 623 } 624 625 static struct afswtch * 626 af_getbyname(const char *name) 627 { 628 struct afswtch *afp; 629 630 for (afp = afs; afp != NULL; afp = afp->af_next) 631 if (strcmp(afp->af_name, name) == 0) 632 return afp; 633 return NULL; 634 } 635 636 static struct afswtch * 637 af_getbyfamily(int af) 638 { 639 struct afswtch *afp; 640 641 for (afp = afs; afp != NULL; afp = afp->af_next) 642 if (afp->af_af == af) 643 return afp; 644 return NULL; 645 } 646 647 static void 648 af_other_status(int s) 649 { 650 struct afswtch *afp; 651 uint8_t afmask[howmany(AF_MAX, NBBY)]; 652 653 memset(afmask, 0, sizeof(afmask)); 654 for (afp = afs; afp != NULL; afp = afp->af_next) { 655 if (afp->af_other_status == NULL) 656 continue; 657 if (afp->af_af != AF_UNSPEC && isset(afmask, afp->af_af)) 658 continue; 659 afp->af_other_status(s); 660 setbit(afmask, afp->af_af); 661 } 662 } 663 664 static void 665 af_all_tunnel_status(int s) 666 { 667 struct afswtch *afp; 668 uint8_t afmask[howmany(AF_MAX, NBBY)]; 669 670 memset(afmask, 0, sizeof(afmask)); 671 for (afp = afs; afp != NULL; afp = afp->af_next) { 672 if (afp->af_status_tunnel == NULL) 673 continue; 674 if (afp->af_af != AF_UNSPEC && isset(afmask, afp->af_af)) 675 continue; 676 afp->af_status_tunnel(s); 677 setbit(afmask, afp->af_af); 678 } 679 } 680 681 static struct cmd *cmds = NULL; 682 683 void 684 cmd_register(struct cmd *p) 685 { 686 p->c_next = cmds; 687 cmds = p; 688 } 689 690 static const struct cmd * 691 cmd_lookup(const char *name, int iscreate) 692 { 693 const struct cmd *p; 694 695 for (p = cmds; p != NULL; p = p->c_next) 696 if (strcmp(name, p->c_name) == 0) { 697 if (iscreate) { 698 if (p->c_iscloneop) 699 return p; 700 } else { 701 if (!p->c_iscloneop) 702 return p; 703 } 704 } 705 return NULL; 706 } 707 708 struct callback { 709 callback_func *cb_func; 710 void *cb_arg; 711 struct callback *cb_next; 712 }; 713 static struct callback *callbacks = NULL; 714 715 void 716 callback_register(callback_func *func, void *arg) 717 { 718 struct callback *cb; 719 720 cb = malloc(sizeof(struct callback)); 721 if (cb == NULL) 722 errx(1, "unable to allocate memory for callback"); 723 cb->cb_func = func; 724 cb->cb_arg = arg; 725 cb->cb_next = callbacks; 726 callbacks = cb; 727 } 728 729 /* specially-handled commands */ 730 static void setifaddr(const char *, int, int, const struct afswtch *); 731 static const struct cmd setifaddr_cmd = DEF_CMD("ifaddr", 0, setifaddr); 732 733 static void setifdstaddr(const char *, int, int, const struct afswtch *); 734 static const struct cmd setifdstaddr_cmd = 735 DEF_CMD("ifdstaddr", 0, setifdstaddr); 736 737 static int 738 ifconfig(int argc, char *const *argv, int iscreate, const struct afswtch *uafp) 739 { 740 const struct afswtch *afp, *nafp; 741 const struct cmd *p; 742 struct callback *cb; 743 int s; 744 745 strlcpy(ifr.ifr_name, name, sizeof ifr.ifr_name); 746 afp = NULL; 747 if (uafp != NULL) 748 afp = uafp; 749 /* 750 * This is the historical "accident" allowing users to configure IPv4 751 * addresses without the "inet" keyword which while a nice feature has 752 * proven to complicate other things. We cannot remove this but only 753 * make sure we will never have a similar implicit default for IPv6 or 754 * any other address familiy. We need a fallback though for 755 * ifconfig IF up/down etc. to work without INET support as people 756 * never used ifconfig IF link up/down, etc. either. 757 */ 758 #ifndef RESCUE 759 #ifdef INET 760 if (afp == NULL && feature_present("inet")) 761 afp = af_getbyname("inet"); 762 #endif 763 #endif 764 if (afp == NULL) 765 afp = af_getbyname("link"); 766 if (afp == NULL) { 767 warnx("Please specify an address_family."); 768 usage(); 769 } 770 top: 771 ifr.ifr_addr.sa_family = 772 afp->af_af == AF_LINK || afp->af_af == AF_UNSPEC ? 773 AF_LOCAL : afp->af_af; 774 775 if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0 && 776 (uafp != NULL || errno != EAFNOSUPPORT || 777 (s = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0)) 778 err(1, "socket(family %u,SOCK_DGRAM)", ifr.ifr_addr.sa_family); 779 780 while (argc > 0) { 781 p = cmd_lookup(*argv, iscreate); 782 if (iscreate && p == NULL) { 783 /* 784 * Push the clone create callback so the new 785 * device is created and can be used for any 786 * remaining arguments. 787 */ 788 cb = callbacks; 789 if (cb == NULL) 790 errx(1, "internal error, no callback"); 791 callbacks = cb->cb_next; 792 cb->cb_func(s, cb->cb_arg); 793 iscreate = 0; 794 /* 795 * Handle any address family spec that 796 * immediately follows and potentially 797 * recreate the socket. 798 */ 799 nafp = af_getbyname(*argv); 800 if (nafp != NULL) { 801 argc--, argv++; 802 if (nafp != afp) { 803 close(s); 804 afp = nafp; 805 goto top; 806 } 807 } 808 /* 809 * Look for a normal parameter. 810 */ 811 continue; 812 } 813 if (p == NULL) { 814 /* 815 * Not a recognized command, choose between setting 816 * the interface address and the dst address. 817 */ 818 p = (setaddr ? &setifdstaddr_cmd : &setifaddr_cmd); 819 } 820 if (p->c_parameter == NEXTARG && p->c_u.c_func) { 821 if (argv[1] == NULL) 822 errx(1, "'%s' requires argument", 823 p->c_name); 824 p->c_u.c_func(argv[1], 0, s, afp); 825 argc--, argv++; 826 } else if (p->c_parameter == OPTARG && p->c_u.c_func) { 827 p->c_u.c_func(argv[1], 0, s, afp); 828 if (argv[1] != NULL) 829 argc--, argv++; 830 } else if (p->c_parameter == NEXTARG2 && p->c_u.c_func2) { 831 if (argc < 3) 832 errx(1, "'%s' requires 2 arguments", 833 p->c_name); 834 p->c_u.c_func2(argv[1], argv[2], s, afp); 835 argc -= 2, argv += 2; 836 } else if (p->c_u.c_func) 837 p->c_u.c_func(*argv, p->c_parameter, s, afp); 838 argc--, argv++; 839 } 840 841 /* 842 * Do any post argument processing required by the address family. 843 */ 844 if (afp->af_postproc != NULL) 845 afp->af_postproc(s, afp); 846 /* 847 * Do deferred callbacks registered while processing 848 * command-line arguments. 849 */ 850 for (cb = callbacks; cb != NULL; cb = cb->cb_next) 851 cb->cb_func(s, cb->cb_arg); 852 /* 853 * Do deferred operations. 854 */ 855 if (clearaddr) { 856 if (afp->af_ridreq == NULL || afp->af_difaddr == 0) { 857 warnx("interface %s cannot change %s addresses!", 858 name, afp->af_name); 859 clearaddr = 0; 860 } 861 } 862 if (clearaddr) { 863 int ret; 864 strlcpy(((struct ifreq *)afp->af_ridreq)->ifr_name, name, 865 sizeof ifr.ifr_name); 866 ret = ioctl(s, afp->af_difaddr, afp->af_ridreq); 867 if (ret < 0) { 868 if (errno == EADDRNOTAVAIL && (doalias >= 0)) { 869 /* means no previous address for interface */ 870 } else 871 Perror("ioctl (SIOCDIFADDR)"); 872 } 873 } 874 if (newaddr) { 875 if (afp->af_addreq == NULL || afp->af_aifaddr == 0) { 876 warnx("interface %s cannot change %s addresses!", 877 name, afp->af_name); 878 newaddr = 0; 879 } 880 } 881 if (newaddr && (setaddr || setmask)) { 882 strlcpy(((struct ifreq *)afp->af_addreq)->ifr_name, name, 883 sizeof ifr.ifr_name); 884 if (ioctl(s, afp->af_aifaddr, afp->af_addreq) < 0) 885 Perror("ioctl (SIOCAIFADDR)"); 886 } 887 888 close(s); 889 return(0); 890 } 891 892 /*ARGSUSED*/ 893 static void 894 setifaddr(const char *addr, int param, int s, const struct afswtch *afp) 895 { 896 if (afp->af_getaddr == NULL) 897 return; 898 /* 899 * Delay the ioctl to set the interface addr until flags are all set. 900 * The address interpretation may depend on the flags, 901 * and the flags may change when the address is set. 902 */ 903 setaddr++; 904 if (doalias == 0 && afp->af_af != AF_LINK) 905 clearaddr = 1; 906 afp->af_getaddr(addr, (doalias >= 0 ? ADDR : RIDADDR)); 907 } 908 909 static void 910 settunnel(const char *src, const char *dst, int s, const struct afswtch *afp) 911 { 912 struct addrinfo *srcres, *dstres; 913 int ecode; 914 915 if (afp->af_settunnel == NULL) { 916 warn("address family %s does not support tunnel setup", 917 afp->af_name); 918 return; 919 } 920 921 if ((ecode = getaddrinfo(src, NULL, NULL, &srcres)) != 0) 922 errx(1, "error in parsing address string: %s", 923 gai_strerror(ecode)); 924 925 if ((ecode = getaddrinfo(dst, NULL, NULL, &dstres)) != 0) 926 errx(1, "error in parsing address string: %s", 927 gai_strerror(ecode)); 928 929 if (srcres->ai_addr->sa_family != dstres->ai_addr->sa_family) 930 errx(1, 931 "source and destination address families do not match"); 932 933 afp->af_settunnel(s, srcres, dstres); 934 935 freeaddrinfo(srcres); 936 freeaddrinfo(dstres); 937 } 938 939 /* ARGSUSED */ 940 static void 941 deletetunnel(const char *vname, int param, int s, const struct afswtch *afp) 942 { 943 944 if (ioctl(s, SIOCDIFPHYADDR, &ifr) < 0) 945 err(1, "SIOCDIFPHYADDR"); 946 } 947 948 #ifdef JAIL 949 static void 950 setifvnet(const char *jname, int dummy __unused, int s, 951 const struct afswtch *afp) 952 { 953 struct ifreq my_ifr; 954 955 memcpy(&my_ifr, &ifr, sizeof(my_ifr)); 956 my_ifr.ifr_jid = jail_getid(jname); 957 if (my_ifr.ifr_jid < 0) 958 errx(1, "%s", jail_errmsg); 959 if (ioctl(s, SIOCSIFVNET, &my_ifr) < 0) 960 err(1, "SIOCSIFVNET"); 961 } 962 963 static void 964 setifrvnet(const char *jname, int dummy __unused, int s, 965 const struct afswtch *afp) 966 { 967 struct ifreq my_ifr; 968 969 memcpy(&my_ifr, &ifr, sizeof(my_ifr)); 970 my_ifr.ifr_jid = jail_getid(jname); 971 if (my_ifr.ifr_jid < 0) 972 errx(1, "%s", jail_errmsg); 973 if (ioctl(s, SIOCSIFRVNET, &my_ifr) < 0) 974 err(1, "SIOCSIFRVNET(%d, %s)", my_ifr.ifr_jid, my_ifr.ifr_name); 975 } 976 #endif 977 978 static void 979 setifnetmask(const char *addr, int dummy __unused, int s, 980 const struct afswtch *afp) 981 { 982 if (afp->af_getaddr != NULL) { 983 setmask++; 984 afp->af_getaddr(addr, MASK); 985 } 986 } 987 988 static void 989 setifbroadaddr(const char *addr, int dummy __unused, int s, 990 const struct afswtch *afp) 991 { 992 if (afp->af_getaddr != NULL) 993 afp->af_getaddr(addr, DSTADDR); 994 } 995 996 static void 997 notealias(const char *addr, int param, int s, const struct afswtch *afp) 998 { 999 #define rqtosa(x) (&(((struct ifreq *)(afp->x))->ifr_addr)) 1000 if (setaddr && doalias == 0 && param < 0) 1001 if (afp->af_addreq != NULL && afp->af_ridreq != NULL) 1002 bcopy((caddr_t)rqtosa(af_addreq), 1003 (caddr_t)rqtosa(af_ridreq), 1004 rqtosa(af_addreq)->sa_len); 1005 doalias = param; 1006 if (param < 0) { 1007 clearaddr = 1; 1008 newaddr = 0; 1009 } else 1010 clearaddr = 0; 1011 #undef rqtosa 1012 } 1013 1014 /*ARGSUSED*/ 1015 static void 1016 setifdstaddr(const char *addr, int param __unused, int s, 1017 const struct afswtch *afp) 1018 { 1019 if (afp->af_getaddr != NULL) 1020 afp->af_getaddr(addr, DSTADDR); 1021 } 1022 1023 /* 1024 * Note: doing an SIOCIGIFFLAGS scribbles on the union portion 1025 * of the ifreq structure, which may confuse other parts of ifconfig. 1026 * Make a private copy so we can avoid that. 1027 */ 1028 static void 1029 setifflags(const char *vname, int value, int s, const struct afswtch *afp) 1030 { 1031 struct ifreq my_ifr; 1032 int flags; 1033 1034 memset(&my_ifr, 0, sizeof(my_ifr)); 1035 (void) strlcpy(my_ifr.ifr_name, name, sizeof(my_ifr.ifr_name)); 1036 1037 if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&my_ifr) < 0) { 1038 Perror("ioctl (SIOCGIFFLAGS)"); 1039 exit(1); 1040 } 1041 flags = (my_ifr.ifr_flags & 0xffff) | (my_ifr.ifr_flagshigh << 16); 1042 1043 if (value < 0) { 1044 value = -value; 1045 flags &= ~value; 1046 } else 1047 flags |= value; 1048 my_ifr.ifr_flags = flags & 0xffff; 1049 my_ifr.ifr_flagshigh = flags >> 16; 1050 if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&my_ifr) < 0) 1051 Perror(vname); 1052 } 1053 1054 void 1055 setifcap(const char *vname, int value, int s, const struct afswtch *afp) 1056 { 1057 int flags; 1058 1059 if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) < 0) { 1060 Perror("ioctl (SIOCGIFCAP)"); 1061 exit(1); 1062 } 1063 flags = ifr.ifr_curcap; 1064 if (value < 0) { 1065 value = -value; 1066 flags &= ~value; 1067 } else 1068 flags |= value; 1069 flags &= ifr.ifr_reqcap; 1070 ifr.ifr_reqcap = flags; 1071 if (ioctl(s, SIOCSIFCAP, (caddr_t)&ifr) < 0) 1072 Perror(vname); 1073 } 1074 1075 static void 1076 setifmetric(const char *val, int dummy __unused, int s, 1077 const struct afswtch *afp) 1078 { 1079 strlcpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 1080 ifr.ifr_metric = atoi(val); 1081 if (ioctl(s, SIOCSIFMETRIC, (caddr_t)&ifr) < 0) 1082 err(1, "ioctl SIOCSIFMETRIC (set metric)"); 1083 } 1084 1085 static void 1086 setifmtu(const char *val, int dummy __unused, int s, 1087 const struct afswtch *afp) 1088 { 1089 strlcpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 1090 ifr.ifr_mtu = atoi(val); 1091 if (ioctl(s, SIOCSIFMTU, (caddr_t)&ifr) < 0) 1092 err(1, "ioctl SIOCSIFMTU (set mtu)"); 1093 } 1094 1095 static void 1096 setifpcp(const char *val, int arg __unused, int s, const struct afswtch *afp) 1097 { 1098 u_long ul; 1099 char *endp; 1100 1101 ul = strtoul(val, &endp, 0); 1102 if (*endp != '\0') 1103 errx(1, "invalid value for pcp"); 1104 if (ul > 7) 1105 errx(1, "value for pcp out of range"); 1106 ifr.ifr_lan_pcp = ul; 1107 if (ioctl(s, SIOCSLANPCP, (caddr_t)&ifr) == -1) 1108 err(1, "SIOCSLANPCP"); 1109 } 1110 1111 static void 1112 disableifpcp(const char *val, int arg __unused, int s, 1113 const struct afswtch *afp) 1114 { 1115 1116 ifr.ifr_lan_pcp = IFNET_PCP_NONE; 1117 if (ioctl(s, SIOCSLANPCP, (caddr_t)&ifr) == -1) 1118 err(1, "SIOCSLANPCP"); 1119 } 1120 1121 static void 1122 setifname(const char *val, int dummy __unused, int s, 1123 const struct afswtch *afp) 1124 { 1125 char *newname; 1126 1127 strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 1128 1129 newname = strdup(val); 1130 if (newname == NULL) 1131 err(1, "no memory to set ifname"); 1132 ifr.ifr_data = newname; 1133 if (ioctl(s, SIOCSIFNAME, (caddr_t)&ifr) < 0) { 1134 free(newname); 1135 err(1, "ioctl SIOCSIFNAME (set name)"); 1136 } 1137 printifname = 1; 1138 strlcpy(name, newname, sizeof(name)); 1139 free(newname); 1140 } 1141 1142 /* ARGSUSED */ 1143 static void 1144 setifdescr(const char *val, int dummy __unused, int s, 1145 const struct afswtch *afp) 1146 { 1147 char *newdescr; 1148 1149 strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 1150 1151 ifr.ifr_buffer.length = strlen(val) + 1; 1152 if (ifr.ifr_buffer.length == 1) { 1153 ifr.ifr_buffer.buffer = newdescr = NULL; 1154 ifr.ifr_buffer.length = 0; 1155 } else { 1156 newdescr = strdup(val); 1157 ifr.ifr_buffer.buffer = newdescr; 1158 if (newdescr == NULL) { 1159 warn("no memory to set ifdescr"); 1160 return; 1161 } 1162 } 1163 1164 if (ioctl(s, SIOCSIFDESCR, (caddr_t)&ifr) < 0) 1165 err(1, "ioctl SIOCSIFDESCR (set descr)"); 1166 1167 free(newdescr); 1168 } 1169 1170 /* ARGSUSED */ 1171 static void 1172 unsetifdescr(const char *val, int value, int s, const struct afswtch *afp) 1173 { 1174 1175 setifdescr("", 0, s, 0); 1176 } 1177 1178 #define IFFBITS \ 1179 "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\7RUNNING" \ 1180 "\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2" \ 1181 "\20MULTICAST\22PPROMISC\23MONITOR\24STATICARP" 1182 1183 #define IFCAPBITS \ 1184 "\020\1RXCSUM\2TXCSUM\3NETCONS\4VLAN_MTU\5VLAN_HWTAGGING\6JUMBO_MTU\7POLLING" \ 1185 "\10VLAN_HWCSUM\11TSO4\12TSO6\13LRO\14WOL_UCAST\15WOL_MCAST\16WOL_MAGIC" \ 1186 "\17TOE4\20TOE6\21VLAN_HWFILTER\23VLAN_HWTSO\24LINKSTATE\25NETMAP" \ 1187 "\26RXCSUM_IPV6\27TXCSUM_IPV6\31TXRTLMT\32HWRXTSTMP" 1188 1189 /* 1190 * Print the status of the interface. If an address family was 1191 * specified, show only it; otherwise, show them all. 1192 */ 1193 static void 1194 status(const struct afswtch *afp, const struct sockaddr_dl *sdl, 1195 struct ifaddrs *ifa) 1196 { 1197 struct ifaddrs *ift; 1198 int allfamilies, s; 1199 struct ifstat ifs; 1200 1201 if (afp == NULL) { 1202 allfamilies = 1; 1203 ifr.ifr_addr.sa_family = AF_LOCAL; 1204 } else { 1205 allfamilies = 0; 1206 ifr.ifr_addr.sa_family = 1207 afp->af_af == AF_LINK ? AF_LOCAL : afp->af_af; 1208 } 1209 strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 1210 1211 s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0); 1212 if (s < 0) 1213 err(1, "socket(family %u,SOCK_DGRAM)", ifr.ifr_addr.sa_family); 1214 1215 printf("%s: ", name); 1216 printb("flags", ifa->ifa_flags, IFFBITS); 1217 if (ioctl(s, SIOCGIFMETRIC, &ifr) != -1) 1218 printf(" metric %d", ifr.ifr_metric); 1219 if (ioctl(s, SIOCGIFMTU, &ifr) != -1) 1220 printf(" mtu %d", ifr.ifr_mtu); 1221 putchar('\n'); 1222 1223 for (;;) { 1224 if ((descr = reallocf(descr, descrlen)) != NULL) { 1225 ifr.ifr_buffer.buffer = descr; 1226 ifr.ifr_buffer.length = descrlen; 1227 if (ioctl(s, SIOCGIFDESCR, &ifr) == 0) { 1228 if (ifr.ifr_buffer.buffer == descr) { 1229 if (strlen(descr) > 0) 1230 printf("\tdescription: %s\n", 1231 descr); 1232 } else if (ifr.ifr_buffer.length > descrlen) { 1233 descrlen = ifr.ifr_buffer.length; 1234 continue; 1235 } 1236 } 1237 } else 1238 warn("unable to allocate memory for interface" 1239 "description"); 1240 break; 1241 } 1242 1243 if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) == 0) { 1244 if (ifr.ifr_curcap != 0) { 1245 printb("\toptions", ifr.ifr_curcap, IFCAPBITS); 1246 putchar('\n'); 1247 } 1248 if (supmedia && ifr.ifr_reqcap != 0) { 1249 printb("\tcapabilities", ifr.ifr_reqcap, IFCAPBITS); 1250 putchar('\n'); 1251 } 1252 } 1253 1254 tunnel_status(s); 1255 1256 for (ift = ifa; ift != NULL; ift = ift->ifa_next) { 1257 if (ift->ifa_addr == NULL) 1258 continue; 1259 if (strcmp(ifa->ifa_name, ift->ifa_name) != 0) 1260 continue; 1261 if (allfamilies) { 1262 const struct afswtch *p; 1263 p = af_getbyfamily(ift->ifa_addr->sa_family); 1264 if (p != NULL && p->af_status != NULL) 1265 p->af_status(s, ift); 1266 } else if (afp->af_af == ift->ifa_addr->sa_family) 1267 afp->af_status(s, ift); 1268 } 1269 #if 0 1270 if (allfamilies || afp->af_af == AF_LINK) { 1271 const struct afswtch *lafp; 1272 1273 /* 1274 * Hack; the link level address is received separately 1275 * from the routing information so any address is not 1276 * handled above. Cobble together an entry and invoke 1277 * the status method specially. 1278 */ 1279 lafp = af_getbyname("lladdr"); 1280 if (lafp != NULL) { 1281 info.rti_info[RTAX_IFA] = (struct sockaddr *)sdl; 1282 lafp->af_status(s, &info); 1283 } 1284 } 1285 #endif 1286 if (allfamilies) 1287 af_other_status(s); 1288 else if (afp->af_other_status != NULL) 1289 afp->af_other_status(s); 1290 1291 strlcpy(ifs.ifs_name, name, sizeof ifs.ifs_name); 1292 if (ioctl(s, SIOCGIFSTATUS, &ifs) == 0) 1293 printf("%s", ifs.ascii); 1294 1295 if (verbose > 0) 1296 sfp_status(s, &ifr, verbose); 1297 1298 close(s); 1299 return; 1300 } 1301 1302 static void 1303 tunnel_status(int s) 1304 { 1305 af_all_tunnel_status(s); 1306 } 1307 1308 void 1309 Perror(const char *cmd) 1310 { 1311 switch (errno) { 1312 1313 case ENXIO: 1314 errx(1, "%s: no such interface", cmd); 1315 break; 1316 1317 case EPERM: 1318 errx(1, "%s: permission denied", cmd); 1319 break; 1320 1321 default: 1322 err(1, "%s", cmd); 1323 } 1324 } 1325 1326 /* 1327 * Print a value a la the %b format of the kernel's printf 1328 */ 1329 void 1330 printb(const char *s, unsigned v, const char *bits) 1331 { 1332 int i, any = 0; 1333 char c; 1334 1335 if (bits && *bits == 8) 1336 printf("%s=%o", s, v); 1337 else 1338 printf("%s=%x", s, v); 1339 if (bits) { 1340 bits++; 1341 putchar('<'); 1342 while ((i = *bits++) != '\0') { 1343 if (v & (1 << (i-1))) { 1344 if (any) 1345 putchar(','); 1346 any = 1; 1347 for (; (c = *bits) > 32; bits++) 1348 putchar(c); 1349 } else 1350 for (; *bits > 32; bits++) 1351 ; 1352 } 1353 putchar('>'); 1354 } 1355 } 1356 1357 void 1358 print_vhid(const struct ifaddrs *ifa, const char *s) 1359 { 1360 struct if_data *ifd; 1361 1362 if (ifa->ifa_data == NULL) 1363 return; 1364 1365 ifd = ifa->ifa_data; 1366 if (ifd->ifi_vhid == 0) 1367 return; 1368 1369 printf("vhid %d ", ifd->ifi_vhid); 1370 } 1371 1372 void 1373 ifmaybeload(const char *name) 1374 { 1375 #define MOD_PREFIX_LEN 3 /* "if_" */ 1376 struct module_stat mstat; 1377 int fileid, modid; 1378 char ifkind[IFNAMSIZ + MOD_PREFIX_LEN], ifname[IFNAMSIZ], *dp; 1379 const char *cp; 1380 1381 /* loading suppressed by the user */ 1382 if (noload) 1383 return; 1384 1385 /* trim the interface number off the end */ 1386 strlcpy(ifname, name, sizeof(ifname)); 1387 for (dp = ifname; *dp != 0; dp++) 1388 if (isdigit(*dp)) { 1389 *dp = 0; 1390 break; 1391 } 1392 1393 /* turn interface and unit into module name */ 1394 strlcpy(ifkind, "if_", sizeof(ifkind)); 1395 strlcat(ifkind, ifname, sizeof(ifkind)); 1396 1397 /* scan files in kernel */ 1398 mstat.version = sizeof(struct module_stat); 1399 for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid)) { 1400 /* scan modules in file */ 1401 for (modid = kldfirstmod(fileid); modid > 0; 1402 modid = modfnext(modid)) { 1403 if (modstat(modid, &mstat) < 0) 1404 continue; 1405 /* strip bus name if present */ 1406 if ((cp = strchr(mstat.name, '/')) != NULL) { 1407 cp++; 1408 } else { 1409 cp = mstat.name; 1410 } 1411 /* already loaded? */ 1412 if (strcmp(ifname, cp) == 0 || 1413 strcmp(ifkind, cp) == 0) 1414 return; 1415 } 1416 } 1417 1418 /* 1419 * Try to load the module. But ignore failures, because ifconfig can't 1420 * infer the names of all drivers (eg mlx4en(4)). 1421 */ 1422 (void) kldload(ifkind); 1423 } 1424 1425 static struct cmd basic_cmds[] = { 1426 DEF_CMD("up", IFF_UP, setifflags), 1427 DEF_CMD("down", -IFF_UP, setifflags), 1428 DEF_CMD("arp", -IFF_NOARP, setifflags), 1429 DEF_CMD("-arp", IFF_NOARP, setifflags), 1430 DEF_CMD("debug", IFF_DEBUG, setifflags), 1431 DEF_CMD("-debug", -IFF_DEBUG, setifflags), 1432 DEF_CMD_ARG("description", setifdescr), 1433 DEF_CMD_ARG("descr", setifdescr), 1434 DEF_CMD("-description", 0, unsetifdescr), 1435 DEF_CMD("-descr", 0, unsetifdescr), 1436 DEF_CMD("promisc", IFF_PPROMISC, setifflags), 1437 DEF_CMD("-promisc", -IFF_PPROMISC, setifflags), 1438 DEF_CMD("add", IFF_UP, notealias), 1439 DEF_CMD("alias", IFF_UP, notealias), 1440 DEF_CMD("-alias", -IFF_UP, notealias), 1441 DEF_CMD("delete", -IFF_UP, notealias), 1442 DEF_CMD("remove", -IFF_UP, notealias), 1443 #ifdef notdef 1444 #define EN_SWABIPS 0x1000 1445 DEF_CMD("swabips", EN_SWABIPS, setifflags), 1446 DEF_CMD("-swabips", -EN_SWABIPS, setifflags), 1447 #endif 1448 DEF_CMD_ARG("netmask", setifnetmask), 1449 DEF_CMD_ARG("metric", setifmetric), 1450 DEF_CMD_ARG("broadcast", setifbroadaddr), 1451 DEF_CMD_ARG2("tunnel", settunnel), 1452 DEF_CMD("-tunnel", 0, deletetunnel), 1453 DEF_CMD("deletetunnel", 0, deletetunnel), 1454 #ifdef JAIL 1455 DEF_CMD_ARG("vnet", setifvnet), 1456 DEF_CMD_ARG("-vnet", setifrvnet), 1457 #endif 1458 DEF_CMD("link0", IFF_LINK0, setifflags), 1459 DEF_CMD("-link0", -IFF_LINK0, setifflags), 1460 DEF_CMD("link1", IFF_LINK1, setifflags), 1461 DEF_CMD("-link1", -IFF_LINK1, setifflags), 1462 DEF_CMD("link2", IFF_LINK2, setifflags), 1463 DEF_CMD("-link2", -IFF_LINK2, setifflags), 1464 DEF_CMD("monitor", IFF_MONITOR, setifflags), 1465 DEF_CMD("-monitor", -IFF_MONITOR, setifflags), 1466 DEF_CMD("staticarp", IFF_STATICARP, setifflags), 1467 DEF_CMD("-staticarp", -IFF_STATICARP, setifflags), 1468 DEF_CMD("rxcsum6", IFCAP_RXCSUM_IPV6, setifcap), 1469 DEF_CMD("-rxcsum6", -IFCAP_RXCSUM_IPV6, setifcap), 1470 DEF_CMD("txcsum6", IFCAP_TXCSUM_IPV6, setifcap), 1471 DEF_CMD("-txcsum6", -IFCAP_TXCSUM_IPV6, setifcap), 1472 DEF_CMD("rxcsum", IFCAP_RXCSUM, setifcap), 1473 DEF_CMD("-rxcsum", -IFCAP_RXCSUM, setifcap), 1474 DEF_CMD("txcsum", IFCAP_TXCSUM, setifcap), 1475 DEF_CMD("-txcsum", -IFCAP_TXCSUM, setifcap), 1476 DEF_CMD("netcons", IFCAP_NETCONS, setifcap), 1477 DEF_CMD("-netcons", -IFCAP_NETCONS, setifcap), 1478 DEF_CMD_ARG("pcp", setifpcp), 1479 DEF_CMD("-pcp", 0, disableifpcp), 1480 DEF_CMD("polling", IFCAP_POLLING, setifcap), 1481 DEF_CMD("-polling", -IFCAP_POLLING, setifcap), 1482 DEF_CMD("tso6", IFCAP_TSO6, setifcap), 1483 DEF_CMD("-tso6", -IFCAP_TSO6, setifcap), 1484 DEF_CMD("tso4", IFCAP_TSO4, setifcap), 1485 DEF_CMD("-tso4", -IFCAP_TSO4, setifcap), 1486 DEF_CMD("tso", IFCAP_TSO, setifcap), 1487 DEF_CMD("-tso", -IFCAP_TSO, setifcap), 1488 DEF_CMD("toe", IFCAP_TOE, setifcap), 1489 DEF_CMD("-toe", -IFCAP_TOE, setifcap), 1490 DEF_CMD("lro", IFCAP_LRO, setifcap), 1491 DEF_CMD("-lro", -IFCAP_LRO, setifcap), 1492 DEF_CMD("wol", IFCAP_WOL, setifcap), 1493 DEF_CMD("-wol", -IFCAP_WOL, setifcap), 1494 DEF_CMD("wol_ucast", IFCAP_WOL_UCAST, setifcap), 1495 DEF_CMD("-wol_ucast", -IFCAP_WOL_UCAST, setifcap), 1496 DEF_CMD("wol_mcast", IFCAP_WOL_MCAST, setifcap), 1497 DEF_CMD("-wol_mcast", -IFCAP_WOL_MCAST, setifcap), 1498 DEF_CMD("wol_magic", IFCAP_WOL_MAGIC, setifcap), 1499 DEF_CMD("-wol_magic", -IFCAP_WOL_MAGIC, setifcap), 1500 DEF_CMD("txrtlmt", IFCAP_TXRTLMT, setifcap), 1501 DEF_CMD("-txrtlmt", -IFCAP_TXRTLMT, setifcap), 1502 DEF_CMD("hwrxtstmp", IFCAP_HWRXTSTMP, setifcap), 1503 DEF_CMD("-hwrxtstmp", -IFCAP_HWRXTSTMP, setifcap), 1504 DEF_CMD("normal", -IFF_LINK0, setifflags), 1505 DEF_CMD("compress", IFF_LINK0, setifflags), 1506 DEF_CMD("noicmp", IFF_LINK1, setifflags), 1507 DEF_CMD_ARG("mtu", setifmtu), 1508 DEF_CMD_ARG("name", setifname), 1509 }; 1510 1511 static __constructor void 1512 ifconfig_ctor(void) 1513 { 1514 size_t i; 1515 1516 for (i = 0; i < nitems(basic_cmds); i++) 1517 cmd_register(&basic_cmds[i]); 1518 } 1519