X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Futil%2Fos_network.c;h=b0490efab1bc6522eaf007af648fad1b70fc004d;hb=72c8645af31896829b674b575c5375706f362a30;hp=21376f94c62f6d1ccbc1487a11d30d7bea5d293d;hpb=5746309cb4be2073d550ad7a6885e918631dbc38;p=oweals%2Fgnunet.git diff --git a/src/util/os_network.c b/src/util/os_network.c index 21376f94c..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,124 +47,29 @@ 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; - } + int r; + int i; + struct EnumNICs3_results *results = NULL; + int results_count; - /* Enumerate NICs */ - EnumNICs (&pTable, &pAddrTable); + r = EnumNICs3 (&results, &results_count); + if (r != GNUNET_OK) + return; - if (pTable) + for (i = 0; i < results_count; i++) { - for (dwIfIdx = 0; dwIfIdx <= pTable->dwNumEntries; dwIfIdx++) - { - char szEntry[1001]; - DWORD dwIP = 0; - 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]; - struct sockaddr_in sa; - - /* Get friendly interface name */ - pAdapterInfo = (IP_ADAPTER_INFO *) malloc (sizeof (IP_ADAPTER_INFO)); - ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO); - - /* 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); - } - - 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); - - sa.sin_family = AF_INET; -#if HAVE_SOCKADDR_IN_SIN_LEN - sa.sin_len = (u_char) sizeof (struct sockaddr_in); -#endif - sa.sin_addr.S_un.S_addr = dwIP; - - if (GNUNET_OK != - proc (proc_cls, szEntry, - pTable->table[dwIfIdx].dwIndex == dwExternalNIC, - (const struct sockaddr *) &sa, sizeof (sa))) - break; - } - } - GlobalFree (pAddrTable); - GlobalFree (pTable); + 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 @@ -185,23 +95,34 @@ GNUNET_OS_network_interfaces_list (GNUNET_OS_NetworkInterfaceProcessor proc, if (GNUNET_OK != proc (proc_cls, ifa_ptr->ifa_name, 0 == strcmp (ifa_ptr->ifa_name, GNUNET_DEFAULT_INTERFACE), - ifa_ptr->ifa_addr, alen)) + 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,8 +133,8 @@ GNUNET_OS_network_interfaces_list (GNUNET_OS_NetworkInterfaceProcessor proc, f = popen ("ifconfig -a 2> /dev/null", "r"); if (!f) { - GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING | - GNUNET_ERROR_TYPE_BULK, "popen", "ifconfig"); + LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, + "popen", "ifconfig"); return; } @@ -236,12 +157,29 @@ GNUNET_OS_network_interfaces_list (GNUNET_OS_NetworkInterfaceProcessor proc, } if (!have_ifc) continue; /* strange input, hope for the best */ + + /* make parsing of ipv6 addresses easier */ + for (replace = line; *replace != '\0'; replace++) + { + if (*replace == '/') + *replace = ' '; + } + prefixlen = -1; + start = line; while (('\0' != *start) && (isspace (*start))) start++; - if ( /* Linux */ - (1 == SSCANF (start, "inet addr:%127s", addrstr)) || - (1 == SSCANF (start, "inet6 addr:%127s", addrstr)) || + + /* 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))) @@ -255,9 +193,35 @@ GNUNET_OS_network_interfaces_list (GNUNET_OS_NetworkInterfaceProcessor proc, 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)) + { + 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 (1 == inet_pton (AF_INET, netmaskstr, &v4)) + { + 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 (GNUNET_OK != proc (proc_cls, ifc, 0 == strcmp (ifc, GNUNET_DEFAULT_INTERFACE), - (const struct sockaddr *) &a4, sizeof (a4))) + (const struct sockaddr *) &a4, + pass_bcaddr, pass_netmask, sizeof (a4))) break; continue; } @@ -270,9 +234,29 @@ GNUNET_OS_network_interfaces_list (GNUNET_OS_NetworkInterfaceProcessor proc, a6.sin6_len = (u_char) sizeof (struct sockaddr_in6); #endif a6.sin6_addr = v6; + + pass_netmask = NULL; + if (prefixlen != -1) + { + 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, sizeof (a6))) + (const struct sockaddr *) &a6, + NULL, pass_netmask, sizeof (a6))) break; continue; }