1 /* vi: set sw=4 ts=4: */
5 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
7 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
11 * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses
16 #include "inet_common.h"
18 int get_integer(int *val, char *arg, int base)
25 res = strtol(arg, &ptr, base);
26 if (!ptr || ptr == arg || *ptr || res > INT_MAX || res < INT_MIN)
31 //XXX: FIXME: use some libbb function instead
32 int get_unsigned(unsigned *val, char *arg, int base)
39 res = strtoul(arg, &ptr, base);
40 if (!ptr || ptr == arg || *ptr || res > UINT_MAX)
46 int get_u32(uint32_t * val, char *arg, int base)
53 res = strtoul(arg, &ptr, base);
54 if (!ptr || ptr == arg || *ptr || res > 0xFFFFFFFFUL)
60 int get_u16(uint16_t * val, char *arg, int base)
67 res = strtoul(arg, &ptr, base);
68 if (!ptr || ptr == arg || *ptr || res > 0xFFFF)
74 int get_u8(uint8_t * val, char *arg, int base)
81 res = strtoul(arg, &ptr, base);
82 if (!ptr || ptr == arg || *ptr || res > 0xFF)
88 int get_s16(int16_t * val, char *arg, int base)
95 res = strtol(arg, &ptr, base);
96 if (!ptr || ptr == arg || *ptr || res > 0x7FFF || res < -0x8000)
102 int get_s8(int8_t * val, char *arg, int base)
109 res = strtol(arg, &ptr, base);
110 if (!ptr || ptr == arg || *ptr || res > 0x7F || res < -0x80)
116 int get_addr_1(inet_prefix * addr, char *name, int family)
119 unsigned char *ap = (unsigned char *) addr->data;
122 memset(addr, 0, sizeof(*addr));
124 if (strcmp(name, bb_str_default) == 0 ||
125 strcmp(name, "all") == 0 || strcmp(name, "any") == 0) {
126 addr->family = family;
127 addr->bytelen = (family == AF_INET6 ? 16 : 4);
132 if (strchr(name, ':')) {
133 addr->family = AF_INET6;
134 if (family != AF_UNSPEC && family != AF_INET6)
136 if (inet_pton(AF_INET6, name, addr->data) <= 0)
143 addr->family = AF_INET;
144 if (family != AF_UNSPEC && family != AF_INET)
148 for (cp = name, i = 0; *cp; cp++) {
149 if (*cp <= '9' && *cp >= '0') {
150 ap[i] = 10 * ap[i] + (*cp - '0');
153 if (*cp == '.' && ++i <= 3)
160 int get_prefix_1(inet_prefix * dst, char *arg, int family)
166 memset(dst, 0, sizeof(*dst));
168 if (strcmp(arg, bb_str_default) == 0 || strcmp(arg, "any") == 0) {
169 dst->family = family;
175 slash = strchr(arg, '/');
178 err = get_addr_1(dst, arg, family);
180 switch (dst->family) {
189 if (get_integer(&plen, slash + 1, 0) || plen > dst->bitlen) {
202 int get_addr(inet_prefix * dst, char *arg, int family)
204 if (family == AF_PACKET) {
205 bb_error_msg_and_die("\"%s\" may be inet address, but it is not allowed in this context", arg);
207 if (get_addr_1(dst, arg, family)) {
208 bb_error_msg_and_die("an inet address is expected rather than \"%s\"", arg);
213 int get_prefix(inet_prefix * dst, char *arg, int family)
215 if (family == AF_PACKET) {
216 bb_error_msg_and_die("\"%s\" may be inet address, but it is not allowed in this context", arg);
218 if (get_prefix_1(dst, arg, family)) {
219 bb_error_msg_and_die("an inet address is expected rather than \"%s\"", arg);
224 uint32_t get_addr32(char *name)
228 if (get_addr_1(&addr, name, AF_INET)) {
229 bb_error_msg_and_die("an IP address is expected rather than \"%s\"", name);
234 void incomplete_command(void)
236 bb_error_msg_and_die("command line is not complete, try option \"help\"");
239 void invarg(const char *arg, const char *opt)
241 bb_error_msg_and_die(bb_msg_invalid_arg, arg, opt);
244 void duparg(const char *key, const char *arg)
246 bb_error_msg_and_die("duplicate \"%s\": \"%s\" is the second value", key, arg);
249 void duparg2(const char *key, const char *arg)
251 bb_error_msg_and_die("either \"%s\" is duplicate, or \"%s\" is garbage", key, arg);
254 int inet_addr_match(inet_prefix * a, inet_prefix * b, int bits)
256 uint32_t *a1 = a->data;
257 uint32_t *a2 = b->data;
258 int words = bits >> 0x05;
263 if (memcmp(a1, a2, words << 2))
273 mask = htonl((0xffffffff) << (0x20 - bits));
275 if ((w1 ^ w2) & mask)
282 const char *rt_addr_n2a(int af, int UNUSED_PARAM len,
283 void *addr, char *buf, int buflen)
288 return inet_ntop(af, addr, buf, buflen);
295 const char *format_host(int af, int len, void *addr, char *buf, int buflen)
297 #ifdef RESOLVE_HOSTNAMES
299 struct hostent *h_ent;
313 h_ent = gethostbyaddr(addr, len, af);
315 safe_strncpy(buf, h_ent->h_name, buflen);
321 return rt_addr_n2a(af, len, addr, buf, buflen);