source: MondoRescue/branches/stable/mindi-busybox/networking/libiproute/utils.c@ 821

Last change on this file since 821 was 821, checked in by Bruno Cornec, 18 years ago

Addition of busybox 1.2.1 as a mindi-busybox new package
This should avoid delivering binary files in mindi not built there (Fedora and Debian are quite serious about that)

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