#include <pcap.h>
#include <ifaddrs.h>
#if defined(NMRPFLASH_LINUX)
-#define NMRPFLASH_AF_ETHERNET AF_PACKET
+#define NMRPFLASH_AF_PACKET AF_PACKET
#include <linux/if_packet.h>
-#elif defined (NMRPFLASH_OSX)
-#define NMRPFLASH_AF_ETHERNET AF_LINK
-#include <net/if_dl.h>
+#else
+#define NMRPFLASH_AF_PACKET AF_LINK
+#include <net/if_types.h>
#endif
#endif
}
#ifndef NMRPFLASH_WINDOWS
-static bool get_hwaddr(uint8_t *hwaddr, const char *intf)
+static inline bool sockaddr_get_hwaddr(struct sockaddr *sa, uint8_t *hwaddr)
{
- struct ifaddrs *ifas, *ifa;
void *src;
+
+ if (sa->sa_family != NMRPFLASH_AF_PACKET) {
+ return false;
+ }
+
+#ifndef NMRPFLASH_LINUX
+ if (((struct sockaddr_dl*)addr)->sdl_type != IFT_ETHER) {
+ return false;
+ }
+ src = LLADDR((struct sockaddr_dl*)sa);
+#else
+ src = ((struct sockaddr_ll*)sa)->sll_addr;
+#endif
+
+ memcpy(hwaddr, src, 6);
+ return true;
+}
+
+static bool get_hwaddr_from_intf(const char *intf, uint8_t *hwaddr)
+{
+ struct ifaddrs *ifas, *ifa;
bool found;
if (getifaddrs(&ifas) != 0) {
for (ifa = ifas; ifa; ifa = ifa->ifa_next) {
if (!strcmp(ifa->ifa_name, intf)) {
- if (ifa->ifa_addr->sa_family != NMRPFLASH_AF_ETHERNET) {
- continue;
+ if (sockaddr_get_hwaddr(ifa->ifa_addr, hwaddr)) {
+ found = true;
+ break;
}
-#ifdef NMRPFLASH_LINUX
- src = ((struct sockaddr_ll*)ifa->ifa_addr)->sll_addr;
-#else
- src = LLADDR((struct sockaddr_dl*)ifa->ifa_addr);
-#endif
- memcpy(hwaddr, src, 6);
- found = true;
- break;
}
}
freeifaddrs(ifas);
return found;
}
+
#else
void win_perror2(const char *msg, DWORD err)
}
}
-static bool get_hwaddr(uint8_t *hwaddr, const char *intf)
+static bool get_hwaddr_from_intf(const char *intf, uint8_t *hwaddr)
{
PIP_ADAPTER_INFO adapters, adapter;
DWORD ret;
continue;
}
-#ifndef NMRPFLASH_WINDOWS
- if (!strcmp(intf, adapter->AdapterName))
-#else
/* Interface names from WinPcap are "\Device\NPF_{GUID}", while
* AdapterName from GetAdaptersInfo is just "{GUID}".*/
- if (strstr(intf, adapter->AdapterName))
-#endif
- {
+ if (strstr(intf, adapter->AdapterName)) {
if (adapter->AddressLength == 6) {
for (i = 0; i != 6; ++i) {
hwaddr[i] = adapter->Address[i];
}
#endif
-
inline uint8_t *ethsock_get_hwaddr(struct ethsock *sock)
{
return sock->hwaddr;
goto cleanup_pcap;
}
- if (!get_hwaddr(sock->hwaddr, intf)) {
+ if (!get_hwaddr_from_intf(intf, sock->hwaddr)) {
fprintf(stderr, "Failed to get MAC address of interface.\n");
goto cleanup_malloc;
}
return 0;
}
-static bool is_ethernet(const pcap_if_t *dev)
+static bool get_hwaddr_from_pcap(const pcap_if_t *dev, uint8_t *hwaddr)
{
- pcap_t *pcap;
+#ifndef NMRPFLASH_WINDOWS
pcap_addr_t *addr;
int i;
- char errbuf[PCAP_ERRBUF_SIZE];
- bool ret = false;
for (addr = dev->addresses; addr; addr = addr->next) {
if (verbosity > 1) {
printf("}\n");
}
- if (addr->addr->sa_family == NMRPFLASH_AF_ETHERNET) {
+ if (sockaddr_get_hwaddr(addr->addr, hwaddr)) {
return true;
}
}
+#endif
- if ((pcap = pcap_create(dev->name, errbuf))) {
- if (pcap_activate(pcap) == 0) {
- ret = (pcap_datalink(pcap) == DLT_EN10MB);
- }
- pcap_close(pcap);
- }
-
- return ret;
+ return get_hwaddr_from_intf(dev->name, hwaddr);
}
int ethsock_list_all(void)
continue;
}
- if (!is_ethernet(dev)) {
+ if (!get_hwaddr_from_pcap(dev, hwaddr)) {
if (verbosity) {
printf("%-15s (not an ethernet device)\n",
dev->name);
continue;
}
- if (!get_hwaddr(hwaddr, dev->name)) {
- if (verbosity) {
- printf("%-15s (failed to get hardware address)\n",
- dev->name);
- }
- continue;
- }
-
#ifndef NMRPFLASH_WINDOWS
printf("%-15s", dev->name);
#else