4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
9 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
19 #include <sys/socket.h>
20 #include <netinet/in.h>
24 #include <arpa/inet.h>
25 #include <asm/types.h>
26 #include <linux/pkt_sched.h>
27 #include <linux/param.h>
28 #include <linux/if_arp.h>
29 #include <linux/mpls.h>
30 #include <linux/snmp.h>
35 #include <sys/capability.h>
41 #include "namespace.h"
46 const char *_SL_
= "\n";
48 static int af_byte_len(int af
);
49 static void print_time(char *buf
, int len
, __u32 time
);
50 static void print_time64(char *buf
, int len
, __s64 time
);
52 int read_prop(const char *dev
, char *prop
, long *value
)
54 char fname
[128], buf
[80], *endp
, *nl
;
59 ret
= snprintf(fname
, sizeof(fname
), "/sys/class/net/%s/%s",
62 if (ret
<= 0 || ret
>= sizeof(fname
)) {
63 fprintf(stderr
, "could not build pathname for property\n");
67 fp
= fopen(fname
, "r");
69 fprintf(stderr
, "fopen %s: %s\n", fname
, strerror(errno
));
73 if (!fgets(buf
, sizeof(buf
), fp
)) {
74 fprintf(stderr
, "property \"%s\" in file %s is currently unknown\n", prop
, fname
);
79 nl
= strchr(buf
, '\n');
84 result
= strtol(buf
, &endp
, 0);
86 if (*endp
|| buf
== endp
) {
87 fprintf(stderr
, "value \"%s\" in file %s is not a number\n",
92 if ((result
== LONG_MAX
|| result
== LONG_MIN
) && errno
== ERANGE
) {
93 fprintf(stderr
, "strtol %s: %s", fname
, strerror(errno
));
100 fprintf(stderr
, "Failed to parse %s\n", fname
);
106 if (c
>= 'A' && c
<= 'F')
108 if (c
>= 'a' && c
<= 'f')
110 if (c
>= '0' && c
<= '9')
116 int get_integer(int *val
, const char *arg
, int base
)
124 res
= strtol(arg
, &ptr
, base
);
126 /* If there were no digits at all, strtol() stores
127 * the original value of nptr in *endptr (and returns 0).
128 * In particular, if *nptr is not '\0' but **endptr is '\0' on return,
129 * the entire string is valid.
131 if (!ptr
|| ptr
== arg
|| *ptr
)
134 /* If an underflow occurs, strtol() returns LONG_MIN.
135 * If an overflow occurs, strtol() returns LONG_MAX.
136 * In both cases, errno is set to ERANGE.
138 if ((res
== LONG_MAX
|| res
== LONG_MIN
) && errno
== ERANGE
)
141 /* Outside range of int */
142 if (res
< INT_MIN
|| res
> INT_MAX
)
149 int mask2bits(__u32 netmask
)
151 unsigned int bits
= 0;
152 __u32 mask
= ntohl(netmask
);
155 /* a valid netmask must be 2^n - 1 */
156 if ((host
& (host
+ 1)) != 0)
159 for (; mask
; mask
<<= 1)
164 static int get_netmask(unsigned int *val
, const char *arg
, int base
)
168 if (!get_unsigned(val
, arg
, base
))
171 /* try converting dotted quad to CIDR */
172 if (!get_addr_1(&addr
, arg
, AF_INET
) && addr
.family
== AF_INET
) {
173 int b
= mask2bits(addr
.data
[0]);
184 int get_unsigned(unsigned int *val
, const char *arg
, int base
)
192 res
= strtoul(arg
, &ptr
, base
);
194 /* empty string or trailing non-digits */
195 if (!ptr
|| ptr
== arg
|| *ptr
)
199 if (res
== ULONG_MAX
&& errno
== ERANGE
)
202 /* out side range of unsigned */
211 * get_time_rtt is "translated" from a similar routine "get_time" in
212 * tc_util.c. We don't use the exact same routine because tc passes
213 * microseconds to the kernel and the callers of get_time_rtt want to
214 * pass milliseconds (standard unit for rtt values since 2.6.27), and
215 * have a different assumption for the units of a "raw" number.
217 int get_time_rtt(unsigned int *val
, const char *arg
, int *raw
)
223 if (strchr(arg
, '.') != NULL
) {
233 if ((t
== HUGE_VALF
|| t
== HUGE_VALL
) && errno
== ERANGE
)
236 res
= strtoul(arg
, &p
, 0);
243 if (res
== ULONG_MAX
&& errno
== ERANGE
)
255 if (strcasecmp(p
, "s") == 0 ||
256 strcasecmp(p
, "sec") == 0 ||
257 strcasecmp(p
, "secs") == 0)
259 else if (strcasecmp(p
, "ms") == 0 ||
260 strcasecmp(p
, "msec") == 0 ||
261 strcasecmp(p
, "msecs") == 0)
262 t
*= 1.0; /* allow suffix, do nothing */
267 /* emulate ceil() without having to bring-in -lm and always be >= 1 */
276 int get_u64(__u64
*val
, const char *arg
, int base
)
278 unsigned long long res
;
284 res
= strtoull(arg
, &ptr
, base
);
286 /* empty string or trailing non-digits */
287 if (!ptr
|| ptr
== arg
|| *ptr
)
291 if (res
== ULLONG_MAX
&& errno
== ERANGE
)
294 /* in case ULL is 128 bits */
295 if (res
> 0xFFFFFFFFFFFFFFFFULL
)
302 int get_u32(__u32
*val
, const char *arg
, int base
)
309 res
= strtoul(arg
, &ptr
, base
);
311 /* empty string or trailing non-digits */
312 if (!ptr
|| ptr
== arg
|| *ptr
)
316 if (res
== ULONG_MAX
&& errno
== ERANGE
)
319 /* in case UL > 32 bits */
320 if (res
> 0xFFFFFFFFUL
)
327 int get_u16(__u16
*val
, const char *arg
, int base
)
334 res
= strtoul(arg
, &ptr
, base
);
336 /* empty string or trailing non-digits */
337 if (!ptr
|| ptr
== arg
|| *ptr
)
341 if (res
== ULONG_MAX
&& errno
== ERANGE
)
351 int get_u8(__u8
*val
, const char *arg
, int base
)
359 res
= strtoul(arg
, &ptr
, base
);
360 /* empty string or trailing non-digits */
361 if (!ptr
|| ptr
== arg
|| *ptr
)
365 if (res
== ULONG_MAX
&& errno
== ERANGE
)
375 int get_s64(__s64
*val
, const char *arg
, int base
)
384 res
= strtoll(arg
, &ptr
, base
);
385 if (!ptr
|| ptr
== arg
|| *ptr
)
387 if ((res
== LLONG_MIN
|| res
== LLONG_MAX
) && errno
== ERANGE
)
389 if (res
> INT64_MAX
|| res
< INT64_MIN
)
396 int get_s32(__s32
*val
, const char *arg
, int base
)
405 res
= strtol(arg
, &ptr
, base
);
406 if (!ptr
|| ptr
== arg
|| *ptr
)
408 if ((res
== LONG_MIN
|| res
== LONG_MAX
) && errno
== ERANGE
)
410 if (res
> INT32_MAX
|| res
< INT32_MIN
)
417 int get_be64(__be64
*val
, const char *arg
, int base
)
420 int ret
= get_u64(&v
, arg
, base
);
428 int get_be32(__be32
*val
, const char *arg
, int base
)
431 int ret
= get_u32(&v
, arg
, base
);
439 int get_be16(__be16
*val
, const char *arg
, int base
)
442 int ret
= get_u16(&v
, arg
, base
);
450 /* This uses a non-standard parsing (ie not inet_aton, or inet_pton)
451 * because of legacy choice to parse 10.8 as 10.8.0.0 not 10.0.0.8
453 static int get_addr_ipv4(__u8
*ap
, const char *cp
)
457 for (i
= 0; i
< 4; i
++) {
461 n
= strtoul(cp
, &endp
, 0);
463 return -1; /* bogus network value */
465 if (endp
== cp
) /* no digits */
473 if (i
== 3 || *endp
!= '.')
474 return -1; /* extra characters */
481 int get_addr64(__u64
*ap
, const char *cp
)
490 for (i
= 0; i
< 4; i
++) {
494 n
= strtoul(cp
, &endp
, 16);
496 return -1; /* bogus network value */
498 if (endp
== cp
) /* no digits */
501 val
.v16
[i
] = htons(n
);
506 if (i
== 3 || *endp
!= ':')
507 return -1; /* extra characters */
516 /* See http://physics.nist.gov/cuu/Units/binary.html */
517 static const struct rate_suffix
{
524 { "mibit", 1024.*1024. },
525 { "mbit", 1000000. },
526 { "gibit", 1024.*1024.*1024. },
527 { "gbit", 1000000000. },
528 { "tibit", 1024.*1024.*1024.*1024. },
529 { "tbit", 1000000000000. },
531 { "KiBps", 8.*1024. },
533 { "MiBps", 8.*1024*1024. },
534 { "MBps", 8000000. },
535 { "GiBps", 8.*1024.*1024.*1024. },
536 { "GBps", 8000000000. },
537 { "TiBps", 8.*1024.*1024.*1024.*1024. },
538 { "TBps", 8000000000000. },
542 int get_rate(unsigned int *rate
, const char *str
)
545 double bps
= strtod(str
, &p
);
546 const struct rate_suffix
*s
;
551 for (s
= suffixes
; s
->name
; ++s
) {
552 if (strcasecmp(s
->name
, p
) == 0) {
560 return -1; /* unknown suffix */
562 bps
/= 8; /* -> bytes per second */
564 /* detect if an overflow happened */
565 if (*rate
!= floor(bps
))
570 int get_rate64(__u64
*rate
, const char *str
)
573 double bps
= strtod(str
, &p
);
574 const struct rate_suffix
*s
;
579 for (s
= suffixes
; s
->name
; ++s
) {
580 if (strcasecmp(s
->name
, p
) == 0) {
588 return -1; /* unknown suffix */
590 bps
/= 8; /* -> bytes per second */
595 int get_size(unsigned int *size
, const char *str
)
600 sz
= strtod(str
, &p
);
605 if (strcasecmp(p
, "kb") == 0 || strcasecmp(p
, "k") == 0)
607 else if (strcasecmp(p
, "gb") == 0 || strcasecmp(p
, "g") == 0)
608 sz
*= 1024*1024*1024;
609 else if (strcasecmp(p
, "gbit") == 0)
610 sz
*= 1024*1024*1024/8;
611 else if (strcasecmp(p
, "mb") == 0 || strcasecmp(p
, "m") == 0)
613 else if (strcasecmp(p
, "mbit") == 0)
615 else if (strcasecmp(p
, "kbit") == 0)
617 else if (strcasecmp(p
, "b") != 0)
623 /* detect if an overflow happened */
624 if (*size
!= floor(sz
))
630 static void set_address_type(inet_prefix
*addr
)
632 switch (addr
->family
) {
635 addr
->flags
|= ADDRTYPE_INET_UNSPEC
;
636 else if (IN_MULTICAST(ntohl(addr
->data
[0])))
637 addr
->flags
|= ADDRTYPE_INET_MULTI
;
639 addr
->flags
|= ADDRTYPE_INET
;
642 if (IN6_IS_ADDR_UNSPECIFIED(addr
->data
))
643 addr
->flags
|= ADDRTYPE_INET_UNSPEC
;
644 else if (IN6_IS_ADDR_MULTICAST(addr
->data
))
645 addr
->flags
|= ADDRTYPE_INET_MULTI
;
647 addr
->flags
|= ADDRTYPE_INET
;
652 static int __get_addr_1(inet_prefix
*addr
, const char *name
, int family
)
654 memset(addr
, 0, sizeof(*addr
));
656 if (strcmp(name
, "default") == 0) {
657 if ((family
== AF_DECnet
) || (family
== AF_MPLS
))
659 addr
->family
= family
;
660 addr
->bytelen
= af_byte_len(addr
->family
);
662 addr
->flags
|= PREFIXLEN_SPECIFIED
;
666 if (strcmp(name
, "all") == 0 ||
667 strcmp(name
, "any") == 0) {
668 if ((family
== AF_DECnet
) || (family
== AF_MPLS
))
670 addr
->family
= family
;
676 if (family
== AF_PACKET
) {
679 len
= ll_addr_a2n((char *) &addr
->data
, sizeof(addr
->data
),
684 addr
->family
= AF_PACKET
;
686 addr
->bitlen
= len
* 8;
690 if (strchr(name
, ':')) {
691 addr
->family
= AF_INET6
;
692 if (family
!= AF_UNSPEC
&& family
!= AF_INET6
)
694 if (inet_pton(AF_INET6
, name
, addr
->data
) <= 0)
701 if (family
== AF_MPLS
) {
702 unsigned int maxlabels
;
705 addr
->family
= AF_MPLS
;
706 if (mpls_pton(AF_MPLS
, name
, addr
->data
,
707 sizeof(addr
->data
)) <= 0)
711 /* How many bytes do I need? */
712 maxlabels
= sizeof(addr
->data
) / sizeof(struct mpls_label
);
713 for (i
= 0; i
< maxlabels
; i
++) {
714 if (ntohl(addr
->data
[i
]) & MPLS_LS_S_MASK
) {
715 addr
->bytelen
= (i
+ 1)*4;
722 addr
->family
= AF_INET
;
723 if (family
!= AF_UNSPEC
&& family
!= AF_INET
)
726 if (get_addr_ipv4((__u8
*)addr
->data
, name
) <= 0)
734 int get_addr_1(inet_prefix
*addr
, const char *name
, int family
)
738 ret
= __get_addr_1(addr
, name
, family
);
742 set_address_type(addr
);
746 int af_bit_len(int af
)
764 static int af_byte_len(int af
)
766 return af_bit_len(af
) / 8;
769 int get_prefix_1(inet_prefix
*dst
, char *arg
, int family
)
772 int err
, bitlen
, flags
;
774 slash
= strchr(arg
, '/');
778 err
= get_addr_1(dst
, arg
, family
);
786 bitlen
= af_bit_len(dst
->family
);
792 if (dst
->bitlen
== -2)
794 if (get_netmask(&plen
, slash
+ 1, 0))
799 flags
|= PREFIXLEN_SPECIFIED
;
802 if (dst
->bitlen
== -2)
807 dst
->bitlen
= bitlen
;
812 static const char *family_name_verbose(int family
)
814 if (family
== AF_UNSPEC
)
816 return family_name(family
);
819 int get_addr(inet_prefix
*dst
, const char *arg
, int family
)
821 if (get_addr_1(dst
, arg
, family
)) {
823 "Error: %s address is expected rather than \"%s\".\n",
824 family_name_verbose(family
), arg
);
830 int get_addr_rta(inet_prefix
*dst
, const struct rtattr
*rta
, int family
)
832 const int len
= RTA_PAYLOAD(rta
);
833 const void *data
= RTA_DATA(rta
);
837 dst
->family
= AF_INET
;
839 memcpy(dst
->data
, data
, 4);
842 dst
->family
= AF_INET6
;
844 memcpy(dst
->data
, data
, 16);
847 dst
->family
= AF_DECnet
;
849 memcpy(dst
->data
, data
, 2);
852 dst
->family
= AF_IPX
;
854 memcpy(dst
->data
, data
, 10);
860 if (family
!= AF_UNSPEC
&& family
!= dst
->family
)
866 set_address_type(dst
);
870 int get_prefix(inet_prefix
*dst
, char *arg
, int family
)
872 if (family
== AF_PACKET
) {
874 "Error: \"%s\" may be inet prefix, but it is not allowed in this context.\n",
879 if (get_prefix_1(dst
, arg
, family
)) {
881 "Error: %s prefix is expected rather than \"%s\".\n",
882 family_name_verbose(family
), arg
);
888 __u32
get_addr32(const char *name
)
892 if (get_addr_1(&addr
, name
, AF_INET
)) {
894 "Error: an IP address is expected rather than \"%s\"\n",
901 void incomplete_command(void)
903 fprintf(stderr
, "Command line is not complete. Try option \"help\"\n");
907 void missarg(const char *key
)
909 fprintf(stderr
, "Error: argument \"%s\" is required\n", key
);
913 void invarg(const char *msg
, const char *arg
)
915 fprintf(stderr
, "Error: argument \"%s\" is wrong: %s\n", arg
, msg
);
919 void duparg(const char *key
, const char *arg
)
922 "Error: duplicate \"%s\": \"%s\" is the second value.\n",
927 void duparg2(const char *key
, const char *arg
)
930 "Error: either \"%s\" is duplicate, or \"%s\" is a garbage.\n",
935 int nodev(const char *dev
)
937 fprintf(stderr
, "Cannot find device \"%s\"\n", dev
);
941 static int __check_ifname(const char *name
)
946 if (*name
== '/' || isspace(*name
))
953 int check_ifname(const char *name
)
955 /* These checks mimic kernel checks in dev_valid_name */
956 if (strlen(name
) >= IFNAMSIZ
)
958 return __check_ifname(name
);
961 int check_altifname(const char *name
)
963 return __check_ifname(name
);
966 /* buf is assumed to be IFNAMSIZ */
967 int get_ifname(char *buf
, const char *name
)
971 ret
= check_ifname(name
);
973 strncpy(buf
, name
, IFNAMSIZ
);
978 const char *get_ifname_rta(int ifindex
, const struct rtattr
*rta
)
983 name
= rta_getattr_str(rta
);
986 "BUG: device with ifindex %d has nil ifname\n",
988 name
= ll_idx_n2a(ifindex
);
991 if (check_ifname(name
))
997 /* Returns false if 'prefix' is a not empty prefix of 'string'.
999 bool matches(const char *prefix
, const char *string
)
1003 while (*string
&& *prefix
== *string
) {
1011 int inet_addr_match(const inet_prefix
*a
, const inet_prefix
*b
, int bits
)
1013 const __u32
*a1
= a
->data
;
1014 const __u32
*a2
= b
->data
;
1015 int words
= bits
>> 0x05;
1020 if (memcmp(a1
, a2
, words
<< 2))
1030 mask
= htonl((0xffffffff) << (0x20 - bits
));
1032 if ((w1
^ w2
) & mask
)
1039 int inet_addr_match_rta(const inet_prefix
*m
, const struct rtattr
*rta
)
1043 if (!rta
|| m
->family
== AF_UNSPEC
|| m
->bitlen
<= 0)
1046 if (get_addr_rta(&dst
, rta
, m
->family
))
1049 return inet_addr_match(&dst
, m
, m
->bitlen
);
1052 int __iproute2_hz_internal
;
1061 return atoi(getenv("HZ")) ? : HZ
;
1063 if (getenv("PROC_NET_PSCHED"))
1064 snprintf(name
, sizeof(name
)-1,
1065 "%s", getenv("PROC_NET_PSCHED"));
1066 else if (getenv("PROC_ROOT"))
1067 snprintf(name
, sizeof(name
)-1,
1068 "%s/net/psched", getenv("PROC_ROOT"));
1070 strcpy(name
, "/proc/net/psched");
1072 fp
= fopen(name
, "r");
1075 unsigned int nom
, denom
;
1077 if (fscanf(fp
, "%*08x%*08x%08x%08x", &nom
, &denom
) == 2)
1087 int __iproute2_user_hz_internal
;
1089 int __get_user_hz(void)
1091 return sysconf(_SC_CLK_TCK
);
1094 const char *rt_addr_n2a_r(int af
, int len
,
1095 const void *addr
, char *buf
, int buflen
)
1100 return inet_ntop(af
, addr
, buf
, buflen
);
1102 return mpls_ntop(af
, addr
, buf
, buflen
);
1104 return ll_addr_n2a(addr
, len
, ARPHRD_VOID
, buf
, buflen
);
1109 struct sockaddr_in sin
;
1110 struct sockaddr_in6 sin6
;
1113 switch (sa
->sa
.sa_family
) {
1115 return inet_ntop(AF_INET
, &sa
->sin
.sin_addr
,
1118 return inet_ntop(AF_INET6
, &sa
->sin6
.sin6_addr
,
1129 const char *rt_addr_n2a(int af
, int len
, const void *addr
)
1131 static char buf
[256];
1133 return rt_addr_n2a_r(af
, len
, addr
, buf
, 256);
1136 int read_family(const char *name
)
1138 int family
= AF_UNSPEC
;
1140 if (strcmp(name
, "inet") == 0)
1142 else if (strcmp(name
, "inet6") == 0)
1144 else if (strcmp(name
, "link") == 0)
1146 else if (strcmp(name
, "ipx") == 0)
1148 else if (strcmp(name
, "mpls") == 0)
1150 else if (strcmp(name
, "bridge") == 0)
1155 const char *family_name(int family
)
1157 if (family
== AF_INET
)
1159 if (family
== AF_INET6
)
1161 if (family
== AF_PACKET
)
1163 if (family
== AF_IPX
)
1165 if (family
== AF_MPLS
)
1167 if (family
== AF_BRIDGE
)
1172 #ifdef RESOLVE_HOSTNAMES
1174 struct namerec
*next
;
1180 static struct namerec
*nht
[NHASH
];
1182 static const char *resolve_address(const void *addr
, int len
, int af
)
1185 struct hostent
*h_ent
;
1187 static int notfirst
;
1190 if (af
== AF_INET6
&& ((__u32
*)addr
)[0] == 0 &&
1191 ((__u32
*)addr
)[1] == 0 && ((__u32
*)addr
)[2] == htonl(0xffff)) {
1197 hash
= *(__u32
*)(addr
+ len
- 4) % NHASH
;
1199 for (n
= nht
[hash
]; n
; n
= n
->next
) {
1200 if (n
->addr
.family
== af
&&
1201 n
->addr
.bytelen
== len
&&
1202 memcmp(n
->addr
.data
, addr
, len
) == 0)
1205 n
= malloc(sizeof(*n
));
1208 n
->addr
.family
= af
;
1209 n
->addr
.bytelen
= len
;
1211 memcpy(n
->addr
.data
, addr
, len
);
1212 n
->next
= nht
[hash
];
1214 if (++notfirst
== 1)
1218 h_ent
= gethostbyaddr(addr
, len
, af
);
1220 n
->name
= strdup(h_ent
->h_name
);
1222 /* Even if we fail, "negative" entry is remembered. */
1227 const char *format_host_r(int af
, int len
, const void *addr
,
1228 char *buf
, int buflen
)
1230 #ifdef RESOLVE_HOSTNAMES
1231 if (resolve_hosts
) {
1234 len
= len
<= 0 ? af_byte_len(af
) : len
;
1237 (n
= resolve_address(addr
, len
, af
)) != NULL
)
1241 return rt_addr_n2a_r(af
, len
, addr
, buf
, buflen
);
1244 const char *format_host(int af
, int len
, const void *addr
)
1246 static char buf
[256];
1248 return format_host_r(af
, len
, addr
, buf
, 256);
1252 char *hexstring_n2a(const __u8
*str
, int len
, char *buf
, int blen
)
1257 for (i
= 0; i
< len
; i
++) {
1260 sprintf(ptr
, "%02x", str
[i
]);
1267 __u8
*hexstring_a2n(const char *str
, __u8
*buf
, int blen
, unsigned int *len
)
1269 unsigned int cnt
= 0;
1272 if (strlen(str
) % 2)
1274 while (cnt
< blen
&& strlen(str
) > 1) {
1278 strncpy(tmpstr
, str
, 2);
1281 tmp
= strtoul(tmpstr
, &endptr
, 16);
1282 if (errno
!= 0 || tmp
> 0xFF || *endptr
!= '\0')
1294 int hex2mem(const char *buf
, uint8_t *mem
, int count
)
1299 for (i
= 0, j
= 0; i
< count
; i
++, j
+= 2) {
1300 c
= get_hex(buf
[j
]);
1306 c
= get_hex(buf
[j
+ 1]);
1316 int addr64_n2a(__u64 addr
, char *buff
, size_t len
)
1318 __u16
*words
= (__u16
*)&addr
;
1324 for (i
= 0; i
< 4; i
++) {
1325 v
= ntohs(words
[i
]);
1330 ret
= snprintf(&buff
[written
], len
- written
, "%x%s", v
, sep
);
1340 /* Print buffer and escape bytes that are !isprint or among 'escape' */
1341 void print_escape_buf(const __u8
*buf
, size_t len
, const char *escape
)
1345 for (i
= 0; i
< len
; ++i
) {
1346 if (isprint(buf
[i
]) && buf
[i
] != '\\' &&
1347 !strchr(escape
, buf
[i
]))
1348 printf("%c", buf
[i
]);
1350 printf("\\%03o", buf
[i
]);
1354 int print_timestamp(FILE *fp
)
1359 gettimeofday(&tv
, NULL
);
1360 tm
= localtime(&tv
.tv_sec
);
1362 if (timestamp_short
) {
1365 strftime(tshort
, sizeof(tshort
), "%Y-%m-%dT%H:%M:%S", tm
);
1366 fprintf(fp
, "[%s.%06ld] ", tshort
, tv
.tv_usec
);
1368 char *tstr
= asctime(tm
);
1370 tstr
[strlen(tstr
)-1] = 0;
1371 fprintf(fp
, "Timestamp: %s %ld usec\n",
1378 unsigned int print_name_and_link(const char *fmt
,
1379 const char *name
, struct rtattr
*tb
[])
1381 const char *link
= NULL
;
1382 unsigned int m_flag
= 0;
1385 if (tb
[IFLA_LINK
]) {
1386 int iflink
= rta_getattr_u32(tb
[IFLA_LINK
]);
1389 if (tb
[IFLA_LINK_NETNSID
]) {
1390 if (is_json_context()) {
1391 print_int(PRINT_JSON
,
1392 "link_index", NULL
, iflink
);
1394 link
= ll_idx_n2a(iflink
);
1397 link
= ll_index_to_name(iflink
);
1399 if (is_json_context()) {
1400 print_string(PRINT_JSON
,
1401 "link", NULL
, link
);
1405 m_flag
= ll_index_to_flags(iflink
);
1406 m_flag
= !(m_flag
& IFF_UP
);
1409 if (is_json_context())
1410 print_null(PRINT_JSON
, "link", NULL
, NULL
);
1416 snprintf(b1
, sizeof(b1
), "%s@%s", name
, link
);
1421 print_color_string(PRINT_ANY
, COLOR_IFNAME
, "ifname", fmt
, name
);
1428 /* Like glibc getline but handle continuation lines and comments */
1429 ssize_t
getcmdline(char **linep
, size_t *lenp
, FILE *in
)
1434 cc
= getline(linep
, lenp
, in
);
1436 return cc
; /* eof or error */
1439 cp
= strchr(*linep
, '#');
1443 while ((cp
= strstr(*linep
, "\\\n")) != NULL
) {
1448 cc1
= getline(&line1
, &len1
, in
);
1450 fprintf(stderr
, "Missing continuation line\n");
1457 cp
= strchr(line1
, '#');
1461 *lenp
= strlen(*linep
) + strlen(line1
) + 1;
1462 *linep
= realloc(*linep
, *lenp
);
1464 fprintf(stderr
, "Out of memory\n");
1469 strcat(*linep
, line1
);
1475 /* split command line into argument vector */
1476 int makeargs(char *line
, char *argv
[], int maxargs
)
1478 static const char ws
[] = " \t\r\n";
1483 /* skip leading whitespace */
1484 cp
+= strspn(cp
, ws
);
1489 if (argc
>= (maxargs
- 1)) {
1490 fprintf(stderr
, "Too many arguments to command\n");
1494 /* word begins with quote */
1495 if (*cp
== '\'' || *cp
== '"') {
1499 /* find ending quote */
1500 cp
= strchr(cp
, quote
);
1502 fprintf(stderr
, "Unterminated quoted string\n");
1508 /* find end of word */
1509 cp
+= strcspn(cp
, ws
);
1514 /* separate words */
1522 void print_nlmsg_timestamp(FILE *fp
, const struct nlmsghdr
*n
)
1525 time_t secs
= ((__u32
*)NLMSG_DATA(n
))[0];
1526 long usecs
= ((__u32
*)NLMSG_DATA(n
))[1];
1528 tstr
= asctime(localtime(&secs
));
1529 tstr
[strlen(tstr
)-1] = 0;
1530 fprintf(fp
, "Timestamp: %s %lu us\n", tstr
, usecs
);
1533 char *int_to_str(int val
, char *buf
)
1535 sprintf(buf
, "%d", val
);
1539 int get_guid(__u64
*guid
, const char *arg
)
1545 #define GUID_STR_LEN 23
1546 /* Verify strict format: format string must be
1547 * xx:xx:xx:xx:xx:xx:xx:xx where xx can be an arbitrary
1551 if (strlen(arg
) != GUID_STR_LEN
)
1554 /* make sure columns are in place */
1555 for (i
= 0; i
< 7; i
++)
1556 if (arg
[2 + i
* 3] != ':')
1560 for (i
= 0; i
< 8; i
++) {
1561 tmp
= strtoul(arg
+ i
* 3, &endptr
, 16);
1562 if (endptr
!= arg
+ i
* 3 + 2)
1568 *guid
|= tmp
<< (56 - 8 * i
);
1574 /* This is a necessary workaround for multicast route dumps */
1575 int get_real_family(int rtm_type
, int rtm_family
)
1577 if (rtm_type
!= RTN_MULTICAST
)
1580 if (rtm_family
== RTNL_FAMILY_IPMR
)
1583 if (rtm_family
== RTNL_FAMILY_IP6MR
)
1589 /* Based on copy_rtnl_link_stats() from kernel at net/core/rtnetlink.c */
1590 static void copy_rtnl_link_stats64(struct rtnl_link_stats64
*stats64
,
1591 const struct rtnl_link_stats
*stats
)
1593 __u64
*a
= (__u64
*)stats64
;
1594 const __u32
*b
= (const __u32
*)stats
;
1595 const __u32
*e
= b
+ sizeof(*stats
) / sizeof(*b
);
1601 #define IPSTATS_MIB_MAX_LEN (__IPSTATS_MIB_MAX * sizeof(__u64))
1602 static void get_snmp_counters(struct rtnl_link_stats64
*stats64
,
1605 __u64
*mib
= (__u64
*)RTA_DATA(s
);
1607 memset(stats64
, 0, sizeof(*stats64
));
1609 stats64
->rx_packets
= mib
[IPSTATS_MIB_INPKTS
];
1610 stats64
->rx_bytes
= mib
[IPSTATS_MIB_INOCTETS
];
1611 stats64
->tx_packets
= mib
[IPSTATS_MIB_OUTPKTS
];
1612 stats64
->tx_bytes
= mib
[IPSTATS_MIB_OUTOCTETS
];
1613 stats64
->rx_errors
= mib
[IPSTATS_MIB_INDISCARDS
];
1614 stats64
->tx_errors
= mib
[IPSTATS_MIB_OUTDISCARDS
];
1615 stats64
->multicast
= mib
[IPSTATS_MIB_INMCASTPKTS
];
1616 stats64
->rx_frame_errors
= mib
[IPSTATS_MIB_CSUMERRORS
];
1619 int get_rtnl_link_stats_rta(struct rtnl_link_stats64
*stats64
,
1620 struct rtattr
*tb
[])
1622 struct rtnl_link_stats stats
;
1627 if (tb
[IFLA_STATS64
]) {
1628 rta
= tb
[IFLA_STATS64
];
1629 size
= sizeof(struct rtnl_link_stats64
);
1631 } else if (tb
[IFLA_STATS
]) {
1632 rta
= tb
[IFLA_STATS
];
1633 size
= sizeof(struct rtnl_link_stats
);
1635 } else if (tb
[IFLA_PROTINFO
]) {
1636 struct rtattr
*ptb
[IPSTATS_MIB_MAX_LEN
+ 1];
1638 parse_rtattr_nested(ptb
, IPSTATS_MIB_MAX_LEN
,
1640 if (ptb
[IFLA_INET6_STATS
])
1641 get_snmp_counters(stats64
, ptb
[IFLA_INET6_STATS
]);
1642 return sizeof(*stats64
);
1647 len
= RTA_PAYLOAD(rta
);
1649 memset(s
+ len
, 0, size
- len
);
1653 memcpy(s
, RTA_DATA(rta
), len
);
1656 copy_rtnl_link_stats64(stats64
, s
);
1661 size_t strlcpy(char *dst
, const char *src
, size_t size
)
1663 size_t srclen
= strlen(src
);
1666 size_t minlen
= min(srclen
, size
- 1);
1668 memcpy(dst
, src
, minlen
);
1674 size_t strlcat(char *dst
, const char *src
, size_t size
)
1676 size_t dlen
= strlen(dst
);
1679 return dlen
+ strlen(src
);
1681 return dlen
+ strlcpy(dst
+ dlen
, src
, size
- dlen
);
1688 /* don't harmstring root/sudo */
1689 if (getuid() != 0 && geteuid() != 0) {
1691 cap_value_t net_admin
= CAP_NET_ADMIN
;
1692 cap_flag_t inheritable
= CAP_INHERITABLE
;
1693 cap_flag_value_t is_set
;
1695 capabilities
= cap_get_proc();
1698 if (cap_get_flag(capabilities
, net_admin
, inheritable
,
1701 /* apps with ambient caps can fork and call ip */
1702 if (is_set
== CAP_CLEAR
) {
1703 if (cap_clear(capabilities
) != 0)
1705 if (cap_set_proc(capabilities
) != 0)
1708 cap_free(capabilities
);
1713 int get_time(unsigned int *time
, const char *str
)
1718 t
= strtod(str
, &p
);
1723 if (strcasecmp(p
, "s") == 0 || strcasecmp(p
, "sec") == 0 ||
1724 strcasecmp(p
, "secs") == 0)
1725 t
*= TIME_UNITS_PER_SEC
;
1726 else if (strcasecmp(p
, "ms") == 0 || strcasecmp(p
, "msec") == 0 ||
1727 strcasecmp(p
, "msecs") == 0)
1728 t
*= TIME_UNITS_PER_SEC
/1000;
1729 else if (strcasecmp(p
, "us") == 0 || strcasecmp(p
, "usec") == 0 ||
1730 strcasecmp(p
, "usecs") == 0)
1731 t
*= TIME_UNITS_PER_SEC
/1000000;
1740 static void print_time(char *buf
, int len
, __u32 time
)
1744 if (tmp
>= TIME_UNITS_PER_SEC
)
1745 snprintf(buf
, len
, "%.3gs", tmp
/TIME_UNITS_PER_SEC
);
1746 else if (tmp
>= TIME_UNITS_PER_SEC
/1000)
1747 snprintf(buf
, len
, "%.3gms", tmp
/(TIME_UNITS_PER_SEC
/1000));
1749 snprintf(buf
, len
, "%uus", time
);
1752 char *sprint_time(__u32 time
, char *buf
)
1754 print_time(buf
, SPRINT_BSIZE
-1, time
);
1758 /* 64 bit times are represented internally in nanoseconds */
1759 int get_time64(__s64
*time
, const char *str
)
1764 nsec
= strtod(str
, &p
);
1769 if (strcasecmp(p
, "s") == 0 ||
1770 strcasecmp(p
, "sec") == 0 ||
1771 strcasecmp(p
, "secs") == 0)
1772 nsec
*= NSEC_PER_SEC
;
1773 else if (strcasecmp(p
, "ms") == 0 ||
1774 strcasecmp(p
, "msec") == 0 ||
1775 strcasecmp(p
, "msecs") == 0)
1776 nsec
*= NSEC_PER_MSEC
;
1777 else if (strcasecmp(p
, "us") == 0 ||
1778 strcasecmp(p
, "usec") == 0 ||
1779 strcasecmp(p
, "usecs") == 0)
1780 nsec
*= NSEC_PER_USEC
;
1781 else if (strcasecmp(p
, "ns") == 0 ||
1782 strcasecmp(p
, "nsec") == 0 ||
1783 strcasecmp(p
, "nsecs") == 0)
1793 static void print_time64(char *buf
, int len
, __s64 time
)
1797 if (time
>= NSEC_PER_SEC
)
1798 snprintf(buf
, len
, "%.3gs", nsec
/NSEC_PER_SEC
);
1799 else if (time
>= NSEC_PER_MSEC
)
1800 snprintf(buf
, len
, "%.3gms", nsec
/NSEC_PER_MSEC
);
1801 else if (time
>= NSEC_PER_USEC
)
1802 snprintf(buf
, len
, "%.3gus", nsec
/NSEC_PER_USEC
);
1804 snprintf(buf
, len
, "%lldns", time
);
1807 char *sprint_time64(__s64 time
, char *buf
)
1809 print_time64(buf
, SPRINT_BSIZE
-1, time
);
1813 int do_batch(const char *name
, bool force
,
1814 int (*cmd
)(int argc
, char *argv
[], void *data
), void *data
)
1818 int ret
= EXIT_SUCCESS
;
1820 if (name
&& strcmp(name
, "-") != 0) {
1821 if (freopen(name
, "r", stdin
) == NULL
) {
1823 "Cannot open file \"%s\" for reading: %s\n",
1824 name
, strerror(errno
));
1825 return EXIT_FAILURE
;
1830 while (getcmdline(&line
, &len
, stdin
) != -1) {
1834 largc
= makeargs(line
, largv
, 100);
1836 continue; /* blank line */
1838 if (cmd(largc
, largv
, data
)) {
1839 fprintf(stderr
, "Command failed %s:%d\n",
1853 int parse_one_of(const char *msg
, const char *realval
, const char * const *list
,
1854 size_t len
, int *p_err
)
1858 for (i
= 0; i
< len
; i
++) {
1859 if (list
[i
] && matches(realval
, list
[i
]) == 0) {
1865 fprintf(stderr
, "Error: argument of \"%s\" must be one of ", msg
);
1866 for (i
= 0; i
< len
; i
++)
1868 fprintf(stderr
, "\"%s\", ", list
[i
]);
1869 fprintf(stderr
, "not \"%s\"\n", realval
);
1874 bool parse_on_off(const char *msg
, const char *realval
, int *p_err
)
1876 static const char * const values_on_off
[] = { "off", "on" };
1878 return parse_one_of(msg
, realval
, values_on_off
, ARRAY_SIZE(values_on_off
), p_err
);
1881 int parse_mapping_gen(int *argcp
, char ***argvp
,
1882 int (*key_cb
)(__u32
*keyp
, const char *key
),
1883 int (*mapping_cb
)(__u32 key
, char *value
, void *data
),
1884 void *mapping_cb_data
)
1887 char **argv
= *argvp
;
1891 char *colon
= strchr(*argv
, ':');
1898 if (key_cb(&key
, *argv
)) {
1902 if (mapping_cb(key
, colon
+ 1, mapping_cb_data
)) {
1915 static int parse_mapping_num(__u32
*keyp
, const char *key
)
1917 return get_u32(keyp
, key
, 0);
1920 int parse_mapping_num_all(__u32
*keyp
, const char *key
)
1922 if (matches(key
, "all") == 0) {
1926 return parse_mapping_num(keyp
, key
);
1929 int parse_mapping(int *argcp
, char ***argvp
, bool allow_all
,
1930 int (*mapping_cb
)(__u32 key
, char *value
, void *data
),
1931 void *mapping_cb_data
)
1934 return parse_mapping_gen(argcp
, argvp
, parse_mapping_num_all
,
1935 mapping_cb
, mapping_cb_data
);
1937 return parse_mapping_gen(argcp
, argvp
, parse_mapping_num
,
1938 mapping_cb
, mapping_cb_data
);
1941 int str_map_lookup_str(const struct str_num_map
*map
, const char *needle
)
1946 /* Process array which is NULL terminated by the string. */
1947 while (map
&& map
->str
) {
1948 if (strcmp(map
->str
, needle
) == 0)
1956 const char *str_map_lookup_u16(const struct str_num_map
*map
, uint16_t val
)
1960 while (map
&& map
->str
) {
1961 if (num
== map
->num
)