Author: axeld Date: 2010-12-09 01:06:45 +0100 (Thu, 09 Dec 2010) New Revision: 39779 Changeset: http://dev.haiku-os.org/changeset/39779 Modified: haiku/trunk/headers/os/net/NetworkAddress.h haiku/trunk/src/kits/network/libnetapi/NetworkAddress.cpp Log: * Added ability to parse link level addresses. Modified: haiku/trunk/headers/os/net/NetworkAddress.h =================================================================== --- haiku/trunk/headers/os/net/NetworkAddress.h 2010-12-08 23:42:47 UTC (rev 39778) +++ haiku/trunk/headers/os/net/NetworkAddress.h 2010-12-09 00:06:45 UTC (rev 39779) @@ -142,6 +142,9 @@ operator sockaddr&(); private: + status_t _ParseLinkAddress(const char* address); + +private: sockaddr_storage fAddress; status_t fStatus; }; Modified: haiku/trunk/src/kits/network/libnetapi/NetworkAddress.cpp =================================================================== --- haiku/trunk/src/kits/network/libnetapi/NetworkAddress.cpp 2010-12-08 23:42:47 UTC (rev 39778) +++ haiku/trunk/src/kits/network/libnetapi/NetworkAddress.cpp 2010-12-09 00:06:45 UTC (rev 39779) @@ -10,12 +10,26 @@ #include <NetworkRoster.h> #include <arpa/inet.h> +#include <ctype.h> #include <errno.h> #include <netinet/in.h> #include <stdio.h> #include <sys/sockio.h> +static uint8 +from_hex(char hex) +{ + if (isdigit(hex)) + return hex - '0'; + + return tolower(hex) - 'a' + 10; +} + + +// #pragma mark - + + BNetworkAddress::BNetworkAddress() { Unset(); @@ -163,6 +177,12 @@ status_t BNetworkAddress::SetTo(int family, const char* host, uint16 port, uint32 flags) { + if (family == AF_LINK) { + if (port != 0) + return B_BAD_VALUE; + return _ParseLinkAddress(host); + } + BNetworkAddressResolver resolver; status_t status = resolver.SetTo(family, host, port, flags); if (status != B_OK) @@ -177,6 +197,12 @@ BNetworkAddress::SetTo(int family, const char* host, const char* service, uint32 flags) { + if (family == AF_LINK) { + if (service != NULL) + return B_BAD_VALUE; + return _ParseLinkAddress(host); + } + BNetworkAddressResolver resolver; status_t status = resolver.SetTo(family, host, service, flags); if (status != B_OK) @@ -1136,3 +1162,31 @@ { return (sockaddr&)fAddress; } + + +// #pragma mark - private + + +status_t +BNetworkAddress::_ParseLinkAddress(const char* address) +{ + uint8 linkAddress[128]; + uint32 length = 0; + while (length < sizeof(linkAddress)) { + if (!isxdigit(address[0]) || !isxdigit(address[1])) + return B_BAD_VALUE; + + linkAddress[length++] = (from_hex(address[0]) << 4) + | from_hex(address[1]); + + if (address[2] == '\0') + break; + if (address[2] != ':') + return B_BAD_VALUE; + + address += 3; + } + + SetToLinkLevel(linkAddress, length); + return B_OK; +}