]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sbin/ifconfig/ifconfig.c
Import DTS from Linux 4.20
[FreeBSD/FreeBSD.git] / sbin / ifconfig / ifconfig.c
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 }