summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/libimobiledevice-glue/socket.h2
-rw-r--r--src/socket.c62
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;