2 * Copyright (c) 2009-2018 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
30 * Copyright (c) 1983, 1993
31 * The Regents of the University of California. All rights reserved.
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
36 * 1. Redistributions of source code must retain the above copyright
37 * notice, this list of conditions and the following disclaimer.
38 * 2. Redistributions in binary form must reproduce the above copyright
39 * notice, this list of conditions and the following disclaimer in the
40 * documentation and/or other materials provided with the distribution.
41 * 4. Neither the name of the University nor the names of its contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
45 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 #include <sys/cdefs.h>
61 __unused
static const char copyright
[] =
62 "@(#) Copyright (c) 1983, 1993\n\
63 The Regents of the University of California. All rights reserved.\n";
66 #include <sys/param.h>
67 #include <sys/ioctl.h>
68 #include <sys/socket.h>
69 #include <sys/sysctl.h>
72 #include <sys/module.h>
73 #include <sys/linker.h>
76 #include <net/ethernet.h>
78 #include <net/if_var.h>
79 #include <net/if_dl.h>
80 #include <net/if_types.h>
81 #include <net/if_mib.h>
82 #include <net/route.h>
83 #include <net/pktsched/pktsched.h>
84 #include <net/network_agent.h>
87 #include <netinet/in.h>
88 #include <netinet/in_var.h>
89 #include <arpa/inet.h>
101 #include <sysexits.h>
103 #include "ifconfig.h"
106 * Since "struct ifreq" is composed of various union members, callers
107 * should pay special attention to interprete the value.
108 * (.e.g. little/big endian difference in the structure.)
121 int bond_details
= 0;
123 #if TARGET_OS_EMBEDDED
126 #else /* !TARGET_OS_EMBEDDED */
129 #endif /* !TARGET_OS_EMBEDDED */
130 int printkeys
= 0; /* Print keying material for interfaces. */
132 static int ifconfig(int argc
, char *const *argv
, int iscreate
,
133 const struct afswtch
*afp
);
134 static void status(const struct afswtch
*afp
, const struct sockaddr_dl
*sdl
,
135 struct ifaddrs
*ifa
);
136 static char *bytes_to_str(unsigned long long bytes
);
137 static char *bps_to_str(unsigned long long rate
);
138 static char *ns_to_str(unsigned long long nsec
);
139 static void tunnel_status(int s
);
140 static void usage(void);
141 static char *sched2str(unsigned int s
);
142 static char *tl2str(unsigned int s
);
143 static char *ift2str(unsigned int t
, unsigned int f
, unsigned int sf
);
145 static struct afswtch
*af_getbyname(const char *name
);
146 static struct afswtch
*af_getbyfamily(int af
);
147 static void af_other_status(int);
149 static struct option
*opts
= NULL
;
152 opt_register(struct option
*p
)
164 /* XXX not right but close enough for now */
166 for (p
= opts
; p
!= NULL
; p
= p
->next
) {
167 strlcat(options
, p
->opt_usage
, sizeof(options
));
168 strlcat(options
, " ", sizeof(options
));
172 "usage: ifconfig %sinterface address_family [address [dest_address]]\n"
174 " ifconfig interface create\n"
175 " ifconfig -a %s[-d] [-m] [-u] [-v] [address_family]\n"
176 " ifconfig -l [-d] [-u] [address_family]\n"
177 " ifconfig %s[-d] [-m] [-u] [-v]\n",
178 options
, options
, options
);
183 main(int argc
, char *argv
[])
185 int c
, namesonly
, downonly
, uponly
;
186 const struct afswtch
*afp
= NULL
;
188 struct ifaddrs
*ifap
, *ifa
;
190 const struct sockaddr_dl
*sdl
;
191 char options
[1024], *cp
;
196 all
= downonly
= uponly
= namesonly
= noload
= 0;
198 /* Parse leading line options */
200 strlcpy(options
, "adklmnuv", sizeof(options
));
202 strlcpy(options
, "abdlmruv", sizeof(options
));
204 for (p
= opts
; p
!= NULL
; p
= p
->next
)
205 strlcat(options
, p
->opt
, sizeof(options
));
206 while ((c
= getopt(argc
, argv
, options
)) != -1) {
208 case 'a': /* scan all interfaces */
211 case 'b': /* bond detailed output */
214 case 'd': /* restrict scan to "down" interfaces */
222 case 'l': /* scan interface names only */
225 case 'm': /* show media choices in status */
229 case 'n': /* suppress module loading */
236 case 'u': /* restrict scan to "up" interfaces */
243 for (p
= opts
; p
!= NULL
; p
= p
->next
)
244 if (p
->opt
[0] == c
) {
256 /* -l cannot be used with -a or -q or -m or -b */
258 (all
|| supmedia
|| bond_details
))
262 if (uponly
&& downonly
)
265 /* no arguments is equivalent to '-a' */
266 if (!namesonly
&& argc
< 1)
269 /* -a and -l allow an address family arg to limit the output */
270 if (all
|| namesonly
) {
276 afp
= af_getbyname(*argv
);
279 if (afp
->af_name
!= NULL
)
281 /* leave with afp non-zero */
284 /* not listing, need an argument */
292 /* check and maybe load support for this interface */
295 ifindex
= if_nametoindex(ifname
);
298 * NOTE: We must special-case the `create' command
299 * right here as we would otherwise fail when trying
300 * to find the interface.
302 if (argc
> 0 && (strcmp(argv
[0], "create") == 0 ||
303 strcmp(argv
[0], "plumb") == 0)) {
304 iflen
= strlcpy(name
, ifname
, sizeof(name
));
305 if (iflen
>= sizeof(name
))
306 errx(1, "%s: cloning name too long",
308 ifconfig(argc
, argv
, 1, NULL
);
311 errx(1, "interface %s does not exist", ifname
);
315 /* Check for address family */
317 afp
= af_getbyname(*argv
);
322 if (getifaddrs(&ifap
) != 0)
323 err(EXIT_FAILURE
, "getifaddrs");
326 for (ifa
= ifap
; ifa
; ifa
= ifa
->ifa_next
) {
327 memset(&paifr
, 0, sizeof(paifr
));
328 strncpy(paifr
.ifr_name
, ifa
->ifa_name
, sizeof(paifr
.ifr_name
));
329 if (sizeof(paifr
.ifr_addr
) >= ifa
->ifa_addr
->sa_len
) {
330 memcpy(&paifr
.ifr_addr
, ifa
->ifa_addr
,
331 ifa
->ifa_addr
->sa_len
);
334 if (ifname
!= NULL
&& strcmp(ifname
, ifa
->ifa_name
) != 0)
336 if (ifa
->ifa_addr
->sa_family
== AF_LINK
)
337 sdl
= (const struct sockaddr_dl
*) ifa
->ifa_addr
;
340 if (cp
!= NULL
&& strcmp(cp
, ifa
->ifa_name
) == 0)
342 iflen
= strlcpy(name
, ifa
->ifa_name
, sizeof(name
));
343 if (iflen
>= sizeof(name
)) {
344 warnx("%s: interface name too long, skipping",
350 if (downonly
&& (ifa
->ifa_flags
& IFF_UP
) != 0)
352 if (uponly
&& (ifa
->ifa_flags
& IFF_UP
) == 0)
356 * Are we just listing the interfaces?
366 ifconfig(argc
, argv
, 0, afp
);
368 status(afp
, sdl
, ifa
);
377 static struct afswtch
*afs
= NULL
;
380 af_register(struct afswtch
*p
)
386 static struct afswtch
*
387 af_getbyname(const char *name
)
391 for (afp
= afs
; afp
!= NULL
; afp
= afp
->af_next
)
392 if (strcmp(afp
->af_name
, name
) == 0)
397 static struct afswtch
*
398 af_getbyfamily(int af
)
402 for (afp
= afs
; afp
!= NULL
; afp
= afp
->af_next
)
403 if (afp
->af_af
== af
)
409 af_other_status(int s
)
412 uint8_t afmask
[howmany(AF_MAX
, NBBY
)];
414 memset(afmask
, 0, sizeof(afmask
));
415 for (afp
= afs
; afp
!= NULL
; afp
= afp
->af_next
) {
416 if (afp
->af_other_status
== NULL
)
418 if (afp
->af_af
!= AF_UNSPEC
&& isset(afmask
, afp
->af_af
))
420 afp
->af_other_status(s
);
421 setbit(afmask
, afp
->af_af
);
426 af_all_tunnel_status(int s
)
429 uint8_t afmask
[howmany(AF_MAX
, NBBY
)];
431 memset(afmask
, 0, sizeof(afmask
));
432 for (afp
= afs
; afp
!= NULL
; afp
= afp
->af_next
) {
433 if (afp
->af_status_tunnel
== NULL
)
435 if (afp
->af_af
!= AF_UNSPEC
&& isset(afmask
, afp
->af_af
))
437 afp
->af_status_tunnel(s
);
438 setbit(afmask
, afp
->af_af
);
442 static struct cmd
*cmds
= NULL
;
445 cmd_register(struct cmd
*p
)
451 static const struct cmd
*
452 cmd_lookup(const char *name
)
454 #define N(a) (sizeof(a)/sizeof(a[0]))
457 for (p
= cmds
; p
!= NULL
; p
= p
->c_next
)
458 if (strcmp(name
, p
->c_name
) == 0)
465 callback_func
*cb_func
;
467 struct callback
*cb_next
;
469 static struct callback
*callbacks
= NULL
;
472 callback_register(callback_func
*func
, void *arg
)
476 cb
= malloc(sizeof(struct callback
));
478 errx(1, "unable to allocate memory for callback");
481 cb
->cb_next
= callbacks
;
485 /* specially-handled commands */
486 static void setifaddr(const char *, int, int, const struct afswtch
*);
487 static const struct cmd setifaddr_cmd
= DEF_CMD("ifaddr", 0, setifaddr
);
489 static void setifdstaddr(const char *, int, int, const struct afswtch
*);
490 static const struct cmd setifdstaddr_cmd
=
491 DEF_CMD("ifdstaddr", 0, setifdstaddr
);
494 ifconfig(int argc
, char *const *argv
, int iscreate
, const struct afswtch
*afp
)
496 const struct afswtch
*nafp
;
500 strncpy(ifr
.ifr_name
, name
, sizeof ifr
.ifr_name
);
503 afp
= af_getbyname("inet");
504 ifr
.ifr_addr
.sa_family
=
505 afp
->af_af
== AF_LINK
|| afp
->af_af
== AF_UNSPEC
?
506 AF_INET
: afp
->af_af
;
508 if ((s
= socket(ifr
.ifr_addr
.sa_family
, SOCK_DGRAM
, 0)) < 0)
509 err(1, "socket(family %u,SOCK_DGRAM", ifr
.ifr_addr
.sa_family
);
514 p
= cmd_lookup(*argv
);
517 * Not a recognized command, choose between setting
518 * the interface address and the dst address.
520 p
= (setaddr
? &setifdstaddr_cmd
: &setifaddr_cmd
);
522 if (p
->c_u
.c_func
|| p
->c_u
.c_func2
) {
523 if (iscreate
&& !p
->c_iscloneop
) {
525 * Push the clone create callback so the new
526 * device is created and can be used for any
527 * remaining arguments.
531 errx(1, "internal error, no callback");
532 callbacks
= cb
->cb_next
;
533 cb
->cb_func(s
, cb
->cb_arg
);
536 * Handle any address family spec that
537 * immediately follows and potentially
538 * recreate the socket.
540 nafp
= af_getbyname(*argv
);
550 if (p
->c_parameter
== NEXTARG
) {
552 errx(1, "'%s' requires argument",
554 p
->c_u
.c_func(argv
[1], 0, s
, afp
);
556 } else if (p
->c_parameter
== OPTARG
) {
557 p
->c_u
.c_func(argv
[1], 0, s
, afp
);
560 } else if (p
->c_parameter
== NEXTARG2
) {
562 errx(1, "'%s' requires 2 arguments",
564 p
->c_u
.c_func2(argv
[1], argv
[2], s
, afp
);
565 argc
-= 2, argv
+= 2;
567 p
->c_u
.c_func(*argv
, p
->c_parameter
, s
, afp
);
573 * Do any post argument processing required by the address family.
575 if (afp
->af_postproc
!= NULL
)
576 afp
->af_postproc(s
, afp
);
578 * Do deferred callbacks registered while processing
579 * command-line arguments.
581 for (cb
= callbacks
; cb
!= NULL
; cb
= cb
->cb_next
)
582 cb
->cb_func(s
, cb
->cb_arg
);
584 * Do deferred operations.
587 if (afp
->af_ridreq
== NULL
|| afp
->af_difaddr
== 0) {
588 warnx("interface %s cannot change %s addresses!",
595 strncpy(afp
->af_ridreq
, name
, sizeof ifr
.ifr_name
);
596 ret
= ioctl(s
, afp
->af_difaddr
, afp
->af_ridreq
);
598 if (errno
== EADDRNOTAVAIL
&& (doalias
>= 0)) {
599 /* means no previous address for interface */
601 Perror("ioctl (SIOCDIFADDR)");
605 if (afp
->af_addreq
== NULL
|| afp
->af_aifaddr
== 0) {
606 warnx("interface %s cannot change %s addresses!",
611 if (newaddr
&& (setaddr
|| setmask
)) {
612 strncpy(afp
->af_addreq
, name
, sizeof ifr
.ifr_name
);
613 if (ioctl(s
, afp
->af_aifaddr
, afp
->af_addreq
) < 0)
614 Perror("ioctl (SIOCAIFADDR)");
623 setifaddr(const char *addr
, int param
, int s
, const struct afswtch
*afp
)
625 if (afp
->af_getaddr
== NULL
)
628 * Delay the ioctl to set the interface addr until flags are all set.
629 * The address interpretation may depend on the flags,
630 * and the flags may change when the address is set.
633 if (doalias
== 0 && afp
->af_af
!= AF_LINK
)
635 afp
->af_getaddr(addr
, (doalias
>= 0 ? ADDR
: RIDADDR
));
639 settunnel(const char *src
, const char *dst
, int s
, const struct afswtch
*afp
)
641 struct addrinfo
*srcres
, *dstres
;
644 if (afp
->af_settunnel
== NULL
) {
645 warn("address family %s does not support tunnel setup",
650 if ((ecode
= getaddrinfo(src
, NULL
, NULL
, &srcres
)) != 0)
651 errx(1, "error in parsing address string: %s",
652 gai_strerror(ecode
));
654 if ((ecode
= getaddrinfo(dst
, NULL
, NULL
, &dstres
)) != 0)
655 errx(1, "error in parsing address string: %s",
656 gai_strerror(ecode
));
658 if (srcres
->ai_addr
->sa_family
!= dstres
->ai_addr
->sa_family
)
660 "source and destination address families do not match");
662 afp
->af_settunnel(s
, srcres
, dstres
);
664 freeaddrinfo(srcres
);
665 freeaddrinfo(dstres
);
670 deletetunnel(const char *vname
, int param
, int s
, const struct afswtch
*afp
)
673 if (ioctl(s
, SIOCDIFPHYADDR
, &ifr
) < 0)
674 err(1, "SIOCDIFPHYADDR");
678 setifnetmask(const char *addr
, int dummy __unused
, int s
,
679 const struct afswtch
*afp
)
681 if (afp
->af_getaddr
!= NULL
) {
683 afp
->af_getaddr(addr
, MASK
);
688 setifbroadaddr(const char *addr
, int dummy __unused
, int s
,
689 const struct afswtch
*afp
)
691 if (afp
->af_getaddr
!= NULL
)
692 afp
->af_getaddr(addr
, DSTADDR
);
696 setifipdst(const char *addr
, int dummy __unused
, int s
,
697 const struct afswtch
*afp
)
699 const struct afswtch
*inet
;
701 inet
= af_getbyname("inet");
704 inet
->af_getaddr(addr
, DSTADDR
);
710 notealias(const char *addr
, int param
, int s
, const struct afswtch
*afp
)
712 #define rqtosa(x) (&(((struct ifreq *)(afp->x))->ifr_addr))
713 if (setaddr
&& doalias
== 0 && param
< 0)
714 if (afp
->af_addreq
!= NULL
&& afp
->af_ridreq
!= NULL
)
715 bcopy((caddr_t
)rqtosa(af_addreq
),
716 (caddr_t
)rqtosa(af_ridreq
),
717 rqtosa(af_addreq
)->sa_len
);
729 setifdstaddr(const char *addr
, int param __unused
, int s
,
730 const struct afswtch
*afp
)
732 if (afp
->af_getaddr
!= NULL
)
733 afp
->af_getaddr(addr
, DSTADDR
);
737 * Note: doing an SIOCIGIFFLAGS scribbles on the union portion
738 * of the ifreq structure, which may confuse other parts of ifconfig.
739 * Make a private copy so we can avoid that.
742 setifflags(const char *vname
, int value
, int s
, const struct afswtch
*afp
)
747 bcopy((char *)&ifr
, (char *)&my_ifr
, sizeof(struct ifreq
));
749 if (ioctl(s
, SIOCGIFFLAGS
, (caddr_t
)&my_ifr
) < 0) {
750 Perror("ioctl (SIOCGIFFLAGS)");
753 strncpy(my_ifr
.ifr_name
, name
, sizeof (my_ifr
.ifr_name
));
754 flags
= my_ifr
.ifr_flags
;
761 my_ifr
.ifr_flags
= flags
& 0xffff;
762 if (ioctl(s
, SIOCSIFFLAGS
, (caddr_t
)&my_ifr
) < 0)
767 setifcap(const char *vname
, int value
, int s
, const struct afswtch
*afp
)
771 if (ioctl(s
, SIOCGIFCAP
, (caddr_t
)&ifr
) < 0) {
772 Perror("ioctl (SIOCGIFCAP)");
775 flags
= ifr
.ifr_curcap
;
781 flags
&= ifr
.ifr_reqcap
;
782 ifr
.ifr_reqcap
= flags
;
783 if (ioctl(s
, SIOCSIFCAP
, (caddr_t
)&ifr
) < 0)
788 setifmetric(const char *val
, int dummy __unused
, int s
,
789 const struct afswtch
*afp
)
791 strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
792 ifr
.ifr_metric
= atoi(val
);
793 if (ioctl(s
, SIOCSIFMETRIC
, (caddr_t
)&ifr
) < 0)
794 warn("ioctl (set metric)");
798 setifmtu(const char *val
, int dummy __unused
, int s
,
799 const struct afswtch
*afp
)
801 strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
802 ifr
.ifr_mtu
= atoi(val
);
803 if (ioctl(s
, SIOCSIFMTU
, (caddr_t
)&ifr
) < 0)
804 warn("ioctl (set mtu)");
809 setifname(const char *val
, int dummy __unused
, int s
,
810 const struct afswtch
*afp
)
814 newname
= strdup(val
);
815 if (newname
== NULL
) {
816 warn("no memory to set ifname");
819 ifr
.ifr_data
= newname
;
820 if (ioctl(s
, SIOCSIFNAME
, (caddr_t
)&ifr
) < 0) {
821 warn("ioctl (set name)");
825 strlcpy(name
, newname
, sizeof(name
));
831 setrouter(const char *vname
, int value
, int s
, const struct afswtch
*afp
)
833 if (afp
->af_setrouter
== NULL
) {
834 warn("address family %s does not support router mode",
839 afp
->af_setrouter(s
, value
);
843 setifdesc(const char *val
, int dummy __unused
, int s
, const struct afswtch
*afp
)
845 struct if_descreq ifdr
;
847 bzero(&ifdr
, sizeof (ifdr
));
848 strncpy(ifdr
.ifdr_name
, name
, sizeof (ifdr
.ifdr_name
));
849 ifdr
.ifdr_len
= strlen(val
);
850 strncpy((char *)ifdr
.ifdr_desc
, val
, sizeof (ifdr
.ifdr_desc
));
852 if (ioctl(s
, SIOCSIFDESC
, (caddr_t
)&ifdr
) < 0) {
853 warn("ioctl (set desc)");
858 settbr(const char *val
, int dummy __unused
, int s
, const struct afswtch
*afp
)
860 struct if_linkparamsreq iflpr
;
863 u_int32_t percent
= 0;
867 bzero(&iflpr
, sizeof (iflpr
));
868 strncpy(iflpr
.iflpr_name
, name
, sizeof (iflpr
.iflpr_name
));
870 bps
= strtold(val
, &cp
);
871 if (val
== cp
|| errno
!= 0) {
872 warn("Invalid value '%s'", val
);
875 rate
= (u_int64_t
)bps
;
877 if (!strcmp(cp
, "b") || !strcmp(cp
, "bps")) {
879 } else if (!strcmp(cp
, "Kb") || !strcmp(cp
, "Kbps")) {
881 } else if (!strcmp(cp
, "Mb") || !strcmp(cp
, "Mbps")) {
883 } else if (!strcmp(cp
, "Gb") || !strcmp(cp
, "Gbps")) {
884 rate
*= 1000 * 1000 * 1000;
885 } else if (!strcmp(cp
, "%")) {
887 if (percent
== 0 || percent
> 100) {
888 printf("Value out of range '%s'", val
);
891 } else if (*cp
!= '\0') {
892 printf("Unknown unit '%s'", cp
);
896 iflpr
.iflpr_output_tbr_rate
= rate
;
897 iflpr
.iflpr_output_tbr_percent
= percent
;
898 if (ioctl(s
, SIOCSIFLINKPARAMS
, &iflpr
) < 0 &&
899 errno
!= ENOENT
&& errno
!= ENXIO
&& errno
!= ENODEV
) {
900 warn("ioctl (set link params)");
901 } else if (errno
== ENXIO
) {
902 printf("TBR cannot be set on %s\n", name
);
903 } else if (errno
== ENOENT
|| rate
== 0) {
904 printf("%s: TBR is now disabled\n", name
);
905 } else if (errno
== ENODEV
) {
906 printf("%s: requires absolute TBR rate\n", name
);
907 } else if (percent
!= 0) {
908 printf("%s: TBR rate set to %u%% of effective link rate\n",
911 printf("%s: TBR rate set to %s\n", name
, bps_to_str(rate
));
916 setthrottle(const char *val
, int dummy __unused
, int s
,
917 const struct afswtch
*afp
)
919 struct if_throttlereq iftr
;
923 bzero(&iftr
, sizeof (iftr
));
924 strncpy(iftr
.ifthr_name
, name
, sizeof (iftr
.ifthr_name
));
926 iftr
.ifthr_level
= strtold(val
, &cp
);
927 if (val
== cp
|| errno
!= 0) {
928 warn("Invalid value '%s'", val
);
932 if (ioctl(s
, SIOCSIFTHROTTLE
, &iftr
) < 0 && errno
!= ENXIO
) {
933 warn("ioctl (set throttling level)");
934 } else if (errno
== ENXIO
) {
935 printf("throttling level cannot be set on %s\n", name
);
937 printf("%s: throttling level set to %d\n", name
,
943 setdisableoutput(const char *val
, int dummy __unused
, int s
,
944 const struct afswtch
*afp
)
949 bzero(&ifr
, sizeof (ifr
));
950 strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
952 ifr
.ifr_ifru
.ifru_disable_output
= strtold(val
, &cp
);
953 if (val
== cp
|| errno
!= 0) {
954 warn("Invalid value '%s'", val
);
958 if (ioctl(s
, SIOCSIFDISABLEOUTPUT
, &ifr
) < 0 && errno
!= ENXIO
) {
959 warn("ioctl set disable output");
960 } else if (errno
== ENXIO
) {
961 printf("output thread can not be disabled on %s\n", name
);
963 printf("output %s on %s\n",
964 ((ifr
.ifr_ifru
.ifru_disable_output
== 0) ? "enabled" : "disabled"),
970 setlog(const char *val
, int dummy __unused
, int s
,
971 const struct afswtch
*afp
)
976 strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
978 ifr
.ifr_log
.ifl_level
= strtold(val
, &cp
);
979 if (val
== cp
|| errno
!= 0) {
980 warn("Invalid value '%s'", val
);
983 ifr
.ifr_log
.ifl_flags
= (IFRLOGF_DLIL
|IFRLOGF_FAMILY
|IFRLOGF_DRIVER
|
986 if (ioctl(s
, SIOCSIFLOG
, &ifr
) < 0)
987 warn("ioctl (set logging parameters)");
991 setcl2k(const char *vname
, int value
, int s
, const struct afswtch
*afp
)
993 strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
994 ifr
.ifr_ifru
.ifru_2kcl
= value
;
996 if (ioctl(s
, SIOCSIF2KCL
, (caddr_t
)&ifr
) < 0)
1001 setexpensive(const char *vname
, int value
, int s
, const struct afswtch
*afp
)
1003 strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
1004 ifr
.ifr_ifru
.ifru_expensive
= value
;
1006 if (ioctl(s
, SIOCSIFEXPENSIVE
, (caddr_t
)&ifr
) < 0)
1011 settimestamp(const char *vname
, int value
, int s
, const struct afswtch
*afp
)
1013 strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
1016 if (ioctl(s
, SIOCSIFTIMESTAMPDISABLE
, (caddr_t
)&ifr
) < 0)
1019 if (ioctl(s
, SIOCSIFTIMESTAMPENABLE
, (caddr_t
)&ifr
) < 0)
1025 setecnmode(const char *val
, int dummy __unused
, int s
,
1026 const struct afswtch
*afp
)
1030 if (strcmp(val
, "default") == 0)
1031 ifr
.ifr_ifru
.ifru_ecn_mode
= IFRTYPE_ECN_DEFAULT
;
1032 else if (strcmp(val
, "enable") == 0)
1033 ifr
.ifr_ifru
.ifru_ecn_mode
= IFRTYPE_ECN_ENABLE
;
1034 else if (strcmp(val
, "disable") == 0)
1035 ifr
.ifr_ifru
.ifru_ecn_mode
= IFRTYPE_ECN_DISABLE
;
1037 ifr
.ifr_ifru
.ifru_ecn_mode
= strtold(val
, &cp
);
1038 if (val
== cp
|| errno
!= 0) {
1039 warn("Invalid ECN mode value '%s'", val
);
1044 strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
1046 if (ioctl(s
, SIOCSECNMODE
, (caddr_t
)&ifr
) < 0)
1047 Perror("ioctl(SIOCSECNMODE)");
1051 setprobeconnectivity(const char *vname
, int value
, int s
, const struct afswtch
*afp
)
1053 strlcpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
1054 ifr
.ifr_ifru
.ifru_probe_connectivity
= value
;
1056 if (ioctl(s
, SIOCSIFPROBECONNECTIVITY
, (caddr_t
)&ifr
) < 0)
1060 #if defined(SIOCSQOSMARKINGMODE) && defined(SIOCSQOSMARKINGENABLED)
1063 setqosmarking(const char *cmd
, const char *arg
, int s
, const struct afswtch
*afp
)
1067 #if (DEBUG | DEVELOPMENT)
1068 printf("%s(%s, %s)\n", __func__
, cmd
, arg
);
1069 #endif /* (DEBUG | DEVELOPMENT) */
1071 strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
1073 if (strcmp(cmd
, "mode") == 0) {
1074 ioc
= SIOCSQOSMARKINGMODE
;
1076 if (strcmp(arg
, "fastlane") == 0)
1077 ifr
.ifr_qosmarking_mode
= IFRTYPE_QOSMARKING_FASTLANE
;
1078 else if (strcasecmp(arg
, "none") == 0 || strcasecmp(arg
, "off") == 0)
1079 ifr
.ifr_qosmarking_mode
= IFRTYPE_QOSMARKING_MODE_NONE
;
1081 err(EX_USAGE
, "bad value for qosmarking mode: %s", arg
);
1082 } else if (strcmp(cmd
, "enabled") == 0) {
1083 ioc
= SIOCSQOSMARKINGENABLED
;
1084 if (strcmp(arg
, "1") == 0 || strcasecmp(arg
, "on") == 0||
1085 strcasecmp(arg
, "yes") == 0 || strcasecmp(arg
, "true") == 0)
1086 ifr
.ifr_qosmarking_enabled
= 1;
1087 else if (strcmp(arg
, "0") == 0 || strcasecmp(arg
, "off") == 0||
1088 strcasecmp(arg
, "no") == 0 || strcasecmp(arg
, "false") == 0)
1089 ifr
.ifr_qosmarking_enabled
= 0;
1091 err(EX_USAGE
, "bad value for qosmarking enabled: %s", arg
);
1093 err(EX_USAGE
, "qosmarking takes mode or enabled");
1096 if (ioctl(s
, ioc
, (caddr_t
)&ifr
) < 0)
1097 err(EX_OSERR
, "ioctl(%s, %s)", cmd
, arg
);
1101 setfastlane(const char *cmd
, const char *arg
, int s
, const struct afswtch
*afp
)
1103 strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
1105 warnx("### fastlane is obsolete, use qosmarking ###");
1107 if (strcmp(cmd
, "capable") == 0) {
1108 if (strcmp(arg
, "1") == 0 || strcasecmp(arg
, "on") == 0||
1109 strcasecmp(arg
, "yes") == 0 || strcasecmp(arg
, "true") == 0)
1110 setqosmarking("mode", "fastlane", s
, afp
);
1111 else if (strcmp(arg
, "0") == 0 || strcasecmp(arg
, "off") == 0||
1112 strcasecmp(arg
, "no") == 0 || strcasecmp(arg
, "false") == 0)
1113 setqosmarking("mode", "off", s
, afp
);
1115 err(EX_USAGE
, "bad value for fastlane %s", cmd
);
1116 } else if (strcmp(cmd
, "enable") == 0) {
1117 if (strcmp(arg
, "1") == 0 || strcasecmp(arg
, "on") == 0||
1118 strcasecmp(arg
, "yes") == 0 || strcasecmp(arg
, "true") == 0)
1119 setqosmarking("enabled", "1", s
, afp
);
1120 else if (strcmp(arg
, "0") == 0 || strcasecmp(arg
, "off") == 0||
1121 strcasecmp(arg
, "no") == 0 || strcasecmp(arg
, "false") == 0)
1122 setqosmarking("enabled", "0", s
, afp
);
1124 err(EX_USAGE
, "bad value for fastlane %s", cmd
);
1126 err(EX_USAGE
, "fastlane takes capable or enable");
1130 #else /* defined(SIOCSQOSMARKINGMODE) && defined(SIOCSQOSMARKINGENABLED) */
1133 setfastlane(const char *cmd
, const char *arg
, int s
, const struct afswtch
*afp
)
1138 strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
1140 if (strcmp(cmd
, "capable") == 0)
1141 ioc
= SIOCSFASTLANECAPABLE
;
1142 else if (strcmp(cmd
, "enable") == 0)
1143 ioc
= SIOCSFASTLEENABLED
;
1145 err(EX_USAGE
, "fastlane takes capable or enabled");
1147 if (strcmp(arg
, "1") == 0 || strcasecmp(arg
, "on") == 0||
1148 strcasecmp(arg
, "yes") == 0 || strcasecmp(arg
, "true") == 0)
1150 else if (strcmp(arg
, "0") == 0 || strcasecmp(arg
, "off") == 0||
1151 strcasecmp(arg
, "no") == 0 || strcasecmp(arg
, "false") == 0)
1154 err(EX_USAGE
, "bad value for fastlane %s", cmd
);
1156 if (ioc
== SIOCSFASTLANECAPABLE
)
1157 ifr
.ifr_fastlane_capable
= value
;
1159 ifr
.ifr_fastlane_enabled
= value
;
1161 if (ioctl(s
, ioc
, (caddr_t
)&ifr
) < 0)
1162 err(EX_OSERR
, "ioctl(%s, %s)", cmd
, arg
);
1167 setqosmarking(const char *cmd
, const char *arg
, int s
, const struct afswtch
*afp
)
1169 if (strcmp(cmd
, "mode") == 0) {
1170 if (strcmp(arg
, "fastlane") == 0)
1171 setfastlane("capable", "on", s
, afp
);
1172 else if (strcmp(arg
, "none") == 0)
1173 setfastlane("capable", "off", s
, afp
);
1175 err(EX_USAGE
, "bad value for qosmarking mode: %s", arg
);
1176 } else if (strcmp(cmd
, "enabled") == 0) {
1177 if (strcmp(arg
, "1") == 0 || strcasecmp(arg
, "on") == 0||
1178 strcasecmp(arg
, "yes") == 0 || strcasecmp(arg
, "true") == 0)
1179 setfastlane("enable", "on", s
, afp
);
1180 else if (strcmp(arg
, "0") == 0 || strcasecmp(arg
, "off") == 0||
1181 strcasecmp(arg
, "no") == 0 || strcasecmp(arg
, "false") == 0)
1182 setfastlane("enable", "off", s
, afp
);
1184 err(EX_USAGE
, "bad value for qosmarking enabled: %s", arg
);
1186 err(EX_USAGE
, "qosmarking takes mode or enabled");
1190 #endif /* defined(SIOCSQOSMARKINGMODE) && defined(SIOCSQOSMARKINGENABLED) */
1193 "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6SMART\7RUNNING" \
1194 "\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2" \
1198 "\020\1AUTOCONFIGURING\4PROBE_CONNECTIVITY\5FASTLN_CAP\6IPV6_DISABLED\7ACCEPT_RTADV\10TXSTART\11RXPOLL" \
1199 "\12VLAN\13BOND\14ARPLL\15NOWINDOWSCALE\16NOAUTOIPV6LL\17EXPENSIVE\20ROUTER4" \
1200 "\21ROUTER6\22LOCALNET_PRIVATE\23ND6ALT\24RESTRICTED_RECV\25AWDL\26NOACKPRI" \
1201 "\27AWDL_RESTRICTED\30CL2K\31ECN_ENABLE\32ECN_DISABLE\33CHANNEL_DRV\34CA" \
1202 "\35SENDLIST\36DIRECTLINK\37FASTLN_ON\40UPDOWNCHANGE"
1205 "\020\1RXCSUM\2TXCSUM\3VLAN_MTU\4VLAN_HWTAGGING\5JUMBO_MTU" \
1206 "\6TSO4\7TSO6\10LRO\11AV\12TXSTATUS\13CHANNEL_IO\14HW_TIMESTAMP\15SW_TIMESTAMP" \
1207 "\16PARTIAL_CSUM\17ZEROINVERT_CSUM"
1209 #define IFRLOGF_BITS \
1210 "\020\1DLIL\21FAMILY\31DRIVER\35FIRMWARE"
1213 * Print the status of the interface. If an address family was
1214 * specified, show only it; otherwise, show them all.
1217 status(const struct afswtch
*afp
, const struct sockaddr_dl
*sdl
,
1218 struct ifaddrs
*ifa
)
1220 struct ifaddrs
*ift
;
1223 struct if_descreq ifdr
;
1224 struct if_linkparamsreq iflpr
;
1226 struct ifmibdata_supplemental ifmsupp
;
1227 size_t miblen
= sizeof(struct ifmibdata_supplemental
);
1228 u_int64_t eflags
= 0;
1233 afp
= af_getbyname("inet");
1237 ifr
.ifr_addr
.sa_family
= afp
->af_af
== AF_LINK
? AF_INET
: afp
->af_af
;
1238 strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
1240 s
= socket(ifr
.ifr_addr
.sa_family
, SOCK_DGRAM
, 0);
1242 err(1, "socket(family %u,SOCK_DGRAM)", ifr
.ifr_addr
.sa_family
);
1244 printf("%s: ", name
);
1245 printb("flags", ifa
->ifa_flags
, IFFBITS
);
1246 if (ioctl(s
, SIOCGIFMETRIC
, &ifr
) != -1)
1248 printf(" metric %d", ifr
.ifr_metric
);
1249 if (ioctl(s
, SIOCGIFMTU
, &ifr
) != -1)
1250 printf(" mtu %d", ifr
.ifr_mtu
);
1251 if (showrtref
&& ioctl(s
, SIOCGIFGETRTREFCNT
, &ifr
) != -1)
1252 printf(" rtref %d", ifr
.ifr_route_refcnt
);
1254 unsigned int ifindex
= if_nametoindex(ifa
->ifa_name
);
1256 printf(" index %u", ifindex
);
1260 if (verbose
&& ioctl(s
, SIOCGIFEFLAGS
, (caddr_t
)&ifr
) != -1 &&
1261 (eflags
= ifr
.ifr_eflags
) != 0) {
1262 printb("\teflags", eflags
, IFEFBITS
);
1266 if (ioctl(s
, SIOCGIFCAP
, (caddr_t
)&ifr
) == 0) {
1267 if (ifr
.ifr_curcap
!= 0) {
1268 curcap
= ifr
.ifr_curcap
;
1269 printb("\toptions", ifr
.ifr_curcap
, IFCAPBITS
);
1272 if (supmedia
&& ifr
.ifr_reqcap
!= 0) {
1273 printb("\tcapabilities", ifr
.ifr_reqcap
, IFCAPBITS
);
1280 for (ift
= ifa
; ift
!= NULL
; ift
= ift
->ifa_next
) {
1281 if (ift
->ifa_addr
== NULL
)
1283 if (strcmp(ifa
->ifa_name
, ift
->ifa_name
) != 0)
1286 const struct afswtch
*p
;
1287 p
= af_getbyfamily(ift
->ifa_addr
->sa_family
);
1288 if (p
!= NULL
&& p
->af_status
!= NULL
)
1289 p
->af_status(s
, ift
);
1290 } else if (afp
->af_af
== ift
->ifa_addr
->sa_family
)
1291 afp
->af_status(s
, ift
);
1294 if (allfamilies
|| afp
->af_af
== AF_LINK
) {
1295 const struct afswtch
*lafp
;
1298 * Hack; the link level address is received separately
1299 * from the routing information so any address is not
1300 * handled above. Cobble together an entry and invoke
1301 * the status method specially.
1303 lafp
= af_getbyname("lladdr");
1305 info
.rti_info
[RTAX_IFA
] = (struct sockaddr
*)sdl
;
1306 lafp
->af_status(s
, &info
);
1312 else if (afp
->af_other_status
!= NULL
)
1313 afp
->af_other_status(s
);
1315 strncpy(ifs
.ifs_name
, name
, sizeof ifs
.ifs_name
);
1316 if (ioctl(s
, SIOCGIFSTATUS
, &ifs
) == 0)
1317 printf("%s", ifs
.ascii
);
1319 /* The rest is for when verbose is set; if not set, we're done */
1323 if (ioctl(s
, SIOCGIFTYPE
, &ifr
) != -1) {
1324 char *c
= ift2str(ifr
.ifr_type
.ift_type
,
1325 ifr
.ifr_type
.ift_family
, ifr
.ifr_type
.ift_subfamily
);
1327 printf("\ttype: %s\n", c
);
1331 struct if_agentidsreq ifar
;
1332 memset(&ifar
, 0, sizeof(ifar
));
1334 strlcpy(ifar
.ifar_name
, name
, sizeof(ifar
.ifar_name
));
1336 if (ioctl(s
, SIOCGIFAGENTIDS
, &ifar
) != -1) {
1337 if (ifar
.ifar_count
!= 0) {
1338 ifar
.ifar_uuids
= calloc(ifar
.ifar_count
, sizeof(uuid_t
));
1339 if (ifar
.ifar_uuids
!= NULL
) {
1340 if (ioctl(s
, SIOCGIFAGENTIDS
, &ifar
) != 1) {
1341 for (int agent_i
= 0; agent_i
< ifar
.ifar_count
; agent_i
++) {
1342 struct netagent_req nar
;
1343 memset(&nar
, 0, sizeof(nar
));
1345 uuid_copy(nar
.netagent_uuid
, ifar
.ifar_uuids
[agent_i
]);
1347 if (ioctl(s
, SIOCGIFAGENTDATA
, &nar
) != 1) {
1348 printf("\tagent domain:%s type:%s flags:0x%x desc:\"%s\"\n",
1349 nar
.netagent_domain
, nar
.netagent_type
,
1350 nar
.netagent_flags
, nar
.netagent_desc
);
1354 free(ifar
.ifar_uuids
);
1360 if (ioctl(s
, SIOCGIFLINKQUALITYMETRIC
, &ifr
) != -1) {
1361 int lqm
= ifr
.ifr_link_quality_metric
;
1363 printf("\tlink quality: %d ", lqm
);
1364 if (lqm
== IFNET_LQM_THRESH_OFF
)
1366 else if (lqm
== IFNET_LQM_THRESH_UNKNOWN
)
1367 printf("(unknown)");
1368 else if (lqm
> IFNET_LQM_THRESH_UNKNOWN
&&
1369 lqm
<= IFNET_LQM_THRESH_BAD
)
1371 else if (lqm
> IFNET_LQM_THRESH_UNKNOWN
&&
1372 lqm
<= IFNET_LQM_THRESH_POOR
)
1374 else if (lqm
> IFNET_LQM_THRESH_POOR
&&
1375 lqm
<= IFNET_LQM_THRESH_GOOD
)
1380 } else if (lqm
> IFNET_LQM_THRESH_UNKNOWN
) {
1381 printf("\tlink quality: %d ", lqm
);
1382 if (lqm
<= IFNET_LQM_THRESH_BAD
)
1384 else if (lqm
<= IFNET_LQM_THRESH_POOR
)
1386 else if (lqm
<= IFNET_LQM_THRESH_GOOD
)
1395 if (ioctl(s
, SIOCGIFINTERFACESTATE
, &ifr
) != -1) {
1397 if (ifr
.ifr_interface_state
.valid_bitmask
&
1398 IF_INTERFACE_STATE_RRC_STATE_VALID
) {
1399 uint8_t rrc_state
= ifr
.ifr_interface_state
.rrc_state
;
1401 printf(" rrc: %u ", rrc_state
);
1402 if (rrc_state
== IF_INTERFACE_STATE_RRC_STATE_CONNECTED
)
1403 printf("(connected)");
1404 else if (rrc_state
== IF_INTERFACE_STATE_RRC_STATE_IDLE
)
1409 if (ifr
.ifr_interface_state
.valid_bitmask
&
1410 IF_INTERFACE_STATE_INTERFACE_AVAILABILITY_VALID
) {
1411 uint8_t ifavail
= ifr
.ifr_interface_state
.interface_availability
;
1413 printf(" availability: %u ", ifavail
);
1414 if (ifavail
== IF_INTERFACE_STATE_INTERFACE_AVAILABLE
)
1416 else if (ifavail
== IF_INTERFACE_STATE_INTERFACE_UNAVAILABLE
)
1421 printf(" availability: (not valid)");
1424 ifr
.ifr_interface_state
.valid_bitmask
&
1425 IF_INTERFACE_STATE_LQM_STATE_VALID
) {
1426 int8_t lqm
= ifr
.ifr_interface_state
.lqm_state
;
1428 printf(" lqm: %d", lqm
);
1430 if (lqm
== IFNET_LQM_THRESH_OFF
)
1432 else if (lqm
== IFNET_LQM_THRESH_UNKNOWN
)
1433 printf("(unknown)");
1434 else if (lqm
== IFNET_LQM_THRESH_BAD
)
1436 else if (lqm
== IFNET_LQM_THRESH_POOR
)
1438 else if (lqm
== IFNET_LQM_THRESH_GOOD
)
1447 bzero(&iflpr
, sizeof (iflpr
));
1448 strncpy(iflpr
.iflpr_name
, name
, sizeof (iflpr
.iflpr_name
));
1449 if (ioctl(s
, SIOCGIFLINKPARAMS
, &iflpr
) != -1) {
1450 u_int64_t ibw_max
= iflpr
.iflpr_input_bw
.max_bw
;
1451 u_int64_t ibw_eff
= iflpr
.iflpr_input_bw
.eff_bw
;
1452 u_int64_t obw_max
= iflpr
.iflpr_output_bw
.max_bw
;
1453 u_int64_t obw_eff
= iflpr
.iflpr_output_bw
.eff_bw
;
1454 u_int64_t obw_tbr
= iflpr
.iflpr_output_tbr_rate
;
1455 u_int32_t obw_pct
= iflpr
.iflpr_output_tbr_percent
;
1456 u_int64_t ilt_max
= iflpr
.iflpr_input_lt
.max_lt
;
1457 u_int64_t ilt_eff
= iflpr
.iflpr_input_lt
.eff_lt
;
1458 u_int64_t olt_max
= iflpr
.iflpr_output_lt
.max_lt
;
1459 u_int64_t olt_eff
= iflpr
.iflpr_output_lt
.eff_lt
;
1462 if (eflags
& IFEF_TXSTART
) {
1463 u_int32_t flags
= iflpr
.iflpr_flags
;
1464 u_int32_t sched
= iflpr
.iflpr_output_sched
;
1465 struct if_throttlereq iftr
;
1467 printf("\tscheduler: %s%s ",
1468 (flags
& IFLPRF_ALTQ
) ? "ALTQ_" : "",
1470 if (flags
& IFLPRF_DRVMANAGED
)
1471 printf("(driver managed)");
1474 bzero(&iftr
, sizeof (iftr
));
1475 strncpy(iftr
.ifthr_name
, name
,
1476 sizeof (iftr
.ifthr_name
));
1477 if (ioctl(s
, SIOCGIFTHROTTLE
, &iftr
) != -1 &&
1478 iftr
.ifthr_level
!= IFNET_THROTTLE_OFF
)
1479 printf("\tthrottling: level %d (%s)\n",
1480 iftr
.ifthr_level
, tl2str(iftr
.ifthr_level
));
1483 if (obw_tbr
!= 0 && obw_eff
> obw_tbr
)
1486 if (ibw_max
!= 0 || obw_max
!= 0) {
1487 if (ibw_max
== obw_max
&& ibw_eff
== obw_eff
&&
1488 ibw_max
== ibw_eff
&& obw_tbr
== 0) {
1489 printf("\tlink rate: %s\n",
1490 bps_to_str(ibw_max
));
1492 printf("\tuplink rate: %s [eff] / ",
1493 bps_to_str(obw_eff
));
1496 printf("%s [tbr] / ",
1497 bps_to_str(obw_tbr
));
1499 printf("%s [tbr %u%%] / ",
1500 bps_to_str(obw_tbr
),
1503 printf("%s", bps_to_str(obw_max
));
1507 if (ibw_eff
== ibw_max
) {
1508 printf("\tdownlink rate: %s\n",
1509 bps_to_str(ibw_max
));
1511 printf("\tdownlink rate: "
1512 "%s [eff] / ", bps_to_str(ibw_eff
));
1513 printf("%s [max]\n",
1514 bps_to_str(ibw_max
));
1517 } else if (obw_tbr
!= 0) {
1518 printf("\tuplink rate: %s [tbr]\n",
1519 bps_to_str(obw_tbr
));
1522 if (ilt_max
!= 0 || olt_max
!= 0) {
1523 if (ilt_max
== olt_max
&& ilt_eff
== olt_eff
&&
1524 ilt_max
== ilt_eff
) {
1525 printf("\tlink latency: %s\n",
1526 ns_to_str(ilt_max
));
1528 if (olt_max
!= 0 && olt_eff
== olt_max
) {
1529 printf("\tuplink latency: %s\n",
1530 ns_to_str(olt_max
));
1531 } else if (olt_max
!= 0) {
1532 printf("\tuplink latency: "
1533 "%s [eff] / ", ns_to_str(olt_eff
));
1534 printf("%s [max]\n",
1535 ns_to_str(olt_max
));
1537 if (ilt_max
!= 0 && ilt_eff
== ilt_max
) {
1538 printf("\tdownlink latency: %s\n",
1539 ns_to_str(ilt_max
));
1540 } else if (ilt_max
!= 0) {
1541 printf("\tdownlink latency: "
1542 "%s [eff] / ", ns_to_str(ilt_eff
));
1543 printf("%s [max]\n",
1544 ns_to_str(ilt_max
));
1550 /* Common OID prefix */
1553 mib
[2] = NETLINK_GENERIC
;
1554 mib
[3] = IFMIB_IFDATA
;
1555 mib
[4] = if_nametoindex(name
);
1556 mib
[5] = IFDATA_SUPPLEMENTAL
;
1557 if (sysctl(mib
, 6, &ifmsupp
, &miblen
, (void *)0, 0) == -1)
1558 err(1, "sysctl IFDATA_SUPPLEMENTAL");
1560 if (ifmsupp
.ifmd_data_extended
.ifi_alignerrs
!= 0) {
1561 printf("\tunaligned pkts: %llu\n",
1562 ifmsupp
.ifmd_data_extended
.ifi_alignerrs
);
1564 if (ifmsupp
.ifmd_data_extended
.ifi_dt_bytes
!= 0) {
1565 printf("\tdata milestone interval: %s\n",
1566 bytes_to_str(ifmsupp
.ifmd_data_extended
.ifi_dt_bytes
));
1569 bzero(&ifdr
, sizeof (ifdr
));
1570 strncpy(ifdr
.ifdr_name
, name
, sizeof (ifdr
.ifdr_name
));
1571 if (ioctl(s
, SIOCGIFDESC
, &ifdr
) != -1 && ifdr
.ifdr_len
) {
1572 printf("\tdesc: %s\n", ifdr
.ifdr_desc
);
1575 if (ioctl(s
, SIOCGIFLOG
, &ifr
) != -1 && ifr
.ifr_log
.ifl_level
) {
1576 printf("\tlogging: level %d ", ifr
.ifr_log
.ifl_level
);
1577 printb("facilities", ifr
.ifr_log
.ifl_flags
, IFRLOGF_BITS
);
1581 if (ioctl(s
, SIOCGIFDELEGATE
, &ifr
) != -1 && ifr
.ifr_delegated
) {
1582 char delegatedif
[IFNAMSIZ
+1];
1583 if (if_indextoname(ifr
.ifr_delegated
, delegatedif
) != NULL
)
1584 printf("\teffective interface: %s\n", delegatedif
);
1587 if (ioctl(s
, SIOCGSTARTDELAY
, &ifr
) != -1) {
1588 if (ifr
.ifr_start_delay_qlen
> 0 &&
1589 ifr
.ifr_start_delay_timeout
> 0) {
1590 printf("\ttxstart qlen: %u packets "
1591 "timeout: %u microseconds\n",
1592 ifr
.ifr_start_delay_qlen
,
1593 ifr
.ifr_start_delay_timeout
/1000);
1596 #if defined(IFCAP_HW_TIMESTAMP) && defined(IFCAP_SW_TIMESTAMP)
1597 if ((curcap
& (IFCAP_HW_TIMESTAMP
| IFCAP_SW_TIMESTAMP
)) &&
1598 ioctl(s
, SIOCGIFTIMESTAMPENABLED
, &ifr
) != -1) {
1599 printf("\ttimestamp: %s\n",
1600 (ifr
.ifr_intval
!= 0) ? "enabled" : "disabled");
1603 #if defined(SIOCGQOSMARKINGENABLED) && defined(SIOCGQOSMARKINGMODE)
1604 if (ioctl(s
, SIOCGQOSMARKINGENABLED
, &ifr
) != -1) {
1605 printf("\tqosmarking enabled: %s mode: ",
1606 ifr
.ifr_qosmarking_enabled
? "yes" : "no");
1607 if (ioctl(s
, SIOCGQOSMARKINGMODE
, &ifr
) != -1) {
1608 switch (ifr
.ifr_qosmarking_mode
) {
1609 case IFRTYPE_QOSMARKING_FASTLANE
:
1610 printf("fastlane\n");
1612 case IFRTYPE_QOSMARKING_MODE_NONE
:
1616 printf("unknown (%u)\n", ifr
.ifr_qosmarking_mode
);
1621 #endif /* defined(SIOCGQOSMARKINGENABLED) && defined(SIOCGQOSMARKINGMODE) */
1627 #define KILOBYTES 1024
1628 #define MEGABYTES (KILOBYTES * KILOBYTES)
1629 #define GIGABYTES (KILOBYTES * KILOBYTES * KILOBYTES)
1632 bytes_to_str(unsigned long long bytes
)
1634 static char buf
[32];
1636 long double n
= bytes
, t
;
1638 if (bytes
>= GIGABYTES
) {
1641 } else if (n
>= MEGABYTES
) {
1644 } else if (n
>= KILOBYTES
) {
1652 snprintf(buf
, sizeof (buf
), "%-4.2Lf %s", t
, u
);
1656 #define GIGABIT_PER_SEC 1000000000 /* gigabit per second */
1657 #define MEGABIT_PER_SEC 1000000 /* megabit per second */
1658 #define KILOBIT_PER_SEC 1000 /* kilobit per second */
1661 bps_to_str(unsigned long long rate
)
1663 static char buf
[32];
1665 long double n
= rate
, t
;
1667 if (rate
>= GIGABIT_PER_SEC
) {
1668 t
= n
/ GIGABIT_PER_SEC
;
1670 } else if (n
>= MEGABIT_PER_SEC
) {
1671 t
= n
/ MEGABIT_PER_SEC
;
1673 } else if (n
>= KILOBIT_PER_SEC
) {
1674 t
= n
/ KILOBIT_PER_SEC
;
1681 snprintf(buf
, sizeof (buf
), "%-4.2Lf %4s", t
, u
);
1685 #define NSEC_PER_SEC 1000000000 /* nanosecond per second */
1686 #define USEC_PER_SEC 1000000 /* microsecond per second */
1687 #define MSEC_PER_SEC 1000 /* millisecond per second */
1690 ns_to_str(unsigned long long nsec
)
1692 static char buf
[32];
1694 long double n
= nsec
, t
;
1696 if (nsec
>= NSEC_PER_SEC
) {
1697 t
= n
/ NSEC_PER_SEC
;
1699 } else if (n
>= USEC_PER_SEC
) {
1700 t
= n
/ USEC_PER_SEC
;
1702 } else if (n
>= MSEC_PER_SEC
) {
1703 t
= n
/ MSEC_PER_SEC
;
1710 snprintf(buf
, sizeof (buf
), "%-4.2Lf %4s", t
, u
);
1715 tunnel_status(int s
)
1717 af_all_tunnel_status(s
);
1721 Perror(const char *cmd
)
1726 errx(1, "%s: no such interface", cmd
);
1730 errx(1, "%s: permission denied", cmd
);
1739 * Print a value a la the %b format of the kernel's printf
1742 printb(const char *s
, unsigned v
, const char *bits
)
1747 if (bits
&& *bits
== 8)
1748 printf("%s=%o", s
, v
);
1750 printf("%s=%x", s
, v
);
1754 while ((i
= *bits
++) != '\0') {
1755 if (v
& (1 << (i
-1))) {
1759 for (; (c
= *bits
) > 32; bits
++)
1762 for (; *bits
> 32; bits
++)
1771 ifmaybeload(const char *name
)
1773 #define MOD_PREFIX_LEN 3 /* "if_" */
1774 struct module_stat mstat
;
1776 char ifkind
[IFNAMSIZ
+ MOD_PREFIX_LEN
], ifname
[IFNAMSIZ
], *dp
;
1779 /* loading suppressed by the user */
1783 /* trim the interface number off the end */
1784 strlcpy(ifname
, name
, sizeof(ifname
));
1785 for (dp
= ifname
; *dp
!= 0; dp
++)
1791 /* turn interface and unit into module name */
1792 strlcpy(ifkind
, "if_", sizeof(ifkind
));
1793 strlcpy(ifkind
+ MOD_PREFIX_LEN
, ifname
,
1794 sizeof(ifkind
) - MOD_PREFIX_LEN
);
1796 /* scan files in kernel */
1797 mstat
.version
= sizeof(struct module_stat
);
1798 for (fileid
= kldnext(0); fileid
> 0; fileid
= kldnext(fileid
)) {
1799 /* scan modules in file */
1800 for (modid
= kldfirstmod(fileid
); modid
> 0;
1801 modid
= modfnext(modid
)) {
1802 if (modstat(modid
, &mstat
) < 0)
1804 /* strip bus name if present */
1805 if ((cp
= strchr(mstat
.name
, '/')) != NULL
) {
1810 /* already loaded? */
1811 if (strncmp(ifname
, cp
, strlen(ifname
) + 1) == 0 ||
1812 strncmp(ifkind
, cp
, strlen(ifkind
) + 1) == 0)
1817 /* not present, we should try to load it */
1822 static struct cmd basic_cmds
[] = {
1823 DEF_CMD("up", IFF_UP
, setifflags
),
1824 DEF_CMD("down", -IFF_UP
, setifflags
),
1825 DEF_CMD("arp", -IFF_NOARP
, setifflags
),
1826 DEF_CMD("-arp", IFF_NOARP
, setifflags
),
1827 DEF_CMD("debug", IFF_DEBUG
, setifflags
),
1828 DEF_CMD("-debug", -IFF_DEBUG
, setifflags
),
1830 DEF_CMD("promisc", IFF_PPROMISC
, setifflags
),
1831 DEF_CMD("-promisc", -IFF_PPROMISC
, setifflags
),
1832 #endif /* IFF_PPROMISC */
1833 DEF_CMD("add", IFF_UP
, notealias
),
1834 DEF_CMD("alias", IFF_UP
, notealias
),
1835 DEF_CMD("-alias", -IFF_UP
, notealias
),
1836 DEF_CMD("delete", -IFF_UP
, notealias
),
1837 DEF_CMD("remove", -IFF_UP
, notealias
),
1839 #define EN_SWABIPS 0x1000
1840 DEF_CMD("swabips", EN_SWABIPS
, setifflags
),
1841 DEF_CMD("-swabips", -EN_SWABIPS
, setifflags
),
1843 DEF_CMD_ARG("netmask", setifnetmask
),
1844 DEF_CMD_ARG("metric", setifmetric
),
1845 DEF_CMD_ARG("broadcast", setifbroadaddr
),
1846 DEF_CMD_ARG("ipdst", setifipdst
),
1847 DEF_CMD_ARG2("tunnel", settunnel
),
1848 DEF_CMD("-tunnel", 0, deletetunnel
),
1849 DEF_CMD("deletetunnel", 0, deletetunnel
),
1850 DEF_CMD("link0", IFF_LINK0
, setifflags
),
1851 DEF_CMD("-link0", -IFF_LINK0
, setifflags
),
1852 DEF_CMD("link1", IFF_LINK1
, setifflags
),
1853 DEF_CMD("-link1", -IFF_LINK1
, setifflags
),
1854 DEF_CMD("link2", IFF_LINK2
, setifflags
),
1855 DEF_CMD("-link2", -IFF_LINK2
, setifflags
),
1857 DEF_CMD("monitor", IFF_MONITOR
:, setifflags
),
1858 DEF_CMD("-monitor", -IFF_MONITOR
, setifflags
),
1859 #endif /* IFF_MONITOR */
1860 #ifdef IFF_STATICARP
1861 DEF_CMD("staticarp", IFF_STATICARP
, setifflags
),
1862 DEF_CMD("-staticarp", -IFF_STATICARP
, setifflags
),
1863 #endif /* IFF_STATICARP */
1865 DEF_CMD("rxcsum", IFCAP_RXCSUM
, setifcap
),
1866 DEF_CMD("-rxcsum", -IFCAP_RXCSUM
, setifcap
),
1867 #endif /* IFCAP_RXCSUM */
1869 DEF_CMD("txcsum", IFCAP_TXCSUM
, setifcap
),
1870 DEF_CMD("-txcsum", -IFCAP_TXCSUM
, setifcap
),
1871 #endif /* IFCAP_TXCSUM */
1872 #ifdef IFCAP_NETCONS
1873 DEF_CMD("netcons", IFCAP_NETCONS
, setifcap
),
1874 DEF_CMD("-netcons", -IFCAP_NETCONS
, setifcap
),
1875 #endif /* IFCAP_NETCONS */
1876 #ifdef IFCAP_POLLING
1877 DEF_CMD("polling", IFCAP_POLLING
, setifcap
),
1878 DEF_CMD("-polling", -IFCAP_POLLING
, setifcap
),
1879 #endif /* IFCAP_POLLING */
1881 DEF_CMD("tso", IFCAP_TSO
, setifcap
),
1882 DEF_CMD("-tso", -IFCAP_TSO
, setifcap
),
1883 #endif /* IFCAP_TSO */
1885 DEF_CMD("lro", IFCAP_LRO
, setifcap
),
1886 DEF_CMD("-lro", -IFCAP_LRO
, setifcap
),
1887 #endif /* IFCAP_LRO */
1889 DEF_CMD("wol", IFCAP_WOL
, setifcap
),
1890 DEF_CMD("-wol", -IFCAP_WOL
, setifcap
),
1891 #endif /* IFCAP_WOL */
1892 #ifdef IFCAP_WOL_UCAST
1893 DEF_CMD("wol_ucast", IFCAP_WOL_UCAST
, setifcap
),
1894 DEF_CMD("-wol_ucast", -IFCAP_WOL_UCAST
, setifcap
),
1895 #endif /* IFCAP_WOL_UCAST */
1896 #ifdef IFCAP_WOL_MCAST
1897 DEF_CMD("wol_mcast", IFCAP_WOL_MCAST
, setifcap
),
1898 DEF_CMD("-wol_mcast", -IFCAP_WOL_MCAST
, setifcap
),
1899 #endif /* IFCAP_WOL_MCAST */
1900 #ifdef IFCAP_WOL_MAGIC
1901 DEF_CMD("wol_magic", IFCAP_WOL_MAGIC
, setifcap
),
1902 DEF_CMD("-wol_magic", -IFCAP_WOL_MAGIC
, setifcap
),
1903 #endif /* IFCAP_WOL_MAGIC */
1904 DEF_CMD("normal", -IFF_LINK0
, setifflags
),
1905 DEF_CMD("compress", IFF_LINK0
, setifflags
),
1906 DEF_CMD("noicmp", IFF_LINK1
, setifflags
),
1907 DEF_CMD_ARG("mtu", setifmtu
),
1909 DEF_CMD_ARG("name", setifname
),
1912 DEF_CMD("av", IFCAP_AV
, setifcap
),
1913 DEF_CMD("-av", -IFCAP_AV
, setifcap
),
1914 #endif /* IFCAP_AV */
1915 DEF_CMD("router", 1, setrouter
),
1916 DEF_CMD("-router", 0, setrouter
),
1917 DEF_CMD_ARG("desc", setifdesc
),
1918 DEF_CMD_ARG("tbr", settbr
),
1919 DEF_CMD_ARG("throttle", setthrottle
),
1920 DEF_CMD_ARG("log", setlog
),
1921 DEF_CMD("cl2k", 1, setcl2k
),
1922 DEF_CMD("-cl2k", 0, setcl2k
),
1923 DEF_CMD("expensive", 1, setexpensive
),
1924 DEF_CMD("-expensive", 0, setexpensive
),
1925 DEF_CMD("timestamp", 1, settimestamp
),
1926 DEF_CMD("-timestamp", 0, settimestamp
),
1927 DEF_CMD_ARG("ecn", setecnmode
),
1928 DEF_CMD_ARG2("fastlane", setfastlane
),
1929 DEF_CMD_ARG2("qosmarking", setqosmarking
),
1930 DEF_CMD_ARG("disable_output", setdisableoutput
),
1931 DEF_CMD("probe_connectivity", 1, setprobeconnectivity
),
1932 DEF_CMD("-probe_connectivity", 0, setprobeconnectivity
),
1935 static __constructor
void
1938 #define N(a) (sizeof(a) / sizeof(a[0]))
1941 for (i
= 0; i
< N(basic_cmds
); i
++)
1942 cmd_register(&basic_cmds
[i
]);
1947 sched2str(unsigned int s
)
1952 case PKTSCHEDT_NONE
:
1961 case PKTSCHEDT_FQ_CODEL
:
1973 tl2str(unsigned int s
)
1978 case IFNET_THROTTLE_OFF
:
1981 case IFNET_THROTTLE_OPPORTUNISTIC
:
1982 c
= "opportunistic";
1993 ift2str(unsigned int t
, unsigned int f
, unsigned int sf
)
1995 static char buf
[256];
2001 case IFRTYPE_SUBFAMILY_USB
:
2004 case IFRTYPE_SUBFAMILY_BLUETOOTH
:
2005 c
= "Bluetooth PAN";
2007 case IFRTYPE_SUBFAMILY_WIFI
:
2010 case IFRTYPE_SUBFAMILY_THUNDERBOLT
:
2011 c
= "IP over Thunderbolt";
2013 case IFRTYPE_SUBFAMILY_ANY
:
2021 c
= "IP over FireWire";
2025 c
= "Packet capture";
2041 case IFT_IEEE8023ADLAG
:
2048 (void) snprintf(buf
, sizeof (buf
),
2049 "0x%x family: %u subfamily: %u",
2050 ifr
.ifr_type
.ift_type
, ifr
.ifr_type
.ift_family
,
2051 ifr
.ifr_type
.ift_subfamily
);
2053 (void) snprintf(buf
, sizeof (buf
),
2054 "%s (0x%x) family: %u subfamily: %u", c
,
2055 ifr
.ifr_type
.ift_type
, ifr
.ifr_type
.ift_family
,
2056 ifr
.ifr_type
.ift_subfamily
);