utils.c revision 7c72df5a95174c21bdc4ca09cd15a88c0c10e568
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>
347c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande#include <ctype.h>
3590f93024a0818dc691138d8401721e797004b042shemminger
360b218ab18dfad3e307f99aed2167a0c74f7ec67aEric W. Biederman#include "rt_names.h"
37aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "utils.h"
38e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan#include "namespace.h"
39aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
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}
53609640f5f0feda8099b04452297d81dd1a8a1777Sabrina Dubroca
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)
81697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger		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)
178697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger			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)
255697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger		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)
283697ac63905cb5ca5389cd840462ee9868123b77fStephen Hemminger		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
510aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (family == AF_DECnet) {
511aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		struct dn_naddr dna;
512e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger
513aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		addr->family = AF_DECnet;
514aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (dnet_pton(AF_DECnet, name, &dna) <= 0)
515aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return -1;
516aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		memcpy(addr->data, dna.a_addr, 2);
517aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		addr->bytelen = 2;
518aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		addr->bitlen = -1;
519aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return 0;
520aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
521aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
522dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman	if (family == AF_MPLS) {
5234af4471606ccf2b0cb7f5d0711f9be25435d8efcDavid Ahern		unsigned int maxlabels;
524dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		int i;
525e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger
526dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		addr->family = AF_MPLS;
5274af4471606ccf2b0cb7f5d0711f9be25435d8efcDavid Ahern		if (mpls_pton(AF_MPLS, name, addr->data,
5284af4471606ccf2b0cb7f5d0711f9be25435d8efcDavid Ahern			      sizeof(addr->data)) <= 0)
529dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman			return -1;
530dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		addr->bytelen = 4;
531dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		addr->bitlen = 20;
532dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		/* How many bytes do I need? */
5334af4471606ccf2b0cb7f5d0711f9be25435d8efcDavid Ahern		maxlabels = sizeof(addr->data) / sizeof(struct mpls_label);
5344af4471606ccf2b0cb7f5d0711f9be25435d8efcDavid Ahern		for (i = 0; i < maxlabels; i++) {
535dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman			if (ntohl(addr->data[i]) & MPLS_LS_S_MASK) {
536dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman				addr->bytelen = (i + 1)*4;
537dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman				break;
538dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman			}
539dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		}
540dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		return 0;
541dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman	}
542dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman
543aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	addr->family = AF_INET;
544aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (family != AF_UNSPEC && family != AF_INET)
545aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
54694afda752956ddc6ff1accf931bc3d03c070bb18Stephen Hemminger
547cafa6c8ec1d6e4bddde190edb742be864ce3f9b3Stephen Hemminger	if (get_addr_ipv4((__u8 *)addr->data, name) <= 0)
548516ffb6b7724e97ca035293dcfd9f94cf6ce3a47Stephen Hemminger		return -1;
54994afda752956ddc6ff1accf931bc3d03c070bb18Stephen Hemminger
550aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	addr->bytelen = 4;
551aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	addr->bitlen = -1;
552aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
553aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
554aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
555f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochanint af_bit_len(int af)
556f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan{
557f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan	switch (af) {
558f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan	case AF_INET6:
559f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan		return 128;
560f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan	case AF_INET:
561f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan		return 32;
562f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan	case AF_DECnet:
563f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan		return 16;
564f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan	case AF_IPX:
565f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan		return 80;
566dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman	case AF_MPLS:
567dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		return 20;
568f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan	}
569f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan
570f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan	return 0;
571f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan}
572f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan
573f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochanint af_byte_len(int af)
574f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan{
575f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan	return af_bit_len(af) / 8;
576f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan}
577f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan
578fb9b1d0f6a9f355bceae435ea43f1c8f3635b2dfosdl.net!shemmingerint get_prefix_1(inet_prefix *dst, char *arg, int family)
579aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
580aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int err;
581e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	unsigned int plen;
582aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char *slash;
583aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
584aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	memset(dst, 0, sizeof(*dst));
585aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
586aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (strcmp(arg, "default") == 0 ||
587aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    strcmp(arg, "any") == 0 ||
588aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    strcmp(arg, "all") == 0) {
589f7dd7e5e713d5820da2ad5cbd3fa88286e20d4f1Thomas Graf		if ((family == AF_DECnet) || (family == AF_MPLS))
590aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return -1;
591aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		dst->family = family;
592aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		dst->bytelen = 0;
593aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		dst->bitlen = 0;
594aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return 0;
595aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
596aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
597aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	slash = strchr(arg, '/');
598aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (slash)
599aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		*slash = 0;
600fb9b1d0f6a9f355bceae435ea43f1c8f3635b2dfosdl.net!shemminger
601aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	err = get_addr_1(dst, arg, family);
602aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (err == 0) {
603106ca2779ebc0d6a17ce7fae073aa38cdbdae6bbRoopa Prabhu		dst->bitlen = af_bit_len(dst->family);
604f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan
605aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (slash) {
6065a0d1cbf69269bfcb510a8b861b8a83aed0f6b85Andreas Henriksson			if (get_netmask(&plen, slash+1, 0)
607656111b2f9c5932350e697a1aaa70ba2d9b40bc7Stephen Hemminger			    || plen > dst->bitlen) {
608aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				err = -1;
609aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				goto done;
610aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			}
611f082b64fb40b467bc1f9e5d245114aae4e256d5cnet[shemminger]!shemminger			dst->flags |= PREFIXLEN_SPECIFIED;
612aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			dst->bitlen = plen;
613aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
614aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
615aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerdone:
616aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (slash)
617aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		*slash = '/';
618aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return err;
619aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
620aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
62134705c807a38909247d1bb29ccdffe42e5c1dab3Phil Sutterstatic const char *family_name_verbose(int family)
62234705c807a38909247d1bb29ccdffe42e5c1dab3Phil Sutter{
62334705c807a38909247d1bb29ccdffe42e5c1dab3Phil Sutter	if (family == AF_UNSPEC)
62434705c807a38909247d1bb29ccdffe42e5c1dab3Phil Sutter		return "any valid";
62534705c807a38909247d1bb29ccdffe42e5c1dab3Phil Sutter	return family_name(family);
62634705c807a38909247d1bb29ccdffe42e5c1dab3Phil Sutter}
62734705c807a38909247d1bb29ccdffe42e5c1dab3Phil Sutter
628c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingerint get_addr(inet_prefix *dst, const char *arg, int family)
629aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
630aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (get_addr_1(dst, arg, family)) {
631e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		fprintf(stderr,
632e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger			"Error: %s address is expected rather than \"%s\".\n",
63334705c807a38909247d1bb29ccdffe42e5c1dab3Phil Sutter			family_name_verbose(family), arg);
634aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		exit(1);
635aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
636aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
637aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
638aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
639fb9b1d0f6a9f355bceae435ea43f1c8f3635b2dfosdl.net!shemmingerint get_prefix(inet_prefix *dst, char *arg, int family)
640aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
641aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (family == AF_PACKET) {
642e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		fprintf(stderr,
643e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger			"Error: \"%s\" may be inet prefix, but it is not allowed in this context.\n",
644e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger			arg);
645aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		exit(1);
646aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
647334af761433685d90790545eb705bfe03ae9d43dMarco Varlese
648aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (get_prefix_1(dst, arg, family)) {
649e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		fprintf(stderr,
650e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger			"Error: %s prefix is expected rather than \"%s\".\n",
65134705c807a38909247d1bb29ccdffe42e5c1dab3Phil Sutter			family_name_verbose(family), arg);
652aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		exit(1);
653aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
654aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
655aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
656aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
657c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger__u32 get_addr32(const char *name)
658aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
659aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	inet_prefix addr;
660e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger
661aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (get_addr_1(&addr, name, AF_INET)) {
662e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		fprintf(stderr,
663e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger			"Error: an IP address is expected rather than \"%s\"\n",
664e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger			name);
665aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		exit(1);
666aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
667aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return addr.data[0];
668aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
669aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
6704094db72b61dadd16e180eab5f62ccbc82e3976dosdl.org!shemmingervoid incomplete_command(void)
671aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
672aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "Command line is not complete. Try option \"help\"\n");
673aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	exit(-1);
674aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
675aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
676c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemmingervoid missarg(const char *key)
677c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger{
678c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	fprintf(stderr, "Error: argument \"%s\" is required\n", key);
679c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger	exit(-1);
680c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger}
681c7699875bee00fbcd057fc62c30d6560b044e007net[shemminger]!shemminger
6824094db72b61dadd16e180eab5f62ccbc82e3976dosdl.org!shemmingervoid invarg(const char *msg, const char *arg)
683aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
684aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "Error: argument \"%s\" is wrong: %s\n", arg, msg);
685aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	exit(-1);
686aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
687aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
6884094db72b61dadd16e180eab5f62ccbc82e3976dosdl.org!shemmingervoid duparg(const char *key, const char *arg)
689aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
690e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	fprintf(stderr,
691e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		"Error: duplicate \"%s\": \"%s\" is the second value.\n",
692e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		key, arg);
693aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	exit(-1);
694aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
695aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
6964094db72b61dadd16e180eab5f62ccbc82e3976dosdl.org!shemmingervoid duparg2(const char *key, const char *arg)
697aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
698e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	fprintf(stderr,
699e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		"Error: either \"%s\" is duplicate, or \"%s\" is a garbage.\n",
700e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		key, arg);
701aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	exit(-1);
702aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
703aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
704625df645b703dc858d54784c35beff64464afae2Phil Sutterint check_ifname(const char *name)
705625df645b703dc858d54784c35beff64464afae2Phil Sutter{
706625df645b703dc858d54784c35beff64464afae2Phil Sutter	/* These checks mimic kernel checks in dev_valid_name */
707625df645b703dc858d54784c35beff64464afae2Phil Sutter	if (*name == '\0')
708625df645b703dc858d54784c35beff64464afae2Phil Sutter		return -1;
709625df645b703dc858d54784c35beff64464afae2Phil Sutter	if (strlen(name) >= IFNAMSIZ)
710625df645b703dc858d54784c35beff64464afae2Phil Sutter		return -1;
711625df645b703dc858d54784c35beff64464afae2Phil Sutter
712625df645b703dc858d54784c35beff64464afae2Phil Sutter	while (*name) {
713625df645b703dc858d54784c35beff64464afae2Phil Sutter		if (*name == '/' || isspace(*name))
714625df645b703dc858d54784c35beff64464afae2Phil Sutter			return -1;
715625df645b703dc858d54784c35beff64464afae2Phil Sutter		++name;
716625df645b703dc858d54784c35beff64464afae2Phil Sutter	}
717625df645b703dc858d54784c35beff64464afae2Phil Sutter	return 0;
718625df645b703dc858d54784c35beff64464afae2Phil Sutter}
719625df645b703dc858d54784c35beff64464afae2Phil Sutter
720625df645b703dc858d54784c35beff64464afae2Phil Sutter/* buf is assumed to be IFNAMSIZ */
721625df645b703dc858d54784c35beff64464afae2Phil Sutterint get_ifname(char *buf, const char *name)
722625df645b703dc858d54784c35beff64464afae2Phil Sutter{
723625df645b703dc858d54784c35beff64464afae2Phil Sutter	int ret;
724625df645b703dc858d54784c35beff64464afae2Phil Sutter
725625df645b703dc858d54784c35beff64464afae2Phil Sutter	ret = check_ifname(name);
726625df645b703dc858d54784c35beff64464afae2Phil Sutter	if (ret == 0)
727625df645b703dc858d54784c35beff64464afae2Phil Sutter		strncpy(buf, name, IFNAMSIZ);
728625df645b703dc858d54784c35beff64464afae2Phil Sutter
729625df645b703dc858d54784c35beff64464afae2Phil Sutter	return ret;
730625df645b703dc858d54784c35beff64464afae2Phil Sutter}
731625df645b703dc858d54784c35beff64464afae2Phil Sutter
7324094db72b61dadd16e180eab5f62ccbc82e3976dosdl.org!shemmingerint matches(const char *cmd, const char *pattern)
733aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
734aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int len = strlen(cmd);
735e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger
736aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (len > strlen(pattern))
737aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return -1;
738aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return memcmp(pattern, cmd, len);
739aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
740aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
7414094db72b61dadd16e180eab5f62ccbc82e3976dosdl.org!shemmingerint inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits)
742aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
7439626dfd54c3cc4deec1c651a0bfee65b50feb78bStephen Hemminger	const __u32 *a1 = a->data;
7449626dfd54c3cc4deec1c651a0bfee65b50feb78bStephen Hemminger	const __u32 *a2 = b->data;
745aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int words = bits >> 0x05;
746aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
747aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	bits &= 0x1f;
748aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
749aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (words)
750aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (memcmp(a1, a2, words << 2))
751aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return -1;
752aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
753aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (bits) {
754aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		__u32 w1, w2;
755aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		__u32 mask;
756aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
757aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		w1 = a1[words];
758aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		w2 = a2[words];
759aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
760aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		mask = htonl((0xffffffff) << (0x20 - bits));
761aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
762aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if ((w1 ^ w2) & mask)
763aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return 1;
764aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
765aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
766aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
767aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
768aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
769aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint __iproute2_hz_internal;
770aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
771aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint __get_hz(void)
772aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
773aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char name[1024];
774aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int hz = 0;
775aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	FILE *fp;
776aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
777aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (getenv("HZ"))
778aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return atoi(getenv("HZ")) ? : HZ;
779aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
780e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	if (getenv("PROC_NET_PSCHED"))
781e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		snprintf(name, sizeof(name)-1,
782e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger			 "%s", getenv("PROC_NET_PSCHED"));
783e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	else if (getenv("PROC_ROOT"))
784e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		snprintf(name, sizeof(name)-1,
785e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger			 "%s/net/psched", getenv("PROC_ROOT"));
786e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	else
787aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		strcpy(name, "/proc/net/psched");
788e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger
789aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fp = fopen(name, "r");
790aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
791aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (fp) {
792e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		unsigned int nom, denom;
793e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger
794aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (fscanf(fp, "%*08x%*08x%08x%08x", &nom, &denom) == 2)
795aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			if (nom == 1000000)
796aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger				hz = denom;
797aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fclose(fp);
798aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
799aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (hz)
800aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return hz;
801aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return HZ;
802aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
803aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
8045e8bc6316b1a6c56598cdb29a737d1d670d74e69net[shemminger]!shemmingerint __iproute2_user_hz_internal;
8055e8bc6316b1a6c56598cdb29a737d1d670d74e69net[shemminger]!shemminger
8065e8bc6316b1a6c56598cdb29a737d1d670d74e69net[shemminger]!shemmingerint __get_user_hz(void)
8075e8bc6316b1a6c56598cdb29a737d1d670d74e69net[shemminger]!shemminger{
8085e8bc6316b1a6c56598cdb29a737d1d670d74e69net[shemminger]!shemminger	return sysconf(_SC_CLK_TCK);
8095e8bc6316b1a6c56598cdb29a737d1d670d74e69net[shemminger]!shemminger}
8105e8bc6316b1a6c56598cdb29a737d1d670d74e69net[shemminger]!shemminger
811e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemmingerconst char *rt_addr_n2a_r(int af, int len,
812e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger			  const void *addr, char *buf, int buflen)
813aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
814aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	switch (af) {
815aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	case AF_INET:
816aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	case AF_INET6:
817aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return inet_ntop(af, addr, buf, buflen);
818dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman	case AF_MPLS:
819dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		return mpls_ntop(af, addr, buf, buflen);
820aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	case AF_IPX:
821aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return ipx_ntop(af, addr, buf, buflen);
822aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	case AF_DECnet:
823aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	{
824e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		struct dn_naddr dna = { 2, { 0, 0, } };
825e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger
826aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		memcpy(dna.a_addr, addr, 2);
827aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return dnet_ntop(af, &dna, buf, buflen);
828aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
8290b218ab18dfad3e307f99aed2167a0c74f7ec67aEric W. Biederman	case AF_PACKET:
8300b218ab18dfad3e307f99aed2167a0c74f7ec67aEric W. Biederman		return ll_addr_n2a(addr, len, ARPHRD_VOID, buf, buflen);
831aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	default:
832aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return "???";
833aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
834aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
835aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
8362e96d2ccd03a29896fc8a2c6ee6b769c512501dfPhil Sutterconst char *rt_addr_n2a(int af, int len, const void *addr)
8372e96d2ccd03a29896fc8a2c6ee6b769c512501dfPhil Sutter{
8382e96d2ccd03a29896fc8a2c6ee6b769c512501dfPhil Sutter	static char buf[256];
8392e96d2ccd03a29896fc8a2c6ee6b769c512501dfPhil Sutter
8402e96d2ccd03a29896fc8a2c6ee6b769c512501dfPhil Sutter	return rt_addr_n2a_r(af, len, addr, buf, 256);
8412e96d2ccd03a29896fc8a2c6ee6b769c512501dfPhil Sutter}
8422e96d2ccd03a29896fc8a2c6ee6b769c512501dfPhil Sutter
84345c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biedermanint read_family(const char *name)
84445c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman{
84545c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	int family = AF_UNSPEC;
846e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger
84745c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	if (strcmp(name, "inet") == 0)
84845c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman		family = AF_INET;
84945c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	else if (strcmp(name, "inet6") == 0)
85045c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman		family = AF_INET6;
85145c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	else if (strcmp(name, "dnet") == 0)
85245c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman		family = AF_DECnet;
85345c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	else if (strcmp(name, "link") == 0)
85445c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman		family = AF_PACKET;
85545c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	else if (strcmp(name, "ipx") == 0)
85645c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman		family = AF_IPX;
857dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman	else if (strcmp(name, "mpls") == 0)
858dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		family = AF_MPLS;
85945c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	else if (strcmp(name, "bridge") == 0)
86045c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman		family = AF_BRIDGE;
86145c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	return family;
86245c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman}
86345c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman
86445c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biedermanconst char *family_name(int family)
86545c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman{
86645c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	if (family == AF_INET)
86745c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman		return "inet";
86845c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	if (family == AF_INET6)
86945c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman		return "inet6";
87045c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	if (family == AF_DECnet)
87145c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman		return "dnet";
87245c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	if (family == AF_PACKET)
87345c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman		return "link";
87445c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	if (family == AF_IPX)
87545c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman		return "ipx";
876dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman	if (family == AF_MPLS)
877dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		return "mpls";
87845c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	if (family == AF_BRIDGE)
87945c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman		return "bridge";
88045c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman	return "???";
88145c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman}
88245c90d1990cbcecf6b24613f44849d6c44f29cdcEric W. Biederman
883aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#ifdef RESOLVE_HOSTNAMES
884e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemmingerstruct namerec {
885aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct namerec *next;
8867dec1bf88bc34e2d0b320f0c23bd1a060c73852bStephen Hemminger	const char *name;
887aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	inet_prefix addr;
888aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger};
889aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
8907dec1bf88bc34e2d0b320f0c23bd1a060c73852bStephen Hemminger#define NHASH 257
8917dec1bf88bc34e2d0b320f0c23bd1a060c73852bStephen Hemmingerstatic struct namerec *nht[NHASH];
892aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
8937dec1bf88bc34e2d0b320f0c23bd1a060c73852bStephen Hemmingerstatic const char *resolve_address(const void *addr, int len, int af)
894aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
895aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct namerec *n;
896aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	struct hostent *h_ent;
897e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	unsigned int hash;
898aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	static int notfirst;
899aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
900aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
901e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	if (af == AF_INET6 && ((__u32 *)addr)[0] == 0 &&
902e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	    ((__u32 *)addr)[1] == 0 && ((__u32 *)addr)[2] == htonl(0xffff)) {
903aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		af = AF_INET;
904aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		addr += 12;
905aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		len = 4;
906aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
907aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
9087dec1bf88bc34e2d0b320f0c23bd1a060c73852bStephen Hemminger	hash = *(__u32 *)(addr + len - 4) % NHASH;
909aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
910aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	for (n = nht[hash]; n; n = n->next) {
911aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (n->addr.family == af &&
912aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		    n->addr.bytelen == len &&
913aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		    memcmp(n->addr.data, addr, len) == 0)
914aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return n->name;
915aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
916e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	n = malloc(sizeof(*n));
917e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	if (n == NULL)
918aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return NULL;
919aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	n->addr.family = af;
920aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	n->addr.bytelen = len;
921aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	n->name = NULL;
922aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	memcpy(n->addr.data, addr, len);
923aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	n->next = nht[hash];
924aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	nht[hash] = n;
925aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (++notfirst == 1)
926aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		sethostent(1);
927aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fflush(stdout);
928aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
929e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	h_ent = gethostbyaddr(addr, len, af);
930e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	if (h_ent != NULL)
931aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		n->name = strdup(h_ent->h_name);
932aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
933aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	/* Even if we fail, "negative" entry is remembered. */
934aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return n->name;
935aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
936aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#endif
937aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
938a418e451643e77fe36861e53359587ba8aa41873Phil Sutterconst char *format_host_r(int af, int len, const void *addr,
9394094db72b61dadd16e180eab5f62ccbc82e3976dosdl.org!shemminger			char *buf, int buflen)
940aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
941aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#ifdef RESOLVE_HOSTNAMES
942aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (resolve_hosts) {
9437dec1bf88bc34e2d0b320f0c23bd1a060c73852bStephen Hemminger		const char *n;
9447dec1bf88bc34e2d0b320f0c23bd1a060c73852bStephen Hemminger
945f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan		len = len <= 0 ? af_byte_len(af) : len;
946f3a2ddc124e09d3990b836e322ed39c76c35546eVadim Kochan
947aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (len > 0 &&
948aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		    (n = resolve_address(addr, len, af)) != NULL)
949aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return n;
950aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
951aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#endif
9522e96d2ccd03a29896fc8a2c6ee6b769c512501dfPhil Sutter	return rt_addr_n2a_r(af, len, addr, buf, buflen);
953aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
954aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
955a418e451643e77fe36861e53359587ba8aa41873Phil Sutterconst char *format_host(int af, int len, const void *addr)
956a418e451643e77fe36861e53359587ba8aa41873Phil Sutter{
957a418e451643e77fe36861e53359587ba8aa41873Phil Sutter	static char buf[256];
958a418e451643e77fe36861e53359587ba8aa41873Phil Sutter
959a418e451643e77fe36861e53359587ba8aa41873Phil Sutter	return format_host_r(af, len, addr, buf, 256);
960a418e451643e77fe36861e53359587ba8aa41873Phil Sutter}
961a418e451643e77fe36861e53359587ba8aa41873Phil Sutter
962aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
963f332d169246447bd5e258ac03d5ee840a70adb1eshemmingerchar *hexstring_n2a(const __u8 *str, int len, char *buf, int blen)
964aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
965f332d169246447bd5e258ac03d5ee840a70adb1eshemminger	char *ptr = buf;
966aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int i;
967aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
968e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	for (i = 0; i < len; i++) {
969aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (blen < 3)
970aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			break;
971aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		sprintf(ptr, "%02x", str[i]);
972aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		ptr += 2;
973aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		blen -= 2;
974aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
975aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return buf;
976aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
977aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
97889ae502056f58a0177b9970f1f79a9683ac7fdd0Sabrina Dubroca__u8 *hexstring_a2n(const char *str, __u8 *buf, int blen, unsigned int *len)
979aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
98089ae502056f58a0177b9970f1f79a9683ac7fdd0Sabrina Dubroca	unsigned int cnt = 0;
981316c2346f7f3e337be9a56e7ad5fc8e04cd26d63Jiri Pirko	char *endptr;
982aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
983316c2346f7f3e337be9a56e7ad5fc8e04cd26d63Jiri Pirko	if (strlen(str) % 2)
984316c2346f7f3e337be9a56e7ad5fc8e04cd26d63Jiri Pirko		return NULL;
985316c2346f7f3e337be9a56e7ad5fc8e04cd26d63Jiri Pirko	while (cnt < blen && strlen(str) > 1) {
986316c2346f7f3e337be9a56e7ad5fc8e04cd26d63Jiri Pirko		unsigned int tmp;
987316c2346f7f3e337be9a56e7ad5fc8e04cd26d63Jiri Pirko		char tmpstr[3];
988316c2346f7f3e337be9a56e7ad5fc8e04cd26d63Jiri Pirko
989316c2346f7f3e337be9a56e7ad5fc8e04cd26d63Jiri Pirko		strncpy(tmpstr, str, 2);
990316c2346f7f3e337be9a56e7ad5fc8e04cd26d63Jiri Pirko		tmpstr[2] = '\0';
9919ba4126dc4d6abb8dc5c8c8d52177849e764a14eBeniamino Galvani		errno = 0;
992316c2346f7f3e337be9a56e7ad5fc8e04cd26d63Jiri Pirko		tmp = strtoul(tmpstr, &endptr, 16);
993316c2346f7f3e337be9a56e7ad5fc8e04cd26d63Jiri Pirko		if (errno != 0 || tmp > 0xFF || *endptr != '\0')
994aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			return NULL;
995316c2346f7f3e337be9a56e7ad5fc8e04cd26d63Jiri Pirko		buf[cnt++] = tmp;
996316c2346f7f3e337be9a56e7ad5fc8e04cd26d63Jiri Pirko		str += 2;
997aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
99889ae502056f58a0177b9970f1f79a9683ac7fdd0Sabrina Dubroca
99989ae502056f58a0177b9970f1f79a9683ac7fdd0Sabrina Dubroca	if (len)
100089ae502056f58a0177b9970f1f79a9683ac7fdd0Sabrina Dubroca		*len = cnt;
100189ae502056f58a0177b9970f1f79a9683ac7fdd0Sabrina Dubroca
1002aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return buf;
1003aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
100490f93024a0818dc691138d8401721e797004b042shemminger
10051c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salimint hex2mem(const char *buf, uint8_t *mem, int count)
10061c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim{
10071c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim	int i, j;
10081c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim	int c;
10091c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim
10101c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim	for (i = 0, j = 0; i < count; i++, j += 2) {
10111c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim		c = get_hex(buf[j]);
10121c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim		if (c < 0)
10132bf1a81a2f0cd9d1e0f7aea93ea49185e7fb5ddfStephen Hemminger			return -1;
10141c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim
10151c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim		mem[i] = c << 4;
10161c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim
10171c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim		c = get_hex(buf[j + 1]);
10181c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim		if (c < 0)
10192bf1a81a2f0cd9d1e0f7aea93ea49185e7fb5ddfStephen Hemminger			return -1;
10201c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim
10211c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim		mem[i] |= c;
10221c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim	}
10231c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim
10241c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim	return 0;
10251c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim}
10261c570c50a362bd0cdf1c08874137d485fae3f5e4Jamal Hadi Salim
10275866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbertint addr64_n2a(__u64 addr, char *buff, size_t len)
10285866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert{
10295866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert	__u16 *words = (__u16 *)&addr;
10305866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert	__u16 v;
10315866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert	int i, ret;
10325866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert	size_t written = 0;
10335866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert	char *sep = ":";
10345866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert
10355866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert	for (i = 0; i < 4; i++) {
10365866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert		v = ntohs(words[i]);
10375866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert
10385866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert		if (i == 3)
10395866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert			sep = "";
10405866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert
10415866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert		ret = snprintf(&buff[written], len - written, "%x%s", v, sep);
10425866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert		if (ret < 0)
10435866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert			return ret;
10445866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert
10455866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert		written += ret;
10465866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert	}
10475866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert
10485866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert	return written;
10495866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert}
10505866bddd9aa9eba57623d57f866afaee9a5e2597Tom Herbert
10517c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande/* Print buffer and escape bytes that are !isprint or among 'escape' */
10527c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalandevoid print_escape_buf(const __u8 *buf, size_t len, const char *escape)
10537c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande{
10547c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande	size_t i;
10557c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande
10567c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande	for (i = 0; i < len; ++i) {
10577c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande		if (isprint(buf[i]) && buf[i] != '\\' &&
10587c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande		    !strchr(escape, buf[i]))
10597c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande			printf("%c", buf[i]);
10607c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande		else
10617c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande			printf("\\%03o", buf[i]);
10627c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande	}
10637c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande}
10647c72df5a95174c21bdc4ca09cd15a88c0c10e568Ivan Delalande
106590f93024a0818dc691138d8401721e797004b042shemmingerint print_timestamp(FILE *fp)
106690f93024a0818dc691138d8401721e797004b042shemminger{
106790f93024a0818dc691138d8401721e797004b042shemminger	struct timeval tv;
106879aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan	struct tm *tm;
106990f93024a0818dc691138d8401721e797004b042shemminger
107090f93024a0818dc691138d8401721e797004b042shemminger	gettimeofday(&tv, NULL);
107179aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan	tm = localtime(&tv.tv_sec);
107279aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan
107379aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan	if (timestamp_short) {
107479aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan		char tshort[40];
107579aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan
107679aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan		strftime(tshort, sizeof(tshort), "%Y-%m-%dT%H:%M:%S", tm);
107779aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan		fprintf(fp, "[%s.%06ld] ", tshort, tv.tv_usec);
107879aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan	} else {
107979aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan		char *tstr = asctime(tm);
108079aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan
108179aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan		tstr[strlen(tstr)-1] = 0;
108279aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan		fprintf(fp, "Timestamp: %s %ld usec\n",
108379aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan			tstr, tv.tv_usec);
108479aa79d0581cef6ddab635f7f2b88e81f920573aVadim Kochan	}
108590f93024a0818dc691138d8401721e797004b042shemminger
108690f93024a0818dc691138d8401721e797004b042shemminger	return 0;
108790f93024a0818dc691138d8401721e797004b042shemminger}
1088351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger
1089351efcde4e62967362a10b29f3b701cfecd7cdfcshemmingerint cmdlineno;
1090351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger
1091351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger/* Like glibc getline but handle continuation lines and comments */
1092d21e88354b2a42b026384730a767f2108bcf8efeAndreas Henrikssonssize_t getcmdline(char **linep, size_t *lenp, FILE *in)
1093351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger{
1094d21e88354b2a42b026384730a767f2108bcf8efeAndreas Henriksson	ssize_t cc;
1095351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	char *cp;
1096ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger
1097e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	cc = getline(linep, lenp, in);
1098e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	if (cc < 0)
1099351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		return cc;	/* eof or error */
1100351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	++cmdlineno;
1101351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger
1102351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	cp = strchr(*linep, '#');
1103ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger	if (cp)
1104351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		*cp = '\0';
1105ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger
1106351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	while ((cp = strstr(*linep, "\\\n")) != NULL) {
1107351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		char *line1 = NULL;
1108351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		size_t len1 = 0;
110921a85d3becf45e02985c466764ae19433d907c40Stephen Hemminger		ssize_t cc1;
1110351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger
1111e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		cc1 = getline(&line1, &len1, in);
1112e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger		if (cc1 < 0) {
1113351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger			fprintf(stderr, "Missing continuation line\n");
1114351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger			return cc1;
1115351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		}
1116351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger
1117351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		++cmdlineno;
1118351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		*cp = 0;
1119351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger
1120351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		cp = strchr(line1, '#');
1121ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemminger		if (cp)
1122351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger			*cp = '\0';
1123351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger
1124d21e88354b2a42b026384730a767f2108bcf8efeAndreas Henriksson		*lenp = strlen(*linep) + strlen(line1) + 1;
1125d21e88354b2a42b026384730a767f2108bcf8efeAndreas Henriksson		*linep = realloc(*linep, *lenp);
1126351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		if (!*linep) {
1127351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger			fprintf(stderr, "Out of memory\n");
1128d21e88354b2a42b026384730a767f2108bcf8efeAndreas Henriksson			*lenp = 0;
1129351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger			return -1;
1130351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		}
1131351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		cc += cc1 - 2;
1132351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		strcat(*linep, line1);
1133351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		free(line1);
1134351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	}
1135351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	return cc;
1136351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger}
1137351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger
1138351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger/* split command line into argument vector */
1139351efcde4e62967362a10b29f3b701cfecd7cdfcshemmingerint makeargs(char *line, char *argv[], int maxargs)
1140351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger{
1141351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	static const char ws[] = " \t\r\n";
1142351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	char *cp;
1143351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	int argc = 0;
1144351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger
114539e3d3836c1384506d0a76a496133c5361940770Christophe Gouault	for (cp = line + strspn(line, ws); *cp; cp += strspn(cp, ws)) {
1146351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		if (argc >= (maxargs - 1)) {
1147351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger			fprintf(stderr, "Too many arguments to command\n");
1148351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger			exit(1);
1149351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		}
115039e3d3836c1384506d0a76a496133c5361940770Christophe Gouault
115139e3d3836c1384506d0a76a496133c5361940770Christophe Gouault		/* word begins with quote */
115239e3d3836c1384506d0a76a496133c5361940770Christophe Gouault		if (*cp == '\'' || *cp == '"') {
115339e3d3836c1384506d0a76a496133c5361940770Christophe Gouault			char quote = *cp++;
115439e3d3836c1384506d0a76a496133c5361940770Christophe Gouault
115539e3d3836c1384506d0a76a496133c5361940770Christophe Gouault			argv[argc++] = cp;
115639e3d3836c1384506d0a76a496133c5361940770Christophe Gouault			/* find ending quote */
115739e3d3836c1384506d0a76a496133c5361940770Christophe Gouault			cp = strchr(cp, quote);
115839e3d3836c1384506d0a76a496133c5361940770Christophe Gouault			if (cp == NULL) {
115939e3d3836c1384506d0a76a496133c5361940770Christophe Gouault				fprintf(stderr, "Unterminated quoted string\n");
116039e3d3836c1384506d0a76a496133c5361940770Christophe Gouault				exit(1);
116139e3d3836c1384506d0a76a496133c5361940770Christophe Gouault			}
116239e3d3836c1384506d0a76a496133c5361940770Christophe Gouault			*cp++ = 0;
116339e3d3836c1384506d0a76a496133c5361940770Christophe Gouault			continue;
116439e3d3836c1384506d0a76a496133c5361940770Christophe Gouault		}
116539e3d3836c1384506d0a76a496133c5361940770Christophe Gouault
1166351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger		argv[argc++] = cp;
116739e3d3836c1384506d0a76a496133c5361940770Christophe Gouault		/* find end of word */
116839e3d3836c1384506d0a76a496133c5361940770Christophe Gouault		cp += strcspn(cp, ws);
116939e3d3836c1384506d0a76a496133c5361940770Christophe Gouault		*cp++ = 0;
1170351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	}
1171351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	argv[argc] = NULL;
1172351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger
1173351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	return argc;
1174351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger}
1175aa574cd60e57d6a31b4d433e0b09bfacd2cb79d1WANG Cong
1176aa574cd60e57d6a31b4d433e0b09bfacd2cb79d1WANG Congint inet_get_addr(const char *src, __u32 *dst, struct in6_addr *dst6)
1177aa574cd60e57d6a31b4d433e0b09bfacd2cb79d1WANG Cong{
1178aa574cd60e57d6a31b4d433e0b09bfacd2cb79d1WANG Cong	if (strchr(src, ':'))
1179aa574cd60e57d6a31b4d433e0b09bfacd2cb79d1WANG Cong		return inet_pton(AF_INET6, src, dst6);
1180aa574cd60e57d6a31b4d433e0b09bfacd2cb79d1WANG Cong	else
1181aa574cd60e57d6a31b4d433e0b09bfacd2cb79d1WANG Cong		return inet_pton(AF_INET, src, dst);
1182aa574cd60e57d6a31b4d433e0b09bfacd2cb79d1WANG Cong}
1183ddb1129b7569235e29990dfeab8c02c4f7258c18Vadim Kochan
1184ddb1129b7569235e29990dfeab8c02c4f7258c18Vadim Kochanvoid print_nlmsg_timestamp(FILE *fp, const struct nlmsghdr *n)
1185ddb1129b7569235e29990dfeab8c02c4f7258c18Vadim Kochan{
1186ddb1129b7569235e29990dfeab8c02c4f7258c18Vadim Kochan	char *tstr;
1187e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	time_t secs = ((__u32 *)NLMSG_DATA(n))[0];
1188e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger	long usecs = ((__u32 *)NLMSG_DATA(n))[1];
1189e1933b9281257c6668df14dce01dbfce6137af5aStephen Hemminger
1190ddb1129b7569235e29990dfeab8c02c4f7258c18Vadim Kochan	tstr = asctime(localtime(&secs));
1191ddb1129b7569235e29990dfeab8c02c4f7258c18Vadim Kochan	tstr[strlen(tstr)-1] = 0;
1192ddb1129b7569235e29990dfeab8c02c4f7258c18Vadim Kochan	fprintf(fp, "Timestamp: %s %lu us\n", tstr, usecs);
1193ddb1129b7569235e29990dfeab8c02c4f7258c18Vadim Kochan}
1194e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan
1195e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochanstatic int on_netns(char *nsname, void *arg)
1196e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan{
1197e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan	struct netns_func *f = arg;
1198e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan
1199e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan	if (netns_switch(nsname))
1200e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan		return -1;
1201e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan
1202e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan	return f->func(nsname, f->arg);
1203e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan}
1204e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan
1205e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochanstatic int on_netns_label(char *nsname, void *arg)
1206e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan{
1207e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan	printf("\nnetns: %s\n", nsname);
1208e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan	return on_netns(nsname, arg);
1209e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan}
1210e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan
1211e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochanint do_each_netns(int (*func)(char *nsname, void *arg), void *arg,
1212e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan		bool show_label)
1213e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan{
1214e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan	struct netns_func nsf = { .func = func, .arg = arg };
1215e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan
1216e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan	if (show_label)
1217e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan		return netns_foreach(on_netns_label, &nsf);
1218e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan
1219e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan	return netns_foreach(on_netns, &nsf);
1220e998e118ddc3a0ab1b325ad7ed4abe59b83e684aVadim Kochan}
1221b217df108ce9ecfa13c6a8ddfd1e3ff69af9fabaVadim Kochan
1222b217df108ce9ecfa13c6a8ddfd1e3ff69af9fabaVadim Kochanchar *int_to_str(int val, char *buf)
1223b217df108ce9ecfa13c6a8ddfd1e3ff69af9fabaVadim Kochan{
1224b217df108ce9ecfa13c6a8ddfd1e3ff69af9fabaVadim Kochan	sprintf(buf, "%d", val);
1225b217df108ce9ecfa13c6a8ddfd1e3ff69af9fabaVadim Kochan	return buf;
1226b217df108ce9ecfa13c6a8ddfd1e3ff69af9fabaVadim Kochan}
1227d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen
1228d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohenint get_guid(__u64 *guid, const char *arg)
1229d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen{
1230d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	unsigned long int tmp;
1231d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	char *endptr;
1232d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	int i;
1233d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen
1234d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen#define GUID_STR_LEN 23
1235d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	/* Verify strict format: format string must be
1236d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	 * xx:xx:xx:xx:xx:xx:xx:xx where xx can be an arbitrary
1237d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	 * hex digit
1238d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	 */
1239d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen
1240d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	if (strlen(arg) != GUID_STR_LEN)
1241d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen		return -1;
1242d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen
1243d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	/* make sure columns are in place */
1244d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	for (i = 0; i < 7; i++)
1245d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen		if (arg[2 + i * 3] != ':')
1246d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen			return -1;
1247d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen
1248d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	*guid = 0;
1249d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	for (i = 0; i < 8; i++) {
1250d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen		tmp = strtoul(arg + i * 3, &endptr, 16);
1251d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen		if (endptr != arg + i * 3 + 2)
1252d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen			return -1;
1253d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen
1254d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen		if (tmp > 255)
1255d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen			return -1;
1256d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen
1257d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen		 *guid |= tmp << (56 - 8 * i);
1258d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	}
1259d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen
1260d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen	return 0;
1261d91fb3f4c7e4dba806541bdc90b1fb60a3581541Eli Cohen}
126256e3eb4c3400c5d857174c54c94f89ae7933301dNikolay Aleksandrov
126356e3eb4c3400c5d857174c54c94f89ae7933301dNikolay Aleksandrov/* This is a necessary workaround for multicast route dumps */
126456e3eb4c3400c5d857174c54c94f89ae7933301dNikolay Aleksandrovint get_real_family(int rtm_type, int rtm_family)
126556e3eb4c3400c5d857174c54c94f89ae7933301dNikolay Aleksandrov{
126656e3eb4c3400c5d857174c54c94f89ae7933301dNikolay Aleksandrov	if (rtm_type != RTN_MULTICAST)
126756e3eb4c3400c5d857174c54c94f89ae7933301dNikolay Aleksandrov		return rtm_family;
126856e3eb4c3400c5d857174c54c94f89ae7933301dNikolay Aleksandrov
12695ce897a03bfda76dc66dc1acfa014fc0e3d3022aHangbin Liu	if (rtm_family == RTNL_FAMILY_IPMR)
12705ce897a03bfda76dc66dc1acfa014fc0e3d3022aHangbin Liu		return AF_INET;
12715ce897a03bfda76dc66dc1acfa014fc0e3d3022aHangbin Liu
12725ce897a03bfda76dc66dc1acfa014fc0e3d3022aHangbin Liu	if (rtm_family == RTNL_FAMILY_IP6MR)
12735ce897a03bfda76dc66dc1acfa014fc0e3d3022aHangbin Liu		return AF_INET6;
12745ce897a03bfda76dc66dc1acfa014fc0e3d3022aHangbin Liu
12755ce897a03bfda76dc66dc1acfa014fc0e3d3022aHangbin Liu	return rtm_family;
127656e3eb4c3400c5d857174c54c94f89ae7933301dNikolay Aleksandrov}
12778d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Sutter
12784f6b73380d2c84b98b7beffe6ca73f635ab72a06Baruch Siach#ifdef NEED_STRLCPY
12798d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Suttersize_t strlcpy(char *dst, const char *src, size_t size)
12808d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Sutter{
128150ea3c64384b1d1bfa9c96de86c21ac8e9fef183Phil Sutter	size_t srclen = strlen(src);
128250ea3c64384b1d1bfa9c96de86c21ac8e9fef183Phil Sutter
12838d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Sutter	if (size) {
128450ea3c64384b1d1bfa9c96de86c21ac8e9fef183Phil Sutter		size_t minlen = min(srclen, size - 1);
128550ea3c64384b1d1bfa9c96de86c21ac8e9fef183Phil Sutter
128650ea3c64384b1d1bfa9c96de86c21ac8e9fef183Phil Sutter		memcpy(dst, src, minlen);
128750ea3c64384b1d1bfa9c96de86c21ac8e9fef183Phil Sutter		dst[minlen] = '\0';
12888d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Sutter	}
128950ea3c64384b1d1bfa9c96de86c21ac8e9fef183Phil Sutter	return srclen;
12908d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Sutter}
12918d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Sutter
12928d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Suttersize_t strlcat(char *dst, const char *src, size_t size)
12938d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Sutter{
12948d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Sutter	size_t dlen = strlen(dst);
12958d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Sutter
129650ea3c64384b1d1bfa9c96de86c21ac8e9fef183Phil Sutter	if (dlen >= size)
12978d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Sutter		return dlen + strlen(src);
12988d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Sutter
12998d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Sutter	return dlen + strlcpy(dst + dlen, src, size - dlen);
13008d15e012a3227d79295cd95582bb6d8a6f0bdc92Phil Sutter}
13014f6b73380d2c84b98b7beffe6ca73f635ab72a06Baruch Siach#endif
1302