X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Futil%2Fos_network.c;h=b0490efab1bc6522eaf007af648fad1b70fc004d;hb=72c8645af31896829b674b575c5375706f362a30;hp=d18e5eb769e35e0ad5109d462f1041c1177a874b;hpb=fe947a9704bed14c2fc74b2f2069596fe884cbad;p=oweals%2Fgnunet.git diff --git a/src/util/os_network.c b/src/util/os_network.c index d18e5eb76..b0490efab 100644 --- a/src/util/os_network.c +++ b/src/util/os_network.c @@ -25,12 +25,17 @@ * @author Nils Durner * @author Heikki Lindholm * @author Jake Dust + * @author LRN */ #include "platform.h" #include "gnunet_common.h" #include "gnunet_os_lib.h" + +#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) +#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename) + /** * @brief Enumerate all network interfaces * @@ -42,125 +47,30 @@ GNUNET_OS_network_interfaces_list (GNUNET_OS_NetworkInterfaceProcessor proc, void *proc_cls) { #ifdef MINGW - PMIB_IFTABLE pTable; - PMIB_IPADDRTABLE pAddrTable; - DWORD dwIfIdx, dwExternalNIC; - IPAddr theIP; - - /* Determine our external NIC */ - theIP = inet_addr ("192.0.34.166"); /* www.example.com */ - if ((!GNGetBestInterface) || - (GNGetBestInterface (theIP, &dwExternalNIC) != NO_ERROR)) - { - dwExternalNIC = 0; - } - - /* Enumerate NICs */ - EnumNICs (&pTable, &pAddrTable); - - if (pTable) - { - for (dwIfIdx = 0; dwIfIdx <= pTable->dwNumEntries; dwIfIdx++) - { - char szEntry[1001]; - DWORD dwIP = 0; - int iItm; - PIP_ADAPTER_INFO pAdapterInfo; - PIP_ADAPTER_INFO pAdapter = NULL; - DWORD dwRetVal = 0; - - /* Get IP-Address */ - int i; - for (i = 0; i < pAddrTable->dwNumEntries; i++) - { - if (pAddrTable->table[i].dwIndex == - pTable->table[dwIfIdx].dwIndex) - { - dwIP = pAddrTable->table[i].dwAddr; - break; - } - } - - if (dwIP) - { - BYTE bPhysAddr[MAXLEN_PHYSADDR]; - char *pszIfName = NULL; - char dst[INET_ADDRSTRLEN]; - - /* Get friendly interface name */ - pAdapterInfo = - (IP_ADAPTER_INFO *) malloc (sizeof (IP_ADAPTER_INFO)); - ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO); + int r; + int i; + struct EnumNICs3_results *results = NULL; + int results_count; - /* Make an initial call to GetAdaptersInfo to get - the necessary size into the ulOutBufLen variable */ - if (GGetAdaptersInfo (pAdapterInfo, &ulOutBufLen) == - ERROR_BUFFER_OVERFLOW) - { - free (pAdapterInfo); - pAdapterInfo = (IP_ADAPTER_INFO *) malloc (ulOutBufLen); - } + r = EnumNICs3 (&results, &results_count); + if (r != GNUNET_OK) + return; - if ((dwRetVal = - GGetAdaptersInfo (pAdapterInfo, &ulOutBufLen)) == NO_ERROR) - { - pAdapter = pAdapterInfo; - while (pAdapter) - { - if (pTable->table[dwIfIdx].dwIndex == pAdapter->Index) - { - char szKey[251]; - long lLen = 250; - - sprintf (szKey, - "SYSTEM\\CurrentControlSet\\Control\\Network\\" - "{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection", - pAdapter->AdapterName); - pszIfName = (char *) malloc (251); - if (QueryRegistry - (HKEY_LOCAL_MACHINE, szKey, "Name", pszIfName, - &lLen) != ERROR_SUCCESS) - { - free (pszIfName); - pszIfName = NULL; - } - } - pAdapter = pAdapter->Next; - } - } - free (pAdapterInfo); - - /* Set entry */ - memset (bPhysAddr, 0, MAXLEN_PHYSADDR); - memcpy (bPhysAddr, - pTable->table[dwIfIdx].bPhysAddr, - pTable->table[dwIfIdx].dwPhysAddrLen); - - snprintf (szEntry, 1000, "%s (%s - %I64u)", - pszIfName ? pszIfName : (char *) - pTable->table[dwIfIdx].bDescr, inet_ntop (AF_INET, - &dwIP, dst, - INET_ADDRSTRLEN), - *((unsigned long long *) bPhysAddr)); - szEntry[1000] = 0; - - if (pszIfName) - free (pszIfName); - - if (GNUNET_OK != - proc (proc_cls, - szEntry, - pAddrTable->table[dwIfIdx].dwIndex == dwExternalNIC, - NULL /* FIXME: pass actual IP address! */ , - 0)) - break; - } - } - GlobalFree (pAddrTable); - GlobalFree (pTable); - } - - return GNUNET_YES; + for (i = 0; i < results_count; i++) + { + if (GNUNET_OK != + proc (proc_cls, results[i].pretty_name, results[i].is_default, + (const struct sockaddr *) &results[i].address, + results[i]. + flags & ENUMNICS3_BCAST_OK ? + (const struct sockaddr *) &results[i].broadcast : NULL, + results[i].flags & ENUMNICS3_MASK_OK ? + (const struct sockaddr *) &results[i].mask : NULL, + results[i].addr_size)) + break; + } + EnumNICs3_free (results); + return; #elif HAVE_GETIFADDRS && HAVE_FREEIFADDRS @@ -169,40 +79,50 @@ GNUNET_OS_network_interfaces_list (GNUNET_OS_NetworkInterfaceProcessor proc, socklen_t alen; if (getifaddrs (&ifa_first) == 0) + { + for (ifa_ptr = ifa_first; ifa_ptr != NULL; ifa_ptr = ifa_ptr->ifa_next) { - for (ifa_ptr = ifa_first; ifa_ptr != NULL; ifa_ptr = ifa_ptr->ifa_next) - { - if (ifa_ptr->ifa_name != NULL && - ifa_ptr->ifa_addr != NULL && (ifa_ptr->ifa_flags & IFF_UP) != 0) - { - if ((ifa_ptr->ifa_addr->sa_family != AF_INET) && - (ifa_ptr->ifa_addr->sa_family != AF_INET6)) - continue; - if (ifa_ptr->ifa_addr->sa_family == AF_INET) - alen = sizeof (struct sockaddr_in); - else - alen = sizeof (struct sockaddr_in6); - if (GNUNET_OK != proc (proc_cls, - ifa_ptr->ifa_name, - 0 == strcmp (ifa_ptr->ifa_name, - GNUNET_DEFAULT_INTERFACE), - ifa_ptr->ifa_addr, alen)) - break; - } - } - freeifaddrs (ifa_first); + if (ifa_ptr->ifa_name != NULL && ifa_ptr->ifa_addr != NULL && + (ifa_ptr->ifa_flags & IFF_UP) != 0) + { + if ((ifa_ptr->ifa_addr->sa_family != AF_INET) && + (ifa_ptr->ifa_addr->sa_family != AF_INET6)) + continue; + if (ifa_ptr->ifa_addr->sa_family == AF_INET) + alen = sizeof (struct sockaddr_in); + else + alen = sizeof (struct sockaddr_in6); + if (GNUNET_OK != + proc (proc_cls, ifa_ptr->ifa_name, + 0 == strcmp (ifa_ptr->ifa_name, GNUNET_DEFAULT_INTERFACE), + ifa_ptr->ifa_addr, ifa_ptr->ifa_broadaddr, + ifa_ptr->ifa_netmask, alen)) + break; + } } + freeifaddrs (ifa_first); + } #else + int i; char line[1024]; + char *replace; const char *start; char ifc[12]; char addrstr[128]; + char bcstr[128]; + char netmaskstr[128]; FILE *f; int have_ifc; struct sockaddr_in a4; struct sockaddr_in6 a6; struct in_addr v4; struct in6_addr v6; + struct sockaddr_in bcaddr; + struct sockaddr_in netmask; + struct sockaddr_in6 netmask6; + struct sockaddr *pass_bcaddr; + struct sockaddr *pass_netmask; + int prefixlen; if (system ("ifconfig -a > /dev/null 2> /dev/null")) if (system ("/sbin/ifconfig -a > /dev/null 2> /dev/null") == 0) @@ -212,73 +132,136 @@ GNUNET_OS_network_interfaces_list (GNUNET_OS_NetworkInterfaceProcessor proc, else f = popen ("ifconfig -a 2> /dev/null", "r"); if (!f) - { - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING | - GNUNET_ERROR_TYPE_BULK, "popen", "ifconfig"); - return; - } + { + LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, + "popen", "ifconfig"); + return; + } have_ifc = GNUNET_NO; ifc[11] = '\0'; while (NULL != fgets (line, sizeof (line), f)) + { + if (strlen (line) == 0) + { + have_ifc = GNUNET_NO; + continue; + } + if (!isspace (line[0])) + { + have_ifc = (1 == SSCANF (line, "%11s", ifc)) ? GNUNET_YES : GNUNET_NO; + /* would end with ':' on OSX, fix it! */ + if (ifc[strlen (ifc) - 1] == ':') + ifc[strlen (ifc) - 1] = '\0'; + continue; + } + if (!have_ifc) + continue; /* strange input, hope for the best */ + + /* make parsing of ipv6 addresses easier */ + for (replace = line; *replace != '\0'; replace++) { - if (strlen (line) == 0) + if (*replace == '/') + *replace = ' '; + } + prefixlen = -1; + + start = line; + while (('\0' != *start) && (isspace (*start))) + start++; + + /* Zero-out stack allocated values */ + memset (addrstr, 0, 128); + memset (netmaskstr, 0, 128); + memset (bcstr, 0, 128); + prefixlen = 0; + + if ( /* Linux */ + (3 == SSCANF (start, "inet addr:%127s Bcast:%127s Mask:%127s", addrstr, bcstr, netmaskstr)) || + (2 == SSCANF (start, "inet addr:%127s Mask:%127s", addrstr, netmaskstr)) || + (2 == SSCANF (start, "inet6 addr:%127s %d", addrstr, &prefixlen)) || + /* Solaris, OS X */ + (1 == SSCANF (start, "inet %127s", addrstr)) || + (1 == SSCANF (start, "inet6 %127s", addrstr))) + { + /* IPv4 */ + if (1 == inet_pton (AF_INET, addrstr, &v4)) + { + memset (&a4, 0, sizeof (a4)); + a4.sin_family = AF_INET; +#if HAVE_SOCKADDR_IN_SIN_LEN + a4.sin_len = (u_char) sizeof (struct sockaddr_in); +#endif + a4.sin_addr = v4; + + pass_bcaddr = NULL; + pass_netmask = NULL; + if (1 == inet_pton (AF_INET, bcstr, &v4)) { - have_ifc = GNUNET_NO; - continue; + memset (&bcaddr, 0, sizeof (bcaddr)); + bcaddr.sin_family = AF_INET; +#if HAVE_SOCKADDR_IN_SIN_LEN + bcaddr.sin_len = (u_char) sizeof (struct sockaddr_in); +#endif + bcaddr.sin_addr = v4; + pass_bcaddr = (struct sockaddr *) &bcaddr; } - if (!isspace (line[0])) + if (1 == inet_pton (AF_INET, netmaskstr, &v4)) { - have_ifc = - (1 == SSCANF (line, "%11s", ifc)) ? GNUNET_YES : GNUNET_NO; - /* would end with ':' on OSX, fix it! */ - if (ifc[strlen (ifc) - 1] == ':') - ifc[strlen (ifc) - 1] = '\0'; - continue; + memset (&netmask, 0, sizeof (netmask)); + netmask.sin_family = AF_INET; +#if HAVE_SOCKADDR_IN_SIN_LEN + netmask.sin_len = (u_char) sizeof (struct sockaddr_in); +#endif + netmask.sin_addr = v4; + pass_netmask = (struct sockaddr *) &netmask; } - if (!have_ifc) - continue; /* strange input, hope for the best */ - start = line; - while (('\0' != *start) && (isspace (*start))) - start++; - if ( /* Linux */ - (1 == SSCANF (start, "inet addr:%127s", addrstr)) || - (1 == SSCANF (start, "inet6 addr:%127s", addrstr)) || - /* Solaris, OS X */ - (1 == SSCANF (start, "inet %127s", addrstr)) || - (1 == SSCANF (start, "inet6 %127s", addrstr))) + + + if (GNUNET_OK != + proc (proc_cls, ifc, 0 == strcmp (ifc, GNUNET_DEFAULT_INTERFACE), + (const struct sockaddr *) &a4, + pass_bcaddr, pass_netmask, sizeof (a4))) + break; + continue; + } + /* IPv6 */ + if (1 == inet_pton (AF_INET6, addrstr, &v6)) + { + memset (&a6, 0, sizeof (a6)); + a6.sin6_family = AF_INET6; +#if HAVE_SOCKADDR_IN_SIN_LEN + a6.sin6_len = (u_char) sizeof (struct sockaddr_in6); +#endif + a6.sin6_addr = v6; + + pass_netmask = NULL; + if (prefixlen != -1) { - /* IPv4 */ - if (1 == inet_pton (AF_INET, addrstr, &v4)) - { - memset (&a4, 0, sizeof (a4)); - a4.sin_family = AF_INET; - a4.sin_addr = v4; - if (GNUNET_OK != - proc (proc_cls, - ifc, - 0 == strcmp (ifc, GNUNET_DEFAULT_INTERFACE), - (const struct sockaddr *) &a4, sizeof (a4))) - break; - continue; - } - /* IPv6 */ - if (1 == inet_pton (AF_INET6, addrstr, &v6)) - { - memset (&a6, 0, sizeof (a6)); - a6.sin6_family = AF_INET6; - a6.sin6_addr = v6; - fprintf (stderr, "procing %s\n", addrstr); - if (GNUNET_OK != - proc (proc_cls, - ifc, - 0 == strcmp (ifc, GNUNET_DEFAULT_INTERFACE), - (const struct sockaddr *) &a6, sizeof (a6))) - break; - continue; - } + memset (v6.s6_addr, 0, sizeof (v6.s6_addr)); + for (i = 0; i < prefixlen; i++) + { + v6.s6_addr[i >> 3] |= 1 << (i & 7); + } + memset (&netmask6, 0, sizeof (netmask6)); + netmask6.sin6_family = AF_INET6; +#if HAVE_SOCKADDR_IN_SIN_LEN + netmask6.sin6_len = (u_char) sizeof (struct sockaddr_in6); +#endif + netmask6.sin6_addr = v6; + + pass_netmask = (struct sockaddr *) &netmask6; } + + if (GNUNET_OK != + proc (proc_cls, ifc, 0 == strcmp (ifc, GNUNET_DEFAULT_INTERFACE), + (const struct sockaddr *) &a6, + NULL, pass_netmask, sizeof (a6))) + break; + continue; + } } + } pclose (f); #endif }