summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Georg <mail@jensge.org>2012-01-01 15:32:51 +0100
committerJens Georg <jensg@openismus.com>2013-12-01 12:40:31 +0100
commit55f9ba62fd7e7787e1e90fd3482ebeb9d32e5f11 (patch)
tree920151f9d8d80c3b5435e597c480086fe3f4b373
parent035c77b4a9d610b73674c2f287bbd815d8764ed0 (diff)
downloadgssdp-wip/client-cache.tar.gz
Add ARP lookup for Linuxwip/client-cache
https://bugzilla.gnome.org/show_bug.cgi?id=653894
-rw-r--r--libgssdp/gssdp-client.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/libgssdp/gssdp-client.c b/libgssdp/gssdp-client.c
index d244374..3ce7656 100644
--- a/libgssdp/gssdp-client.c
+++ b/libgssdp/gssdp-client.c
@@ -40,6 +40,11 @@
#include <sys/utsname.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#ifdef __linux__
+/* headers for ARP */
+#include <net/if_arp.h>
+#include <sys/ioctl.h>
+#endif
#else
#define _WIN32_WINNT 0x502
#include <winsock2.h>
@@ -1697,5 +1702,41 @@ init_network_info (GSSDPClient *client, GError **error)
char *
arp_lookup (GSSDPClient *client, const char *ip_address)
{
+#if defined(__linux__)
+ struct arpreq req;
+ struct sockaddr_in *sin;
+ GSocket *socket;
+
+ memset (&req, 0, sizeof (req));
+
+ /* FIXME: Update when we support IPv6 properly */
+ sin = (struct sockaddr_in *) &req.arp_pa;
+ sin->sin_family = AF_INET;
+ sin->sin_addr.s_addr = inet_addr (ip_address);
+
+ strncpy (req.arp_dev,
+ client->priv->device.iface_name,
+ sizeof (req.arp_dev));
+ socket = gssdp_socket_source_get_socket (client->priv->search_socket);
+
+ if (ioctl (g_socket_get_fd (socket), SIOCGARP, (caddr_t) &req) < 0) {
+ return NULL;
+ }
+
+ if (req.arp_flags & ATF_COM) {
+ unsigned char *buf = (unsigned char *) req.arp_ha.sa_data;
+
+ return g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
+ buf[0],
+ buf[1],
+ buf[2],
+ buf[3],
+ buf[4],
+ buf[5]);
+ }
+
+ return NULL;
+#else
return g_strdup (ip_address);
+#endif
}