1aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger/*
2aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * utils.c
3aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
4aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		This program is free software; you can redistribute it and/or
5aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		modify it under the terms of the GNU General Public License
6aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		as published by the Free Software Foundation; either version
7aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		2 of the License, or (at your option) any later version.
8aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
9aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
10aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
11aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger */
12aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
13aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdio.h>
14aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdlib.h>
15697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger#include <math.h>
16aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <unistd.h>
17aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <syslog.h>
18aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <fcntl.h>
195bd9dd49aecb66cae5e6d34197ab0487d946cc1dStrake#include <limits.h>
20aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/socket.h>
21aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <netinet/in.h>
22aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <string.h>
23625df645b703dc858d54784c35beff64464afae2Phil Sutter#include <ctype.h>
24aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <netdb.h>
25aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <arpa/inet.h>
265dfe556188df2a3b2bfe73c8bc3b3b9216171a93osdl.org!shemminger#include <asm/types.h>
27aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <linux/pkt_sched.h>
285bd9dd49aecb66cae5e6d34197ab0487d946cc1dStrake#include <linux/param.h>
290b218ab18dfad3e307f99aed2167a0c74f7ec67aEric W. Biederman#include <linux/if_arp.h>
30dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman#include <linux/mpls.h>
3190f93024a0818dc691138d8401721e797004b042shemminger#include <time.h>
3290f93024a0818dc691138d8401721e797004b042shemminger#include <sys/time.h>
3330d10db5667d3ca86917ca86c1a65cfcc45965f9Hagen Paul Pfeifer#include <errno.h>
3490f93024a0818dc691138d8401721e797004b042shemminger
350b218ab18dfad3e307f99aed2167a0c74f7ec67aEric W. Biederman#include "rt_names.h"
36aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "utils.h"
37e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan#include "namespace.h"
38aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
396648853975332e5f34d03a1e2a6e09f5e1742099Ivan Veceraint resolve_hosts;
40e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemmingerint timestamp_short;
4179aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan
42609640f5f0feda8099b04452297d81dd1a8a1777Sabrina Dubrocaint get_hex(char c)
43609640f5f0feda8099b04452297d81dd1a8a1777Sabrina Dubroca{
44609640f5f0feda8099b04452297d81dd1a8a1777Sabrina Dubroca	if (c >= 'A' && c <= 'F')
45609640f5f0feda8099b04452297d81dd1a8a1777Sabrina Dubroca		return c - 'A' + 10;
46609640f5f0feda8099b04452297d81dd1a8a1777Sabrina Dubroca	if (c >= 'a' && c <= 'f')
47609640f5f0feda8099b04452297d81dd1a8a1777Sabrina Dubroca		return c - 'a' + 10;
48609640f5f0feda8099b04452297d81dd1a8a1777Sabrina Dubroca	if (c >= '0' && c <= '9')
49609640f5f0feda8099b04452297d81dd1a8a1777Sabrina Dubroca		return c - '0';
50609640f5f0feda8099b04452297d81dd1a8a1777Sabrina Dubroca
51609640f5f0feda8099b04452297d81dd1a8a1777Sabrina Dubroca	return -1;
52609640f5f0feda8099b04452297d81dd1a8a1777Sabrina Dubroca}
53aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
544094db72b61dadd16e180eab5f62ccbc82e3976dosdl.org!shemmingerint get_integer(int *val, const char *arg, int base)
55aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
56aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	long res;
57aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char *ptr;
58aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
59aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (!arg || !*arg)
60aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
61697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
62aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	res = strtol(arg, &ptr, base);
63697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
64697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	/* If there were no digits at all, strtol()  stores
65e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	 * the original value of nptr in *endptr (and returns 0).
66697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	 * In particular, if *nptr is not '\0' but **endptr is '\0' on return,
67697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	 * the entire string is valid.
68697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	 */
69697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if (!ptr || ptr == arg || *ptr)
70697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger		return -1;
71697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
72697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	/* If an underflow occurs, strtol() returns LONG_MIN.
73697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	 * If an overflow occurs,  strtol() returns LONG_MAX.
74697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	 * In both cases, errno is set to ERANGE.
75697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	 */
76697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if ((res == LONG_MAX || res == LONG_MIN) && errno == ERANGE)
77aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
78697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
79697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	/* Outside range of int */
80697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if (res < INT_MIN || res > INT_MAX)
81aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
82697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
83aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	*val = res;
84aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
85aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
86aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
876b1ac654e9364ad279d3c82d8a3ef93efa9f3dfaStephen Hemmingerint mask2bits(__u32 netmask)
884b270b172a6e570f4e9fa1ebb4bc67b0e715ee48Stephen Hemminger{
89e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	unsigned int bits = 0;
906b1ac654e9364ad279d3c82d8a3ef93efa9f3dfaStephen Hemminger	__u32 mask = ntohl(netmask);
916b1ac654e9364ad279d3c82d8a3ef93efa9f3dfaStephen Hemminger	__u32 host = ~mask;
924b270b172a6e570f4e9fa1ebb4bc67b0e715ee48Stephen Hemminger
936b1ac654e9364ad279d3c82d8a3ef93efa9f3dfaStephen Hemminger	/* a valid netmask must be 2^n - 1 */
946b1ac654e9364ad279d3c82d8a3ef93efa9f3dfaStephen Hemminger	if ((host & (host + 1)) != 0)
956b1ac654e9364ad279d3c82d8a3ef93efa9f3dfaStephen Hemminger		return -1;
964b270b172a6e570f4e9fa1ebb4bc67b0e715ee48Stephen Hemminger
976b1ac654e9364ad279d3c82d8a3ef93efa9f3dfaStephen Hemminger	for (; mask; mask <<= 1)
986b1ac654e9364ad279d3c82d8a3ef93efa9f3dfaStephen Hemminger		++bits;
994b270b172a6e570f4e9fa1ebb4bc67b0e715ee48Stephen Hemminger	return bits;
1004b270b172a6e570f4e9fa1ebb4bc67b0e715ee48Stephen Hemminger}
1014b270b172a6e570f4e9fa1ebb4bc67b0e715ee48Stephen Hemminger
102e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemmingerstatic int get_netmask(unsigned int *val, const char *arg, int base)
1035a0d1cbf69269bfcb510a8b861b8a83aed0f6b85Andreas Henriksson{
1045a0d1cbf69269bfcb510a8b861b8a83aed0f6b85Andreas Henriksson	inet_prefix addr;
1055a0d1cbf69269bfcb510a8b861b8a83aed0f6b85Andreas Henriksson
1065a0d1cbf69269bfcb510a8b861b8a83aed0f6b85Andreas Henriksson	if (!get_unsigned(val, arg, base))
1075a0d1cbf69269bfcb510a8b861b8a83aed0f6b85Andreas Henriksson		return 0;
1085a0d1cbf69269bfcb510a8b861b8a83aed0f6b85Andreas Henriksson
1095a0d1cbf69269bfcb510a8b861b8a83aed0f6b85Andreas Henriksson	/* try coverting dotted quad to CIDR */
1106b1ac654e9364ad279d3c82d8a3ef93efa9f3dfaStephen Hemminger	if (!get_addr_1(&addr, arg, AF_INET) && addr.family == AF_INET) {
1116b1ac654e9364ad279d3c82d8a3ef93efa9f3dfaStephen Hemminger		int b = mask2bits(addr.data[0]);
112e9e9365b562ef5084bf21fb01e928c52c7078c93Stephen Hemminger
1136b1ac654e9364ad279d3c82d8a3ef93efa9f3dfaStephen Hemminger		if (b >= 0) {
1146b1ac654e9364ad279d3c82d8a3ef93efa9f3dfaStephen Hemminger			*val = b;
1155a0d1cbf69269bfcb510a8b861b8a83aed0f6b85Andreas Henriksson			return 0;
1166b1ac654e9364ad279d3c82d8a3ef93efa9f3dfaStephen Hemminger		}
1175a0d1cbf69269bfcb510a8b861b8a83aed0f6b85Andreas Henriksson	}
1185a0d1cbf69269bfcb510a8b861b8a83aed0f6b85Andreas Henriksson
1195a0d1cbf69269bfcb510a8b861b8a83aed0f6b85Andreas Henriksson	return -1;
1205a0d1cbf69269bfcb510a8b861b8a83aed0f6b85Andreas Henriksson}
1215a0d1cbf69269bfcb510a8b861b8a83aed0f6b85Andreas Henriksson
122e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemmingerint get_unsigned(unsigned int *val, const char *arg, int base)
123aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
124aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	unsigned long res;
125aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char *ptr;
126aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
127aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (!arg || !*arg)
128aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
129697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
130aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	res = strtoul(arg, &ptr, base);
131697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
132697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	/* empty string or trailing non-digits */
133697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if (!ptr || ptr == arg || *ptr)
134697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger		return -1;
135697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
136697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	/* overflow */
137697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if (res == ULONG_MAX && errno == ERANGE)
138aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
139697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
140697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	/* out side range of unsigned */
141697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if (res > UINT_MAX)
142697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger		return -1;
143697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
144aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	*val = res;
145aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
146aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
147aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
14854e0b2e71d723e3b493ff53d1332b48250f5d4bcRick Jones/*
149db6b0cfa518de3b27c05bdf3efe05a7f77c4d97dGerrit Renker * get_time_rtt is "translated" from a similar routine "get_time" in
150db6b0cfa518de3b27c05bdf3efe05a7f77c4d97dGerrit Renker * tc_util.c.  We don't use the exact same routine because tc passes
151db6b0cfa518de3b27c05bdf3efe05a7f77c4d97dGerrit Renker * microseconds to the kernel and the callers of get_time_rtt want to
152db6b0cfa518de3b27c05bdf3efe05a7f77c4d97dGerrit Renker * pass milliseconds (standard unit for rtt values since 2.6.27), and
153db6b0cfa518de3b27c05bdf3efe05a7f77c4d97dGerrit Renker * have a different assumption for the units of a "raw" number.
15454e0b2e71d723e3b493ff53d1332b48250f5d4bcRick Jones */
155e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemmingerint get_time_rtt(unsigned int *val, const char *arg, int *raw)
15654e0b2e71d723e3b493ff53d1332b48250f5d4bcRick Jones{
15754e0b2e71d723e3b493ff53d1332b48250f5d4bcRick Jones	double t;
15854e0b2e71d723e3b493ff53d1332b48250f5d4bcRick Jones	unsigned long res;
15954e0b2e71d723e3b493ff53d1332b48250f5d4bcRick Jones	char *p;
16054e0b2e71d723e3b493ff53d1332b48250f5d4bcRick Jones
161697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if (strchr(arg, '.') != NULL) {
162697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger		t = strtod(arg, &p);
16354e0b2e71d723e3b493ff53d1332b48250f5d4bcRick Jones		if (t < 0.0)
16454e0b2e71d723e3b493ff53d1332b48250f5d4bcRick Jones			return -1;
165697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
1664d9a264f09cd41fdf5896b03db8443fe1af32f14Florian Westphal		/* no digits? */
1674d9a264f09cd41fdf5896b03db8443fe1af32f14Florian Westphal		if (!p || p == arg)
168697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger			return -1;
169697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
170697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger		/* over/underflow */
171697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger		if ((t == HUGE_VALF || t == HUGE_VALL) && errno == ERANGE)
172697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger			return -1;
173697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	} else {
174897fb84fd9b872a544076f88430bc35fc12b7cc8Gerrit Renker		res = strtoul(arg, &p, 0);
175697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
1764d9a264f09cd41fdf5896b03db8443fe1af32f14Florian Westphal		/* empty string? */
1774d9a264f09cd41fdf5896b03db8443fe1af32f14Florian Westphal		if (!p || p == arg)
17854e0b2e71d723e3b493ff53d1332b48250f5d4bcRick Jones			return -1;
179697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
180697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger		/* overflow */
181697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger		if (res == ULONG_MAX && errno == ERANGE)
18254e0b2e71d723e3b493ff53d1332b48250f5d4bcRick Jones			return -1;
183697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
18454e0b2e71d723e3b493ff53d1332b48250f5d4bcRick Jones		t = (double)res;
18554e0b2e71d723e3b493ff53d1332b48250f5d4bcRick Jones	}
186697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
18754e0b2e71d723e3b493ff53d1332b48250f5d4bcRick Jones	if (p == arg)
18854e0b2e71d723e3b493ff53d1332b48250f5d4bcRick Jones		return -1;
18954e0b2e71d723e3b493ff53d1332b48250f5d4bcRick Jones	*raw = 1;
19054e0b2e71d723e3b493ff53d1332b48250f5d4bcRick Jones
19154e0b2e71d723e3b493ff53d1332b48250f5d4bcRick Jones	if (*p) {
19254e0b2e71d723e3b493ff53d1332b48250f5d4bcRick Jones		*raw = 0;
193e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		if (strcasecmp(p, "s") == 0 ||
194e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		    strcasecmp(p, "sec") == 0 ||
195e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		    strcasecmp(p, "secs") == 0)
196e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger			t *= 1000;
197e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		else if (strcasecmp(p, "ms") == 0 ||
198e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger			 strcasecmp(p, "msec") == 0 ||
199e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger			 strcasecmp(p, "msecs") == 0)
20054e0b2e71d723e3b493ff53d1332b48250f5d4bcRick Jones			t *= 1.0; /* allow suffix, do nothing */
201e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		else
202e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger			return -1;
203e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	}
20454e0b2e71d723e3b493ff53d1332b48250f5d4bcRick Jones
20554e0b2e71d723e3b493ff53d1332b48250f5d4bcRick Jones	/* emulate ceil() without having to bring-in -lm and always be >= 1 */
206db6b0cfa518de3b27c05bdf3efe05a7f77c4d97dGerrit Renker	*val = t;
207db6b0cfa518de3b27c05bdf3efe05a7f77c4d97dGerrit Renker	if (*val < t)
208db6b0cfa518de3b27c05bdf3efe05a7f77c4d97dGerrit Renker		*val += 1;
209e9e9365b562ef5084bf21fb01e928c52c7078c93Stephen Hemminger
210e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	return 0;
21154e0b2e71d723e3b493ff53d1332b48250f5d4bcRick Jones
21254e0b2e71d723e3b493ff53d1332b48250f5d4bcRick Jones}
21354e0b2e71d723e3b493ff53d1332b48250f5d4bcRick Jones
214c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerint get_u64(__u64 *val, const char *arg, int base)
215c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
216c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	unsigned long long res;
217c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	char *ptr;
218c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
219c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	if (!arg || !*arg)
220c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger		return -1;
221697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
222c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	res = strtoull(arg, &ptr, base);
223697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
224697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	/* empty string or trailing non-digits */
225697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if (!ptr || ptr == arg || *ptr)
226697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger		return -1;
227697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
228697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	/* overflow */
229697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if (res == ULLONG_MAX && errno == ERANGE)
230697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger		return -1;
231697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
232697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	/* in case ULL is 128 bits */
233697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if (res > 0xFFFFFFFFFFFFFFFFULL)
234697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger		return -1;
235697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
236e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	*val = res;
237e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	return 0;
238c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
239c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
2404094db72b61dadd16e180eab5f62ccbc82e3976dosdl.org!shemmingerint get_u32(__u32 *val, const char *arg, int base)
241aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
242aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	unsigned long res;
243aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char *ptr;
244aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
245aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (!arg || !*arg)
246aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
247aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	res = strtoul(arg, &ptr, base);
248697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
249697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	/* empty string or trailing non-digits */
250697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if (!ptr || ptr == arg || *ptr)
251697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger		return -1;
252697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
253697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	/* overflow */
254697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if (res == ULONG_MAX && errno == ERANGE)
255aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
256697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
257697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	/* in case UL > 32 bits */
258697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if (res > 0xFFFFFFFFUL)
259aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
260697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
261aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	*val = res;
262aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
263aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
264aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
2654094db72b61dadd16e180eab5f62ccbc82e3976dosdl.org!shemmingerint get_u16(__u16 *val, const char *arg, int base)
266aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
267aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	unsigned long res;
268aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char *ptr;
269aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
270aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (!arg || !*arg)
271aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
272aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	res = strtoul(arg, &ptr, base);
273697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
274697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	/* empty string or trailing non-digits */
275697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if (!ptr || ptr == arg || *ptr)
276697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger		return -1;
277697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
278697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	/* overflow */
279697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if (res == ULONG_MAX && errno == ERANGE)
280aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
281697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
282697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if (res > 0xFFFFUL)
283aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
284697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
285aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	*val = res;
286aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
287aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
288aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
2894094db72b61dadd16e180eab5f62ccbc82e3976dosdl.org!shemmingerint get_u8(__u8 *val, const char *arg, int base)
290aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
291aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	unsigned long res;
292aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char *ptr;
293aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
294aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (!arg || !*arg)
295aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
296697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
297aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	res = strtoul(arg, &ptr, base);
298697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	/* empty string or trailing non-digits */
299697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if (!ptr || ptr == arg || *ptr)
300697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger		return -1;
301697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
302697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	/* overflow */
303697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if (res == ULONG_MAX && errno == ERANGE)
304aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
305697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
306697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if (res > 0xFFUL)
307697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger		return -1;
308697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
309aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	*val = res;
310aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
311aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
312aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
31330d10db5667d3ca86917ca86c1a65cfcc45965f9Hagen Paul Pfeiferint get_s32(__s32 *val, const char *arg, int base)
31430d10db5667d3ca86917ca86c1a65cfcc45965f9Hagen Paul Pfeifer{
31530d10db5667d3ca86917ca86c1a65cfcc45965f9Hagen Paul Pfeifer	long res;
31630d10db5667d3ca86917ca86c1a65cfcc45965f9Hagen Paul Pfeifer	char *ptr;
31730d10db5667d3ca86917ca86c1a65cfcc45965f9Hagen Paul Pfeifer
31830d10db5667d3ca86917ca86c1a65cfcc45965f9Hagen Paul Pfeifer	errno = 0;
31930d10db5667d3ca86917ca86c1a65cfcc45965f9Hagen Paul Pfeifer
32030d10db5667d3ca86917ca86c1a65cfcc45965f9Hagen Paul Pfeifer	if (!arg || !*arg)
32130d10db5667d3ca86917ca86c1a65cfcc45965f9Hagen Paul Pfeifer		return -1;
32230d10db5667d3ca86917ca86c1a65cfcc45965f9Hagen Paul Pfeifer	res = strtol(arg, &ptr, base);
323697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if (!ptr || ptr == arg || *ptr)
324697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger		return -1;
325697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if ((res == LONG_MIN || res == LONG_MAX) && errno == ERANGE)
32630d10db5667d3ca86917ca86c1a65cfcc45965f9Hagen Paul Pfeifer		return -1;
327697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if (res > INT32_MAX || res < INT32_MIN)
328697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger		return -1;
329697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
33030d10db5667d3ca86917ca86c1a65cfcc45965f9Hagen Paul Pfeifer	*val = res;
33130d10db5667d3ca86917ca86c1a65cfcc45965f9Hagen Paul Pfeifer	return 0;
33230d10db5667d3ca86917ca86c1a65cfcc45965f9Hagen Paul Pfeifer}
33330d10db5667d3ca86917ca86c1a65cfcc45965f9Hagen Paul Pfeifer
3344094db72b61dadd16e180eab5f62ccbc82e3976dosdl.org!shemmingerint get_s16(__s16 *val, const char *arg, int base)
335aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
336aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	long res;
337aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char *ptr;
338aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
339aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (!arg || !*arg)
340aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
341aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	res = strtol(arg, &ptr, base);
342697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if (!ptr || ptr == arg || *ptr)
343697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger		return -1;
344697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if ((res == LONG_MIN || res == LONG_MAX) && errno == ERANGE)
345697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger		return -1;
346697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if (res > 0x7FFF || res < -0x8000)
347aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
348697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger
349aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	*val = res;
350aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
351aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
352aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
3534094db72b61dadd16e180eab5f62ccbc82e3976dosdl.org!shemmingerint get_s8(__s8 *val, const char *arg, int base)
354aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
355aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	long res;
356aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char *ptr;
357aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
358aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (!arg || !*arg)
359aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
360aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	res = strtol(arg, &ptr, base);
361697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if (!ptr || ptr == arg || *ptr)
362697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger		return -1;
363697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if ((res == LONG_MIN || res == LONG_MAX) && errno == ERANGE)
364697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger		return -1;
365697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger	if (res > 0x7F || res < -0x80)
366aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
367aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	*val = res;
368aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
369aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
370aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
3719f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubrocaint get_be64(__be64 *val, const char *arg, int base)
3729f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca{
3739f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca	__u64 v;
3749f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca	int ret = get_u64(&v, arg, base);
3759f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca
3769f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca	if (!ret)
3779f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca		*val = htonll(v);
3789f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca
3799f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca	return ret;
3809f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca}
3819f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca
3829f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubrocaint get_be32(__be32 *val, const char *arg, int base)
3839f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca{
3849f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca	__u32 v;
3859f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca	int ret = get_u32(&v, arg, base);
3869f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca
3879f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca	if (!ret)
3889f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca		*val = htonl(v);
3899f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca
3909f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca	return ret;
3919f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca}
3929f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca
3939f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubrocaint get_be16(__be16 *val, const char *arg, int base)
3949f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca{
3959f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca	__u16 v;
3969f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca	int ret = get_u16(&v, arg, base);
3979f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca
3989f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca	if (!ret)
3999f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca		*val = htons(v);
4009f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca
4019f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca	return ret;
4029f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca}
4039f7401fa4967178a071c53498f6bdc460c7cc4eaSabrina Dubroca
404cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger/* This uses a non-standard parsing (ie not inet_aton, or inet_pton)
405cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger * because of legacy choice to parse 10.8 as 10.8.0.0 not 10.0.0.8
406cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger */
407cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemmingerstatic int get_addr_ipv4(__u8 *ap, const char *cp)
408aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
409cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger	int i;
410cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger
411cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger	for (i = 0; i < 4; i++) {
412cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger		unsigned long n;
413cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger		char *endp;
414e9e9365b562ef5084bf21fb01e928c52c7078c93Stephen Hemminger
415cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger		n = strtoul(cp, &endp, 0);
416cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger		if (n > 255)
417cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger			return -1;	/* bogus network value */
418cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger
419cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger		if (endp == cp) /* no digits */
420cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger			return -1;
42194afda752956ddc6ff1accf931bc3d03c070bb18Stephen Hemminger
422cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger		ap[i] = n;
423cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger
424cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger		if (*endp == '\0')
425cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger			break;
426cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger
427cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger		if (i == 3 || *endp != '.')
428e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger			return -1;	/* extra characters */
429cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger		cp = endp + 1;
430cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger	}
431cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger
432cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger	return 1;
433cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger}
434cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger
4355866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbertint get_addr64(__u64 *ap, const char *cp)
4365866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert{
4375866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert	int i;
4385866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert
4395866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert	union {
4405866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert		__u16 v16[4];
4415866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert		__u64 v64;
4425866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert	} val;
4435866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert
4445866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert	for (i = 0; i < 4; i++) {
4455866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert		unsigned long n;
4465866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert		char *endp;
4475866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert
4485866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert		n = strtoul(cp, &endp, 16);
4495866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert		if (n > 0xffff)
4505866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert			return -1;	/* bogus network value */
4515866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert
4525866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert		if (endp == cp) /* no digits */
4535866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert			return -1;
4545866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert
4555866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert		val.v16[i] = htons(n);
4565866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert
4575866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert		if (*endp == '\0')
4585866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert			break;
4595866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert
4605866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert		if (i == 3 || *endp != ':')
4615866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert			return -1;	/* extra characters */
4625866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert		cp = endp + 1;
4635866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert	}
4645866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert
4655866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert	*ap = val.v64;
4665866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert
4675866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert	return 1;
4685866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert}
4695866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert
470cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemmingerint get_addr_1(inet_prefix *addr, const char *name, int family)
471cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger{
472aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	memset(addr, 0, sizeof(*addr));
473aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
474aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (strcmp(name, "default") == 0 ||
475aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    strcmp(name, "all") == 0 ||
476aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    strcmp(name, "any") == 0) {
477dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		if ((family == AF_DECnet) || (family == AF_MPLS))
478aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return -1;
479aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		addr->family = family;
480aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		addr->bytelen = (family == AF_INET6 ? 16 : 4);
481aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		addr->bitlen = -1;
482aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return 0;
483aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
484aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
4850b218ab18dfad3e307f99aed2167a0c74f7ec67aEric W. Biederman	if (family == AF_PACKET) {
4860b218ab18dfad3e307f99aed2167a0c74f7ec67aEric W. Biederman		int len;
487e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger
4888b59612f99f6e854a3f918c40b843d8df240d1e5David Ahern		len = ll_addr_a2n((char *) &addr->data, sizeof(addr->data),
4898b59612f99f6e854a3f918c40b843d8df240d1e5David Ahern				  name);
4900b218ab18dfad3e307f99aed2167a0c74f7ec67aEric W. Biederman		if (len < 0)
4910b218ab18dfad3e307f99aed2167a0c74f7ec67aEric W. Biederman			return -1;
4920b218ab18dfad3e307f99aed2167a0c74f7ec67aEric W. Biederman
4930b218ab18dfad3e307f99aed2167a0c74f7ec67aEric W. Biederman		addr->family = AF_PACKET;
4940b218ab18dfad3e307f99aed2167a0c74f7ec67aEric W. Biederman		addr->bytelen = len;
4950b218ab18dfad3e307f99aed2167a0c74f7ec67aEric W. Biederman		addr->bitlen = len * 8;
4960b218ab18dfad3e307f99aed2167a0c74f7ec67aEric W. Biederman		return 0;
4970b218ab18dfad3e307f99aed2167a0c74f7ec67aEric W. Biederman	}
4980b218ab18dfad3e307f99aed2167a0c74f7ec67aEric W. Biederman
499aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (strchr(name, ':')) {
500aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		addr->family = AF_INET6;
501aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (family != AF_UNSPEC && family != AF_INET6)
502aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return -1;
503aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (inet_pton(AF_INET6, name, addr->data) <= 0)
504aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return -1;
505aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		addr->bytelen = 16;
506aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		addr->bitlen = -1;
507aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return 0;
508aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
509aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
5106644900d2116a2a397bf0ed26ffd845ca2136b52San Mehat#ifndef ANDROID
511aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (family == AF_DECnet) {
512aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		struct dn_naddr dna;
513e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger
514aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		addr->family = AF_DECnet;
515aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (dnet_pton(AF_DECnet, name, &dna) <= 0)
516aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return -1;
517aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		memcpy(addr->data, dna.a_addr, 2);
518aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		addr->bytelen = 2;
519aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		addr->bitlen = -1;
520aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return 0;
521aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
5226644900d2116a2a397bf0ed26ffd845ca2136b52San Mehat#endif
523aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
524dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman	if (family == AF_MPLS) {
5254af4471606ccf2b0cb7f5d0711f9be25435d8efcDavid Ahern		unsigned int maxlabels;
526dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		int i;
527e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger
528dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		addr->family = AF_MPLS;
5294af4471606ccf2b0cb7f5d0711f9be25435d8efcDavid Ahern		if (mpls_pton(AF_MPLS, name, addr->data,
5304af4471606ccf2b0cb7f5d0711f9be25435d8efcDavid Ahern			      sizeof(addr->data)) <= 0)
531dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman			return -1;
532dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		addr->bytelen = 4;
533dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		addr->bitlen = 20;
534dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		/* How many bytes do I need? */
5354af4471606ccf2b0cb7f5d0711f9be25435d8efcDavid Ahern		maxlabels = sizeof(addr->data) / sizeof(struct mpls_label);
5364af4471606ccf2b0cb7f5d0711f9be25435d8efcDavid Ahern		for (i = 0; i < maxlabels; i++) {
537dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman			if (ntohl(addr->data[i]) & MPLS_LS_S_MASK) {
538dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman				addr->bytelen = (i + 1)*4;
539dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman				break;
540dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman			}
541dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		}
542dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		return 0;
543dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman	}
544dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman
545aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	addr->family = AF_INET;
546aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (family != AF_UNSPEC && family != AF_INET)
547aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
54894afda752956ddc6ff1accf931bc3d03c070bb18Stephen Hemminger
549cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger	if (get_addr_ipv4((__u8 *)addr->data, name) <= 0)
550516ffb6b7724e97ca035293dcfd9f94cf6ce3a47Stephen Hemminger		return -1;
55194afda752956ddc6ff1accf931bc3d03c070bb18Stephen Hemminger
552aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	addr->bytelen = 4;
553aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	addr->bitlen = -1;
554aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
555aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
556aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
557f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochanint af_bit_len(int af)
558f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan{
559f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan	switch (af) {
560f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan	case AF_INET6:
561f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan		return 128;
562f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan	case AF_INET:
563f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan		return 32;
564f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan	case AF_DECnet:
565f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan		return 16;
566f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan	case AF_IPX:
567f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan		return 80;
568dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman	case AF_MPLS:
569dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		return 20;
570f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan	}
571f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan
572f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan	return 0;
573f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan}
574f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan
575f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochanint af_byte_len(int af)
576f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan{
577f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan	return af_bit_len(af) / 8;
578f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan}
579f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan
580fb9b1d0f6a9f355bceae435ea43f1c8f3635b2dfosdl.net!shemmingerint get_prefix_1(inet_prefix *dst, char *arg, int family)
581aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
582aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int err;
583e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	unsigned int plen;
584aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char *slash;
585aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
586aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	memset(dst, 0, sizeof(*dst));
587aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
588aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (strcmp(arg, "default") == 0 ||
589aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    strcmp(arg, "any") == 0 ||
590aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    strcmp(arg, "all") == 0) {
591f7dd7e5e713d5820da2ad5cbd3fa88286e20d4f1Thomas Graf		if ((family == AF_DECnet) || (family == AF_MPLS))
592aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return -1;
593aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		dst->family = family;
594aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		dst->bytelen = 0;
595aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		dst->bitlen = 0;
596aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return 0;
597aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
598aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
599aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	slash = strchr(arg, '/');
600aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (slash)
601aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		*slash = 0;
602fb9b1d0f6a9f355bceae435ea43f1c8f3635b2dfosdl.net!shemminger
603aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	err = get_addr_1(dst, arg, family);
604aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (err == 0) {
605106ca2779ebc0d6a17ce7fae073aa38cdbdae6bbRoopa Prabhu		dst->bitlen = af_bit_len(dst->family);
606f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan
607aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (slash) {
6085a0d1cbf69269bfcb510a8b861b8a83aed0f6b85Andreas Henriksson			if (get_netmask(&plen, slash+1, 0)
609656111b2f9c5932350e697a1aaa70ba2d9b40bc7Stephen Hemminger			    || plen > dst->bitlen) {
610aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				err = -1;
611aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				goto done;
612aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
613f082b64fb40b467bc1f9e5d245114aae4e256d5cnet[shemminger]!shemminger			dst->flags |= PREFIXLEN_SPECIFIED;
614aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			dst->bitlen = plen;
615aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
616aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
617aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerdone:
618aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (slash)
619aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		*slash = '/';
620aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return err;
621aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
622aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
62334705c807a38909247d1bb29ccdffe42e5c1dab3Phil Sutterstatic const char *family_name_verbose(int family)
62434705c807a38909247d1bb29ccdffe42e5c1dab3Phil Sutter{
62534705c807a38909247d1bb29ccdffe42e5c1dab3Phil Sutter	if (family == AF_UNSPEC)
62634705c807a38909247d1bb29ccdffe42e5c1dab3Phil Sutter		return "any valid";
62734705c807a38909247d1bb29ccdffe42e5c1dab3Phil Sutter	return family_name(family);
62834705c807a38909247d1bb29ccdffe42e5c1dab3Phil Sutter}
62934705c807a38909247d1bb29ccdffe42e5c1dab3Phil Sutter
630c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerint get_addr(inet_prefix *dst, const char *arg, int family)
631aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
632aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (get_addr_1(dst, arg, family)) {
633e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		fprintf(stderr,
634e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger			"Error: %s address is expected rather than \"%s\".\n",
63534705c807a38909247d1bb29ccdffe42e5c1dab3Phil Sutter			family_name_verbose(family), arg);
636aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		exit(1);
637aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
638aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
639aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
640aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
641fb9b1d0f6a9f355bceae435ea43f1c8f3635b2dfosdl.net!shemmingerint get_prefix(inet_prefix *dst, char *arg, int family)
642aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
643aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (family == AF_PACKET) {
644e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		fprintf(stderr,
645e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger			"Error: \"%s\" may be inet prefix, but it is not allowed in this context.\n",
646e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger			arg);
647aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		exit(1);
648aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
649334af761433685d90790545eb705bfe03ae9d43dMarco Varlese
650aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (get_prefix_1(dst, arg, family)) {
651e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		fprintf(stderr,
652e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger			"Error: %s prefix is expected rather than \"%s\".\n",
65334705c807a38909247d1bb29ccdffe42e5c1dab3Phil Sutter			family_name_verbose(family), arg);
654aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		exit(1);
655aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
656aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
657aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
658aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
659c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger__u32 get_addr32(const char *name)
660aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
661aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	inet_prefix addr;
662e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger
663aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (get_addr_1(&addr, name, AF_INET)) {
664e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		fprintf(stderr,
665e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger			"Error: an IP address is expected rather than \"%s\"\n",
666e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger			name);
667aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		exit(1);
668aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
669aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return addr.data[0];
670aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
671aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
6724094db72b61dadd16e180eab5f62ccbc82e3976dosdl.org!shemmingervoid incomplete_command(void)
673aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
674aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "Command line is not complete. Try option \"help\"\n");
675aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	exit(-1);
676aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
677aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
678c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingervoid missarg(const char *key)
679c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
680c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	fprintf(stderr, "Error: argument \"%s\" is required\n", key);
681c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	exit(-1);
682c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
683c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
6844094db72b61dadd16e180eab5f62ccbc82e3976dosdl.org!shemmingervoid invarg(const char *msg, const char *arg)
685aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
686aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "Error: argument \"%s\" is wrong: %s\n", arg, msg);
687aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	exit(-1);
688aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
689aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
6904094db72b61dadd16e180eab5f62ccbc82e3976dosdl.org!shemmingervoid duparg(const char *key, const char *arg)
691aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
692e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	fprintf(stderr,
693e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		"Error: duplicate \"%s\": \"%s\" is the second value.\n",
694e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		key, arg);
695aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	exit(-1);
696aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
697aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
6984094db72b61dadd16e180eab5f62ccbc82e3976dosdl.org!shemmingervoid duparg2(const char *key, const char *arg)
699aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
700e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	fprintf(stderr,
701e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		"Error: either \"%s\" is duplicate, or \"%s\" is a garbage.\n",
702e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		key, arg);
703aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	exit(-1);
704aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
705aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
706625df645b703dc858d54784c35beff64464afae2Phil Sutterint check_ifname(const char *name)
707625df645b703dc858d54784c35beff64464afae2Phil Sutter{
708625df645b703dc858d54784c35beff64464afae2Phil Sutter	/* These checks mimic kernel checks in dev_valid_name */
709625df645b703dc858d54784c35beff64464afae2Phil Sutter	if (*name == '\0')
710625df645b703dc858d54784c35beff64464afae2Phil Sutter		return -1;
711625df645b703dc858d54784c35beff64464afae2Phil Sutter	if (strlen(name) >= IFNAMSIZ)
712625df645b703dc858d54784c35beff64464afae2Phil Sutter		return -1;
713625df645b703dc858d54784c35beff64464afae2Phil Sutter
714625df645b703dc858d54784c35beff64464afae2Phil Sutter	while (*name) {
715625df645b703dc858d54784c35beff64464afae2Phil Sutter		if (*name == '/' || isspace(*name))
716625df645b703dc858d54784c35beff64464afae2Phil Sutter			return -1;
717625df645b703dc858d54784c35beff64464afae2Phil Sutter		++name;
718625df645b703dc858d54784c35beff64464afae2Phil Sutter	}
719625df645b703dc858d54784c35beff64464afae2Phil Sutter	return 0;
720625df645b703dc858d54784c35beff64464afae2Phil Sutter}
721625df645b703dc858d54784c35beff64464afae2Phil Sutter
722625df645b703dc858d54784c35beff64464afae2Phil Sutter/* buf is assumed to be IFNAMSIZ */
723625df645b703dc858d54784c35beff64464afae2Phil Sutterint get_ifname(char *buf, const char *name)
724625df645b703dc858d54784c35beff64464afae2Phil Sutter{
725625df645b703dc858d54784c35beff64464afae2Phil Sutter	int ret;
726625df645b703dc858d54784c35beff64464afae2Phil Sutter
727625df645b703dc858d54784c35beff64464afae2Phil Sutter	ret = check_ifname(name);
728625df645b703dc858d54784c35beff64464afae2Phil Sutter	if (ret == 0)
729625df645b703dc858d54784c35beff64464afae2Phil Sutter		strncpy(buf, name, IFNAMSIZ);
730625df645b703dc858d54784c35beff64464afae2Phil Sutter
731625df645b703dc858d54784c35beff64464afae2Phil Sutter	return ret;
732625df645b703dc858d54784c35beff64464afae2Phil Sutter}
733625df645b703dc858d54784c35beff64464afae2Phil Sutter
7344094db72b61dadd16e180eab5f62ccbc82e3976dosdl.org!shemmingerint matches(const char *cmd, const char *pattern)
735aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
736aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int len = strlen(cmd);
737e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger
738aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (len > strlen(pattern))
739aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
740aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return memcmp(pattern, cmd, len);
741aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
742aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
7434094db72b61dadd16e180eab5f62ccbc82e3976dosdl.org!shemmingerint inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits)
744aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
7459626dfd54c3cc4deec1c651a0bfee65b50feb78bStephen Hemminger	const __u32 *a1 = a->data;
7469626dfd54c3cc4deec1c651a0bfee65b50feb78bStephen Hemminger	const __u32 *a2 = b->data;
747aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int words = bits >> 0x05;
748aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
749aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	bits &= 0x1f;
750aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
751aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (words)
752aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (memcmp(a1, a2, words << 2))
753aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return -1;
754aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
755aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (bits) {
756aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		__u32 w1, w2;
757aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		__u32 mask;
758aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
759aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		w1 = a1[words];
760aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		w2 = a2[words];
761aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
762aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		mask = htonl((0xffffffff) << (0x20 - bits));
763aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
764aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if ((w1 ^ w2) & mask)
765aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return 1;
766aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
767aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
768aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
769aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
770aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
771aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint __iproute2_hz_internal;
772aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
773aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint __get_hz(void)
774aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
775aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char name[1024];
776aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int hz = 0;
777aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	FILE *fp;
778aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
779aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (getenv("HZ"))
780aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return atoi(getenv("HZ")) ? : HZ;
781aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
782e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	if (getenv("PROC_NET_PSCHED"))
783e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		snprintf(name, sizeof(name)-1,
784e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger			 "%s", getenv("PROC_NET_PSCHED"));
785e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	else if (getenv("PROC_ROOT"))
786e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		snprintf(name, sizeof(name)-1,
787e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger			 "%s/net/psched", getenv("PROC_ROOT"));
788e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	else
789aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		strcpy(name, "/proc/net/psched");
790e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger
791aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fp = fopen(name, "r");
792aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
793aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (fp) {
794e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		unsigned int nom, denom;
795e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger
796aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (fscanf(fp, "%*08x%*08x%08x%08x", &nom, &denom) == 2)
797aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (nom == 1000000)
798aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				hz = denom;
799aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fclose(fp);
800aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
801aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (hz)
802aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return hz;
803aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return HZ;
804aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
805aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
8065e8bc6316b1a6c56598cdb29a737d1d670d74e69net[shemminger]!shemmingerint __iproute2_user_hz_internal;
8075e8bc6316b1a6c56598cdb29a737d1d670d74e69net[shemminger]!shemminger
8085e8bc6316b1a6c56598cdb29a737d1d670d74e69net[shemminger]!shemmingerint __get_user_hz(void)
8095e8bc6316b1a6c56598cdb29a737d1d670d74e69net[shemminger]!shemminger{
8105e8bc6316b1a6c56598cdb29a737d1d670d74e69net[shemminger]!shemminger	return sysconf(_SC_CLK_TCK);
8115e8bc6316b1a6c56598cdb29a737d1d670d74e69net[shemminger]!shemminger}
8125e8bc6316b1a6c56598cdb29a737d1d670d74e69net[shemminger]!shemminger
813e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemmingerconst char *rt_addr_n2a_r(int af, int len,
814e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger			  const void *addr, char *buf, int buflen)
815aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
816aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	switch (af) {
817aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	case AF_INET:
818aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	case AF_INET6:
819aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return inet_ntop(af, addr, buf, buflen);
8206644900d2116a2a397bf0ed26ffd845ca2136b52San Mehat#ifndef ANDROID
821dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman	case AF_MPLS:
822dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		return mpls_ntop(af, addr, buf, buflen);
823aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	case AF_IPX:
824aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return ipx_ntop(af, addr, buf, buflen);
825aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	case AF_DECnet:
826aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	{
827e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		struct dn_naddr dna = { 2, { 0, 0, } };
828e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger
829aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		memcpy(dna.a_addr, addr, 2);
830aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return dnet_ntop(af, &dna, buf, buflen);
831aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
8326644900d2116a2a397bf0ed26ffd845ca2136b52San Mehat#endif
8330b218ab18dfad3e307f99aed2167a0c74f7ec67aEric W. Biederman	case AF_PACKET:
8340b218ab18dfad3e307f99aed2167a0c74f7ec67aEric W. Biederman		return ll_addr_n2a(addr, len, ARPHRD_VOID, buf, buflen);
835aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	default:
836aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return "???";
837aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
838aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
839aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
8402e96d2ccd03a29896fc8a2c6ee6b769c512501dfPhil Sutterconst char *rt_addr_n2a(int af, int len, const void *addr)
8412e96d2ccd03a29896fc8a2c6ee6b769c512501dfPhil Sutter{
8422e96d2ccd03a29896fc8a2c6ee6b769c512501dfPhil Sutter	static char buf[256];
8432e96d2ccd03a29896fc8a2c6ee6b769c512501dfPhil Sutter
8442e96d2ccd03a29896fc8a2c6ee6b769c512501dfPhil Sutter	return rt_addr_n2a_r(af, len, addr, buf, 256);
8452e96d2ccd03a29896fc8a2c6ee6b769c512501dfPhil Sutter}
8462e96d2ccd03a29896fc8a2c6ee6b769c512501dfPhil Sutter
84745c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biedermanint read_family(const char *name)
84845c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman{
84945c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	int family = AF_UNSPEC;
850e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger
85145c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	if (strcmp(name, "inet") == 0)
85245c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman		family = AF_INET;
85345c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	else if (strcmp(name, "inet6") == 0)
85445c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman		family = AF_INET6;
85545c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	else if (strcmp(name, "dnet") == 0)
85645c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman		family = AF_DECnet;
85745c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	else if (strcmp(name, "link") == 0)
85845c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman		family = AF_PACKET;
85945c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	else if (strcmp(name, "ipx") == 0)
86045c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman		family = AF_IPX;
861dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman	else if (strcmp(name, "mpls") == 0)
862dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		family = AF_MPLS;
86345c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	else if (strcmp(name, "bridge") == 0)
86445c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman		family = AF_BRIDGE;
86545c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	return family;
86645c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman}
86745c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman
86845c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biedermanconst char *family_name(int family)
86945c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman{
87045c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	if (family == AF_INET)
87145c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman		return "inet";
87245c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	if (family == AF_INET6)
87345c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman		return "inet6";
87445c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	if (family == AF_DECnet)
87545c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman		return "dnet";
87645c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	if (family == AF_PACKET)
87745c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman		return "link";
87845c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	if (family == AF_IPX)
87945c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman		return "ipx";
880dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman	if (family == AF_MPLS)
881dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		return "mpls";
88245c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	if (family == AF_BRIDGE)
88345c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman		return "bridge";
88445c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	return "???";
88545c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman}
88645c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman
887aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#ifdef RESOLVE_HOSTNAMES
888e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemmingerstruct namerec {
889aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct namerec *next;
8907dec1bf88bc34e2d0b320f0c23bd1a060c73852bStephen Hemminger	const char *name;
891aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	inet_prefix addr;
892aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger};
893aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
8947dec1bf88bc34e2d0b320f0c23bd1a060c73852bStephen Hemminger#define NHASH 257
8957dec1bf88bc34e2d0b320f0c23bd1a060c73852bStephen Hemmingerstatic struct namerec *nht[NHASH];
896aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
8977dec1bf88bc34e2d0b320f0c23bd1a060c73852bStephen Hemmingerstatic const char *resolve_address(const void *addr, int len, int af)
898aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
899aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct namerec *n;
900aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct hostent *h_ent;
901e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	unsigned int hash;
902aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	static int notfirst;
903aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
904aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
905e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	if (af == AF_INET6 && ((__u32 *)addr)[0] == 0 &&
906e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	    ((__u32 *)addr)[1] == 0 && ((__u32 *)addr)[2] == htonl(0xffff)) {
907aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		af = AF_INET;
908aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		addr += 12;
909aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		len = 4;
910aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
911aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
9127dec1bf88bc34e2d0b320f0c23bd1a060c73852bStephen Hemminger	hash = *(__u32 *)(addr + len - 4) % NHASH;
913aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
914aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	for (n = nht[hash]; n; n = n->next) {
915aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (n->addr.family == af &&
916aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		    n->addr.bytelen == len &&
917aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		    memcmp(n->addr.data, addr, len) == 0)
918aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return n->name;
919aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
920e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	n = malloc(sizeof(*n));
921e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	if (n == NULL)
922aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return NULL;
923aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	n->addr.family = af;
924aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	n->addr.bytelen = len;
925aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	n->name = NULL;
926aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	memcpy(n->addr.data, addr, len);
927aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	n->next = nht[hash];
928aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	nht[hash] = n;
929aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (++notfirst == 1)
930aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		sethostent(1);
931aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fflush(stdout);
932aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
933e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	h_ent = gethostbyaddr(addr, len, af);
934e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	if (h_ent != NULL)
935aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		n->name = strdup(h_ent->h_name);
936aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
937aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	/* Even if we fail, "negative" entry is remembered. */
938aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return n->name;
939aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
940aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#endif
941aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
942a418e451643e77fe36861e53359587ba8aa41873Phil Sutterconst char *format_host_r(int af, int len, const void *addr,
9434094db72b61dadd16e180eab5f62ccbc82e3976dosdl.org!shemminger			char *buf, int buflen)
944aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
945aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#ifdef RESOLVE_HOSTNAMES
946aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (resolve_hosts) {
9477dec1bf88bc34e2d0b320f0c23bd1a060c73852bStephen Hemminger		const char *n;
9487dec1bf88bc34e2d0b320f0c23bd1a060c73852bStephen Hemminger
949f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan		len = len <= 0 ? af_byte_len(af) : len;
950f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan
951aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (len > 0 &&
952aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		    (n = resolve_address(addr, len, af)) != NULL)
953aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return n;
954aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
955aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#endif
9562e96d2ccd03a29896fc8a2c6ee6b769c512501dfPhil Sutter	return rt_addr_n2a_r(af, len, addr, buf, buflen);
957aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
958aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
959a418e451643e77fe36861e53359587ba8aa41873Phil Sutterconst char *format_host(int af, int len, const void *addr)
960a418e451643e77fe36861e53359587ba8aa41873Phil Sutter{
961a418e451643e77fe36861e53359587ba8aa41873Phil Sutter	static char buf[256];
962a418e451643e77fe36861e53359587ba8aa41873Phil Sutter
963a418e451643e77fe36861e53359587ba8aa41873Phil Sutter	return format_host_r(af, len, addr, buf, 256);
964aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
965aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
966aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
967f332d169246447bd5e258ac03d5ee840a70adb1eshemmingerchar *hexstring_n2a(const __u8 *str, int len, char *buf, int blen)
968aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
969f332d169246447bd5e258ac03d5ee840a70adb1eshemminger	char *ptr = buf;
970aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int i;
971aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
972e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	for (i = 0; i < len; i++) {
973aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (blen < 3)
974aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			break;
975aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		sprintf(ptr, "%02x", str[i]);
976aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		ptr += 2;
977aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		blen -= 2;
978aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
979aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return buf;
980aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
981aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
98289ae502056f58a0177b9970f1f79a9683ac7fdd0Sabrina Dubroca__u8 *hexstring_a2n(const char *str, __u8 *buf, int blen, unsigned int *len)
983aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
98489ae502056f58a0177b9970f1f79a9683ac7fdd0Sabrina Dubroca	unsigned int cnt = 0;
985316c2346f7f3e337be9a56e7ad5fc8e04cd26d63Jiri Pirko	char *endptr;
986aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
987316c2346f7f3e337be9a56e7ad5fc8e04cd26d63Jiri Pirko	if (strlen(str) % 2)
988316c2346f7f3e337be9a56e7ad5fc8e04cd26d63Jiri Pirko		return NULL;
989316c2346f7f3e337be9a56e7ad5fc8e04cd26d63Jiri Pirko	while (cnt < blen && strlen(str) > 1) {
990316c2346f7f3e337be9a56e7ad5fc8e04cd26d63Jiri Pirko		unsigned int tmp;
991316c2346f7f3e337be9a56e7ad5fc8e04cd26d63Jiri Pirko		char tmpstr[3];
992316c2346f7f3e337be9a56e7ad5fc8e04cd26d63Jiri Pirko
993316c2346f7f3e337be9a56e7ad5fc8e04cd26d63Jiri Pirko		strncpy(tmpstr, str, 2);
994316c2346f7f3e337be9a56e7ad5fc8e04cd26d63Jiri Pirko		tmpstr[2] = '\0';
9959ba4126dc4d6abb8dc5c8c8d52177849e764a14eBeniamino Galvani		errno = 0;
996316c2346f7f3e337be9a56e7ad5fc8e04cd26d63Jiri Pirko		tmp = strtoul(tmpstr, &endptr, 16);
997316c2346f7f3e337be9a56e7ad5fc8e04cd26d63Jiri Pirko		if (errno != 0 || tmp > 0xFF || *endptr != '\0')
998aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return NULL;
999316c2346f7f3e337be9a56e7ad5fc8e04cd26d63Jiri Pirko		buf[cnt++] = tmp;
1000316c2346f7f3e337be9a56e7ad5fc8e04cd26d63Jiri Pirko		str += 2;
1001aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
100289ae502056f58a0177b9970f1f79a9683ac7fdd0Sabrina Dubroca
100389ae502056f58a0177b9970f1f79a9683ac7fdd0Sabrina Dubroca	if (len)
100489ae502056f58a0177b9970f1f79a9683ac7fdd0Sabrina Dubroca		*len = cnt;
100589ae502056f58a0177b9970f1f79a9683ac7fdd0Sabrina Dubroca
1006aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return buf;
1007aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
100890f93024a0818dc691138d8401721e797004b042shemminger
10091c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salimint hex2mem(const char *buf, uint8_t *mem, int count)
10101c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim{
10111c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim	int i, j;
10121c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim	int c;
10131c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim
10141c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim	for (i = 0, j = 0; i < count; i++, j += 2) {
10151c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim		c = get_hex(buf[j]);
10161c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim		if (c < 0)
10172bf1a81a2f0cd9d1e0f7aea93ea49185e7fb5ddfStephen Hemminger			return -1;
10181c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim
10191c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim		mem[i] = c << 4;
10201c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim
10211c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim		c = get_hex(buf[j + 1]);
10221c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim		if (c < 0)
10232bf1a81a2f0cd9d1e0f7aea93ea49185e7fb5ddfStephen Hemminger			return -1;
10241c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim
10251c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim		mem[i] |= c;
10261c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim	}
10271c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim
10281c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim	return 0;
10291c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim}
10301c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim
10315866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbertint addr64_n2a(__u64 addr, char *buff, size_t len)
10325866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert{
10335866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert	__u16 *words = (__u16 *)&addr;
10345866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert	__u16 v;
10355866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert	int i, ret;
10365866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert	size_t written = 0;
10375866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert	char *sep = ":";
10385866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert
10395866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert	for (i = 0; i < 4; i++) {
10405866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert		v = ntohs(words[i]);
10415866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert
10425866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert		if (i == 3)
10435866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert			sep = "";
10445866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert
10455866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert		ret = snprintf(&buff[written], len - written, "%x%s", v, sep);
10465866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert		if (ret < 0)
10475866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert			return ret;
10485866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert
10495866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert		written += ret;
10505866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert	}
10515866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert
10525866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert	return written;
10535866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert}
10545866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert
10557c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande/* Print buffer and escape bytes that are !isprint or among 'escape' */
10567c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalandevoid print_escape_buf(const __u8 *buf, size_t len, const char *escape)
10577c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande{
10587c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande	size_t i;
10597c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande
10607c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande	for (i = 0; i < len; ++i) {
10617c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande		if (isprint(buf[i]) && buf[i] != '\\' &&
10627c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande		    !strchr(escape, buf[i]))
10637c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande			printf("%c", buf[i]);
10647c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande		else
10657c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande			printf("\\%03o", buf[i]);
10667c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande	}
10677c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande}
10687c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande
106990f93024a0818dc691138d8401721e797004b042shemmingerint print_timestamp(FILE *fp)
107090f93024a0818dc691138d8401721e797004b042shemminger{
107190f93024a0818dc691138d8401721e797004b042shemminger	struct timeval tv;
107279aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan	struct tm *tm;
107390f93024a0818dc691138d8401721e797004b042shemminger
107490f93024a0818dc691138d8401721e797004b042shemminger	gettimeofday(&tv, NULL);
107579aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan	tm = localtime(&tv.tv_sec);
107679aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan
107779aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan	if (timestamp_short) {
107879aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan		char tshort[40];
107979aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan
108079aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan		strftime(tshort, sizeof(tshort), "%Y-%m-%dT%H:%M:%S", tm);
108179aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan		fprintf(fp, "[%s.%06ld] ", tshort, tv.tv_usec);
108279aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan	} else {
108379aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan		char *tstr = asctime(tm);
108479aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan
108579aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan		tstr[strlen(tstr)-1] = 0;
108679aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan		fprintf(fp, "Timestamp: %s %ld usec\n",
108779aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan			tstr, tv.tv_usec);
108879aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan	}
108990f93024a0818dc691138d8401721e797004b042shemminger
109090f93024a0818dc691138d8401721e797004b042shemminger	return 0;
109190f93024a0818dc691138d8401721e797004b042shemminger}
1092351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger
1093351efcde4e62967362a10b29f3b701cfecd7cdfcshemmingerint cmdlineno;
1094351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger
1095351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger/* Like glibc getline but handle continuation lines and comments */
1096d21e88354b2a42b026384730a767f2108bcf8efeAndreas Henrikssonssize_t getcmdline(char **linep, size_t *lenp, FILE *in)
1097351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger{
1098d21e88354b2a42b026384730a767f2108bcf8efeAndreas Henriksson	ssize_t cc;
1099351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	char *cp;
1100ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger
1101e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	cc = getline(linep, lenp, in);
1102e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	if (cc < 0)
1103351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		return cc;	/* eof or error */
1104351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	++cmdlineno;
1105351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger
1106351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	cp = strchr(*linep, '#');
1107ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger	if (cp)
1108351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		*cp = '\0';
1109ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger
1110351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	while ((cp = strstr(*linep, "\\\n")) != NULL) {
1111351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		char *line1 = NULL;
1112351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		size_t len1 = 0;
111321a85d3becf45e02985c466764ae19433d907c40Stephen Hemminger		ssize_t cc1;
1114351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger
1115e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		cc1 = getline(&line1, &len1, in);
1116e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		if (cc1 < 0) {
1117351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger			fprintf(stderr, "Missing continuation line\n");
1118351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger			return cc1;
1119351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		}
1120351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger
1121351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		++cmdlineno;
1122351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		*cp = 0;
1123351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger
1124351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		cp = strchr(line1, '#');
1125ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger		if (cp)
1126351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger			*cp = '\0';
1127351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger
1128d21e88354b2a42b026384730a767f2108bcf8efeAndreas Henriksson		*lenp = strlen(*linep) + strlen(line1) + 1;
1129d21e88354b2a42b026384730a767f2108bcf8efeAndreas Henriksson		*linep = realloc(*linep, *lenp);
1130351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		if (!*linep) {
1131351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger			fprintf(stderr, "Out of memory\n");
1132d21e88354b2a42b026384730a767f2108bcf8efeAndreas Henriksson			*lenp = 0;
1133351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger			return -1;
1134351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		}
1135351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		cc += cc1 - 2;
1136351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		strcat(*linep, line1);
1137351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		free(line1);
1138351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	}
1139351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	return cc;
1140351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger}
1141351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger
1142351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger/* split command line into argument vector */
1143351efcde4e62967362a10b29f3b701cfecd7cdfcshemmingerint makeargs(char *line, char *argv[], int maxargs)
1144351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger{
1145351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	static const char ws[] = " \t\r\n";
1146351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	char *cp;
1147351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	int argc = 0;
1148351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger
114939e3d3836c1384506d0a76a496133c5361940770Christophe Gouault	for (cp = line + strspn(line, ws); *cp; cp += strspn(cp, ws)) {
1150351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		if (argc >= (maxargs - 1)) {
1151351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger			fprintf(stderr, "Too many arguments to command\n");
1152351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger			exit(1);
1153351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		}
115439e3d3836c1384506d0a76a496133c5361940770Christophe Gouault
115539e3d3836c1384506d0a76a496133c5361940770Christophe Gouault		/* word begins with quote */
115639e3d3836c1384506d0a76a496133c5361940770Christophe Gouault		if (*cp == '\'' || *cp == '"') {
115739e3d3836c1384506d0a76a496133c5361940770Christophe Gouault			char quote = *cp++;
115839e3d3836c1384506d0a76a496133c5361940770Christophe Gouault
115939e3d3836c1384506d0a76a496133c5361940770Christophe Gouault			argv[argc++] = cp;
116039e3d3836c1384506d0a76a496133c5361940770Christophe Gouault			/* find ending quote */
116139e3d3836c1384506d0a76a496133c5361940770Christophe Gouault			cp = strchr(cp, quote);
116239e3d3836c1384506d0a76a496133c5361940770Christophe Gouault			if (cp == NULL) {
116339e3d3836c1384506d0a76a496133c5361940770Christophe Gouault				fprintf(stderr, "Unterminated quoted string\n");
116439e3d3836c1384506d0a76a496133c5361940770Christophe Gouault				exit(1);
116539e3d3836c1384506d0a76a496133c5361940770Christophe Gouault			}
116639e3d3836c1384506d0a76a496133c5361940770Christophe Gouault			*cp++ = 0;
116739e3d3836c1384506d0a76a496133c5361940770Christophe Gouault			continue;
116839e3d3836c1384506d0a76a496133c5361940770Christophe Gouault		}
116939e3d3836c1384506d0a76a496133c5361940770Christophe Gouault
1170351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		argv[argc++] = cp;
117139e3d3836c1384506d0a76a496133c5361940770Christophe Gouault		/* find end of word */
117239e3d3836c1384506d0a76a496133c5361940770Christophe Gouault		cp += strcspn(cp, ws);
117339e3d3836c1384506d0a76a496133c5361940770Christophe Gouault		*cp++ = 0;
1174351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	}
1175351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	argv[argc] = NULL;
1176351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger
1177351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	return argc;
1178351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger}
1179aa574cd60e57d6a31b4d433e0b09bfacd2cb79d1WANG Cong
1180aa574cd60e57d6a31b4d433e0b09bfacd2cb79d1WANG Congint inet_get_addr(const char *src, __u32 *dst, struct in6_addr *dst6)
1181aa574cd60e57d6a31b4d433e0b09bfacd2cb79d1WANG Cong{
1182aa574cd60e57d6a31b4d433e0b09bfacd2cb79d1WANG Cong	if (strchr(src, ':'))
1183aa574cd60e57d6a31b4d433e0b09bfacd2cb79d1WANG Cong		return inet_pton(AF_INET6, src, dst6);
1184aa574cd60e57d6a31b4d433e0b09bfacd2cb79d1WANG Cong	else
1185aa574cd60e57d6a31b4d433e0b09bfacd2cb79d1WANG Cong		return inet_pton(AF_INET, src, dst);
1186aa574cd60e57d6a31b4d433e0b09bfacd2cb79d1WANG Cong}
1187ddb1129b7569235e29990dfeab8c02c4f7258c18Vadim Kochan
1188ddb1129b7569235e29990dfeab8c02c4f7258c18Vadim Kochanvoid print_nlmsg_timestamp(FILE *fp, const struct nlmsghdr *n)
1189ddb1129b7569235e29990dfeab8c02c4f7258c18Vadim Kochan{
1190ddb1129b7569235e29990dfeab8c02c4f7258c18Vadim Kochan	char *tstr;
1191e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	time_t secs = ((__u32 *)NLMSG_DATA(n))[0];
1192e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	long usecs = ((__u32 *)NLMSG_DATA(n))[1];
1193e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger
1194ddb1129b7569235e29990dfeab8c02c4f7258c18Vadim Kochan	tstr = asctime(localtime(&secs));
1195ddb1129b7569235e29990dfeab8c02c4f7258c18Vadim Kochan	tstr[strlen(tstr)-1] = 0;
1196ddb1129b7569235e29990dfeab8c02c4f7258c18Vadim Kochan	fprintf(fp, "Timestamp: %s %lu us\n", tstr, usecs);
1197ddb1129b7569235e29990dfeab8c02c4f7258c18Vadim Kochan}
1198e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan
1199e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochanstatic int on_netns(char *nsname, void *arg)
1200e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan{
1201e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan	struct netns_func *f = arg;
1202e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan
1203e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan	if (netns_switch(nsname))
1204e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan		return -1;
1205e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan
1206e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan	return f->func(nsname, f->arg);
1207e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan}
1208e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan
1209e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochanstatic int on_netns_label(char *nsname, void *arg)
1210e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan{
1211e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan	printf("\nnetns: %s\n", nsname);
1212e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan	return on_netns(nsname, arg);
1213e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan}
1214e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan
1215e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochanint do_each_netns(int (*func)(char *nsname, void *arg), void *arg,
1216e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan		bool show_label)
1217e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan{
1218e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan	struct netns_func nsf = { .func = func, .arg = arg };
1219e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan
1220e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan	if (show_label)
1221e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan		return netns_foreach(on_netns_label, &nsf);
1222e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan
1223e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan	return netns_foreach(on_netns, &nsf);
1224e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan}
1225b217df108ce9ecfa13c6a8ddfd1e3ff69af9fabaVadim Kochan
1226b217df108ce9ecfa13c6a8ddfd1e3ff69af9fabaVadim Kochanchar *int_to_str(int val, char *buf)
1227b217df108ce9ecfa13c6a8ddfd1e3ff69af9fabaVadim Kochan{
1228b217df108ce9ecfa13c6a8ddfd1e3ff69af9fabaVadim Kochan	sprintf(buf, "%d", val);
1229b217df108ce9ecfa13c6a8ddfd1e3ff69af9fabaVadim Kochan	return buf;
1230b217df108ce9ecfa13c6a8ddfd1e3ff69af9fabaVadim Kochan}
1231d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen
1232d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohenint get_guid(__u64 *guid, const char *arg)
1233d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen{
1234d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	unsigned long int tmp;
1235d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	char *endptr;
1236d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	int i;
1237d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen
1238d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen#define GUID_STR_LEN 23
1239d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	/* Verify strict format: format string must be
1240d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	 * xx:xx:xx:xx:xx:xx:xx:xx where xx can be an arbitrary
1241d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	 * hex digit
1242d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	 */
1243d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen
1244d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	if (strlen(arg) != GUID_STR_LEN)
1245d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen		return -1;
1246d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen
1247d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	/* make sure columns are in place */
1248d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	for (i = 0; i < 7; i++)
1249d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen		if (arg[2 + i * 3] != ':')
1250d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen			return -1;
1251d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen
1252d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	*guid = 0;
1253d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	for (i = 0; i < 8; i++) {
1254d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen		tmp = strtoul(arg + i * 3, &endptr, 16);
1255d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen		if (endptr != arg + i * 3 + 2)
1256d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen			return -1;
1257d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen
1258d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen		if (tmp > 255)
1259d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen			return -1;
1260d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen
1261d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen		 *guid |= tmp << (56 - 8 * i);
1262d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	}
1263d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen
1264d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	return 0;
1265d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen}
126656e3eb4c3400c5d857174c54c94f89ae7933301dNikolay Aleksandrov
126756e3eb4c3400c5d857174c54c94f89ae7933301dNikolay Aleksandrov/* This is a necessary workaround for multicast route dumps */
126856e3eb4c3400c5d857174c54c94f89ae7933301dNikolay Aleksandrovint get_real_family(int rtm_type, int rtm_family)
126956e3eb4c3400c5d857174c54c94f89ae7933301dNikolay Aleksandrov{
127056e3eb4c3400c5d857174c54c94f89ae7933301dNikolay Aleksandrov	if (rtm_type != RTN_MULTICAST)
127156e3eb4c3400c5d857174c54c94f89ae7933301dNikolay Aleksandrov		return rtm_family;
127256e3eb4c3400c5d857174c54c94f89ae7933301dNikolay Aleksandrov
12735ce897a03bfda76dc66dc1acfa014fc0e3d3022aHangbin Liu	if (rtm_family == RTNL_FAMILY_IPMR)
12745ce897a03bfda76dc66dc1acfa014fc0e3d3022aHangbin Liu		return AF_INET;
12755ce897a03bfda76dc66dc1acfa014fc0e3d3022aHangbin Liu
12765ce897a03bfda76dc66dc1acfa014fc0e3d3022aHangbin Liu	if (rtm_family == RTNL_FAMILY_IP6MR)
12775ce897a03bfda76dc66dc1acfa014fc0e3d3022aHangbin Liu		return AF_INET6;
12785ce897a03bfda76dc66dc1acfa014fc0e3d3022aHangbin Liu
12795ce897a03bfda76dc66dc1acfa014fc0e3d3022aHangbin Liu	return rtm_family;
128056e3eb4c3400c5d857174c54c94f89ae7933301dNikolay Aleksandrov}
12818d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Sutter
12824f6b73380d2c84b98b7beffe6ca73f635ab72a06Baruch Siach#ifdef NEED_STRLCPY
12838d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Suttersize_t strlcpy(char *dst, const char *src, size_t size)
12848d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Sutter{
128550ea3c64384b1d1bfa9c96de86c21ac8e9fef183Phil Sutter	size_t srclen = strlen(src);
128650ea3c64384b1d1bfa9c96de86c21ac8e9fef183Phil Sutter
12878d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Sutter	if (size) {
128850ea3c64384b1d1bfa9c96de86c21ac8e9fef183Phil Sutter		size_t minlen = min(srclen, size - 1);
128950ea3c64384b1d1bfa9c96de86c21ac8e9fef183Phil Sutter
129050ea3c64384b1d1bfa9c96de86c21ac8e9fef183Phil Sutter		memcpy(dst, src, minlen);
129150ea3c64384b1d1bfa9c96de86c21ac8e9fef183Phil Sutter		dst[minlen] = '\0';
12928d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Sutter	}
129350ea3c64384b1d1bfa9c96de86c21ac8e9fef183Phil Sutter	return srclen;
12948d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Sutter}
12958d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Sutter
12968d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Suttersize_t strlcat(char *dst, const char *src, size_t size)
12978d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Sutter{
12988d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Sutter	size_t dlen = strlen(dst);
12998d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Sutter
130050ea3c64384b1d1bfa9c96de86c21ac8e9fef183Phil Sutter	if (dlen >= size)
13018d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Sutter		return dlen + strlen(src);
13028d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Sutter
13038d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Sutter	return dlen + strlcpy(dst + dlen, src, size - dlen);
13048d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Sutter}
13054f6b73380d2c84b98b7beffe6ca73f635ab72a06Baruch Siach#endif
1306