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