]> git.proxmox.com Git - mirror_iproute2.git/blob - lib/utils.c
Fix compile warning in get_addr_1
[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 <syslog.h>
18 #include <fcntl.h>
19 #include <limits.h>
20 #include <sys/socket.h>
21 #include <netinet/in.h>
22 #include <string.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 <time.h>
31 #include <sys/time.h>
32 #include <errno.h>
33
34 #include "rt_names.h"
35 #include "utils.h"
36 #include "namespace.h"
37
38 int timestamp_short;
39
40 int get_hex(char c)
41 {
42 if (c >= 'A' && c <= 'F')
43 return c - 'A' + 10;
44 if (c >= 'a' && c <= 'f')
45 return c - 'a' + 10;
46 if (c >= '0' && c <= '9')
47 return c - '0';
48
49 return -1;
50 }
51
52 int get_integer(int *val, const char *arg, int base)
53 {
54 long res;
55 char *ptr;
56
57 if (!arg || !*arg)
58 return -1;
59
60 res = strtol(arg, &ptr, base);
61
62 /* If there were no digits at all, strtol() stores
63 * the original value of nptr in *endptr (and returns 0).
64 * In particular, if *nptr is not '\0' but **endptr is '\0' on return,
65 * the entire string is valid.
66 */
67 if (!ptr || ptr == arg || *ptr)
68 return -1;
69
70 /* If an underflow occurs, strtol() returns LONG_MIN.
71 * If an overflow occurs, strtol() returns LONG_MAX.
72 * In both cases, errno is set to ERANGE.
73 */
74 if ((res == LONG_MAX || res == LONG_MIN) && errno == ERANGE)
75 return -1;
76
77 /* Outside range of int */
78 if (res < INT_MIN || res > INT_MAX)
79 return -1;
80
81 *val = res;
82 return 0;
83 }
84
85 int mask2bits(__u32 netmask)
86 {
87 unsigned int bits = 0;
88 __u32 mask = ntohl(netmask);
89 __u32 host = ~mask;
90
91 /* a valid netmask must be 2^n - 1 */
92 if ((host & (host + 1)) != 0)
93 return -1;
94
95 for (; mask; mask <<= 1)
96 ++bits;
97 return bits;
98 }
99
100 static int get_netmask(unsigned int *val, const char *arg, int base)
101 {
102 inet_prefix addr;
103
104 if (!get_unsigned(val, arg, base))
105 return 0;
106
107 /* try coverting dotted quad to CIDR */
108 if (!get_addr_1(&addr, arg, AF_INET) && addr.family == AF_INET) {
109 int b = mask2bits(addr.data[0]);
110
111 if (b >= 0) {
112 *val = b;
113 return 0;
114 }
115 }
116
117 return -1;
118 }
119
120 int get_unsigned(unsigned int *val, const char *arg, int base)
121 {
122 unsigned long res;
123 char *ptr;
124
125 if (!arg || !*arg)
126 return -1;
127
128 res = strtoul(arg, &ptr, base);
129
130 /* empty string or trailing non-digits */
131 if (!ptr || ptr == arg || *ptr)
132 return -1;
133
134 /* overflow */
135 if (res == ULONG_MAX && errno == ERANGE)
136 return -1;
137
138 /* out side range of unsigned */
139 if (res > UINT_MAX)
140 return -1;
141
142 *val = res;
143 return 0;
144 }
145
146 /*
147 * get_time_rtt is "translated" from a similar routine "get_time" in
148 * tc_util.c. We don't use the exact same routine because tc passes
149 * microseconds to the kernel and the callers of get_time_rtt want to
150 * pass milliseconds (standard unit for rtt values since 2.6.27), and
151 * have a different assumption for the units of a "raw" number.
152 */
153 int get_time_rtt(unsigned int *val, const char *arg, int *raw)
154 {
155 double t;
156 unsigned long res;
157 char *p;
158
159 if (strchr(arg, '.') != NULL) {
160 t = strtod(arg, &p);
161 if (t < 0.0)
162 return -1;
163
164 /* no digits? */
165 if (!p || p == arg)
166 return -1;
167
168 /* over/underflow */
169 if ((t == HUGE_VALF || t == HUGE_VALL) && errno == ERANGE)
170 return -1;
171 } else {
172 res = strtoul(arg, &p, 0);
173
174 /* empty string? */
175 if (!p || p == arg)
176 return -1;
177
178 /* overflow */
179 if (res == ULONG_MAX && errno == ERANGE)
180 return -1;
181
182 t = (double)res;
183 }
184
185 if (p == arg)
186 return -1;
187 *raw = 1;
188
189 if (*p) {
190 *raw = 0;
191 if (strcasecmp(p, "s") == 0 ||
192 strcasecmp(p, "sec") == 0 ||
193 strcasecmp(p, "secs") == 0)
194 t *= 1000;
195 else if (strcasecmp(p, "ms") == 0 ||
196 strcasecmp(p, "msec") == 0 ||
197 strcasecmp(p, "msecs") == 0)
198 t *= 1.0; /* allow suffix, do nothing */
199 else
200 return -1;
201 }
202
203 /* emulate ceil() without having to bring-in -lm and always be >= 1 */
204 *val = t;
205 if (*val < t)
206 *val += 1;
207
208 return 0;
209
210 }
211
212 int get_u64(__u64 *val, const char *arg, int base)
213 {
214 unsigned long long res;
215 char *ptr;
216
217 if (!arg || !*arg)
218 return -1;
219
220 res = strtoull(arg, &ptr, base);
221
222 /* empty string or trailing non-digits */
223 if (!ptr || ptr == arg || *ptr)
224 return -1;
225
226 /* overflow */
227 if (res == ULLONG_MAX && errno == ERANGE)
228 return -1;
229
230 /* in case ULL is 128 bits */
231 if (res > 0xFFFFFFFFFFFFFFFFULL)
232 return -1;
233
234 *val = res;
235 return 0;
236 }
237
238 int get_u32(__u32 *val, const char *arg, int base)
239 {
240 unsigned long res;
241 char *ptr;
242
243 if (!arg || !*arg)
244 return -1;
245 res = strtoul(arg, &ptr, base);
246
247 /* empty string or trailing non-digits */
248 if (!ptr || ptr == arg || *ptr)
249 return -1;
250
251 /* overflow */
252 if (res == ULONG_MAX && errno == ERANGE)
253 return -1;
254
255 /* in case UL > 32 bits */
256 if (res > 0xFFFFFFFFUL)
257 return -1;
258
259 *val = res;
260 return 0;
261 }
262
263 int get_u16(__u16 *val, const char *arg, int base)
264 {
265 unsigned long res;
266 char *ptr;
267
268 if (!arg || !*arg)
269 return -1;
270 res = strtoul(arg, &ptr, base);
271
272 /* empty string or trailing non-digits */
273 if (!ptr || ptr == arg || *ptr)
274 return -1;
275
276 /* overflow */
277 if (res == ULONG_MAX && errno == ERANGE)
278 return -1;
279
280 if (res > 0xFFFFUL)
281 return -1;
282
283 *val = res;
284 return 0;
285 }
286
287 int get_u8(__u8 *val, const char *arg, int base)
288 {
289 unsigned long res;
290 char *ptr;
291
292 if (!arg || !*arg)
293 return -1;
294
295 res = strtoul(arg, &ptr, base);
296 /* empty string or trailing non-digits */
297 if (!ptr || ptr == arg || *ptr)
298 return -1;
299
300 /* overflow */
301 if (res == ULONG_MAX && errno == ERANGE)
302 return -1;
303
304 if (res > 0xFFUL)
305 return -1;
306
307 *val = res;
308 return 0;
309 }
310
311 int get_s32(__s32 *val, const char *arg, int base)
312 {
313 long res;
314 char *ptr;
315
316 errno = 0;
317
318 if (!arg || !*arg)
319 return -1;
320 res = strtol(arg, &ptr, base);
321 if (!ptr || ptr == arg || *ptr)
322 return -1;
323 if ((res == LONG_MIN || res == LONG_MAX) && errno == ERANGE)
324 return -1;
325 if (res > INT32_MAX || res < INT32_MIN)
326 return -1;
327
328 *val = res;
329 return 0;
330 }
331
332 int get_s16(__s16 *val, const char *arg, int base)
333 {
334 long res;
335 char *ptr;
336
337 if (!arg || !*arg)
338 return -1;
339 res = strtol(arg, &ptr, base);
340 if (!ptr || ptr == arg || *ptr)
341 return -1;
342 if ((res == LONG_MIN || res == LONG_MAX) && errno == ERANGE)
343 return -1;
344 if (res > 0x7FFF || res < -0x8000)
345 return -1;
346
347 *val = res;
348 return 0;
349 }
350
351 int get_s8(__s8 *val, const char *arg, int base)
352 {
353 long res;
354 char *ptr;
355
356 if (!arg || !*arg)
357 return -1;
358 res = strtol(arg, &ptr, base);
359 if (!ptr || ptr == arg || *ptr)
360 return -1;
361 if ((res == LONG_MIN || res == LONG_MAX) && errno == ERANGE)
362 return -1;
363 if (res > 0x7F || res < -0x80)
364 return -1;
365 *val = res;
366 return 0;
367 }
368
369 int get_be64(__be64 *val, const char *arg, int base)
370 {
371 __u64 v;
372 int ret = get_u64(&v, arg, base);
373
374 if (!ret)
375 *val = htonll(v);
376
377 return ret;
378 }
379
380 int get_be32(__be32 *val, const char *arg, int base)
381 {
382 __u32 v;
383 int ret = get_u32(&v, arg, base);
384
385 if (!ret)
386 *val = htonl(v);
387
388 return ret;
389 }
390
391 int get_be16(__be16 *val, const char *arg, int base)
392 {
393 __u16 v;
394 int ret = get_u16(&v, arg, base);
395
396 if (!ret)
397 *val = htons(v);
398
399 return ret;
400 }
401
402 /* This uses a non-standard parsing (ie not inet_aton, or inet_pton)
403 * because of legacy choice to parse 10.8 as 10.8.0.0 not 10.0.0.8
404 */
405 static int get_addr_ipv4(__u8 *ap, const char *cp)
406 {
407 int i;
408
409 for (i = 0; i < 4; i++) {
410 unsigned long n;
411 char *endp;
412
413 n = strtoul(cp, &endp, 0);
414 if (n > 255)
415 return -1; /* bogus network value */
416
417 if (endp == cp) /* no digits */
418 return -1;
419
420 ap[i] = n;
421
422 if (*endp == '\0')
423 break;
424
425 if (i == 3 || *endp != '.')
426 return -1; /* extra characters */
427 cp = endp + 1;
428 }
429
430 return 1;
431 }
432
433 int get_addr64(__u64 *ap, const char *cp)
434 {
435 int i;
436
437 union {
438 __u16 v16[4];
439 __u64 v64;
440 } val;
441
442 for (i = 0; i < 4; i++) {
443 unsigned long n;
444 char *endp;
445
446 n = strtoul(cp, &endp, 16);
447 if (n > 0xffff)
448 return -1; /* bogus network value */
449
450 if (endp == cp) /* no digits */
451 return -1;
452
453 val.v16[i] = htons(n);
454
455 if (*endp == '\0')
456 break;
457
458 if (i == 3 || *endp != ':')
459 return -1; /* extra characters */
460 cp = endp + 1;
461 }
462
463 *ap = val.v64;
464
465 return 1;
466 }
467
468 int get_addr_1(inet_prefix *addr, const char *name, int family)
469 {
470 memset(addr, 0, sizeof(*addr));
471
472 if (strcmp(name, "default") == 0 ||
473 strcmp(name, "all") == 0 ||
474 strcmp(name, "any") == 0) {
475 if ((family == AF_DECnet) || (family == AF_MPLS))
476 return -1;
477 addr->family = family;
478 addr->bytelen = (family == AF_INET6 ? 16 : 4);
479 addr->bitlen = -1;
480 return 0;
481 }
482
483 if (family == AF_PACKET) {
484 int len;
485
486 len = ll_addr_a2n((char *) &addr->data, sizeof(addr->data),
487 name);
488 if (len < 0)
489 return -1;
490
491 addr->family = AF_PACKET;
492 addr->bytelen = len;
493 addr->bitlen = len * 8;
494 return 0;
495 }
496
497 if (strchr(name, ':')) {
498 addr->family = AF_INET6;
499 if (family != AF_UNSPEC && family != AF_INET6)
500 return -1;
501 if (inet_pton(AF_INET6, name, addr->data) <= 0)
502 return -1;
503 addr->bytelen = 16;
504 addr->bitlen = -1;
505 return 0;
506 }
507
508 if (family == AF_DECnet) {
509 struct dn_naddr dna;
510
511 addr->family = AF_DECnet;
512 if (dnet_pton(AF_DECnet, name, &dna) <= 0)
513 return -1;
514 memcpy(addr->data, dna.a_addr, 2);
515 addr->bytelen = 2;
516 addr->bitlen = -1;
517 return 0;
518 }
519
520 if (family == AF_MPLS) {
521 int i;
522
523 addr->family = AF_MPLS;
524 if (mpls_pton(AF_MPLS, name, addr->data) <= 0)
525 return -1;
526 addr->bytelen = 4;
527 addr->bitlen = 20;
528 /* How many bytes do I need? */
529 for (i = 0; i < 8; i++) {
530 if (ntohl(addr->data[i]) & MPLS_LS_S_MASK) {
531 addr->bytelen = (i + 1)*4;
532 break;
533 }
534 }
535 return 0;
536 }
537
538 addr->family = AF_INET;
539 if (family != AF_UNSPEC && family != AF_INET)
540 return -1;
541
542 if (get_addr_ipv4((__u8 *)addr->data, name) <= 0)
543 return -1;
544
545 addr->bytelen = 4;
546 addr->bitlen = -1;
547 return 0;
548 }
549
550 int af_bit_len(int af)
551 {
552 switch (af) {
553 case AF_INET6:
554 return 128;
555 case AF_INET:
556 return 32;
557 case AF_DECnet:
558 return 16;
559 case AF_IPX:
560 return 80;
561 case AF_MPLS:
562 return 20;
563 }
564
565 return 0;
566 }
567
568 int af_byte_len(int af)
569 {
570 return af_bit_len(af) / 8;
571 }
572
573 int get_prefix_1(inet_prefix *dst, char *arg, int family)
574 {
575 int err;
576 unsigned int plen;
577 char *slash;
578
579 memset(dst, 0, sizeof(*dst));
580
581 if (strcmp(arg, "default") == 0 ||
582 strcmp(arg, "any") == 0 ||
583 strcmp(arg, "all") == 0) {
584 if ((family == AF_DECnet) || (family == AF_MPLS))
585 return -1;
586 dst->family = family;
587 dst->bytelen = 0;
588 dst->bitlen = 0;
589 return 0;
590 }
591
592 slash = strchr(arg, '/');
593 if (slash)
594 *slash = 0;
595
596 err = get_addr_1(dst, arg, family);
597 if (err == 0) {
598 dst->bitlen = af_bit_len(dst->family);
599
600 if (slash) {
601 if (get_netmask(&plen, slash+1, 0)
602 || plen > dst->bitlen) {
603 err = -1;
604 goto done;
605 }
606 dst->flags |= PREFIXLEN_SPECIFIED;
607 dst->bitlen = plen;
608 }
609 }
610 done:
611 if (slash)
612 *slash = '/';
613 return err;
614 }
615
616 int get_addr(inet_prefix *dst, const char *arg, int family)
617 {
618 if (get_addr_1(dst, arg, family)) {
619 fprintf(stderr,
620 "Error: %s address is expected rather than \"%s\".\n",
621 family_name(dst->family), arg);
622 exit(1);
623 }
624 return 0;
625 }
626
627 int get_prefix(inet_prefix *dst, char *arg, int family)
628 {
629 if (family == AF_PACKET) {
630 fprintf(stderr,
631 "Error: \"%s\" may be inet prefix, but it is not allowed in this context.\n",
632 arg);
633 exit(1);
634 }
635
636 if (get_prefix_1(dst, arg, family)) {
637 fprintf(stderr,
638 "Error: %s prefix is expected rather than \"%s\".\n",
639 family_name(dst->family), arg);
640 exit(1);
641 }
642 return 0;
643 }
644
645 __u32 get_addr32(const char *name)
646 {
647 inet_prefix addr;
648
649 if (get_addr_1(&addr, name, AF_INET)) {
650 fprintf(stderr,
651 "Error: an IP address is expected rather than \"%s\"\n",
652 name);
653 exit(1);
654 }
655 return addr.data[0];
656 }
657
658 void incomplete_command(void)
659 {
660 fprintf(stderr, "Command line is not complete. Try option \"help\"\n");
661 exit(-1);
662 }
663
664 void missarg(const char *key)
665 {
666 fprintf(stderr, "Error: argument \"%s\" is required\n", key);
667 exit(-1);
668 }
669
670 void invarg(const char *msg, const char *arg)
671 {
672 fprintf(stderr, "Error: argument \"%s\" is wrong: %s\n", arg, msg);
673 exit(-1);
674 }
675
676 void duparg(const char *key, const char *arg)
677 {
678 fprintf(stderr,
679 "Error: duplicate \"%s\": \"%s\" is the second value.\n",
680 key, arg);
681 exit(-1);
682 }
683
684 void duparg2(const char *key, const char *arg)
685 {
686 fprintf(stderr,
687 "Error: either \"%s\" is duplicate, or \"%s\" is a garbage.\n",
688 key, arg);
689 exit(-1);
690 }
691
692 int matches(const char *cmd, const char *pattern)
693 {
694 int len = strlen(cmd);
695
696 if (len > strlen(pattern))
697 return -1;
698 return memcmp(pattern, cmd, len);
699 }
700
701 int inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits)
702 {
703 const __u32 *a1 = a->data;
704 const __u32 *a2 = b->data;
705 int words = bits >> 0x05;
706
707 bits &= 0x1f;
708
709 if (words)
710 if (memcmp(a1, a2, words << 2))
711 return -1;
712
713 if (bits) {
714 __u32 w1, w2;
715 __u32 mask;
716
717 w1 = a1[words];
718 w2 = a2[words];
719
720 mask = htonl((0xffffffff) << (0x20 - bits));
721
722 if ((w1 ^ w2) & mask)
723 return 1;
724 }
725
726 return 0;
727 }
728
729 int __iproute2_hz_internal;
730
731 int __get_hz(void)
732 {
733 char name[1024];
734 int hz = 0;
735 FILE *fp;
736
737 if (getenv("HZ"))
738 return atoi(getenv("HZ")) ? : HZ;
739
740 if (getenv("PROC_NET_PSCHED"))
741 snprintf(name, sizeof(name)-1,
742 "%s", getenv("PROC_NET_PSCHED"));
743 else if (getenv("PROC_ROOT"))
744 snprintf(name, sizeof(name)-1,
745 "%s/net/psched", getenv("PROC_ROOT"));
746 else
747 strcpy(name, "/proc/net/psched");
748
749 fp = fopen(name, "r");
750
751 if (fp) {
752 unsigned int nom, denom;
753
754 if (fscanf(fp, "%*08x%*08x%08x%08x", &nom, &denom) == 2)
755 if (nom == 1000000)
756 hz = denom;
757 fclose(fp);
758 }
759 if (hz)
760 return hz;
761 return HZ;
762 }
763
764 int __iproute2_user_hz_internal;
765
766 int __get_user_hz(void)
767 {
768 return sysconf(_SC_CLK_TCK);
769 }
770
771 const char *rt_addr_n2a_r(int af, int len,
772 const void *addr, char *buf, int buflen)
773 {
774 switch (af) {
775 case AF_INET:
776 case AF_INET6:
777 return inet_ntop(af, addr, buf, buflen);
778 case AF_MPLS:
779 return mpls_ntop(af, addr, buf, buflen);
780 case AF_IPX:
781 return ipx_ntop(af, addr, buf, buflen);
782 case AF_DECnet:
783 {
784 struct dn_naddr dna = { 2, { 0, 0, } };
785
786 memcpy(dna.a_addr, addr, 2);
787 return dnet_ntop(af, &dna, buf, buflen);
788 }
789 case AF_PACKET:
790 return ll_addr_n2a(addr, len, ARPHRD_VOID, buf, buflen);
791 default:
792 return "???";
793 }
794 }
795
796 const char *rt_addr_n2a(int af, int len, const void *addr)
797 {
798 static char buf[256];
799
800 return rt_addr_n2a_r(af, len, addr, buf, 256);
801 }
802
803 int read_family(const char *name)
804 {
805 int family = AF_UNSPEC;
806
807 if (strcmp(name, "inet") == 0)
808 family = AF_INET;
809 else if (strcmp(name, "inet6") == 0)
810 family = AF_INET6;
811 else if (strcmp(name, "dnet") == 0)
812 family = AF_DECnet;
813 else if (strcmp(name, "link") == 0)
814 family = AF_PACKET;
815 else if (strcmp(name, "ipx") == 0)
816 family = AF_IPX;
817 else if (strcmp(name, "mpls") == 0)
818 family = AF_MPLS;
819 else if (strcmp(name, "bridge") == 0)
820 family = AF_BRIDGE;
821 return family;
822 }
823
824 const char *family_name(int family)
825 {
826 if (family == AF_INET)
827 return "inet";
828 if (family == AF_INET6)
829 return "inet6";
830 if (family == AF_DECnet)
831 return "dnet";
832 if (family == AF_PACKET)
833 return "link";
834 if (family == AF_IPX)
835 return "ipx";
836 if (family == AF_MPLS)
837 return "mpls";
838 if (family == AF_BRIDGE)
839 return "bridge";
840 return "???";
841 }
842
843 #ifdef RESOLVE_HOSTNAMES
844 struct namerec {
845 struct namerec *next;
846 const char *name;
847 inet_prefix addr;
848 };
849
850 #define NHASH 257
851 static struct namerec *nht[NHASH];
852
853 static const char *resolve_address(const void *addr, int len, int af)
854 {
855 struct namerec *n;
856 struct hostent *h_ent;
857 unsigned int hash;
858 static int notfirst;
859
860
861 if (af == AF_INET6 && ((__u32 *)addr)[0] == 0 &&
862 ((__u32 *)addr)[1] == 0 && ((__u32 *)addr)[2] == htonl(0xffff)) {
863 af = AF_INET;
864 addr += 12;
865 len = 4;
866 }
867
868 hash = *(__u32 *)(addr + len - 4) % NHASH;
869
870 for (n = nht[hash]; n; n = n->next) {
871 if (n->addr.family == af &&
872 n->addr.bytelen == len &&
873 memcmp(n->addr.data, addr, len) == 0)
874 return n->name;
875 }
876 n = malloc(sizeof(*n));
877 if (n == NULL)
878 return NULL;
879 n->addr.family = af;
880 n->addr.bytelen = len;
881 n->name = NULL;
882 memcpy(n->addr.data, addr, len);
883 n->next = nht[hash];
884 nht[hash] = n;
885 if (++notfirst == 1)
886 sethostent(1);
887 fflush(stdout);
888
889 h_ent = gethostbyaddr(addr, len, af);
890 if (h_ent != NULL)
891 n->name = strdup(h_ent->h_name);
892
893 /* Even if we fail, "negative" entry is remembered. */
894 return n->name;
895 }
896 #endif
897
898 const char *format_host_r(int af, int len, const void *addr,
899 char *buf, int buflen)
900 {
901 #ifdef RESOLVE_HOSTNAMES
902 if (resolve_hosts) {
903 const char *n;
904
905 len = len <= 0 ? af_byte_len(af) : len;
906
907 if (len > 0 &&
908 (n = resolve_address(addr, len, af)) != NULL)
909 return n;
910 }
911 #endif
912 return rt_addr_n2a_r(af, len, addr, buf, buflen);
913 }
914
915 const char *format_host(int af, int len, const void *addr)
916 {
917 static char buf[256];
918
919 return format_host_r(af, len, addr, buf, 256);
920 }
921
922
923 char *hexstring_n2a(const __u8 *str, int len, char *buf, int blen)
924 {
925 char *ptr = buf;
926 int i;
927
928 for (i = 0; i < len; i++) {
929 if (blen < 3)
930 break;
931 sprintf(ptr, "%02x", str[i]);
932 ptr += 2;
933 blen -= 2;
934 }
935 return buf;
936 }
937
938 __u8 *hexstring_a2n(const char *str, __u8 *buf, int blen, unsigned int *len)
939 {
940 unsigned int cnt = 0;
941 char *endptr;
942
943 if (strlen(str) % 2)
944 return NULL;
945 while (cnt < blen && strlen(str) > 1) {
946 unsigned int tmp;
947 char tmpstr[3];
948
949 strncpy(tmpstr, str, 2);
950 tmpstr[2] = '\0';
951 errno = 0;
952 tmp = strtoul(tmpstr, &endptr, 16);
953 if (errno != 0 || tmp > 0xFF || *endptr != '\0')
954 return NULL;
955 buf[cnt++] = tmp;
956 str += 2;
957 }
958
959 if (len)
960 *len = cnt;
961
962 return buf;
963 }
964
965 int addr64_n2a(__u64 addr, char *buff, size_t len)
966 {
967 __u16 *words = (__u16 *)&addr;
968 __u16 v;
969 int i, ret;
970 size_t written = 0;
971 char *sep = ":";
972
973 for (i = 0; i < 4; i++) {
974 v = ntohs(words[i]);
975
976 if (i == 3)
977 sep = "";
978
979 ret = snprintf(&buff[written], len - written, "%x%s", v, sep);
980 if (ret < 0)
981 return ret;
982
983 written += ret;
984 }
985
986 return written;
987 }
988
989 int print_timestamp(FILE *fp)
990 {
991 struct timeval tv;
992 struct tm *tm;
993
994 gettimeofday(&tv, NULL);
995 tm = localtime(&tv.tv_sec);
996
997 if (timestamp_short) {
998 char tshort[40];
999
1000 strftime(tshort, sizeof(tshort), "%Y-%m-%dT%H:%M:%S", tm);
1001 fprintf(fp, "[%s.%06ld] ", tshort, tv.tv_usec);
1002 } else {
1003 char *tstr = asctime(tm);
1004
1005 tstr[strlen(tstr)-1] = 0;
1006 fprintf(fp, "Timestamp: %s %ld usec\n",
1007 tstr, tv.tv_usec);
1008 }
1009
1010 return 0;
1011 }
1012
1013 int cmdlineno;
1014
1015 /* Like glibc getline but handle continuation lines and comments */
1016 ssize_t getcmdline(char **linep, size_t *lenp, FILE *in)
1017 {
1018 ssize_t cc;
1019 char *cp;
1020
1021 cc = getline(linep, lenp, in);
1022 if (cc < 0)
1023 return cc; /* eof or error */
1024 ++cmdlineno;
1025
1026 cp = strchr(*linep, '#');
1027 if (cp)
1028 *cp = '\0';
1029
1030 while ((cp = strstr(*linep, "\\\n")) != NULL) {
1031 char *line1 = NULL;
1032 size_t len1 = 0;
1033 ssize_t cc1;
1034
1035 cc1 = getline(&line1, &len1, in);
1036 if (cc1 < 0) {
1037 fprintf(stderr, "Missing continuation line\n");
1038 return cc1;
1039 }
1040
1041 ++cmdlineno;
1042 *cp = 0;
1043
1044 cp = strchr(line1, '#');
1045 if (cp)
1046 *cp = '\0';
1047
1048 *lenp = strlen(*linep) + strlen(line1) + 1;
1049 *linep = realloc(*linep, *lenp);
1050 if (!*linep) {
1051 fprintf(stderr, "Out of memory\n");
1052 *lenp = 0;
1053 return -1;
1054 }
1055 cc += cc1 - 2;
1056 strcat(*linep, line1);
1057 free(line1);
1058 }
1059 return cc;
1060 }
1061
1062 /* split command line into argument vector */
1063 int makeargs(char *line, char *argv[], int maxargs)
1064 {
1065 static const char ws[] = " \t\r\n";
1066 char *cp;
1067 int argc = 0;
1068
1069 for (cp = line + strspn(line, ws); *cp; cp += strspn(cp, ws)) {
1070 if (argc >= (maxargs - 1)) {
1071 fprintf(stderr, "Too many arguments to command\n");
1072 exit(1);
1073 }
1074
1075 /* word begins with quote */
1076 if (*cp == '\'' || *cp == '"') {
1077 char quote = *cp++;
1078
1079 argv[argc++] = cp;
1080 /* find ending quote */
1081 cp = strchr(cp, quote);
1082 if (cp == NULL) {
1083 fprintf(stderr, "Unterminated quoted string\n");
1084 exit(1);
1085 }
1086 *cp++ = 0;
1087 continue;
1088 }
1089
1090 argv[argc++] = cp;
1091 /* find end of word */
1092 cp += strcspn(cp, ws);
1093 *cp++ = 0;
1094 }
1095 argv[argc] = NULL;
1096
1097 return argc;
1098 }
1099
1100 int inet_get_addr(const char *src, __u32 *dst, struct in6_addr *dst6)
1101 {
1102 if (strchr(src, ':'))
1103 return inet_pton(AF_INET6, src, dst6);
1104 else
1105 return inet_pton(AF_INET, src, dst);
1106 }
1107
1108 void print_nlmsg_timestamp(FILE *fp, const struct nlmsghdr *n)
1109 {
1110 char *tstr;
1111 time_t secs = ((__u32 *)NLMSG_DATA(n))[0];
1112 long usecs = ((__u32 *)NLMSG_DATA(n))[1];
1113
1114 tstr = asctime(localtime(&secs));
1115 tstr[strlen(tstr)-1] = 0;
1116 fprintf(fp, "Timestamp: %s %lu us\n", tstr, usecs);
1117 }
1118
1119 static int on_netns(char *nsname, void *arg)
1120 {
1121 struct netns_func *f = arg;
1122
1123 if (netns_switch(nsname))
1124 return -1;
1125
1126 return f->func(nsname, f->arg);
1127 }
1128
1129 static int on_netns_label(char *nsname, void *arg)
1130 {
1131 printf("\nnetns: %s\n", nsname);
1132 return on_netns(nsname, arg);
1133 }
1134
1135 int do_each_netns(int (*func)(char *nsname, void *arg), void *arg,
1136 bool show_label)
1137 {
1138 struct netns_func nsf = { .func = func, .arg = arg };
1139
1140 if (show_label)
1141 return netns_foreach(on_netns_label, &nsf);
1142
1143 return netns_foreach(on_netns, &nsf);
1144 }
1145
1146 char *int_to_str(int val, char *buf)
1147 {
1148 sprintf(buf, "%d", val);
1149 return buf;
1150 }
1151
1152 int get_guid(__u64 *guid, const char *arg)
1153 {
1154 unsigned long int tmp;
1155 char *endptr;
1156 int i;
1157
1158 #define GUID_STR_LEN 23
1159 /* Verify strict format: format string must be
1160 * xx:xx:xx:xx:xx:xx:xx:xx where xx can be an arbitrary
1161 * hex digit
1162 */
1163
1164 if (strlen(arg) != GUID_STR_LEN)
1165 return -1;
1166
1167 /* make sure columns are in place */
1168 for (i = 0; i < 7; i++)
1169 if (arg[2 + i * 3] != ':')
1170 return -1;
1171
1172 *guid = 0;
1173 for (i = 0; i < 8; i++) {
1174 tmp = strtoul(arg + i * 3, &endptr, 16);
1175 if (endptr != arg + i * 3 + 2)
1176 return -1;
1177
1178 if (tmp > 255)
1179 return -1;
1180
1181 *guid |= tmp << (56 - 8 * i);
1182 }
1183
1184 return 0;
1185 }
1186
1187 /* This is a necessary workaround for multicast route dumps */
1188 int get_real_family(int rtm_type, int rtm_family)
1189 {
1190 if (rtm_type != RTN_MULTICAST)
1191 return rtm_family;
1192
1193 return rtm_family == RTNL_FAMILY_IPMR ? AF_INET : AF_INET6;
1194 }