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