]>
git.proxmox.com Git - mirror_iproute2.git/blob - lib/utils.c
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
9 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
14 * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses
22 #include <sys/socket.h>
23 #include <netinet/in.h>
26 #include <arpa/inet.h>
28 #include <linux/pkt_sched.h>
32 int get_integer(int *val
, char *arg
, int base
)
39 res
= strtol(arg
, &ptr
, base
);
40 if (!ptr
|| ptr
== arg
|| *ptr
|| res
> INT_MAX
|| res
< INT_MIN
)
46 int get_unsigned(unsigned *val
, char *arg
, int base
)
53 res
= strtoul(arg
, &ptr
, base
);
54 if (!ptr
|| ptr
== arg
|| *ptr
|| res
> UINT_MAX
)
60 int get_u32(__u32
*val
, char *arg
, int base
)
67 res
= strtoul(arg
, &ptr
, base
);
68 if (!ptr
|| ptr
== arg
|| *ptr
|| res
> 0xFFFFFFFFUL
)
74 int get_u16(__u16
*val
, char *arg
, int base
)
81 res
= strtoul(arg
, &ptr
, base
);
82 if (!ptr
|| ptr
== arg
|| *ptr
|| res
> 0xFFFF)
88 int get_u8(__u8
*val
, char *arg
, int base
)
95 res
= strtoul(arg
, &ptr
, base
);
96 if (!ptr
|| ptr
== arg
|| *ptr
|| res
> 0xFF)
102 int get_s16(__s16
*val
, char *arg
, int base
)
109 res
= strtol(arg
, &ptr
, base
);
110 if (!ptr
|| ptr
== arg
|| *ptr
|| res
> 0x7FFF || res
< -0x8000)
116 int get_s8(__s8
*val
, char *arg
, int base
)
123 res
= strtol(arg
, &ptr
, base
);
124 if (!ptr
|| ptr
== arg
|| *ptr
|| res
> 0x7F || res
< -0x80)
130 int get_addr_1(inet_prefix
*addr
, char *name
, int family
)
133 unsigned char *ap
= (unsigned char*)addr
->data
;
136 memset(addr
, 0, sizeof(*addr
));
138 if (strcmp(name
, "default") == 0 ||
139 strcmp(name
, "all") == 0 ||
140 strcmp(name
, "any") == 0) {
141 if (family
== AF_DECnet
)
143 addr
->family
= family
;
144 addr
->bytelen
= (family
== AF_INET6
? 16 : 4);
149 if (strchr(name
, ':')) {
150 addr
->family
= AF_INET6
;
151 if (family
!= AF_UNSPEC
&& family
!= AF_INET6
)
153 if (inet_pton(AF_INET6
, name
, addr
->data
) <= 0)
160 if (family
== AF_DECnet
) {
162 addr
->family
= AF_DECnet
;
163 if (dnet_pton(AF_DECnet
, name
, &dna
) <= 0)
165 memcpy(addr
->data
, dna
.a_addr
, 2);
171 addr
->family
= AF_INET
;
172 if (family
!= AF_UNSPEC
&& family
!= AF_INET
)
176 for (cp
=name
, i
=0; *cp
; cp
++) {
177 if (*cp
<= '9' && *cp
>= '0') {
178 ap
[i
] = 10*ap
[i
] + (*cp
-'0');
181 if (*cp
== '.' && ++i
<= 3)
188 int get_prefix_1(inet_prefix
*dst
, char *arg
, int family
)
194 memset(dst
, 0, sizeof(*dst
));
196 if (strcmp(arg
, "default") == 0 ||
197 strcmp(arg
, "any") == 0 ||
198 strcmp(arg
, "all") == 0) {
199 if (family
== AF_DECnet
)
201 dst
->family
= family
;
207 slash
= strchr(arg
, '/');
210 err
= get_addr_1(dst
, arg
, family
);
212 switch(dst
->family
) {
224 if (get_integer(&plen
, slash
+1, 0) || plen
> dst
->bitlen
) {
237 int get_addr(inet_prefix
*dst
, char *arg
, int family
)
239 if (family
== AF_PACKET
) {
240 fprintf(stderr
, "Error: \"%s\" may be inet address, but it is not allowed in this context.\n", arg
);
243 if (get_addr_1(dst
, arg
, family
)) {
244 fprintf(stderr
, "Error: an inet address is expected rather than \"%s\".\n", arg
);
250 int get_prefix(inet_prefix
*dst
, char *arg
, int family
)
252 if (family
== AF_PACKET
) {
253 fprintf(stderr
, "Error: \"%s\" may be inet prefix, but it is not allowed in this context.\n", arg
);
256 if (get_prefix_1(dst
, arg
, family
)) {
257 fprintf(stderr
, "Error: an inet prefix is expected rather than \"%s\".\n", arg
);
263 __u32
get_addr32(char *name
)
266 if (get_addr_1(&addr
, name
, AF_INET
)) {
267 fprintf(stderr
, "Error: an IP address is expected rather than \"%s\"\n", name
);
273 void incomplete_command()
275 fprintf(stderr
, "Command line is not complete. Try option \"help\"\n");
279 void invarg(char *msg
, char *arg
)
281 fprintf(stderr
, "Error: argument \"%s\" is wrong: %s\n", arg
, msg
);
285 void duparg(char *key
, char *arg
)
287 fprintf(stderr
, "Error: duplicate \"%s\": \"%s\" is the second value.\n", key
, arg
);
291 void duparg2(char *key
, char *arg
)
293 fprintf(stderr
, "Error: either \"%s\" is duplicate, or \"%s\" is a garbage.\n", key
, arg
);
297 int matches(char *cmd
, char *pattern
)
299 int len
= strlen(cmd
);
300 if (len
> strlen(pattern
))
302 return memcmp(pattern
, cmd
, len
);
305 int inet_addr_match(inet_prefix
*a
, inet_prefix
*b
, int bits
)
309 int words
= bits
>> 0x05;
314 if (memcmp(a1
, a2
, words
<< 2))
324 mask
= htonl((0xffffffff) << (0x20 - bits
));
326 if ((w1
^ w2
) & mask
)
333 int __iproute2_hz_internal
;
342 return atoi(getenv("HZ")) ? : HZ
;
344 if (getenv("PROC_NET_PSCHED")) {
345 snprintf(name
, sizeof(name
)-1, "%s", getenv("PROC_NET_PSCHED"));
346 } else if (getenv("PROC_ROOT")) {
347 snprintf(name
, sizeof(name
)-1, "%s/net/psched", getenv("PROC_ROOT"));
349 strcpy(name
, "/proc/net/psched");
351 fp
= fopen(name
, "r");
355 if (fscanf(fp
, "%*08x%*08x%08x%08x", &nom
, &denom
) == 2)
365 const char *rt_addr_n2a(int af
, int len
, void *addr
, char *buf
, int buflen
)
370 return inet_ntop(af
, addr
, buf
, buflen
);
372 return ipx_ntop(af
, addr
, buf
, buflen
);
375 struct dn_naddr dna
= { 2, { 0, 0, }};
376 memcpy(dna
.a_addr
, addr
, 2);
377 return dnet_ntop(af
, &dna
, buf
, buflen
);
384 #ifdef RESOLVE_HOSTNAMES
387 struct namerec
*next
;
392 static struct namerec
*nht
[256];
394 char *resolve_address(char *addr
, int len
, int af
)
397 struct hostent
*h_ent
;
402 if (af
== AF_INET6
&& ((__u32
*)addr
)[0] == 0 &&
403 ((__u32
*)addr
)[1] == 0 && ((__u32
*)addr
)[2] == htonl(0xffff)) {
409 hash
= addr
[len
-1] ^ addr
[len
-2] ^ addr
[len
-3] ^ addr
[len
-4];
411 for (n
= nht
[hash
]; n
; n
= n
->next
) {
412 if (n
->addr
.family
== af
&&
413 n
->addr
.bytelen
== len
&&
414 memcmp(n
->addr
.data
, addr
, len
) == 0)
417 if ((n
= malloc(sizeof(*n
))) == NULL
)
420 n
->addr
.bytelen
= len
;
422 memcpy(n
->addr
.data
, addr
, len
);
429 if ((h_ent
= gethostbyaddr(addr
, len
, af
)) != NULL
)
430 n
->name
= strdup(h_ent
->h_name
);
432 /* Even if we fail, "negative" entry is remembered. */
438 const char *format_host(int af
, int len
, void *addr
, char *buf
, int buflen
)
440 #ifdef RESOLVE_HOSTNAMES
455 /* I see no reasons why gethostbyname
456 may not work for DECnet */
465 (n
= resolve_address(addr
, len
, af
)) != NULL
)
469 return rt_addr_n2a(af
, len
, addr
, buf
, buflen
);
473 __u8
* hexstring_n2a(const __u8
*str
, int len
, __u8
*buf
, int blen
)
478 for (i
=0; i
<len
; i
++) {
481 sprintf(ptr
, "%02x", str
[i
]);
484 if (i
!= len
-1 && blen
> 1) {
492 __u8
* hexstring_a2n(const __u8
*str
, __u8
*buf
, int blen
)
502 while ((ch
= *str
) != ':' && ch
!= 0) {
503 if (ch
>= '0' && ch
<= '9')
505 else if (ch
>= 'a' && ch
<= 'f')
507 else if (ch
>= 'A' && ch
<= 'F')
526 memset(buf
+cnt
, 0, blen
-cnt
);