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