summaryrefslogtreecommitdiffstats
path: root/lib/libUPnP/Neptune/Source/System/Bsd/NptBsdNetwork.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libUPnP/Neptune/Source/System/Bsd/NptBsdNetwork.cpp')
-rw-r--r--lib/libUPnP/Neptune/Source/System/Bsd/NptBsdNetwork.cpp651
1 files changed, 651 insertions, 0 deletions
diff --git a/lib/libUPnP/Neptune/Source/System/Bsd/NptBsdNetwork.cpp b/lib/libUPnP/Neptune/Source/System/Bsd/NptBsdNetwork.cpp
new file mode 100644
index 0000000..6208185
--- /dev/null
+++ b/lib/libUPnP/Neptune/Source/System/Bsd/NptBsdNetwork.cpp
@@ -0,0 +1,651 @@
+/*****************************************************************
+|
+| Neptune - Network :: BSD Implementation
+|
+| (c) 2001-2016 Gilles Boccon-Gibod
+| Author: Gilles Boccon-Gibod (bok@bok.net)
+|
+ ****************************************************************/
+
+/*----------------------------------------------------------------------
+| includes
++---------------------------------------------------------------------*/
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <net/if.h>
+//#include <net/if_arp.h>
+#include <netdb.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "NptConfig.h"
+#include "NptTypes.h"
+#include "NptStreams.h"
+#include "NptThreads.h"
+#include "NptNetwork.h"
+#include "NptUtils.h"
+#include "NptConstants.h"
+#include "NptSockets.h"
+
+#if defined(NPT_CONFIG_HAVE_NET_IF_DL_H)
+#include <net/if_dl.h>
+#endif
+#if defined(NPT_CONFIG_HAVE_NET_IF_TYPES_H)
+#include <net/if_types.h>
+#endif
+
+#if defined(NPT_CONFIG_HAVE_GETIFADDRS)
+#include <ifaddrs.h>
+#endif
+
+/*----------------------------------------------------------------------
+| platform adaptation
++---------------------------------------------------------------------*/
+#if !defined(IFHWADDRLEN)
+#define IFHWADDRLEN 6 // default to 48 bits
+#endif
+#if !defined(ARPHRD_ETHER)
+#define ARPHRD_ETHER 1
+#endif
+
+#if defined(_SIZEOF_ADDR_IFREQ)
+#define NPT_IFREQ_SIZE(ifr) _SIZEOF_ADDR_IFREQ(*ifr)
+#elif defined(NPT_CONFIG_HAVE_SOCKADDR_SA_LEN)
+#define NPT_IFREQ_SIZE(ifr) (sizeof(ifr->ifr_name) + ifr->ifr_addr.sa_len)
+#else
+#define NPT_IFREQ_SIZE(ifr) sizeof(*ifr)
+#endif
+
+/*----------------------------------------------------------------------
+| IPv6 support
++---------------------------------------------------------------------*/
+#if defined(NPT_CONFIG_HAVE_ARPA_INET_H)
+#include <arpa/inet.h>
+#endif
+
+/*----------------------------------------------------------------------
+| NPT_IpAddress::Any and NPT_IpAddress::Loopback
++---------------------------------------------------------------------*/
+#if defined(NPT_CONFIG_ENABLE_IPV6)
+const NPT_IpAddress NPT_IpAddress::Any(NPT_IpAddress::IPV6, in6addr_any.s6_addr, 16);
+const NPT_IpAddress NPT_IpAddress::Loopback(NPT_IpAddress::IPV6, in6addr_loopback.s6_addr, 16);
+#else
+const NPT_IpAddress NPT_IpAddress::Any;
+const NPT_IpAddress NPT_IpAddress::Loopback(127,0,0,1);
+#endif
+
+#if defined(NPT_CONFIG_HAVE_INET_NTOP)
+/*----------------------------------------------------------------------
+| NPT_IpAddress::ToString
++---------------------------------------------------------------------*/
+NPT_String
+NPT_IpAddress::ToString() const
+{
+ NPT_String address;
+ char workspace[128];
+ int af = AF_INET;
+#if defined(NPT_CONFIG_ENABLE_IPV6)
+ if (m_Type == IPV6) {
+ af = AF_INET6;
+ }
+#endif
+ const char* string = inet_ntop(af, &m_Address[0], workspace, sizeof(workspace));
+ if (string) {
+ address = string;
+ }
+
+ return address;
+}
+#else
+/*----------------------------------------------------------------------
+| NPT_IpAddress::ToString
++---------------------------------------------------------------------*/
+NPT_String
+NPT_IpAddress::ToString() const
+{
+ NPT_String address;
+ address.Reserve(16);
+ address += NPT_String::FromInteger(m_Address[0]);
+ address += '.';
+ address += NPT_String::FromInteger(m_Address[1]);
+ address += '.';
+ address += NPT_String::FromInteger(m_Address[2]);
+ address += '.';
+ address += NPT_String::FromInteger(m_Address[3]);
+
+ return address;
+}
+#endif
+
+#if defined(NPT_CONFIG_HAVE_INET_PTON)
+/*----------------------------------------------------------------------
+| NPT_IpAddress::Parse
++---------------------------------------------------------------------*/
+NPT_Result
+NPT_IpAddress::Parse(const char* name)
+{
+ int result;
+
+ // check the name
+ if (name == NULL) return NPT_ERROR_INVALID_PARAMETERS;
+
+ // clear the address
+ NPT_SetMemory(&m_Address[0], 0, sizeof(m_Address));
+
+#if defined(NPT_CONFIG_ENABLE_IPV6)
+ // try IPv6 first
+ result = inet_pton(AF_INET6, name, &m_Address[0]);
+ if (result > 0) {
+ m_Type = IPV6;
+ return NPT_SUCCESS;
+ }
+#endif
+
+ // try IPv4 next
+ result = inet_pton(AF_INET, name, &m_Address[0]);
+ if (result > 0) {
+ m_Type = IPV4;
+ return NPT_SUCCESS;
+ }
+
+ if (result == 0) {
+ return NPT_ERROR_INVALID_SYNTAX;
+ } else {
+ return NPT_FAILURE;
+ }
+}
+#else
+/*----------------------------------------------------------------------
+| NPT_IpAddress::Parse
++---------------------------------------------------------------------*/
+NPT_Result
+NPT_IpAddress::Parse(const char* name)
+{
+ // check the name
+ if (name == NULL) return NPT_ERROR_INVALID_PARAMETERS;
+
+ // clear the address
+ NPT_SetMemory(&m_Address[0], 0, sizeof(m_Address));
+
+ // parse
+ unsigned int fragment;
+ bool fragment_empty = true;
+ unsigned char address[4];
+ unsigned int accumulator;
+ for (fragment = 0, accumulator = 0; fragment < 4; ++name) {
+ if (*name == '\0' || *name == '.') {
+ // fragment terminator
+ if (fragment_empty) return NPT_ERROR_INVALID_SYNTAX;
+ address[fragment++] = accumulator;
+ if (*name == '\0') break;
+ accumulator = 0;
+ fragment_empty = true;
+ } else if (*name >= '0' && *name <= '9') {
+ // numerical character
+ accumulator = accumulator*10 + (*name - '0');
+ if (accumulator > 255) return NPT_ERROR_INVALID_SYNTAX;
+ fragment_empty = false;
+ } else {
+ // invalid character
+ return NPT_ERROR_INVALID_SYNTAX;
+ }
+ }
+
+ if (fragment == 4 && *name == '\0' && !fragment_empty) {
+ m_Address[0] = address[0];
+ m_Address[1] = address[1];
+ m_Address[2] = address[2];
+ m_Address[3] = address[3];
+ return NPT_SUCCESS;
+ } else {
+ return NPT_ERROR_INVALID_SYNTAX;
+ }
+}
+#endif
+
+#if defined(NPT_CONFIG_HAVE_GETIFADDRS)
+/*----------------------------------------------------------------------
+| NPT_NetworkInterface::GetNetworkInterfaces
++---------------------------------------------------------------------*/
+NPT_Result
+NPT_NetworkInterface::GetNetworkInterfaces(NPT_List<NPT_NetworkInterface*>& interfaces)
+{
+ interfaces.Clear();
+
+ struct ifaddrs* addrs = NULL;
+ int result = getifaddrs(&addrs);
+ if (result != 0) {
+ return NPT_ERROR_BASE_UNIX-errno;
+ }
+
+ for (struct ifaddrs* addr = addrs;
+ addr;
+ addr = addr->ifa_next) {
+
+ // get detailed info about the interface
+ NPT_Flags flags = 0;
+ // process the flags
+ if ((addr->ifa_flags & IFF_UP) == 0) {
+ // the interface is not up, ignore it
+ continue;
+ }
+ if (addr->ifa_flags & IFF_BROADCAST) {
+ flags |= NPT_NETWORK_INTERFACE_FLAG_BROADCAST;
+ }
+ if (addr->ifa_flags & IFF_LOOPBACK) {
+ flags |= NPT_NETWORK_INTERFACE_FLAG_LOOPBACK;
+ }
+#if defined(IFF_POINTOPOINT)
+ if (addr->ifa_flags & IFF_POINTOPOINT) {
+ flags |= NPT_NETWORK_INTERFACE_FLAG_POINT_TO_POINT;
+ }
+#endif // defined(IFF_POINTOPOINT)
+ if (addr->ifa_flags & IFF_PROMISC) {
+ flags |= NPT_NETWORK_INTERFACE_FLAG_PROMISCUOUS;
+ }
+ if (addr->ifa_flags & IFF_MULTICAST) {
+ flags |= NPT_NETWORK_INTERFACE_FLAG_MULTICAST;
+ }
+
+ // get a pointer to an interface we've looped over before
+ // or create a new one
+ NPT_NetworkInterface* interface = NULL;
+ for (NPT_List<NPT_NetworkInterface*>::Iterator iface_iter = interfaces.GetFirstItem();
+ iface_iter;
+ ++iface_iter) {
+ if ((*iface_iter)->GetName() == (const char*)addr->ifa_name) {
+ interface = *iface_iter;
+ break;
+ }
+ }
+ if (interface == NULL) {
+ // create a new interface object
+ interface = new NPT_NetworkInterface(addr->ifa_name, flags);
+
+ // add the interface to the list
+ interfaces.Add(interface);
+ }
+
+ if (addr->ifa_addr == NULL) {
+ continue;
+ }
+ switch (addr->ifa_addr->sa_family) {
+ case AF_INET: {
+ // primary address
+ NPT_IpAddress primary_address(ntohl(((struct sockaddr_in*)addr->ifa_addr)->sin_addr.s_addr));
+
+ // broadcast address
+ NPT_IpAddress broadcast_address;
+ if (addr->ifa_broadaddr) {
+ broadcast_address.Set(ntohl(((struct sockaddr_in*)addr->ifa_broadaddr)->sin_addr.s_addr));
+ }
+
+ // point to point address
+ NPT_IpAddress destination_address;
+ if (addr->ifa_dstaddr) {
+ destination_address.Set(ntohl(((struct sockaddr_in*)addr->ifa_dstaddr)->sin_addr.s_addr));
+ }
+
+ // netmask
+ NPT_IpAddress netmask(0xFFFFFFFF);
+ if (addr->ifa_netmask) {
+ netmask.Set(ntohl(((struct sockaddr_in*)addr->ifa_netmask)->sin_addr.s_addr));
+ }
+
+ // add the address to the interface
+ NPT_NetworkInterfaceAddress iface_address(
+ primary_address,
+ broadcast_address,
+ destination_address,
+ netmask);
+ interface->AddAddress(iface_address);
+
+ break;
+ }
+
+#if defined(NPT_CONFIG_ENABLE_IPV6)
+ case AF_INET6: {
+ // primary address
+ const struct sockaddr_in6* ipv6_address = (const struct sockaddr_in6*)addr->ifa_addr;
+ NPT_IpAddress primary_address(NPT_IpAddress::IPV6, ipv6_address->sin6_addr.s6_addr, 16, ipv6_address->sin6_scope_id);
+
+ // empty broadcast address (no broadcast address for IPv6)
+ NPT_IpAddress broadcast_address(NPT_IpAddress::IPV6);
+
+ // point to point address
+ NPT_IpAddress destination_address(NPT_IpAddress::IPV6);
+ if (flags & NPT_NETWORK_INTERFACE_FLAG_POINT_TO_POINT) {
+ if (addr->ifa_dstaddr) {
+ ipv6_address = (const struct sockaddr_in6*)addr->ifa_dstaddr;
+ destination_address.Set(ipv6_address->sin6_addr.s6_addr, 16, ipv6_address->sin6_scope_id);
+ }
+ }
+
+ // empty netmask (does not work for IPv6)
+ NPT_IpAddress netmask((NPT_IpAddress::IPV6));
+
+ // add the address to the interface
+ NPT_NetworkInterfaceAddress iface_address(
+ primary_address,
+ broadcast_address,
+ destination_address,
+ netmask);
+ interface->AddAddress(iface_address);
+
+ break;
+ }
+#endif
+
+#if defined(AF_LINK) && defined(NPT_CONFIG_HAVE_SOCKADDR_DL)
+ case AF_LINK: {
+ struct sockaddr_dl* mac_addr = (struct sockaddr_dl*)addr->ifa_addr;
+ NPT_MacAddress::Type mac_addr_type = NPT_MacAddress::TYPE_UNKNOWN;
+ switch (mac_addr->sdl_type) {
+#if defined(IFT_LOOP)
+ case IFT_LOOP: mac_addr_type = NPT_MacAddress::TYPE_LOOPBACK; break;
+#endif
+#if defined(IFT_ETHER)
+ case IFT_ETHER: mac_addr_type = NPT_MacAddress::TYPE_ETHERNET; break;
+#endif
+#if defined(IFT_PPP)
+ case IFT_PPP: mac_addr_type = NPT_MacAddress::TYPE_PPP; break;
+#endif
+ }
+ interface->SetMacAddress(mac_addr_type,
+ (const unsigned char*)(&mac_addr->sdl_data[mac_addr->sdl_nlen]),
+ mac_addr->sdl_alen);
+ break;
+ }
+#endif
+ }
+ }
+
+ freeifaddrs(addrs);
+
+ return NPT_SUCCESS;
+}
+#else
+const unsigned int NPT_BSD_NETWORK_MAX_IFCONF_SIZE = 1<<20;
+
+/*----------------------------------------------------------------------
+| NPT_NetworkInterface::GetNetworkInterfaces
++---------------------------------------------------------------------*/
+NPT_Result
+NPT_NetworkInterface::GetNetworkInterfaces(NPT_List<NPT_NetworkInterface*>& interfaces)
+{
+//#if defined(NPT_CONFIG_ENABLE_IPV6)
+// int net = socket(PF_INET6, SOCK_DGRAM, 0);
+//#else
+ int net = socket(PF_INET, SOCK_DGRAM, 0);
+//#endif
+ if (net < 0) {
+ return NPT_ERROR_BASE_UNIX-errno;
+ }
+
+ // Try to get the config until we have enough memory for it
+ // According to "Unix Network Programming", some implementations
+ // do not return an error when the supplied buffer is too small
+ // so we need to try, increasing the buffer size every time,
+ // until we get the same size twice. We cannot assume success when
+ // the returned size is smaller than the supplied buffer, because
+ // some implementations can return less that the buffer size if
+ // another structure does not fit.
+ unsigned int buffer_size = 4096; // initial guess
+ unsigned int last_size = 0;
+ struct ifconf config;
+ unsigned char* buffer = NULL;
+ for (;buffer_size < NPT_BSD_NETWORK_MAX_IFCONF_SIZE;) {
+ buffer = new unsigned char[buffer_size];
+ config.ifc_len = buffer_size;
+ config.ifc_buf = (char*)buffer;
+ if (ioctl(net, SIOCGIFCONF, &config) < 0) {
+ if (errno != EINVAL || last_size != 0) {
+ delete[] buffer;
+ close(net);
+ return NPT_ERROR_BASE_UNIX-errno;
+ }
+ } else {
+ if ((unsigned int)config.ifc_len == last_size) {
+ // same size, we can use the buffer
+ break;
+ }
+ // different size, we need to reallocate
+ last_size = config.ifc_len;
+ }
+
+ // supply 4096 more bytes more next time around
+ buffer_size += 4096;
+ delete[] buffer;
+ buffer = NULL;
+ }
+ if (buffer == NULL) {
+ close(net);
+ return NPT_ERROR_NOT_ENOUGH_SPACE;
+ }
+
+ // iterate over all objects
+ unsigned char *entries;
+ for (entries = (unsigned char*)config.ifc_req; entries < (unsigned char*)config.ifc_req+config.ifc_len;) {
+ struct ifreq* entry = (struct ifreq*)entries;
+
+ // point to the next entry
+ entries += NPT_IFREQ_SIZE(entry);
+
+ // ignore anything except AF_INET, AF_INET6 (if enabled) and AF_LINK addresses
+ if (entry->ifr_addr.sa_family != AF_INET
+#if defined(NPT_CONFIG_ENABLE_IPV6)
+ && entry->ifr_addr.sa_family != AF_INET6
+#endif
+#if defined(AF_LINK)
+ && entry->ifr_addr.sa_family != AF_LINK
+#endif
+ ) {
+ continue;
+ }
+
+ // get detailed info about the interface
+ NPT_Flags flags = 0;
+#if defined(SIOCGIFFLAGS)
+ struct ifreq query = *entry;
+ if (ioctl(net, SIOCGIFFLAGS, &query) < 0) continue;
+
+ // process the flags
+ if ((query.ifr_flags & IFF_UP) == 0) {
+ // the interface is not up, ignore it
+ continue;
+ }
+ if (query.ifr_flags & IFF_BROADCAST) {
+ flags |= NPT_NETWORK_INTERFACE_FLAG_BROADCAST;
+ }
+ if (query.ifr_flags & IFF_LOOPBACK) {
+ flags |= NPT_NETWORK_INTERFACE_FLAG_LOOPBACK;
+ }
+#if defined(IFF_POINTOPOINT)
+ if (query.ifr_flags & IFF_POINTOPOINT) {
+ flags |= NPT_NETWORK_INTERFACE_FLAG_POINT_TO_POINT;
+ }
+#endif // defined(IFF_POINTOPOINT)
+ if (query.ifr_flags & IFF_PROMISC) {
+ flags |= NPT_NETWORK_INTERFACE_FLAG_PROMISCUOUS;
+ }
+ if (query.ifr_flags & IFF_MULTICAST) {
+ flags |= NPT_NETWORK_INTERFACE_FLAG_MULTICAST;
+ }
+#endif // defined(SIOCGIFFLAGS)
+
+ // get a pointer to an interface we've looped over before
+ // or create a new one
+ NPT_NetworkInterface* interface = NULL;
+ for (NPT_List<NPT_NetworkInterface*>::Iterator iface_iter = interfaces.GetFirstItem();
+ iface_iter;
+ ++iface_iter) {
+ if ((*iface_iter)->GetName() == (const char*)entry->ifr_name) {
+ interface = *iface_iter;
+ break;
+ }
+ }
+ if (interface == NULL) {
+ // create a new interface object
+ interface = new NPT_NetworkInterface(entry->ifr_name, flags);
+
+ // add the interface to the list
+ interfaces.Add(interface);
+
+ // get the mac address
+#if defined(SIOCGIFHWADDR)
+ if (ioctl(net, SIOCGIFHWADDR, &query) == 0) {
+ NPT_MacAddress::Type mac_addr_type;
+ unsigned int mac_addr_length = IFHWADDRLEN;
+ switch (query.ifr_addr.sa_family) {
+#if defined(ARPHRD_ETHER)
+ case ARPHRD_ETHER:
+ mac_addr_type = NPT_MacAddress::TYPE_ETHERNET;
+ break;
+#endif
+
+#if defined(ARPHRD_LOOPBACK)
+ case ARPHRD_LOOPBACK:
+ mac_addr_type = NPT_MacAddress::TYPE_LOOPBACK;
+ length = 0;
+ break;
+#endif
+
+#if defined(ARPHRD_PPP)
+ case ARPHRD_PPP:
+ mac_addr_type = NPT_MacAddress::TYPE_PPP;
+ mac_addr_length = 0;
+ break;
+#endif
+
+#if defined(ARPHRD_IEEE80211)
+ case ARPHRD_IEEE80211:
+ mac_addr_type = NPT_MacAddress::TYPE_IEEE_802_11;
+ break;
+#endif
+
+ default:
+ mac_addr_type = NPT_MacAddress::TYPE_UNKNOWN;
+ mac_addr_length = sizeof(query.ifr_addr.sa_data);
+ break;
+ }
+
+ interface->SetMacAddress(mac_addr_type, (const unsigned char*)query.ifr_addr.sa_data, mac_addr_length);
+ }
+#endif
+ }
+
+ switch (entry->ifr_addr.sa_family) {
+ case AF_INET: {
+ // primary address
+ NPT_IpAddress primary_address(ntohl(((struct sockaddr_in*)&entry->ifr_addr)->sin_addr.s_addr));
+
+ // broadcast address
+ NPT_IpAddress broadcast_address;
+#if defined(SIOCGIFBRDADDR)
+ if (flags & NPT_NETWORK_INTERFACE_FLAG_BROADCAST) {
+ if (ioctl(net, SIOCGIFBRDADDR, &query) == 0) {
+ broadcast_address.Set(ntohl(((struct sockaddr_in*)&query.ifr_addr)->sin_addr.s_addr));
+ }
+ }
+#endif
+
+ // point to point address
+ NPT_IpAddress destination_address;
+#if defined(SIOCGIFDSTADDR)
+ if (flags & NPT_NETWORK_INTERFACE_FLAG_POINT_TO_POINT) {
+ if (ioctl(net, SIOCGIFDSTADDR, &query) == 0) {
+ destination_address.Set(ntohl(((struct sockaddr_in*)&query.ifr_addr)->sin_addr.s_addr));
+ }
+ }
+#endif
+
+ // netmask
+ NPT_IpAddress netmask(0xFFFFFFFF);
+#if defined(SIOCGIFNETMASK)
+ if (ioctl(net, SIOCGIFNETMASK, &query) == 0) {
+ netmask.Set(ntohl(((struct sockaddr_in*)&query.ifr_addr)->sin_addr.s_addr));
+ }
+#endif
+
+ // add the address to the interface
+ NPT_NetworkInterfaceAddress iface_address(
+ primary_address,
+ broadcast_address,
+ destination_address,
+ netmask);
+ interface->AddAddress(iface_address);
+
+ break;
+ }
+
+#if defined(NPT_CONFIG_ENABLE_IPV6)
+ case AF_INET6: {
+ // primary address
+ const struct sockaddr_in6* ipv6_address = (const struct sockaddr_in6*)&entry->ifr_addr;
+ NPT_IpAddress primary_address(NPT_IpAddress::IPV6, ipv6_address->sin6_addr.s6_addr, 16, ipv6_address->sin6_scope_id);
+
+ // empty broadcast address (no broadcast address for IPv6)
+ NPT_IpAddress broadcast_address(NPT_IpAddress::IPV6);
+
+ // point to point address
+ NPT_IpAddress destination_address(NPT_IpAddress::IPV6);
+#if defined(SIOCGIFDSTADDR)
+ if (flags & NPT_NETWORK_INTERFACE_FLAG_POINT_TO_POINT) {
+ if (ioctl(net, SIOCGIFDSTADDR, &query) == 0) {
+ ipv6_address = (const struct sockaddr_in6*)&query.ifr_addr;
+ destination_address.Set(ipv6_address->sin6_addr.s6_addr, 16, ipv6_address->sin6_scope_id);
+ }
+ }
+#endif
+
+ // empty netmask (does not work for IPv6)
+ NPT_IpAddress netmask((NPT_IpAddress::IPV6));
+
+ // add the address to the interface
+ NPT_NetworkInterfaceAddress iface_address(
+ primary_address,
+ broadcast_address,
+ destination_address,
+ netmask);
+ interface->AddAddress(iface_address);
+
+ break;
+ }
+#endif
+
+#if defined(AF_LINK) && defined(NPT_CONFIG_HAVE_SOCKADDR_DL)
+ case AF_LINK: {
+ struct sockaddr_dl* mac_addr = (struct sockaddr_dl*)&entry->ifr_addr;
+ NPT_MacAddress::Type mac_addr_type = NPT_MacAddress::TYPE_UNKNOWN;
+ switch (mac_addr->sdl_type) {
+#if defined(IFT_LOOP)
+ case IFT_LOOP: mac_addr_type = NPT_MacAddress::TYPE_LOOPBACK; break;
+#endif
+#if defined(IFT_ETHER)
+ case IFT_ETHER: mac_addr_type = NPT_MacAddress::TYPE_ETHERNET; break;
+#endif
+#if defined(IFT_PPP)
+ case IFT_PPP: mac_addr_type = NPT_MacAddress::TYPE_PPP; break;
+#endif
+ }
+ interface->SetMacAddress(mac_addr_type,
+ (const unsigned char*)(&mac_addr->sdl_data[mac_addr->sdl_nlen]),
+ mac_addr->sdl_alen);
+ break;
+ }
+#endif
+ }
+ }
+
+ // free resources
+ delete[] buffer;
+ close(net);
+
+ return NPT_SUCCESS;
+}
+#endif