mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-02 04:22:27 +00:00
ptp-helper: Fix interface listing and MAC retrieval on OSX
This commit is contained in:
parent
957a81eef9
commit
d33784ccd0
1 changed files with 102 additions and 27 deletions
|
@ -41,6 +41,11 @@
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <ifaddrs.h>
|
||||||
|
#include <net/if_dl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_PTP_HELPER_SETUID
|
#ifdef HAVE_PTP_HELPER_SETUID
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
|
@ -235,6 +240,7 @@ setup_sockets (void)
|
||||||
|
|
||||||
/* Probe all non-loopback interfaces */
|
/* Probe all non-loopback interfaces */
|
||||||
if (!ifaces) {
|
if (!ifaces) {
|
||||||
|
#ifndef __APPLE__
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
struct ifconf ifc;
|
struct ifconf ifc;
|
||||||
gchar buf[8192];
|
gchar buf[8192];
|
||||||
|
@ -242,39 +248,56 @@ setup_sockets (void)
|
||||||
ifc.ifc_len = sizeof (buf);
|
ifc.ifc_len = sizeof (buf);
|
||||||
ifc.ifc_buf = buf;
|
ifc.ifc_buf = buf;
|
||||||
if (ioctl (g_socket_get_fd (socket_event), SIOCGIFCONF, &ifc) != -1) {
|
if (ioctl (g_socket_get_fd (socket_event), SIOCGIFCONF, &ifc) != -1) {
|
||||||
struct ifreq *it = ifc.ifc_req;
|
guint i, idx = 0;
|
||||||
const struct ifreq *const end =
|
|
||||||
it + (ifc.ifc_len / sizeof (struct ifreq));
|
|
||||||
guint idx = 0;
|
|
||||||
|
|
||||||
probed_ifaces = g_new0 (gchar *, ifc.ifc_len + 1);
|
probed_ifaces = g_new0 (gchar *, ifc.ifc_len + 1);
|
||||||
|
|
||||||
for (; it != end; ++it) {
|
for (i = 0; i < ifc.ifc_len / sizeof (struct ifreq); i++) {
|
||||||
strcpy (ifr.ifr_name, it->ifr_name);
|
strcpy (ifr.ifr_name, ifc.ifc_req[i].ifr_name);
|
||||||
if (ioctl (g_socket_get_fd (socket_event), SIOCGIFFLAGS, &ifr) == 0) {
|
if (ioctl (g_socket_get_fd (socket_event), SIOCGIFFLAGS, &ifr) == 0) {
|
||||||
if ((ifr.ifr_flags & IFF_LOOPBACK))
|
if ((ifr.ifr_flags & IFF_LOOPBACK))
|
||||||
continue;
|
continue;
|
||||||
probed_ifaces[idx] = g_strdup (it->ifr_name);
|
probed_ifaces[idx] = g_strdup (ifc.ifc_req[i].ifr_name);
|
||||||
idx++;
|
idx++;
|
||||||
} else {
|
} else {
|
||||||
g_warning ("can't get flags of interface '%s'", it->ifr_name);
|
g_warning ("can't get flags of interface '%s'",
|
||||||
probed_ifaces[idx] = g_strdup (it->ifr_name);
|
ifc.ifc_req[i].ifr_name);
|
||||||
|
probed_ifaces[idx] = g_strdup (ifc.ifc_req[i].ifr_name);
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (idx != 0)
|
if (idx != 0)
|
||||||
ifaces = probed_ifaces;
|
ifaces = probed_ifaces;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
struct ifaddrs *ifaddr, *ifa;
|
||||||
|
|
||||||
|
if (getifaddrs (&ifaddr) != -1) {
|
||||||
|
GPtrArray *arr;
|
||||||
|
|
||||||
|
arr = g_ptr_array_new ();
|
||||||
|
|
||||||
|
for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
|
||||||
|
if ((ifa->ifa_flags & IFF_LOOPBACK))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!ifa->ifa_addr || ifa->ifa_addr->sa_family != AF_LINK)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
g_ptr_array_add (arr, g_strdup (ifa->ifa_name));
|
||||||
|
}
|
||||||
|
freeifaddrs (ifaddr);
|
||||||
|
|
||||||
|
g_ptr_array_add (arr, NULL);
|
||||||
|
ifaces = probed_ifaces = (gchar **) g_ptr_array_free (arr, FALSE);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* Get a clock id from the MAC address if none was given */
|
/* Get a clock id from the MAC address if none was given */
|
||||||
if (clock_id == (guint64) - 1) {
|
if (clock_id == (guint64) - 1) {
|
||||||
gboolean success = FALSE;
|
gboolean success = FALSE;
|
||||||
|
|
||||||
/* FIXME: On Apple platforms use IOKit APIs to iterate
|
|
||||||
* network interfaces and get MAC addresses. Think different!
|
|
||||||
*/
|
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
|
|
||||||
|
@ -305,12 +328,10 @@ setup_sockets (void)
|
||||||
ifc.ifc_len = sizeof (buf);
|
ifc.ifc_len = sizeof (buf);
|
||||||
ifc.ifc_buf = buf;
|
ifc.ifc_buf = buf;
|
||||||
if (ioctl (g_socket_get_fd (socket_event), SIOCGIFCONF, &ifc) != -1) {
|
if (ioctl (g_socket_get_fd (socket_event), SIOCGIFCONF, &ifc) != -1) {
|
||||||
struct ifreq *it = ifc.ifc_req;
|
guint i;
|
||||||
const struct ifreq *const end =
|
|
||||||
it + (ifc.ifc_len / sizeof (struct ifreq));
|
|
||||||
|
|
||||||
for (; it != end; ++it) {
|
for (i = 0; i < ifc.ifc_len / sizeof (struct ifreq); i++) {
|
||||||
strcpy (ifr.ifr_name, it->ifr_name);
|
strcpy (ifr.ifr_name, ifc.ifc_req[i].ifr_name);
|
||||||
if (ioctl (g_socket_get_fd (socket_event), SIOCGIFFLAGS, &ifr) == 0) {
|
if (ioctl (g_socket_get_fd (socket_event), SIOCGIFFLAGS, &ifr) == 0) {
|
||||||
if ((ifr.ifr_flags & IFF_LOOPBACK))
|
if ((ifr.ifr_flags & IFF_LOOPBACK))
|
||||||
continue;
|
continue;
|
||||||
|
@ -329,11 +350,61 @@ setup_sockets (void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
g_warning ("can't get flags of interface '%s'", it->ifr_name);
|
g_warning ("can't get flags of interface '%s'",
|
||||||
|
ifc.ifc_req[i].ifr_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
struct ifaddrs *ifaddr, *ifa;
|
||||||
|
|
||||||
|
if (getifaddrs (&ifaddr) != -1) {
|
||||||
|
for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
|
||||||
|
struct sockaddr_dl *sdl = (struct sockaddr_dl *) ifa->ifa_addr;
|
||||||
|
guint8 mac_addr[6];
|
||||||
|
|
||||||
|
if ((ifa->ifa_flags & IFF_LOOPBACK))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!ifa->ifa_addr || ifa->ifa_addr->sa_family != AF_LINK)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ifaces) {
|
||||||
|
gchar **p = ifaces;
|
||||||
|
gboolean found = FALSE;
|
||||||
|
|
||||||
|
while (*p) {
|
||||||
|
if (strcmp (*p, ifa->ifa_name) == 0) {
|
||||||
|
found = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sdl->sdl_alen != 6)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
memcpy (mac_addr, LLADDR (sdl), sdl->sdl_alen);
|
||||||
|
|
||||||
|
clock_id_array[0] = mac_addr[0];
|
||||||
|
clock_id_array[1] = mac_addr[1];
|
||||||
|
clock_id_array[2] = mac_addr[2];
|
||||||
|
clock_id_array[3] = 0xff;
|
||||||
|
clock_id_array[4] = 0xfe;
|
||||||
|
clock_id_array[5] = mac_addr[3];
|
||||||
|
clock_id_array[6] = mac_addr[4];
|
||||||
|
clock_id_array[7] = mac_addr[5];
|
||||||
|
success = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
freeifaddrs (ifaddr);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
|
@ -356,18 +427,22 @@ setup_sockets (void)
|
||||||
while (*ptr) {
|
while (*ptr) {
|
||||||
gint c = 0;
|
gint c = 0;
|
||||||
if (!g_socket_join_multicast_group (socket_event, mcast_addr, FALSE, *ptr,
|
if (!g_socket_join_multicast_group (socket_event, mcast_addr, FALSE, *ptr,
|
||||||
&err))
|
&err)
|
||||||
g_warning ("Couldn't join multicast group on interface '%s': %s",
|
&& !g_error_matches (err, G_IO_ERROR, G_IO_ERROR_ADDRESS_IN_USE))
|
||||||
*ptr, err->message);
|
g_warning ("Couldn't join multicast group on interface '%s': %s", *ptr,
|
||||||
|
err->message);
|
||||||
else
|
else
|
||||||
c++;
|
c++;
|
||||||
|
g_clear_error (&err);
|
||||||
|
|
||||||
if (!g_socket_join_multicast_group (socket_general, mcast_addr, FALSE,
|
if (!g_socket_join_multicast_group (socket_general, mcast_addr, FALSE,
|
||||||
*ptr, &err))
|
*ptr, &err)
|
||||||
g_warning ("Couldn't join multicast group on interface '%s': %s",
|
&& !g_error_matches (err, G_IO_ERROR, G_IO_ERROR_ADDRESS_IN_USE))
|
||||||
*ptr, err->message);
|
g_warning ("Couldn't join multicast group on interface '%s': %s", *ptr,
|
||||||
|
err->message);
|
||||||
else
|
else
|
||||||
c++;
|
c++;
|
||||||
|
g_clear_error (&err);
|
||||||
|
|
||||||
if (c == 2)
|
if (c == 2)
|
||||||
success = TRUE;
|
success = TRUE;
|
||||||
|
|
Loading…
Reference in a new issue