add code to return list of network adapters

Jean-Francois Dockes Jean-Francois Dockes 2016-01-05

changed libupnpp/getsyshwaddr.h
changed libupnpp/upnpplib.cxx
changed libupnpp/upnpputils.hxx
changed Makefile.am
copied libupnpp/getsyshwaddr.c -> libupnpp/getsyshwaddr.cxx
libupnpp/getsyshwaddr.h Diff Switch to side-by-side view
Loading...
libupnpp/upnpplib.cxx Diff Switch to side-by-side view
Loading...
libupnpp/upnpputils.hxx Diff Switch to side-by-side view
Loading...
Makefile.am Diff Switch to side-by-side view
Loading...
libupnpp/getsyshwaddr.c to libupnpp/getsyshwaddr.cxx
--- a/libupnpp/getsyshwaddr.c
+++ b/libupnpp/getsyshwaddr.cxx
@@ -67,137 +67,141 @@
 
 #include "libupnpp/getsyshwaddr.h"
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define MACADDR_IS_ZERO(x) \
-  ((x[0] == 0x00) && \
-   (x[1] == 0x00) && \
-   (x[2] == 0x00) && \
-   (x[3] == 0x00) && \
-   (x[4] == 0x00) && \
-   (x[5] == 0x00))
+#define MACADDR_IS_ZERO(x)                      \
+    ((x[0] == 0x00) &&                          \
+     (x[1] == 0x00) &&                          \
+     (x[2] == 0x00) &&                          \
+     (x[3] == 0x00) &&                          \
+     (x[4] == 0x00) &&                          \
+     (x[5] == 0x00))
 
 #define DPRINTF(A,B,C,D) 
 
-int getsyshwaddr(const char *iface, char *ip, int ilen, char *buf, int hlen)
+using namespace std;
+
+int getsyshwaddr(const string& iface,
+                 string *ip, string *hwaddr,
+                 vector<string> *ifaces)
 {
-	unsigned char mac[6];
-	int ret = -1;
-	int ifnamelen = 0;
-
-	if (iface && *iface) {
-		ifnamelen = strnlen(iface, 200);
-	}
-
-	memset(&mac, 0, sizeof(mac));
+    unsigned char mac[6];
+    int ret = -1;
+
+    memset(&mac, 0, sizeof(mac));
 
 #ifndef WIN32
 #if HAVE_GETIFADDRS
-	struct ifaddrs *ifap, *p;
-
-	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)
-		{
-			struct sockaddr_in *addr_in;
-			uint8_t a;
-
-			if (ifnamelen && strncmp(iface, p->ifa_name, ifnamelen) != 0 )
-				continue;
-
-			addr_in = (struct sockaddr_in *)p->ifa_addr;
-			a = (htonl(addr_in->sin_addr.s_addr) >> 0x18) & 0xFF;
-			if (a == 127)
-				continue;
-
-			if (ip)
-				inet_ntop(AF_INET, (const void *) &(addr_in->sin_addr), 
-						  ip, ilen);
+    struct ifaddrs *ifap, *p;
+
+    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)
+        {
+            struct sockaddr_in *addr_in;
+            uint8_t a;
+            if (ifaces && strcmp(p->ifa_name , "lo")) {
+                ifaces->push_back(p->ifa_name);
+            }
+            if (iface.size() && iface.compare(p->ifa_name))
+                continue;
+
+            addr_in = (struct sockaddr_in *)p->ifa_addr;
+            a = (htonl(addr_in->sin_addr.s_addr) >> 0x18) & 0xFF;
+            if (a == 127)
+                continue;
+
+            if (ip) {
+				char ipbuf[100];
+                inet_ntop(AF_INET, (const void *) &(addr_in->sin_addr), 
+                          ipbuf, 99);
+				ip->assign(ipbuf);
+			}
 
 #ifdef __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);
-			if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0)
-			{
-				close(fd);
-				continue;
-			}
-			memcpy(mac, ifr.ifr_hwaddr.sa_data, 6);
-			close(fd);
+            struct ifreq ifr;
+            int fd;
+            fd = socket(AF_INET, SOCK_DGRAM, 0);
+            if (fd < 0)
+                continue;
+            strncpy(ifr.ifr_name, p->ifa_name, IFNAMSIZ);
+            if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0)
+            {
+                close(fd);
+                continue;
+            }
+            memcpy(mac, ifr.ifr_hwaddr.sa_data, 6);
+            close(fd);
 #else  /* ! __linux__ -> */
-			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);
+            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 /* ! HAVE_GETIFADDRS -> */
 
-	struct if_nameindex *ifaces, *if_idx;
-	struct ifreq ifr;
-	int fd;
-
-	/* Get the spatially unique node identifier */
-	fd = socket(AF_INET, SOCK_DGRAM, 0);
-	if (fd < 0)
-		return ret;
-
-	ifaces = if_nameindex();
-	if (!ifaces)
-		return ret;
-
-	for (if_idx = ifaces; if_idx->if_index; if_idx++)
-	{
-		if (ifnamelen && strncmp(name, if_idx->if_name, ifnamelen) != 0 )
-			continue;
-
-		strncpy(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;
-		if (MACADDR_IS_ZERO(ifr.ifr_hwaddr.sa_data))
-			continue;
-		memcpy(mac, ifr.ifr_hwaddr.sa_data, 6);
-		if (ip) {
-			if (ioctl(fd, SIOCGIFADDR, &ifr) == 0) {
-				// Not sure at all that this branch is ever used on modern
-				// systems. So just procrastinate until/if we ever need this.
+    struct if_nameindex *ifaces, *if_idx;
+    struct ifreq ifr;
+    int fd;
+
+    /* Get the spatially unique node identifier */
+    fd = socket(AF_INET, SOCK_DGRAM, 0);
+    if (fd < 0)
+        return ret;
+
+    ifaces = if_nameindex();
+    if (!ifaces)
+        return ret;
+
+    for (if_idx = ifaces; if_idx->if_index; if_idx++)
+    {
+        if (ifaces && strcmp(if_idx->if_name , "lo")) {
+            ifaces->push_back(if_idx->if_name);
+        }
+        if (iface.size() && iface.compare(if_idx->if_name))
+            continue;
+
+        strncpy(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;
+        if (MACADDR_IS_ZERO(ifr.ifr_hwaddr.sa_data))
+            continue;
+        memcpy(mac, ifr.ifr_hwaddr.sa_data, 6);
+        if (ip) {
+            if (ioctl(fd, SIOCGIFADDR, &ifr) == 0) {
+                // Not sure at all that this branch is ever used on modern
+                // systems. So just procrastinate until/if we ever need this.
 #error please fill in the code to retrieve the IP address, 
-			}
-		}
-
-		ret = 0;
-		break;
-	}
-	if_freenameindex(ifaces);
-	close(fd);
+            }
+        }
+
+        ret = 0;
+        break;
+    }
+    if_freenameindex(ifaces);
+    close(fd);
 #endif /* GETIFADDRS */
 
 #else /* WIN32 -> */
 
     DWORD dwBufLen = sizeof(IP_ADAPTER_INFO);
-	PIP_ADAPTER_INFO pAdapterInfo = (IP_ADAPTER_INFO *)malloc(dwBufLen);
+    PIP_ADAPTER_INFO pAdapterInfo = (IP_ADAPTER_INFO *)malloc(dwBufLen);
     if (pAdapterInfo == NULL) {
+        fprintf(stderr, "getsyshwaddr: malloc failed\n");
         return -1;
     }
 
@@ -206,63 +210,65 @@
     if (GetAdaptersInfo(pAdapterInfo, &dwBufLen) == ERROR_BUFFER_OVERFLOW) {
         pAdapterInfo = (IP_ADAPTER_INFO *)realloc(pAdapterInfo, dwBufLen);
         if (pAdapterInfo == NULL) {
+            fprintf(stderr, "getsyshwaddr: GetAdaptersInfo (call 1) failed\n");
             return -1;
         }
     }
 
-	// Get the full list and walk it
-    if (GetAdaptersInfo(pAdapterInfo, &dwBufLen) != NO_ERROR) {
+    // Get the full list and walk it
+    if (GetAdaptersInfo(pAdapterInfo, &dwBufLen) == NO_ERROR) {
         PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
 
-        while (pAdapter) {
-			/* If the interface name was specified, check it */
-			if (ifnamelen && 
-				strncmp(iface, pAdapter->AdapterName, ifnamelen) != 0)
+        for (;pAdapter != NULL; pAdapter = pAdapter->Next) {
+			//fprintf(stderr, "Testing adapter name [%s] Description [%s] "
+			// "against input [%s]\n",
+			// pAdapter->AdapterName, pAdapter->Description, iface);
+            // Note: AdapterName is a GUID which as far as I can see appears
+            // nowhere in the GUI. Description is sthing like
+            // "Intel Pro 100 #2", better.
+            if (ifaces) {
+                ifaces->push_back(pAdapter->Description);
+            }
+            if (iface.size() && iface.compare(pAdapter->Description))
 				continue;
 
-			/* CurrentIpAddress->IpAddress.String stores the IPv4 address 
-			   as a char string in dotted notation */
-			/* Skip localhost ? */
-			if (!strncmp("127.0.0", 
-						 pAdapter->CurrentIpAddress->IpAddress.String, 7))
-				continue;
-			/* Store the IP address in dotted notation format */
-			if (ip) {
-				strncpy(ip, pAdapter->CurrentIpAddress->IpAddress.String, ilen);
-				ip[ilen-1] = 0;
-			}
-
-			/* The MAC is in the pAdapter->Address char array */
-			memcpy(mac, pAdapter->Address, 6);
-
-			if (!MACADDR_IS_ZERO(mac)) {
-				ret = 0;
-				break;
-			}
-
-			pAdapter = pAdapter->Next;
+            /* CurrentIpAddress->IpAddress.String stores the IPv4 address 
+               as a char string in dotted notation */
+            /* Skip localhost ? */
+            if (!strncmp("127.0.0", 
+                         pAdapter->CurrentIpAddress->IpAddress.String, 7)) {
+                continue;
+            }
+            /* Store the IP address in dotted notation format */
+            if (ip) {
+                ip->assign(pAdapter->CurrentIpAddress->IpAddress.String);
+            }
+
+            /* The MAC is in the pAdapter->Address char array */
+            memcpy(mac, pAdapter->Address, 6);
+
+            if (!MACADDR_IS_ZERO(mac)) {
+                ret = 0;
+                break;
+            }
         } 
+    } else {
+        fprintf(stderr, "getsyshwaddr: GetAdaptersInfo (call 2) failed\n");
     }
     if (pAdapterInfo)
         free(pAdapterInfo);
 
 #endif
 
-	if (ret == 0)
-	{
-		if (hlen > 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 (hlen == 6)
-			memmove(buf, mac, 6);
-	}
-	return ret;
+    if (ret == 0 && hwaddr) {
+		char buf[100];
+		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);
+		hwaddr->assign(buf);
+    }
+    return ret;
 }
-
-#ifdef __cplusplus
-}
-#endif
 
 /* Local Variables: */
 /* mode: c++ */