diff options
-rw-r--r-- | include/libimobiledevice-glue/socket.h | 2 | ||||
-rw-r--r-- | src/socket.c | 62 |
2 files changed, 64 insertions, 0 deletions
diff --git a/include/libimobiledevice-glue/socket.h b/include/libimobiledevice-glue/socket.h index 9567270..fac5df5 100644 --- a/include/libimobiledevice-glue/socket.h +++ b/include/libimobiledevice-glue/socket.h @@ -65,4 +65,6 @@ void socket_set_verbose(int level); const char *socket_addr_to_string(struct sockaddr *addr, char *addr_out, size_t addr_out_size); +int get_primary_mac_address(unsigned char mac_addr_buf[6]); + #endif /* SOCKET_SOCKET_H */ diff --git a/src/socket.c b/src/socket.c index 067ef41..2ffab4a 100644 --- a/src/socket.c +++ b/src/socket.c @@ -55,6 +55,12 @@ static int wsa_init = 0; #ifdef AF_INET6 #include <net/if.h> #include <ifaddrs.h> +#ifdef __APPLE__ +#include <net/if_dl.h> +#endif +#ifdef __linux__ +#include <netpacket/packet.h> +#endif #endif #endif #include "common.h" @@ -417,6 +423,7 @@ static void freeifaddrs(struct ifaddrs *ifa) free(ifa->ifa_addr); free(ifa->ifa_netmask); free(ifa->ifa_dstaddr); + free(ifa->ifa_data); freeifaddrs(ifa->ifa_next); free(ifa); } @@ -501,6 +508,7 @@ static int getifaddrs(struct ifaddrs** ifap) ifa = ifanew; ifa->ifa_next = NULL; } + ifa->ifa_data = NULL; /* name */ ifa->ifa_name = strdup(adapter->AdapterName); @@ -522,6 +530,12 @@ static int getifaddrs(struct ifaddrs** ifap) ifa->ifa_netmask = (struct sockaddr*)malloc(sizeof(struct sockaddr_storage)); memset(ifa->ifa_netmask, 0, sizeof(struct sockaddr_storage)); + /* store mac address */ + if (adapter->PhysicalAddressLength == 6) { + ifa->ifa_data = malloc(6); + memcpy(ifa->ifa_data, adapter->PhysicalAddress, 6); + } + /* pre-Vista must hunt for matching prefix in linked list, otherwise use * OnLinkPrefixLength from IP_ADAPTER_UNICAST_ADDRESS structure. * FirstPrefix requires Windows XP SP1, from SP1 to pre-Vista provides a @@ -685,6 +699,54 @@ static int getifaddrs(struct ifaddrs** ifap) #endif #endif +LIBIMOBILEDEVICE_GLUE_API int get_primary_mac_address(unsigned char mac_addr_buf[6]) +{ + int result = -1; + struct ifaddrs *ifaddr = NULL, *ifa = NULL; + if (getifaddrs(&ifaddr) != -1) { + for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { + if (ifa->ifa_addr == NULL) { + continue; + } + if ((ifa->ifa_flags & IFF_UP) == 0) { + continue; + } + if (ifa->ifa_flags & IFF_LOOPBACK) { + continue; + } +#if defined(__APPLE__) + if (ifa->ifa_addr->sa_family != AF_LINK) { + continue; + } + if (!strcmp(ifa->ifa_name, "en0")) { + memcpy(mac_addr_buf, (unsigned char *)LLADDR((struct sockaddr_dl *)(ifa)->ifa_addr), 6); + result = 0; + break; + } +#elif defined (__linux__) + if (ifa->ifa_addr->sa_family != AF_PACKET) { + continue; + } + if (strcmp(ifa->ifa_name, "lo") != 0) { + memcpy(mac_addr_buf, ((struct sockaddr_ll*)ifa->ifa_addr)->sll_addr, 6); + result = 0; + break; + } +#elif defined (WIN32) + if (ifa->ifa_data) { + memcpy(mac_addr_buf, ifa->ifa_data, 6); + result = 0; + break; + } +#else +#error get_primary_mac_address is not supported on this platform. +#endif + } + freeifaddrs(ifaddr); + } + return result; +} + static int32_t _sockaddr_in6_scope_id(struct sockaddr_in6* addr) { int32_t res = -1; |