blob: 161c8ea3c13cfbeff9e45f9c588e0c856209564d
1 | /* vi: set sw=4 ts=4: */ |
2 | /* |
3 | * Utility routines. |
4 | */ |
5 | |
6 | //kbuild:lib-$(CONFIG_ARP) += in_ether.o |
7 | //kbuild:lib-$(CONFIG_IFCONFIG) += in_ether.o |
8 | //kbuild:lib-$(CONFIG_IFENSLAVE) += in_ether.o |
9 | |
10 | #include "libbb.h" |
11 | #include <net/if_arp.h> |
12 | #include <net/ethernet.h> |
13 | |
14 | /* Convert Ethernet address from "XX[:]XX[:]XX[:]XX[:]XX[:]XX" to sockaddr. |
15 | * Return nonzero on error. |
16 | */ |
17 | int FAST_FUNC in_ether(const char *bufp, struct sockaddr *sap) |
18 | { |
19 | char *ptr; |
20 | int i, j; |
21 | unsigned char val; |
22 | unsigned char c; |
23 | |
24 | sap->sa_family = ARPHRD_ETHER; |
25 | ptr = (char *) sap->sa_data; |
26 | |
27 | i = ETH_ALEN; |
28 | goto first; |
29 | do { |
30 | /* We might get a semicolon here */ |
31 | if (*bufp == ':') |
32 | bufp++; |
33 | first: |
34 | j = val = 0; |
35 | do { |
36 | c = *bufp; |
37 | if (((unsigned char)(c - '0')) <= 9) { |
38 | c -= '0'; |
39 | } else if ((unsigned char)((c|0x20) - 'a') <= 5) { |
40 | c = (unsigned char)((c|0x20) - 'a') + 10; |
41 | } else { |
42 | if (j && (c == ':' || c == '\0')) |
43 | /* One-digit byte: __:X:__ */ |
44 | break; |
45 | return -1; |
46 | } |
47 | ++bufp; |
48 | val <<= 4; |
49 | val += c; |
50 | j ^= 1; |
51 | } while (j); |
52 | |
53 | *ptr++ = val; |
54 | } while (--i); |
55 | |
56 | /* Error if we aren't at end of string */ |
57 | return *bufp; |
58 | } |
59 |