source: MondoRescue/branches/2.2.8.selinux/mindi-busybox/networking/libiproute/utils.c@ 3332

Last change on this file since 3332 was 1765, checked in by Bruno Cornec, 17 years ago

Update to busybox 1.7.2

File size: 6.0 KB
Line 
1/* vi: set sw=4 ts=4: */
2/*
3 * utils.c
4 *
5 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
6 *
7 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
8 *
9 * Changes:
10 *
11 * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses
12 */
13
14#include "libbb.h"
15#include "utils.h"
16#include "inet_common.h"
17
18int get_integer(int *val, char *arg, int base)
19{
20 long res;
21 char *ptr;
22
23 if (!arg || !*arg)
24 return -1;
25 res = strtol(arg, &ptr, base);
26 if (!ptr || ptr == arg || *ptr || res > INT_MAX || res < INT_MIN)
27 return -1;
28 *val = res;
29 return 0;
30}
31//XXX: FIXME: use some libbb function instead
32int get_unsigned(unsigned *val, char *arg, int base)
33{
34 unsigned long res;
35 char *ptr;
36
37 if (!arg || !*arg)
38 return -1;
39 res = strtoul(arg, &ptr, base);
40 if (!ptr || ptr == arg || *ptr || res > UINT_MAX)
41 return -1;
42 *val = res;
43 return 0;
44}
45
46int get_u32(uint32_t * val, char *arg, int base)
47{
48 unsigned long res;
49 char *ptr;
50
51 if (!arg || !*arg)
52 return -1;
53 res = strtoul(arg, &ptr, base);
54 if (!ptr || ptr == arg || *ptr || res > 0xFFFFFFFFUL)
55 return -1;
56 *val = res;
57 return 0;
58}
59
60int get_u16(uint16_t * val, char *arg, int base)
61{
62 unsigned long res;
63 char *ptr;
64
65 if (!arg || !*arg)
66 return -1;
67 res = strtoul(arg, &ptr, base);
68 if (!ptr || ptr == arg || *ptr || res > 0xFFFF)
69 return -1;
70 *val = res;
71 return 0;
72}
73
74int get_u8(uint8_t * val, char *arg, int base)
75{
76 unsigned long res;
77 char *ptr;
78
79 if (!arg || !*arg)
80 return -1;
81 res = strtoul(arg, &ptr, base);
82 if (!ptr || ptr == arg || *ptr || res > 0xFF)
83 return -1;
84 *val = res;
85 return 0;
86}
87
88int get_s16(int16_t * val, char *arg, int base)
89{
90 long res;
91 char *ptr;
92
93 if (!arg || !*arg)
94 return -1;
95 res = strtol(arg, &ptr, base);
96 if (!ptr || ptr == arg || *ptr || res > 0x7FFF || res < -0x8000)
97 return -1;
98 *val = res;
99 return 0;
100}
101
102int get_s8(int8_t * val, char *arg, int base)
103{
104 long res;
105 char *ptr;
106
107 if (!arg || !*arg)
108 return -1;
109 res = strtol(arg, &ptr, base);
110 if (!ptr || ptr == arg || *ptr || res > 0x7F || res < -0x80)
111 return -1;
112 *val = res;
113 return 0;
114}
115
116int get_addr_1(inet_prefix * addr, char *name, int family)
117{
118 char *cp;
119 unsigned char *ap = (unsigned char *) addr->data;
120 int i;
121
122 memset(addr, 0, sizeof(*addr));
123
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);
128 addr->bitlen = -1;
129 return 0;
130 }
131
132 if (strchr(name, ':')) {
133 addr->family = AF_INET6;
134 if (family != AF_UNSPEC && family != AF_INET6)
135 return -1;
136 if (inet_pton(AF_INET6, name, addr->data) <= 0)
137 return -1;
138 addr->bytelen = 16;
139 addr->bitlen = -1;
140 return 0;
141 }
142
143 addr->family = AF_INET;
144 if (family != AF_UNSPEC && family != AF_INET)
145 return -1;
146 addr->bytelen = 4;
147 addr->bitlen = -1;
148 for (cp = name, i = 0; *cp; cp++) {
149 if (*cp <= '9' && *cp >= '0') {
150 ap[i] = 10 * ap[i] + (*cp - '0');
151 continue;
152 }
153 if (*cp == '.' && ++i <= 3)
154 continue;
155 return -1;
156 }
157 return 0;
158}
159
160int get_prefix_1(inet_prefix * dst, char *arg, int family)
161{
162 int err;
163 int plen;
164 char *slash;
165
166 memset(dst, 0, sizeof(*dst));
167
168 if (strcmp(arg, bb_str_default) == 0 || strcmp(arg, "any") == 0) {
169 dst->family = family;
170 dst->bytelen = 0;
171 dst->bitlen = 0;
172 return 0;
173 }
174
175 slash = strchr(arg, '/');
176 if (slash)
177 *slash = '\0';
178 err = get_addr_1(dst, arg, family);
179 if (err == 0) {
180 switch (dst->family) {
181 case AF_INET6:
182 dst->bitlen = 128;
183 break;
184 default:
185 case AF_INET:
186 dst->bitlen = 32;
187 }
188 if (slash) {
189 if (get_integer(&plen, slash + 1, 0) || plen > dst->bitlen) {
190 err = -1;
191 goto done;
192 }
193 dst->bitlen = plen;
194 }
195 }
196 done:
197 if (slash)
198 *slash = '/';
199 return err;
200}
201
202int get_addr(inet_prefix * dst, char *arg, int family)
203{
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);
206 }
207 if (get_addr_1(dst, arg, family)) {
208 bb_error_msg_and_die("an inet address is expected rather than \"%s\"", arg);
209 }
210 return 0;
211}
212
213int get_prefix(inet_prefix * dst, char *arg, int family)
214{
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);
217 }
218 if (get_prefix_1(dst, arg, family)) {
219 bb_error_msg_and_die("an inet address is expected rather than \"%s\"", arg);
220 }
221 return 0;
222}
223
224uint32_t get_addr32(char *name)
225{
226 inet_prefix addr;
227
228 if (get_addr_1(&addr, name, AF_INET)) {
229 bb_error_msg_and_die("an IP address is expected rather than \"%s\"", name);
230 }
231 return addr.data[0];
232}
233
234void incomplete_command(void)
235{
236 bb_error_msg_and_die("command line is not complete, try option \"help\"");
237}
238
239void invarg(const char *arg, const char *opt)
240{
241 bb_error_msg_and_die(bb_msg_invalid_arg, arg, opt);
242}
243
244void duparg(const char *key, const char *arg)
245{
246 bb_error_msg_and_die("duplicate \"%s\": \"%s\" is the second value", key, arg);
247}
248
249void duparg2(const char *key, const char *arg)
250{
251 bb_error_msg_and_die("either \"%s\" is duplicate, or \"%s\" is garbage", key, arg);
252}
253
254int inet_addr_match(inet_prefix * a, inet_prefix * b, int bits)
255{
256 uint32_t *a1 = a->data;
257 uint32_t *a2 = b->data;
258 int words = bits >> 0x05;
259
260 bits &= 0x1f;
261
262 if (words)
263 if (memcmp(a1, a2, words << 2))
264 return -1;
265
266 if (bits) {
267 uint32_t w1, w2;
268 uint32_t mask;
269
270 w1 = a1[words];
271 w2 = a2[words];
272
273 mask = htonl((0xffffffff) << (0x20 - bits));
274
275 if ((w1 ^ w2) & mask)
276 return 1;
277 }
278
279 return 0;
280}
281
282const char *rt_addr_n2a(int af, int ATTRIBUTE_UNUSED len,
283 void *addr, char *buf, int buflen)
284{
285 switch (af) {
286 case AF_INET:
287 case AF_INET6:
288 return inet_ntop(af, addr, buf, buflen);
289 default:
290 return "???";
291 }
292}
293
294
295const char *format_host(int af, int len, void *addr, char *buf, int buflen)
296{
297#ifdef RESOLVE_HOSTNAMES
298 if (resolve_hosts) {
299 struct hostent *h_ent;
300
301 if (len <= 0) {
302 switch (af) {
303 case AF_INET:
304 len = 4;
305 break;
306 case AF_INET6:
307 len = 16;
308 break;
309 default:;
310 }
311 }
312 if (len > 0) {
313 h_ent = gethostbyaddr(addr, len, af);
314 if (h_ent != NULL) {
315 safe_strncpy(buf, h_ent->h_name, buflen);
316 return buf;
317 }
318 }
319 }
320#endif
321 return rt_addr_n2a(af, len, addr, buf, buflen);
322}
Note: See TracBrowser for help on using the repository browser.