ebe6d9d875
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
58 lines
1.1 KiB
C
58 lines
1.1 KiB
C
/* vi: set sw=4 ts=4: */
|
|
/*
|
|
* Utility routines.
|
|
*/
|
|
//kbuild:lib-$(CONFIG_ARP) += in_ether.o
|
|
//kbuild:lib-$(CONFIG_IFCONFIG) += in_ether.o
|
|
//kbuild:lib-$(CONFIG_IFENSLAVE) += in_ether.o
|
|
|
|
#include "libbb.h"
|
|
#include <net/if_arp.h>
|
|
#include <net/ethernet.h>
|
|
|
|
/* Convert Ethernet address from "XX[:]XX[:]XX[:]XX[:]XX[:]XX" to sockaddr.
|
|
* Return nonzero on error.
|
|
*/
|
|
int FAST_FUNC in_ether(const char *bufp, struct sockaddr *sap)
|
|
{
|
|
char *ptr;
|
|
int i, j;
|
|
unsigned char val;
|
|
unsigned char c;
|
|
|
|
sap->sa_family = ARPHRD_ETHER;
|
|
ptr = (char *) sap->sa_data;
|
|
|
|
i = ETH_ALEN;
|
|
goto first;
|
|
do {
|
|
/* We might get a semicolon here */
|
|
if (*bufp == ':')
|
|
bufp++;
|
|
first:
|
|
j = val = 0;
|
|
do {
|
|
c = *bufp;
|
|
if (((unsigned char)(c - '0')) <= 9) {
|
|
c -= '0';
|
|
} else if ((unsigned char)((c|0x20) - 'a') <= 5) {
|
|
c = (unsigned char)((c|0x20) - 'a') + 10;
|
|
} else {
|
|
if (j && (c == ':' || c == '\0'))
|
|
/* One-digit byte: __:X:__ */
|
|
break;
|
|
return -1;
|
|
}
|
|
++bufp;
|
|
val <<= 4;
|
|
val += c;
|
|
j ^= 1;
|
|
} while (j);
|
|
|
|
*ptr++ = val;
|
|
} while (--i);
|
|
|
|
/* Error if we aren't at end of string */
|
|
return *bufp;
|
|
}
|