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>
36 int scan_number(char *arg
, unsigned *val
)
43 res
= strtoul(arg
, &ptr
, 0);
44 if (!ptr
|| ptr
== arg
|| *ptr
|| res
> UINT_MAX
)
50 int get_integer(int *val
, char *arg
, int base
)
57 res
= strtol(arg
, &ptr
, base
);
58 if (!ptr
|| ptr
== arg
|| *ptr
|| res
> INT_MAX
|| res
< INT_MIN
)
64 int get_unsigned(unsigned *val
, char *arg
, int base
)
71 res
= strtoul(arg
, &ptr
, base
);
72 if (!ptr
|| ptr
== arg
|| *ptr
|| res
> UINT_MAX
)
78 int get_u32(__u32
*val
, char *arg
, int base
)
85 res
= strtoul(arg
, &ptr
, base
);
86 if (!ptr
|| ptr
== arg
|| *ptr
|| res
> 0xFFFFFFFFUL
)
92 int get_u16(__u16
*val
, char *arg
, int base
)
99 res
= strtoul(arg
, &ptr
, base
);
100 if (!ptr
|| ptr
== arg
|| *ptr
|| res
> 0xFFFF)
106 int get_u8(__u8
*val
, char *arg
, int base
)
113 res
= strtoul(arg
, &ptr
, base
);
114 if (!ptr
|| ptr
== arg
|| *ptr
|| res
> 0xFF)
120 int get_s16(__s16
*val
, char *arg
, int base
)
127 res
= strtol(arg
, &ptr
, base
);
128 if (!ptr
|| ptr
== arg
|| *ptr
|| res
> 0x7FFF || res
< -0x8000)
134 int get_s8(__s8
*val
, char *arg
, int base
)
141 res
= strtol(arg
, &ptr
, base
);
142 if (!ptr
|| ptr
== arg
|| *ptr
|| res
> 0x7F || res
< -0x80)
148 int get_addr_1(inet_prefix
*addr
, char *name
, int family
)
151 unsigned char *ap
= (unsigned char*)addr
->data
;
154 memset(addr
, 0, sizeof(*addr
));
156 if (strcmp(name
, "default") == 0 || strcmp(name
, "any") == 0) {
157 addr
->family
= family
;
158 addr
->bytelen
= (family
== AF_INET6
? 16 : 4);
163 if (strchr(name
, ':')) {
164 addr
->family
= AF_INET6
;
165 if (family
!= AF_UNSPEC
&& family
!= AF_INET6
)
167 if (inet_pton(AF_INET6
, name
, addr
->data
) <= 0)
174 addr
->family
= AF_INET
;
175 if (family
!= AF_UNSPEC
&& family
!= AF_INET
)
179 for (cp
=name
, i
=0; *cp
; cp
++) {
180 if (*cp
<= '9' && *cp
>= '0') {
181 ap
[i
] = 10*ap
[i
] + (*cp
-'0');
184 if (*cp
== '.' && ++i
<= 3)
191 int get_prefix_1(inet_prefix
*dst
, char *arg
, int family
)
197 memset(dst
, 0, sizeof(*dst
));
199 if (strcmp(arg
, "default") == 0 || strcmp(arg
, "any") == 0) {
200 dst
->family
= family
;
206 slash
= strchr(arg
, '/');
209 err
= get_addr_1(dst
, arg
, family
);
211 dst
->bitlen
= (dst
->family
== AF_INET6
? 128 : 32);
213 if (scan_number(slash
+1, &plen
) || plen
> dst
->bitlen
) {
226 int get_addr(inet_prefix
*dst
, char *arg
, int family
)
228 if (get_addr_1(dst
, arg
, family
)) {
229 fprintf(stderr
, _("ip: %s is invalid inet address\n"), arg
);
235 int get_prefix(inet_prefix
*dst
, char *arg
, int family
)
237 if (get_prefix_1(dst
, arg
, family
)) {
238 fprintf(stderr
, _("ip: %s is invalid inet prefix\n"), arg
);
244 __u32
get_addr32(char *name
)
247 if (get_addr_1(&addr
, name
, AF_INET
)) {
248 fprintf(stderr
, _("ip: %s is invalid IPv4 address\n"), name
);
254 void invarg(char *msg
)
256 fprintf(stderr
, _("ip: argument is wrong: %s\n"), msg
);
260 int matches(char *cmd
, char *pattern
)
262 int len
= strlen(cmd
);
263 if (len
> strlen(pattern
))
265 return memcmp(pattern
, cmd
, len
);
268 int inet_addr_match(inet_prefix
*a
, inet_prefix
*b
, int bits
)
272 int words
= bits
>> 0x05;
277 if (memcmp(a1
, a2
, words
<< 2))
287 mask
= htonl((0xffffffff) << (0x20 - bits
));
289 if ((w1
^ w2
) & mask
)
296 const char *format_host(int af
, void *addr
, __u8
*abuf
, int alen
)
298 #ifdef RESOLVE_HOSTNAMES
301 struct hostent
*h_ent
;
311 (h_ent
= gethostbyaddr(addr
, addrlen
, af
)) != NULL
) {
312 snprintf(abuf
, alen
-1, "%s", h_ent
->h_name
);
317 return inet_ntop(af
, addr
, abuf
, alen
);