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