]> git.proxmox.com Git - mirror_iproute2.git/blob - lib/utils.c
devlink: Introduce and use string to number mapper
[mirror_iproute2.git] / lib / utils.c
1 /*
2 * utils.c
3 *
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.
8 *
9 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
10 *
11 */
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <math.h>
16 #include <unistd.h>
17 #include <fcntl.h>
18 #include <limits.h>
19 #include <sys/socket.h>
20 #include <netinet/in.h>
21 #include <string.h>
22 #include <ctype.h>
23 #include <netdb.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>
31 #include <time.h>
32 #include <sys/time.h>
33 #include <errno.h>
34 #ifdef HAVE_LIBCAP
35 #include <sys/capability.h>
36 #endif
37
38 #include "rt_names.h"
39 #include "utils.h"
40 #include "ll_map.h"
41 #include "namespace.h"
42
43 int resolve_hosts;
44 int timestamp_short;
45 int pretty;
46 const char *_SL_ = "\n";
47
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);
51
52 int read_prop(const char *dev, char *prop, long *value)
53 {
54 char fname[128], buf[80], *endp, *nl;
55 FILE *fp;
56 long result;
57 int ret;
58
59 ret = snprintf(fname, sizeof(fname), "/sys/class/net/%s/%s",
60 dev, prop);
61
62 if (ret <= 0 || ret >= sizeof(fname)) {
63 fprintf(stderr, "could not build pathname for property\n");
64 return -1;
65 }
66
67 fp = fopen(fname, "r");
68 if (fp == NULL) {
69 fprintf(stderr, "fopen %s: %s\n", fname, strerror(errno));
70 return -1;
71 }
72
73 if (!fgets(buf, sizeof(buf), fp)) {
74 fprintf(stderr, "property \"%s\" in file %s is currently unknown\n", prop, fname);
75 fclose(fp);
76 goto out;
77 }
78
79 nl = strchr(buf, '\n');
80 if (nl)
81 *nl = '\0';
82
83 fclose(fp);
84 result = strtol(buf, &endp, 0);
85
86 if (*endp || buf == endp) {
87 fprintf(stderr, "value \"%s\" in file %s is not a number\n",
88 buf, fname);
89 goto out;
90 }
91
92 if ((result == LONG_MAX || result == LONG_MIN) && errno == ERANGE) {
93 fprintf(stderr, "strtol %s: %s", fname, strerror(errno));
94 goto out;
95 }
96
97 *value = result;
98 return 0;
99 out:
100 fprintf(stderr, "Failed to parse %s\n", fname);
101 return -1;
102 }
103
104 int get_hex(char c)
105 {
106 if (c >= 'A' && c <= 'F')
107 return c - 'A' + 10;
108 if (c >= 'a' && c <= 'f')
109 return c - 'a' + 10;
110 if (c >= '0' && c <= '9')
111 return c - '0';
112
113 return -1;
114 }
115
116 int get_integer(int *val, const char *arg, int base)
117 {
118 long res;
119 char *ptr;
120
121 if (!arg || !*arg)
122 return -1;
123
124 res = strtol(arg, &ptr, base);
125
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.
130 */
131 if (!ptr || ptr == arg || *ptr)
132 return -1;
133
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.
137 */
138 if ((res == LONG_MAX || res == LONG_MIN) && errno == ERANGE)
139 return -1;
140
141 /* Outside range of int */
142 if (res < INT_MIN || res > INT_MAX)
143 return -1;
144
145 *val = res;
146 return 0;
147 }
148
149 int mask2bits(__u32 netmask)
150 {
151 unsigned int bits = 0;
152 __u32 mask = ntohl(netmask);
153 __u32 host = ~mask;
154
155 /* a valid netmask must be 2^n - 1 */
156 if ((host & (host + 1)) != 0)
157 return -1;
158
159 for (; mask; mask <<= 1)
160 ++bits;
161 return bits;
162 }
163
164 static int get_netmask(unsigned int *val, const char *arg, int base)
165 {
166 inet_prefix addr;
167
168 if (!get_unsigned(val, arg, base))
169 return 0;
170
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]);
174
175 if (b >= 0) {
176 *val = b;
177 return 0;
178 }
179 }
180
181 return -1;
182 }
183
184 int get_unsigned(unsigned int *val, const char *arg, int base)
185 {
186 unsigned long res;
187 char *ptr;
188
189 if (!arg || !*arg)
190 return -1;
191
192 res = strtoul(arg, &ptr, base);
193
194 /* empty string or trailing non-digits */
195 if (!ptr || ptr == arg || *ptr)
196 return -1;
197
198 /* overflow */
199 if (res == ULONG_MAX && errno == ERANGE)
200 return -1;
201
202 /* out side range of unsigned */
203 if (res > UINT_MAX)
204 return -1;
205
206 *val = res;
207 return 0;
208 }
209
210 /*
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.
216 */
217 int get_time_rtt(unsigned int *val, const char *arg, int *raw)
218 {
219 double t;
220 unsigned long res;
221 char *p;
222
223 if (strchr(arg, '.') != NULL) {
224 t = strtod(arg, &p);
225 if (t < 0.0)
226 return -1;
227
228 /* no digits? */
229 if (!p || p == arg)
230 return -1;
231
232 /* over/underflow */
233 if ((t == HUGE_VALF || t == HUGE_VALL) && errno == ERANGE)
234 return -1;
235 } else {
236 res = strtoul(arg, &p, 0);
237
238 /* empty string? */
239 if (!p || p == arg)
240 return -1;
241
242 /* overflow */
243 if (res == ULONG_MAX && errno == ERANGE)
244 return -1;
245
246 t = (double)res;
247 }
248
249 if (p == arg)
250 return -1;
251 *raw = 1;
252
253 if (*p) {
254 *raw = 0;
255 if (strcasecmp(p, "s") == 0 ||
256 strcasecmp(p, "sec") == 0 ||
257 strcasecmp(p, "secs") == 0)
258 t *= 1000;
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 */
263 else
264 return -1;
265 }
266
267 /* emulate ceil() without having to bring-in -lm and always be >= 1 */
268 *val = t;
269 if (*val < t)
270 *val += 1;
271
272 return 0;
273
274 }
275
276 int get_u64(__u64 *val, const char *arg, int base)
277 {
278 unsigned long long res;
279 char *ptr;
280
281 if (!arg || !*arg)
282 return -1;
283
284 res = strtoull(arg, &ptr, base);
285
286 /* empty string or trailing non-digits */
287 if (!ptr || ptr == arg || *ptr)
288 return -1;
289
290 /* overflow */
291 if (res == ULLONG_MAX && errno == ERANGE)
292 return -1;
293
294 /* in case ULL is 128 bits */
295 if (res > 0xFFFFFFFFFFFFFFFFULL)
296 return -1;
297
298 *val = res;
299 return 0;
300 }
301
302 int get_u32(__u32 *val, const char *arg, int base)
303 {
304 unsigned long res;
305 char *ptr;
306
307 if (!arg || !*arg)
308 return -1;
309 res = strtoul(arg, &ptr, base);
310
311 /* empty string or trailing non-digits */
312 if (!ptr || ptr == arg || *ptr)
313 return -1;
314
315 /* overflow */
316 if (res == ULONG_MAX && errno == ERANGE)
317 return -1;
318
319 /* in case UL > 32 bits */
320 if (res > 0xFFFFFFFFUL)
321 return -1;
322
323 *val = res;
324 return 0;
325 }
326
327 int get_u16(__u16 *val, const char *arg, int base)
328 {
329 unsigned long res;
330 char *ptr;
331
332 if (!arg || !*arg)
333 return -1;
334 res = strtoul(arg, &ptr, base);
335
336 /* empty string or trailing non-digits */
337 if (!ptr || ptr == arg || *ptr)
338 return -1;
339
340 /* overflow */
341 if (res == ULONG_MAX && errno == ERANGE)
342 return -1;
343
344 if (res > 0xFFFFUL)
345 return -1;
346
347 *val = res;
348 return 0;
349 }
350
351 int get_u8(__u8 *val, const char *arg, int base)
352 {
353 unsigned long res;
354 char *ptr;
355
356 if (!arg || !*arg)
357 return -1;
358
359 res = strtoul(arg, &ptr, base);
360 /* empty string or trailing non-digits */
361 if (!ptr || ptr == arg || *ptr)
362 return -1;
363
364 /* overflow */
365 if (res == ULONG_MAX && errno == ERANGE)
366 return -1;
367
368 if (res > 0xFFUL)
369 return -1;
370
371 *val = res;
372 return 0;
373 }
374
375 int get_s64(__s64 *val, const char *arg, int base)
376 {
377 long long res;
378 char *ptr;
379
380 errno = 0;
381
382 if (!arg || !*arg)
383 return -1;
384 res = strtoll(arg, &ptr, base);
385 if (!ptr || ptr == arg || *ptr)
386 return -1;
387 if ((res == LLONG_MIN || res == LLONG_MAX) && errno == ERANGE)
388 return -1;
389 if (res > INT64_MAX || res < INT64_MIN)
390 return -1;
391
392 *val = res;
393 return 0;
394 }
395
396 int get_s32(__s32 *val, const char *arg, int base)
397 {
398 long res;
399 char *ptr;
400
401 errno = 0;
402
403 if (!arg || !*arg)
404 return -1;
405 res = strtol(arg, &ptr, base);
406 if (!ptr || ptr == arg || *ptr)
407 return -1;
408 if ((res == LONG_MIN || res == LONG_MAX) && errno == ERANGE)
409 return -1;
410 if (res > INT32_MAX || res < INT32_MIN)
411 return -1;
412
413 *val = res;
414 return 0;
415 }
416
417 int get_be64(__be64 *val, const char *arg, int base)
418 {
419 __u64 v;
420 int ret = get_u64(&v, arg, base);
421
422 if (!ret)
423 *val = htonll(v);
424
425 return ret;
426 }
427
428 int get_be32(__be32 *val, const char *arg, int base)
429 {
430 __u32 v;
431 int ret = get_u32(&v, arg, base);
432
433 if (!ret)
434 *val = htonl(v);
435
436 return ret;
437 }
438
439 int get_be16(__be16 *val, const char *arg, int base)
440 {
441 __u16 v;
442 int ret = get_u16(&v, arg, base);
443
444 if (!ret)
445 *val = htons(v);
446
447 return ret;
448 }
449
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
452 */
453 static int get_addr_ipv4(__u8 *ap, const char *cp)
454 {
455 int i;
456
457 for (i = 0; i < 4; i++) {
458 unsigned long n;
459 char *endp;
460
461 n = strtoul(cp, &endp, 0);
462 if (n > 255)
463 return -1; /* bogus network value */
464
465 if (endp == cp) /* no digits */
466 return -1;
467
468 ap[i] = n;
469
470 if (*endp == '\0')
471 break;
472
473 if (i == 3 || *endp != '.')
474 return -1; /* extra characters */
475 cp = endp + 1;
476 }
477
478 return 1;
479 }
480
481 int get_addr64(__u64 *ap, const char *cp)
482 {
483 int i;
484
485 union {
486 __u16 v16[4];
487 __u64 v64;
488 } val;
489
490 for (i = 0; i < 4; i++) {
491 unsigned long n;
492 char *endp;
493
494 n = strtoul(cp, &endp, 16);
495 if (n > 0xffff)
496 return -1; /* bogus network value */
497
498 if (endp == cp) /* no digits */
499 return -1;
500
501 val.v16[i] = htons(n);
502
503 if (*endp == '\0')
504 break;
505
506 if (i == 3 || *endp != ':')
507 return -1; /* extra characters */
508 cp = endp + 1;
509 }
510
511 *ap = val.v64;
512
513 return 1;
514 }
515
516 /* See http://physics.nist.gov/cuu/Units/binary.html */
517 static const struct rate_suffix {
518 const char *name;
519 double scale;
520 } suffixes[] = {
521 { "bit", 1. },
522 { "Kibit", 1024. },
523 { "kbit", 1000. },
524 { "mibit", 1024.*1024. },
525 { "mbit", 1000000. },
526 { "gibit", 1024.*1024.*1024. },
527 { "gbit", 1000000000. },
528 { "tibit", 1024.*1024.*1024.*1024. },
529 { "tbit", 1000000000000. },
530 { "Bps", 8. },
531 { "KiBps", 8.*1024. },
532 { "KBps", 8000. },
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. },
539 { NULL }
540 };
541
542 int get_rate(unsigned int *rate, const char *str)
543 {
544 char *p;
545 double bps = strtod(str, &p);
546 const struct rate_suffix *s;
547
548 if (p == str)
549 return -1;
550
551 for (s = suffixes; s->name; ++s) {
552 if (strcasecmp(s->name, p) == 0) {
553 bps *= s->scale;
554 p += strlen(p);
555 break;
556 }
557 }
558
559 if (*p)
560 return -1; /* unknown suffix */
561
562 bps /= 8; /* -> bytes per second */
563 *rate = bps;
564 /* detect if an overflow happened */
565 if (*rate != floor(bps))
566 return -1;
567 return 0;
568 }
569
570 int get_rate64(__u64 *rate, const char *str)
571 {
572 char *p;
573 double bps = strtod(str, &p);
574 const struct rate_suffix *s;
575
576 if (p == str)
577 return -1;
578
579 for (s = suffixes; s->name; ++s) {
580 if (strcasecmp(s->name, p) == 0) {
581 bps *= s->scale;
582 p += strlen(p);
583 break;
584 }
585 }
586
587 if (*p)
588 return -1; /* unknown suffix */
589
590 bps /= 8; /* -> bytes per second */
591 *rate = bps;
592 return 0;
593 }
594
595 int get_size(unsigned int *size, const char *str)
596 {
597 double sz;
598 char *p;
599
600 sz = strtod(str, &p);
601 if (p == str)
602 return -1;
603
604 if (*p) {
605 if (strcasecmp(p, "kb") == 0 || strcasecmp(p, "k") == 0)
606 sz *= 1024;
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)
612 sz *= 1024*1024;
613 else if (strcasecmp(p, "mbit") == 0)
614 sz *= 1024*1024/8;
615 else if (strcasecmp(p, "kbit") == 0)
616 sz *= 1024/8;
617 else if (strcasecmp(p, "b") != 0)
618 return -1;
619 }
620
621 *size = sz;
622
623 /* detect if an overflow happened */
624 if (*size != floor(sz))
625 return -1;
626
627 return 0;
628 }
629
630 static void set_address_type(inet_prefix *addr)
631 {
632 switch (addr->family) {
633 case AF_INET:
634 if (!addr->data[0])
635 addr->flags |= ADDRTYPE_INET_UNSPEC;
636 else if (IN_MULTICAST(ntohl(addr->data[0])))
637 addr->flags |= ADDRTYPE_INET_MULTI;
638 else
639 addr->flags |= ADDRTYPE_INET;
640 break;
641 case AF_INET6:
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;
646 else
647 addr->flags |= ADDRTYPE_INET;
648 break;
649 }
650 }
651
652 static int __get_addr_1(inet_prefix *addr, const char *name, int family)
653 {
654 memset(addr, 0, sizeof(*addr));
655
656 if (strcmp(name, "default") == 0) {
657 if ((family == AF_DECnet) || (family == AF_MPLS))
658 return -1;
659 addr->family = family;
660 addr->bytelen = af_byte_len(addr->family);
661 addr->bitlen = -2;
662 addr->flags |= PREFIXLEN_SPECIFIED;
663 return 0;
664 }
665
666 if (strcmp(name, "all") == 0 ||
667 strcmp(name, "any") == 0) {
668 if ((family == AF_DECnet) || (family == AF_MPLS))
669 return -1;
670 addr->family = family;
671 addr->bytelen = 0;
672 addr->bitlen = -2;
673 return 0;
674 }
675
676 if (family == AF_PACKET) {
677 int len;
678
679 len = ll_addr_a2n((char *) &addr->data, sizeof(addr->data),
680 name);
681 if (len < 0)
682 return -1;
683
684 addr->family = AF_PACKET;
685 addr->bytelen = len;
686 addr->bitlen = len * 8;
687 return 0;
688 }
689
690 if (strchr(name, ':')) {
691 addr->family = AF_INET6;
692 if (family != AF_UNSPEC && family != AF_INET6)
693 return -1;
694 if (inet_pton(AF_INET6, name, addr->data) <= 0)
695 return -1;
696 addr->bytelen = 16;
697 addr->bitlen = -1;
698 return 0;
699 }
700
701 if (family == AF_MPLS) {
702 unsigned int maxlabels;
703 int i;
704
705 addr->family = AF_MPLS;
706 if (mpls_pton(AF_MPLS, name, addr->data,
707 sizeof(addr->data)) <= 0)
708 return -1;
709 addr->bytelen = 4;
710 addr->bitlen = 20;
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;
716 break;
717 }
718 }
719 return 0;
720 }
721
722 addr->family = AF_INET;
723 if (family != AF_UNSPEC && family != AF_INET)
724 return -1;
725
726 if (get_addr_ipv4((__u8 *)addr->data, name) <= 0)
727 return -1;
728
729 addr->bytelen = 4;
730 addr->bitlen = -1;
731 return 0;
732 }
733
734 int get_addr_1(inet_prefix *addr, const char *name, int family)
735 {
736 int ret;
737
738 ret = __get_addr_1(addr, name, family);
739 if (ret)
740 return ret;
741
742 set_address_type(addr);
743 return 0;
744 }
745
746 int af_bit_len(int af)
747 {
748 switch (af) {
749 case AF_INET6:
750 return 128;
751 case AF_INET:
752 return 32;
753 case AF_DECnet:
754 return 16;
755 case AF_IPX:
756 return 80;
757 case AF_MPLS:
758 return 20;
759 }
760
761 return 0;
762 }
763
764 static int af_byte_len(int af)
765 {
766 return af_bit_len(af) / 8;
767 }
768
769 int get_prefix_1(inet_prefix *dst, char *arg, int family)
770 {
771 char *slash;
772 int err, bitlen, flags;
773
774 slash = strchr(arg, '/');
775 if (slash)
776 *slash = 0;
777
778 err = get_addr_1(dst, arg, family);
779
780 if (slash)
781 *slash = '/';
782
783 if (err)
784 return err;
785
786 bitlen = af_bit_len(dst->family);
787
788 flags = 0;
789 if (slash) {
790 unsigned int plen;
791
792 if (dst->bitlen == -2)
793 return -1;
794 if (get_netmask(&plen, slash + 1, 0))
795 return -1;
796 if (plen > bitlen)
797 return -1;
798
799 flags |= PREFIXLEN_SPECIFIED;
800 bitlen = plen;
801 } else {
802 if (dst->bitlen == -2)
803 bitlen = 0;
804 }
805
806 dst->flags |= flags;
807 dst->bitlen = bitlen;
808
809 return 0;
810 }
811
812 static const char *family_name_verbose(int family)
813 {
814 if (family == AF_UNSPEC)
815 return "any valid";
816 return family_name(family);
817 }
818
819 int get_addr(inet_prefix *dst, const char *arg, int family)
820 {
821 if (get_addr_1(dst, arg, family)) {
822 fprintf(stderr,
823 "Error: %s address is expected rather than \"%s\".\n",
824 family_name_verbose(family), arg);
825 exit(1);
826 }
827 return 0;
828 }
829
830 int get_addr_rta(inet_prefix *dst, const struct rtattr *rta, int family)
831 {
832 const int len = RTA_PAYLOAD(rta);
833 const void *data = RTA_DATA(rta);
834
835 switch (len) {
836 case 4:
837 dst->family = AF_INET;
838 dst->bytelen = 4;
839 memcpy(dst->data, data, 4);
840 break;
841 case 16:
842 dst->family = AF_INET6;
843 dst->bytelen = 16;
844 memcpy(dst->data, data, 16);
845 break;
846 case 2:
847 dst->family = AF_DECnet;
848 dst->bytelen = 2;
849 memcpy(dst->data, data, 2);
850 break;
851 case 10:
852 dst->family = AF_IPX;
853 dst->bytelen = 10;
854 memcpy(dst->data, data, 10);
855 break;
856 default:
857 return -1;
858 }
859
860 if (family != AF_UNSPEC && family != dst->family)
861 return -2;
862
863 dst->bitlen = -1;
864 dst->flags = 0;
865
866 set_address_type(dst);
867 return 0;
868 }
869
870 int get_prefix(inet_prefix *dst, char *arg, int family)
871 {
872 if (family == AF_PACKET) {
873 fprintf(stderr,
874 "Error: \"%s\" may be inet prefix, but it is not allowed in this context.\n",
875 arg);
876 exit(1);
877 }
878
879 if (get_prefix_1(dst, arg, family)) {
880 fprintf(stderr,
881 "Error: %s prefix is expected rather than \"%s\".\n",
882 family_name_verbose(family), arg);
883 exit(1);
884 }
885 return 0;
886 }
887
888 __u32 get_addr32(const char *name)
889 {
890 inet_prefix addr;
891
892 if (get_addr_1(&addr, name, AF_INET)) {
893 fprintf(stderr,
894 "Error: an IP address is expected rather than \"%s\"\n",
895 name);
896 exit(1);
897 }
898 return addr.data[0];
899 }
900
901 void incomplete_command(void)
902 {
903 fprintf(stderr, "Command line is not complete. Try option \"help\"\n");
904 exit(-1);
905 }
906
907 void missarg(const char *key)
908 {
909 fprintf(stderr, "Error: argument \"%s\" is required\n", key);
910 exit(-1);
911 }
912
913 void invarg(const char *msg, const char *arg)
914 {
915 fprintf(stderr, "Error: argument \"%s\" is wrong: %s\n", arg, msg);
916 exit(-1);
917 }
918
919 void duparg(const char *key, const char *arg)
920 {
921 fprintf(stderr,
922 "Error: duplicate \"%s\": \"%s\" is the second value.\n",
923 key, arg);
924 exit(-1);
925 }
926
927 void duparg2(const char *key, const char *arg)
928 {
929 fprintf(stderr,
930 "Error: either \"%s\" is duplicate, or \"%s\" is a garbage.\n",
931 key, arg);
932 exit(-1);
933 }
934
935 int nodev(const char *dev)
936 {
937 fprintf(stderr, "Cannot find device \"%s\"\n", dev);
938 return -1;
939 }
940
941 static int __check_ifname(const char *name)
942 {
943 if (*name == '\0')
944 return -1;
945 while (*name) {
946 if (*name == '/' || isspace(*name))
947 return -1;
948 ++name;
949 }
950 return 0;
951 }
952
953 int check_ifname(const char *name)
954 {
955 /* These checks mimic kernel checks in dev_valid_name */
956 if (strlen(name) >= IFNAMSIZ)
957 return -1;
958 return __check_ifname(name);
959 }
960
961 int check_altifname(const char *name)
962 {
963 return __check_ifname(name);
964 }
965
966 /* buf is assumed to be IFNAMSIZ */
967 int get_ifname(char *buf, const char *name)
968 {
969 int ret;
970
971 ret = check_ifname(name);
972 if (ret == 0)
973 strncpy(buf, name, IFNAMSIZ);
974
975 return ret;
976 }
977
978 const char *get_ifname_rta(int ifindex, const struct rtattr *rta)
979 {
980 const char *name;
981
982 if (rta) {
983 name = rta_getattr_str(rta);
984 } else {
985 fprintf(stderr,
986 "BUG: device with ifindex %d has nil ifname\n",
987 ifindex);
988 name = ll_idx_n2a(ifindex);
989 }
990
991 if (check_ifname(name))
992 return NULL;
993
994 return name;
995 }
996
997 /* Returns false if 'prefix' is a not empty prefix of 'string'.
998 */
999 bool matches(const char *prefix, const char *string)
1000 {
1001 if (!*prefix)
1002 return true;
1003 while (*string && *prefix == *string) {
1004 prefix++;
1005 string++;
1006 }
1007
1008 return !!*prefix;
1009 }
1010
1011 int inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits)
1012 {
1013 const __u32 *a1 = a->data;
1014 const __u32 *a2 = b->data;
1015 int words = bits >> 0x05;
1016
1017 bits &= 0x1f;
1018
1019 if (words)
1020 if (memcmp(a1, a2, words << 2))
1021 return -1;
1022
1023 if (bits) {
1024 __u32 w1, w2;
1025 __u32 mask;
1026
1027 w1 = a1[words];
1028 w2 = a2[words];
1029
1030 mask = htonl((0xffffffff) << (0x20 - bits));
1031
1032 if ((w1 ^ w2) & mask)
1033 return 1;
1034 }
1035
1036 return 0;
1037 }
1038
1039 int inet_addr_match_rta(const inet_prefix *m, const struct rtattr *rta)
1040 {
1041 inet_prefix dst;
1042
1043 if (!rta || m->family == AF_UNSPEC || m->bitlen <= 0)
1044 return 0;
1045
1046 if (get_addr_rta(&dst, rta, m->family))
1047 return -1;
1048
1049 return inet_addr_match(&dst, m, m->bitlen);
1050 }
1051
1052 int __iproute2_hz_internal;
1053
1054 int __get_hz(void)
1055 {
1056 char name[1024];
1057 int hz = 0;
1058 FILE *fp;
1059
1060 if (getenv("HZ"))
1061 return atoi(getenv("HZ")) ? : HZ;
1062
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"));
1069 else
1070 strcpy(name, "/proc/net/psched");
1071
1072 fp = fopen(name, "r");
1073
1074 if (fp) {
1075 unsigned int nom, denom;
1076
1077 if (fscanf(fp, "%*08x%*08x%08x%08x", &nom, &denom) == 2)
1078 if (nom == 1000000)
1079 hz = denom;
1080 fclose(fp);
1081 }
1082 if (hz)
1083 return hz;
1084 return HZ;
1085 }
1086
1087 int __iproute2_user_hz_internal;
1088
1089 int __get_user_hz(void)
1090 {
1091 return sysconf(_SC_CLK_TCK);
1092 }
1093
1094 const char *rt_addr_n2a_r(int af, int len,
1095 const void *addr, char *buf, int buflen)
1096 {
1097 switch (af) {
1098 case AF_INET:
1099 case AF_INET6:
1100 return inet_ntop(af, addr, buf, buflen);
1101 case AF_MPLS:
1102 return mpls_ntop(af, addr, buf, buflen);
1103 case AF_PACKET:
1104 return ll_addr_n2a(addr, len, ARPHRD_VOID, buf, buflen);
1105 case AF_BRIDGE:
1106 {
1107 const union {
1108 struct sockaddr sa;
1109 struct sockaddr_in sin;
1110 struct sockaddr_in6 sin6;
1111 } *sa = addr;
1112
1113 switch (sa->sa.sa_family) {
1114 case AF_INET:
1115 return inet_ntop(AF_INET, &sa->sin.sin_addr,
1116 buf, buflen);
1117 case AF_INET6:
1118 return inet_ntop(AF_INET6, &sa->sin6.sin6_addr,
1119 buf, buflen);
1120 }
1121
1122 /* fallthrough */
1123 }
1124 default:
1125 return "???";
1126 }
1127 }
1128
1129 const char *rt_addr_n2a(int af, int len, const void *addr)
1130 {
1131 static char buf[256];
1132
1133 return rt_addr_n2a_r(af, len, addr, buf, 256);
1134 }
1135
1136 int read_family(const char *name)
1137 {
1138 int family = AF_UNSPEC;
1139
1140 if (strcmp(name, "inet") == 0)
1141 family = AF_INET;
1142 else if (strcmp(name, "inet6") == 0)
1143 family = AF_INET6;
1144 else if (strcmp(name, "link") == 0)
1145 family = AF_PACKET;
1146 else if (strcmp(name, "ipx") == 0)
1147 family = AF_IPX;
1148 else if (strcmp(name, "mpls") == 0)
1149 family = AF_MPLS;
1150 else if (strcmp(name, "bridge") == 0)
1151 family = AF_BRIDGE;
1152 return family;
1153 }
1154
1155 const char *family_name(int family)
1156 {
1157 if (family == AF_INET)
1158 return "inet";
1159 if (family == AF_INET6)
1160 return "inet6";
1161 if (family == AF_PACKET)
1162 return "link";
1163 if (family == AF_IPX)
1164 return "ipx";
1165 if (family == AF_MPLS)
1166 return "mpls";
1167 if (family == AF_BRIDGE)
1168 return "bridge";
1169 return "???";
1170 }
1171
1172 #ifdef RESOLVE_HOSTNAMES
1173 struct namerec {
1174 struct namerec *next;
1175 const char *name;
1176 inet_prefix addr;
1177 };
1178
1179 #define NHASH 257
1180 static struct namerec *nht[NHASH];
1181
1182 static const char *resolve_address(const void *addr, int len, int af)
1183 {
1184 struct namerec *n;
1185 struct hostent *h_ent;
1186 unsigned int hash;
1187 static int notfirst;
1188
1189
1190 if (af == AF_INET6 && ((__u32 *)addr)[0] == 0 &&
1191 ((__u32 *)addr)[1] == 0 && ((__u32 *)addr)[2] == htonl(0xffff)) {
1192 af = AF_INET;
1193 addr += 12;
1194 len = 4;
1195 }
1196
1197 hash = *(__u32 *)(addr + len - 4) % NHASH;
1198
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)
1203 return n->name;
1204 }
1205 n = malloc(sizeof(*n));
1206 if (n == NULL)
1207 return NULL;
1208 n->addr.family = af;
1209 n->addr.bytelen = len;
1210 n->name = NULL;
1211 memcpy(n->addr.data, addr, len);
1212 n->next = nht[hash];
1213 nht[hash] = n;
1214 if (++notfirst == 1)
1215 sethostent(1);
1216 fflush(stdout);
1217
1218 h_ent = gethostbyaddr(addr, len, af);
1219 if (h_ent != NULL)
1220 n->name = strdup(h_ent->h_name);
1221
1222 /* Even if we fail, "negative" entry is remembered. */
1223 return n->name;
1224 }
1225 #endif
1226
1227 const char *format_host_r(int af, int len, const void *addr,
1228 char *buf, int buflen)
1229 {
1230 #ifdef RESOLVE_HOSTNAMES
1231 if (resolve_hosts) {
1232 const char *n;
1233
1234 len = len <= 0 ? af_byte_len(af) : len;
1235
1236 if (len > 0 &&
1237 (n = resolve_address(addr, len, af)) != NULL)
1238 return n;
1239 }
1240 #endif
1241 return rt_addr_n2a_r(af, len, addr, buf, buflen);
1242 }
1243
1244 const char *format_host(int af, int len, const void *addr)
1245 {
1246 static char buf[256];
1247
1248 return format_host_r(af, len, addr, buf, 256);
1249 }
1250
1251
1252 char *hexstring_n2a(const __u8 *str, int len, char *buf, int blen)
1253 {
1254 char *ptr = buf;
1255 int i;
1256
1257 for (i = 0; i < len; i++) {
1258 if (blen < 3)
1259 break;
1260 sprintf(ptr, "%02x", str[i]);
1261 ptr += 2;
1262 blen -= 2;
1263 }
1264 return buf;
1265 }
1266
1267 __u8 *hexstring_a2n(const char *str, __u8 *buf, int blen, unsigned int *len)
1268 {
1269 unsigned int cnt = 0;
1270 char *endptr;
1271
1272 if (strlen(str) % 2)
1273 return NULL;
1274 while (cnt < blen && strlen(str) > 1) {
1275 unsigned int tmp;
1276 char tmpstr[3];
1277
1278 strncpy(tmpstr, str, 2);
1279 tmpstr[2] = '\0';
1280 errno = 0;
1281 tmp = strtoul(tmpstr, &endptr, 16);
1282 if (errno != 0 || tmp > 0xFF || *endptr != '\0')
1283 return NULL;
1284 buf[cnt++] = tmp;
1285 str += 2;
1286 }
1287
1288 if (len)
1289 *len = cnt;
1290
1291 return buf;
1292 }
1293
1294 int hex2mem(const char *buf, uint8_t *mem, int count)
1295 {
1296 int i, j;
1297 int c;
1298
1299 for (i = 0, j = 0; i < count; i++, j += 2) {
1300 c = get_hex(buf[j]);
1301 if (c < 0)
1302 return -1;
1303
1304 mem[i] = c << 4;
1305
1306 c = get_hex(buf[j + 1]);
1307 if (c < 0)
1308 return -1;
1309
1310 mem[i] |= c;
1311 }
1312
1313 return 0;
1314 }
1315
1316 int addr64_n2a(__u64 addr, char *buff, size_t len)
1317 {
1318 __u16 *words = (__u16 *)&addr;
1319 __u16 v;
1320 int i, ret;
1321 size_t written = 0;
1322 char *sep = ":";
1323
1324 for (i = 0; i < 4; i++) {
1325 v = ntohs(words[i]);
1326
1327 if (i == 3)
1328 sep = "";
1329
1330 ret = snprintf(&buff[written], len - written, "%x%s", v, sep);
1331 if (ret < 0)
1332 return ret;
1333
1334 written += ret;
1335 }
1336
1337 return written;
1338 }
1339
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)
1342 {
1343 size_t i;
1344
1345 for (i = 0; i < len; ++i) {
1346 if (isprint(buf[i]) && buf[i] != '\\' &&
1347 !strchr(escape, buf[i]))
1348 printf("%c", buf[i]);
1349 else
1350 printf("\\%03o", buf[i]);
1351 }
1352 }
1353
1354 int print_timestamp(FILE *fp)
1355 {
1356 struct timeval tv;
1357 struct tm *tm;
1358
1359 gettimeofday(&tv, NULL);
1360 tm = localtime(&tv.tv_sec);
1361
1362 if (timestamp_short) {
1363 char tshort[40];
1364
1365 strftime(tshort, sizeof(tshort), "%Y-%m-%dT%H:%M:%S", tm);
1366 fprintf(fp, "[%s.%06ld] ", tshort, tv.tv_usec);
1367 } else {
1368 char *tstr = asctime(tm);
1369
1370 tstr[strlen(tstr)-1] = 0;
1371 fprintf(fp, "Timestamp: %s %ld usec\n",
1372 tstr, tv.tv_usec);
1373 }
1374
1375 return 0;
1376 }
1377
1378 unsigned int print_name_and_link(const char *fmt,
1379 const char *name, struct rtattr *tb[])
1380 {
1381 const char *link = NULL;
1382 unsigned int m_flag = 0;
1383 SPRINT_BUF(b1);
1384
1385 if (tb[IFLA_LINK]) {
1386 int iflink = rta_getattr_u32(tb[IFLA_LINK]);
1387
1388 if (iflink) {
1389 if (tb[IFLA_LINK_NETNSID]) {
1390 if (is_json_context()) {
1391 print_int(PRINT_JSON,
1392 "link_index", NULL, iflink);
1393 } else {
1394 link = ll_idx_n2a(iflink);
1395 }
1396 } else {
1397 link = ll_index_to_name(iflink);
1398
1399 if (is_json_context()) {
1400 print_string(PRINT_JSON,
1401 "link", NULL, link);
1402 link = NULL;
1403 }
1404
1405 m_flag = ll_index_to_flags(iflink);
1406 m_flag = !(m_flag & IFF_UP);
1407 }
1408 } else {
1409 if (is_json_context())
1410 print_null(PRINT_JSON, "link", NULL, NULL);
1411 else
1412 link = "NONE";
1413 }
1414
1415 if (link) {
1416 snprintf(b1, sizeof(b1), "%s@%s", name, link);
1417 name = b1;
1418 }
1419 }
1420
1421 print_color_string(PRINT_ANY, COLOR_IFNAME, "ifname", fmt, name);
1422
1423 return m_flag;
1424 }
1425
1426 int cmdlineno;
1427
1428 /* Like glibc getline but handle continuation lines and comments */
1429 ssize_t getcmdline(char **linep, size_t *lenp, FILE *in)
1430 {
1431 ssize_t cc;
1432 char *cp;
1433
1434 cc = getline(linep, lenp, in);
1435 if (cc < 0)
1436 return cc; /* eof or error */
1437 ++cmdlineno;
1438
1439 cp = strchr(*linep, '#');
1440 if (cp)
1441 *cp = '\0';
1442
1443 while ((cp = strstr(*linep, "\\\n")) != NULL) {
1444 char *line1 = NULL;
1445 size_t len1 = 0;
1446 ssize_t cc1;
1447
1448 cc1 = getline(&line1, &len1, in);
1449 if (cc1 < 0) {
1450 fprintf(stderr, "Missing continuation line\n");
1451 return cc1;
1452 }
1453
1454 ++cmdlineno;
1455 *cp = 0;
1456
1457 cp = strchr(line1, '#');
1458 if (cp)
1459 *cp = '\0';
1460
1461 *lenp = strlen(*linep) + strlen(line1) + 1;
1462 *linep = realloc(*linep, *lenp);
1463 if (!*linep) {
1464 fprintf(stderr, "Out of memory\n");
1465 *lenp = 0;
1466 return -1;
1467 }
1468 cc += cc1 - 2;
1469 strcat(*linep, line1);
1470 free(line1);
1471 }
1472 return cc;
1473 }
1474
1475 /* split command line into argument vector */
1476 int makeargs(char *line, char *argv[], int maxargs)
1477 {
1478 static const char ws[] = " \t\r\n";
1479 char *cp = line;
1480 int argc = 0;
1481
1482 while (*cp) {
1483 /* skip leading whitespace */
1484 cp += strspn(cp, ws);
1485
1486 if (*cp == '\0')
1487 break;
1488
1489 if (argc >= (maxargs - 1)) {
1490 fprintf(stderr, "Too many arguments to command\n");
1491 exit(1);
1492 }
1493
1494 /* word begins with quote */
1495 if (*cp == '\'' || *cp == '"') {
1496 char quote = *cp++;
1497
1498 argv[argc++] = cp;
1499 /* find ending quote */
1500 cp = strchr(cp, quote);
1501 if (cp == NULL) {
1502 fprintf(stderr, "Unterminated quoted string\n");
1503 exit(1);
1504 }
1505 } else {
1506 argv[argc++] = cp;
1507
1508 /* find end of word */
1509 cp += strcspn(cp, ws);
1510 if (*cp == '\0')
1511 break;
1512 }
1513
1514 /* separate words */
1515 *cp++ = 0;
1516 }
1517 argv[argc] = NULL;
1518
1519 return argc;
1520 }
1521
1522 void print_nlmsg_timestamp(FILE *fp, const struct nlmsghdr *n)
1523 {
1524 char *tstr;
1525 time_t secs = ((__u32 *)NLMSG_DATA(n))[0];
1526 long usecs = ((__u32 *)NLMSG_DATA(n))[1];
1527
1528 tstr = asctime(localtime(&secs));
1529 tstr[strlen(tstr)-1] = 0;
1530 fprintf(fp, "Timestamp: %s %lu us\n", tstr, usecs);
1531 }
1532
1533 char *int_to_str(int val, char *buf)
1534 {
1535 sprintf(buf, "%d", val);
1536 return buf;
1537 }
1538
1539 int get_guid(__u64 *guid, const char *arg)
1540 {
1541 unsigned long tmp;
1542 char *endptr;
1543 int i;
1544
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
1548 * hex digit
1549 */
1550
1551 if (strlen(arg) != GUID_STR_LEN)
1552 return -1;
1553
1554 /* make sure columns are in place */
1555 for (i = 0; i < 7; i++)
1556 if (arg[2 + i * 3] != ':')
1557 return -1;
1558
1559 *guid = 0;
1560 for (i = 0; i < 8; i++) {
1561 tmp = strtoul(arg + i * 3, &endptr, 16);
1562 if (endptr != arg + i * 3 + 2)
1563 return -1;
1564
1565 if (tmp > 255)
1566 return -1;
1567
1568 *guid |= tmp << (56 - 8 * i);
1569 }
1570
1571 return 0;
1572 }
1573
1574 /* This is a necessary workaround for multicast route dumps */
1575 int get_real_family(int rtm_type, int rtm_family)
1576 {
1577 if (rtm_type != RTN_MULTICAST)
1578 return rtm_family;
1579
1580 if (rtm_family == RTNL_FAMILY_IPMR)
1581 return AF_INET;
1582
1583 if (rtm_family == RTNL_FAMILY_IP6MR)
1584 return AF_INET6;
1585
1586 return rtm_family;
1587 }
1588
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)
1592 {
1593 __u64 *a = (__u64 *)stats64;
1594 const __u32 *b = (const __u32 *)stats;
1595 const __u32 *e = b + sizeof(*stats) / sizeof(*b);
1596
1597 while (b < e)
1598 *a++ = *b++;
1599 }
1600
1601 #define IPSTATS_MIB_MAX_LEN (__IPSTATS_MIB_MAX * sizeof(__u64))
1602 static void get_snmp_counters(struct rtnl_link_stats64 *stats64,
1603 struct rtattr *s)
1604 {
1605 __u64 *mib = (__u64 *)RTA_DATA(s);
1606
1607 memset(stats64, 0, sizeof(*stats64));
1608
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];
1617 }
1618
1619 int get_rtnl_link_stats_rta(struct rtnl_link_stats64 *stats64,
1620 struct rtattr *tb[])
1621 {
1622 struct rtnl_link_stats stats;
1623 void *s;
1624 struct rtattr *rta;
1625 int size, len;
1626
1627 if (tb[IFLA_STATS64]) {
1628 rta = tb[IFLA_STATS64];
1629 size = sizeof(struct rtnl_link_stats64);
1630 s = stats64;
1631 } else if (tb[IFLA_STATS]) {
1632 rta = tb[IFLA_STATS];
1633 size = sizeof(struct rtnl_link_stats);
1634 s = &stats;
1635 } else if (tb[IFLA_PROTINFO]) {
1636 struct rtattr *ptb[IPSTATS_MIB_MAX_LEN + 1];
1637
1638 parse_rtattr_nested(ptb, IPSTATS_MIB_MAX_LEN,
1639 tb[IFLA_PROTINFO]);
1640 if (ptb[IFLA_INET6_STATS])
1641 get_snmp_counters(stats64, ptb[IFLA_INET6_STATS]);
1642 return sizeof(*stats64);
1643 } else {
1644 return -1;
1645 }
1646
1647 len = RTA_PAYLOAD(rta);
1648 if (len < size)
1649 memset(s + len, 0, size - len);
1650 else
1651 len = size;
1652
1653 memcpy(s, RTA_DATA(rta), len);
1654
1655 if (s != stats64)
1656 copy_rtnl_link_stats64(stats64, s);
1657 return size;
1658 }
1659
1660 #ifdef NEED_STRLCPY
1661 size_t strlcpy(char *dst, const char *src, size_t size)
1662 {
1663 size_t srclen = strlen(src);
1664
1665 if (size) {
1666 size_t minlen = min(srclen, size - 1);
1667
1668 memcpy(dst, src, minlen);
1669 dst[minlen] = '\0';
1670 }
1671 return srclen;
1672 }
1673
1674 size_t strlcat(char *dst, const char *src, size_t size)
1675 {
1676 size_t dlen = strlen(dst);
1677
1678 if (dlen >= size)
1679 return dlen + strlen(src);
1680
1681 return dlen + strlcpy(dst + dlen, src, size - dlen);
1682 }
1683 #endif
1684
1685 void drop_cap(void)
1686 {
1687 #ifdef HAVE_LIBCAP
1688 /* don't harmstring root/sudo */
1689 if (getuid() != 0 && geteuid() != 0) {
1690 cap_t capabilities;
1691 cap_value_t net_admin = CAP_NET_ADMIN;
1692 cap_flag_t inheritable = CAP_INHERITABLE;
1693 cap_flag_value_t is_set;
1694
1695 capabilities = cap_get_proc();
1696 if (!capabilities)
1697 exit(EXIT_FAILURE);
1698 if (cap_get_flag(capabilities, net_admin, inheritable,
1699 &is_set) != 0)
1700 exit(EXIT_FAILURE);
1701 /* apps with ambient caps can fork and call ip */
1702 if (is_set == CAP_CLEAR) {
1703 if (cap_clear(capabilities) != 0)
1704 exit(EXIT_FAILURE);
1705 if (cap_set_proc(capabilities) != 0)
1706 exit(EXIT_FAILURE);
1707 }
1708 cap_free(capabilities);
1709 }
1710 #endif
1711 }
1712
1713 int get_time(unsigned int *time, const char *str)
1714 {
1715 double t;
1716 char *p;
1717
1718 t = strtod(str, &p);
1719 if (p == str)
1720 return -1;
1721
1722 if (*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;
1732 else
1733 return -1;
1734 }
1735
1736 *time = t;
1737 return 0;
1738 }
1739
1740 static void print_time(char *buf, int len, __u32 time)
1741 {
1742 double tmp = time;
1743
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));
1748 else
1749 snprintf(buf, len, "%uus", time);
1750 }
1751
1752 char *sprint_time(__u32 time, char *buf)
1753 {
1754 print_time(buf, SPRINT_BSIZE-1, time);
1755 return buf;
1756 }
1757
1758 /* 64 bit times are represented internally in nanoseconds */
1759 int get_time64(__s64 *time, const char *str)
1760 {
1761 double nsec;
1762 char *p;
1763
1764 nsec = strtod(str, &p);
1765 if (p == str)
1766 return -1;
1767
1768 if (*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)
1784 nsec *= 1;
1785 else
1786 return -1;
1787 }
1788
1789 *time = nsec;
1790 return 0;
1791 }
1792
1793 static void print_time64(char *buf, int len, __s64 time)
1794 {
1795 double nsec = time;
1796
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);
1803 else
1804 snprintf(buf, len, "%lldns", time);
1805 }
1806
1807 char *sprint_time64(__s64 time, char *buf)
1808 {
1809 print_time64(buf, SPRINT_BSIZE-1, time);
1810 return buf;
1811 }
1812
1813 int do_batch(const char *name, bool force,
1814 int (*cmd)(int argc, char *argv[], void *data), void *data)
1815 {
1816 char *line = NULL;
1817 size_t len = 0;
1818 int ret = EXIT_SUCCESS;
1819
1820 if (name && strcmp(name, "-") != 0) {
1821 if (freopen(name, "r", stdin) == NULL) {
1822 fprintf(stderr,
1823 "Cannot open file \"%s\" for reading: %s\n",
1824 name, strerror(errno));
1825 return EXIT_FAILURE;
1826 }
1827 }
1828
1829 cmdlineno = 0;
1830 while (getcmdline(&line, &len, stdin) != -1) {
1831 char *largv[100];
1832 int largc;
1833
1834 largc = makeargs(line, largv, 100);
1835 if (!largc)
1836 continue; /* blank line */
1837
1838 if (cmd(largc, largv, data)) {
1839 fprintf(stderr, "Command failed %s:%d\n",
1840 name, cmdlineno);
1841 ret = EXIT_FAILURE;
1842 if (!force)
1843 break;
1844 }
1845 }
1846
1847 if (line)
1848 free(line);
1849
1850 return ret;
1851 }
1852
1853 int parse_one_of(const char *msg, const char *realval, const char * const *list,
1854 size_t len, int *p_err)
1855 {
1856 int i;
1857
1858 for (i = 0; i < len; i++) {
1859 if (list[i] && matches(realval, list[i]) == 0) {
1860 *p_err = 0;
1861 return i;
1862 }
1863 }
1864
1865 fprintf(stderr, "Error: argument of \"%s\" must be one of ", msg);
1866 for (i = 0; i < len; i++)
1867 if (list[i])
1868 fprintf(stderr, "\"%s\", ", list[i]);
1869 fprintf(stderr, "not \"%s\"\n", realval);
1870 *p_err = -EINVAL;
1871 return 0;
1872 }
1873
1874 bool parse_on_off(const char *msg, const char *realval, int *p_err)
1875 {
1876 static const char * const values_on_off[] = { "off", "on" };
1877
1878 return parse_one_of(msg, realval, values_on_off, ARRAY_SIZE(values_on_off), p_err);
1879 }
1880
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)
1885 {
1886 int argc = *argcp;
1887 char **argv = *argvp;
1888 int ret = 0;
1889
1890 while (argc > 0) {
1891 char *colon = strchr(*argv, ':');
1892 __u32 key;
1893
1894 if (!colon)
1895 break;
1896 *colon = '\0';
1897
1898 if (key_cb(&key, *argv)) {
1899 ret = 1;
1900 break;
1901 }
1902 if (mapping_cb(key, colon + 1, mapping_cb_data)) {
1903 ret = 1;
1904 break;
1905 }
1906
1907 argc--, argv++;
1908 }
1909
1910 *argcp = argc;
1911 *argvp = argv;
1912 return ret;
1913 }
1914
1915 static int parse_mapping_num(__u32 *keyp, const char *key)
1916 {
1917 return get_u32(keyp, key, 0);
1918 }
1919
1920 int parse_mapping_num_all(__u32 *keyp, const char *key)
1921 {
1922 if (matches(key, "all") == 0) {
1923 *keyp = (__u32) -1;
1924 return 0;
1925 }
1926 return parse_mapping_num(keyp, key);
1927 }
1928
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)
1932 {
1933 if (allow_all)
1934 return parse_mapping_gen(argcp, argvp, parse_mapping_num_all,
1935 mapping_cb, mapping_cb_data);
1936 else
1937 return parse_mapping_gen(argcp, argvp, parse_mapping_num,
1938 mapping_cb, mapping_cb_data);
1939 }
1940
1941 int str_map_lookup_str(const struct str_num_map *map, const char *needle)
1942 {
1943 if (!needle)
1944 return -EINVAL;
1945
1946 /* Process array which is NULL terminated by the string. */
1947 while (map && map->str) {
1948 if (strcmp(map->str, needle) == 0)
1949 return map->num;
1950
1951 map++;
1952 }
1953 return -EINVAL;
1954 }
1955
1956 const char *str_map_lookup_u16(const struct str_num_map *map, uint16_t val)
1957 {
1958 int num = val;
1959
1960 while (map && map->str) {
1961 if (num == map->num)
1962 return map->str;
1963
1964 map++;
1965 }
1966 return NULL;
1967 }