Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

Diff of /getifaddr.c [f18c3c] .. [f557f8] Maximize Restore

  Switch to side-by-side view

--- a/getifaddr.c
+++ b/getifaddr.c
@@ -1,34 +1,12 @@
+/* $Id$ */
 /* MiniUPnP project
  * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- *
- * Copyright (c) 2006, Thomas Bernard
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * The name of the author may not be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-#include <stdio.h>
-#include <stdlib.h>
+ * (c) 2006 Thomas Bernard 
+ * This software is subject to the conditions detailed
+ * in the LICENCE file provided within the distribution */
+
 #include <string.h>
+#include <syslog.h>
 #include <unistd.h>
 #include <sys/ioctl.h>
 #include <sys/types.h>
@@ -36,370 +14,42 @@
 #include <net/if.h>
 #include <arpa/inet.h>
 #include <netinet/in.h>
-#include <netdb.h>
-#include <errno.h>
 #if defined(sun)
 #include <sys/sockio.h>
 #endif
 
-#include "config.h"
-#if HAVE_GETIFADDRS
-# include <ifaddrs.h>
-# ifdef __linux__
-#  ifndef AF_LINK
-#   define AF_LINK AF_INET
-#  endif
-# else
-#  include <net/if_dl.h>
-# endif
-# ifndef IFF_SLAVE
-#  define IFF_SLAVE 0
-# endif
-#endif
-#ifdef HAVE_NETLINK
-# include <linux/rtnetlink.h>
-# include <linux/netlink.h>
-#endif
-#include "upnpglobalvars.h"
 #include "getifaddr.h"
-#include "minissdp.h"
-#include "utils.h"
-#include "log.h"
 
-static int
-getifaddr(const char *ifname)
+int
+getifaddr(const char * ifname, char * buf, int len)
 {
-#if HAVE_GETIFADDRS
-	struct ifaddrs *ifap, *p;
-	struct sockaddr_in *addr_in;
-
-	if (getifaddrs(&ifap) != 0)
+	/* SIOCGIFADDR struct ifreq *  */
+	int s;
+	struct ifreq ifr;
+	int ifrlen;
+	struct sockaddr_in * addr;
+	ifrlen = sizeof(ifr);
+	s = socket(PF_INET, SOCK_DGRAM, 0);
+	if(s < 0)
 	{
-		DPRINTF(E_ERROR, L_GENERAL, "getifaddrs(): %s\n", strerror(errno));
+		syslog(LOG_ERR, "socket(PF_INET, SOCK_DGRAM): %m");
 		return -1;
 	}
-
-	for (p = ifap; p != NULL; p = p->ifa_next)
+	strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+	if(ioctl(s, SIOCGIFADDR, &ifr, &ifrlen) < 0)
 	{
-		if (!p->ifa_addr || p->ifa_addr->sa_family != AF_INET)
-			continue;
-		if (ifname && strcmp(p->ifa_name, ifname) != 0)
-			continue;
-		addr_in = (struct sockaddr_in *)p->ifa_addr;
-		if (!ifname && (p->ifa_flags & (IFF_LOOPBACK | IFF_SLAVE)))
-			continue;
-		memcpy(&lan_addr[n_lan_addr].addr, &addr_in->sin_addr, sizeof(lan_addr[n_lan_addr].addr));
-		if (!inet_ntop(AF_INET, &addr_in->sin_addr, lan_addr[n_lan_addr].str, sizeof(lan_addr[0].str)) )
-		{
-			DPRINTF(E_ERROR, L_GENERAL, "inet_ntop(): %s\n", strerror(errno));
-			continue;
-		}
-		addr_in = (struct sockaddr_in *)p->ifa_netmask;
-		memcpy(&lan_addr[n_lan_addr].mask, &addr_in->sin_addr, sizeof(lan_addr[n_lan_addr].mask));
-		lan_addr[n_lan_addr].ifindex = if_nametoindex(p->ifa_name);
-		lan_addr[n_lan_addr].snotify = OpenAndConfSSDPNotifySocket(&lan_addr[n_lan_addr]);
-		if (lan_addr[n_lan_addr].snotify >= 0)
-			n_lan_addr++;
-		if (ifname || n_lan_addr >= MAX_LAN_ADDR)
-			break;
-	}
-	freeifaddrs(ifap);
-	if (ifname && !p)
-	{
-		DPRINTF(E_ERROR, L_GENERAL, "Network interface %s not found\n", ifname);
-		return -1;
-	}
-#else
-	int s = socket(PF_INET, SOCK_STREAM, 0);
-	struct sockaddr_in addr;
-	struct ifconf ifc;
-	struct ifreq *ifr;
-	char buf[8192];
-	int i, n;
-
-	memset(&ifc, '\0', sizeof(ifc));
-	ifc.ifc_buf = buf;
-	ifc.ifc_len = sizeof(buf);
-
-	if (ioctl(s, SIOCGIFCONF, &ifc) < 0)
-	{
-		DPRINTF(E_ERROR, L_GENERAL, "SIOCGIFCONF: %s\n", strerror(errno));
+		syslog(LOG_ERR, "ioctl(s, SIOCGIFADDR, ...): %m");
 		close(s);
 		return -1;
 	}
-
-	n = ifc.ifc_len / sizeof(struct ifreq);
-	for (i = 0; i < n; i++)
+	addr = (struct sockaddr_in *)&ifr.ifr_addr;
+	if(!inet_ntop(AF_INET, &addr->sin_addr, buf, len))
 	{
-		ifr = &ifc.ifc_req[i];
-		if (ifname && strcmp(ifr->ifr_name, ifname) != 0)
-			continue;
-		if (!ifname &&
-		    (ioctl(s, SIOCGIFFLAGS, ifr) < 0 || ifr->ifr_ifru.ifru_flags & IFF_LOOPBACK))
-			continue;
-		if (ioctl(s, SIOCGIFADDR, ifr) < 0)
-			continue;
-		memcpy(&addr, &(ifr->ifr_addr), sizeof(addr));
-		memcpy(&lan_addr[n_lan_addr].addr, &addr.sin_addr, sizeof(lan_addr[n_lan_addr].addr));
-		if (!inet_ntop(AF_INET, &addr.sin_addr, lan_addr[n_lan_addr].str, sizeof(lan_addr[0].str)))
-		{
-			DPRINTF(E_ERROR, L_GENERAL, "inet_ntop(): %s\n", strerror(errno));
-			close(s);
-			continue;
-		}
-		if (ioctl(s, SIOCGIFNETMASK, ifr) < 0)
-			continue;
-		memcpy(&addr, &(ifr->ifr_addr), sizeof(addr));
-		memcpy(&lan_addr[n_lan_addr].mask, &addr.sin_addr, sizeof(addr));
-		lan_addr[n_lan_addr].ifindex = if_nametoindex(ifr->ifr_name);
-		lan_addr[n_lan_addr].snotify = OpenAndConfSSDPNotifySocket(&lan_addr[n_lan_addr]);
-		if (lan_addr[n_lan_addr].snotify >= 0)
-			n_lan_addr++;
-		if (ifname || n_lan_addr >= MAX_LAN_ADDR)
-			break;
+		syslog(LOG_ERR, "inet_ntop(): %m");
+		close(s);
+		return -1;
 	}
 	close(s);
-	if (ifname && i == n)
-	{
-		DPRINTF(E_ERROR, L_GENERAL, "Network interface %s not found\n", ifname);
-		return -1;
-	}
-#endif
-	return n_lan_addr;
-}
-
-int
-getsyshwaddr(char *buf, int len)
-{
-	unsigned char mac[6];
-	int ret = -1;
-#if defined(HAVE_GETIFADDRS) && !defined (__linux__) && !defined (__sun__)
-	struct ifaddrs *ifap, *p;
-	struct sockaddr_in *addr_in;
-	uint8_t a;
-
-	if (getifaddrs(&ifap) != 0)
-	{
-		DPRINTF(E_ERROR, L_GENERAL, "getifaddrs(): %s\n", strerror(errno));
-		return -1;
-	}
-	for (p = ifap; p != NULL; p = p->ifa_next)
-	{
-		if (p->ifa_addr && p->ifa_addr->sa_family == AF_LINK)
-		{
-			addr_in = (struct sockaddr_in *)p->ifa_addr;
-			a = (htonl(addr_in->sin_addr.s_addr) >> 0x18) & 0xFF;
-			if (a == 127)
-				continue;
-#if defined(__linux__)
-			struct ifreq ifr;
-			int fd;
-			fd = socket(AF_INET, SOCK_DGRAM, 0);
-			if (fd < 0)
-				continue;
-			strncpy(ifr.ifr_name, p->ifa_name, IFNAMSIZ);
-			ret = ioctl(fd, SIOCGIFHWADDR, &ifr);
-			close(fd);
-			if (ret < 0)
-				continue;
-			memcpy(mac, ifr.ifr_hwaddr.sa_data, 6);
-#else
-			struct sockaddr_dl *sdl;
-			sdl = (struct sockaddr_dl*)p->ifa_addr;
-			memcpy(mac, LLADDR(sdl), sdl->sdl_alen);
-#endif
-			if (MACADDR_IS_ZERO(mac))
-				continue;
-			ret = 0;
-			break;
-		}
-	}
-	freeifaddrs(ifap);
-#else
-	struct if_nameindex *ifaces, *if_idx;
-	struct ifreq ifr;
-	int fd;
-
-	memset(&mac, '\0', sizeof(mac));
-	/* Get the spatially unique node identifier */
-	fd = socket(AF_INET, SOCK_DGRAM, 0);
-	if (fd < 0)
-		return ret;
-
-	ifaces = if_nameindex();
-	if (!ifaces)
-	{
-		close(fd);
-		return ret;
-	}
-
-	for (if_idx = ifaces; if_idx->if_index; if_idx++)
-	{
-		strncpyt(ifr.ifr_name, if_idx->if_name, IFNAMSIZ);
-		if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0)
-			continue;
-		if (ifr.ifr_ifru.ifru_flags & IFF_LOOPBACK)
-			continue;
-		if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0)
-			continue;
-#ifdef __sun__
-		if (MACADDR_IS_ZERO(ifr.ifr_addr.sa_data))
-			continue;
-		memcpy(mac, ifr.ifr_addr.sa_data, 6);
-#else
-		if (MACADDR_IS_ZERO(ifr.ifr_hwaddr.sa_data))
-			continue;
-		memcpy(mac, ifr.ifr_hwaddr.sa_data, 6);
-#endif
-		ret = 0;
-		break;
-	}
-	if_freenameindex(ifaces);
-	close(fd);
-#endif
-	if (ret == 0)
-	{
-		if (len > 12)
-			sprintf(buf, "%02x%02x%02x%02x%02x%02x",
-			        mac[0]&0xFF, mac[1]&0xFF, mac[2]&0xFF,
-			        mac[3]&0xFF, mac[4]&0xFF, mac[5]&0xFF);
-		else if (len == 6)
-			memmove(buf, mac, 6);
-	}
-	return ret;
-}
-
-int
-get_remote_mac(struct in_addr ip_addr, unsigned char *mac)
-{
-	struct in_addr arp_ent;
-	FILE * arp;
-	char remote_ip[16];
-	int matches, hwtype, flags;
-	memset(mac, 0xFF, 6);
-
-	arp = fopen("/proc/net/arp", "r");
-	if (!arp)
-		return 1;
-	while (!feof(arp))
-	{
-		matches = fscanf(arp, "%15s 0x%8X 0x%8X %2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx",
-		                      remote_ip, &hwtype, &flags,
-		                      &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]);
-		if (matches != 9)
-			continue;
-		inet_pton(AF_INET, remote_ip, &arp_ent);
-		if (ip_addr.s_addr == arp_ent.s_addr)
-			break;
-		mac[0] = 0xFF;
-	}
-	fclose(arp);
-
-	if (mac[0] == 0xFF)
-	{
-		memset(mac, 0xFF, 6);
-		return 1;
-	}
-
 	return 0;
 }
 
-void
-reload_ifaces(int force_notify)
-{
-	struct in_addr old_addr[MAX_LAN_ADDR];
-	int i, j;
-
-	memset(&old_addr, 0xFF, sizeof(old_addr));
-	for (i = 0; i < n_lan_addr; i++)
-	{
-		memcpy(&old_addr[i], &lan_addr[i].addr, sizeof(struct in_addr));
-		close(lan_addr[i].snotify);
-	}
-	n_lan_addr = 0;
-
-	i = 0;
-	do {
-		getifaddr(runtime_vars.ifaces[i]);
-		i++;
-	} while (runtime_vars.ifaces[i]);
-
-	for (i = 0; i < n_lan_addr; i++)
-	{
-		for (j = 0; j < MAX_LAN_ADDR; j++)
-		{
-			if (memcmp(&lan_addr[i].addr, &old_addr[j], sizeof(struct in_addr)) == 0)
-				break;
-		}
-		/* Send out startup notifies if it's a new interface, or on SIGHUP */
-		if (force_notify || j == MAX_LAN_ADDR)
-		{
-			DPRINTF(E_INFO, L_GENERAL, "Enabling interface %s/%s\n",
-				lan_addr[i].str, inet_ntoa(lan_addr[i].mask));
-			SendSSDPGoodbyes(lan_addr[i].snotify);
-			SendSSDPNotifies(lan_addr[i].snotify, lan_addr[i].str,
-					runtime_vars.port, runtime_vars.notify_interval);
-		}
-	}
-}
-
-int
-OpenAndConfMonitorSocket(void)
-{
-#ifdef HAVE_NETLINK
-	struct sockaddr_nl addr;
-	int s;
-	int ret;
-
-	s = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
-	if (s < 0)
-	{
-		perror("couldn't open NETLINK_ROUTE socket");
-		return -1;
-	}
-
-	memset(&addr, 0, sizeof(addr));
-	addr.nl_family = AF_NETLINK;
-	addr.nl_groups = RTMGRP_IPV4_IFADDR;
-
-	ret = bind(s, (struct sockaddr*)&addr, sizeof(addr));
-	if (ret < 0)
-	{
-		perror("couldn't bind");
-		close(s);
-		return -1;
-	}
-
-	return s;
-#else
-	return -1;
-#endif
-}
-
-void
-ProcessMonitorEvent(int s)
-{
-#ifdef HAVE_NETLINK
-	int len;
-	char buf[4096];
-	struct nlmsghdr *nlh;
-	int changed = 0;
-
-	nlh = (struct nlmsghdr*)buf;
-
-	len = recv(s, nlh, sizeof(buf), 0);
-	if (len <= 0)
-		return;
-	while ((NLMSG_OK(nlh, len)) && (nlh->nlmsg_type != NLMSG_DONE))
-	{
-		if (nlh->nlmsg_type == RTM_NEWADDR ||
-		    nlh->nlmsg_type == RTM_DELADDR)
-		{
-			changed = 1;
-		}
-		nlh = NLMSG_NEXT(nlh, len);
-	}
-	if (changed)
-		reload_ifaces(0);
-#endif
-}