From 879b426308c7ca6d7f28ed1a8251096e9c6c3ff7 Mon Sep 17 00:00:00 2001 From: SASANO Takayoshi Date: Tue, 6 Oct 2020 06:17:55 +0900 Subject: [PATCH 1/2] CNetworkInfo::getNetworkInterface() OpenBSD/NetBSD support added IPv4 default routing information request code for OpenBSD/NetBSD. --- NetworkInfo.cpp | 69 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 61 insertions(+), 8 deletions(-) diff --git a/NetworkInfo.cpp b/NetworkInfo.cpp index 0c27b6b..e4e57f8 100644 --- a/NetworkInfo.cpp +++ b/NetworkInfo.cpp @@ -26,13 +26,18 @@ #include #include -#if !defined(_WIN32) && !defined(_WIN64) +#if defined(__linux__) || defined(__OpenBSD__) || defined(__NetBSD__) #include #include #include #include #include -#else +#if defined(__OpenBSD__) || defined(__NetBSD__) +#include +#include +#include +#endif +#elif defined(_WIN32) || defined(_WIN64) #include #include #pragma comment(lib, "iphlpapi.lib") @@ -61,17 +66,16 @@ void CNetworkInfo::getNetworkInterface(unsigned char* info) ::strcpy((char*)info, "(address unknown)"); -#if !defined(_WIN32) && !defined(_WIN64) - const unsigned int IFLISTSIZ = 25U; +#if defined(__linux__) || defined(__NetBSD__) || defined(__OpenBSD__) + char* dflt = NULL; - FILE* fp = ::fopen("/proc/net/route" , "r"); +#if defined(__linux__) + FILE* fp = ::fopen("/proc/net/route" , "r"); // IPv4 routing if (fp == NULL) { LogError("Unabled to open /proc/route"); return; } - char* dflt = NULL; - char line[100U]; while (::fgets(line, 100U, fp)) { char* p1 = strtok(line , " \t"); @@ -87,11 +91,60 @@ void CNetworkInfo::getNetworkInterface(unsigned char* info) ::fclose(fp); +#elif defined(__OpenBSD__) || defined(__NetBSD__) + const int mib[] = { + CTL_NET, + PF_ROUTE, + 0, // protocol + AF_INET, // IPv4 routing + NET_RT_DUMP, + 0, // show all routes +#if defined(__OpenBSD__) + 0, // table id +#endif + }; + const int cnt = sizeof(mib) / sizeof(int); + size_t size; + char ifname[IF_NAMESIZE] = {}; + + if (::sysctl(mib, cnt, NULL, &size, NULL, 0) == -1 || size <= 0) { + LogError("Unable to estimate routing table size"); + return; + } + + char *buf = new char[size]; + if (::sysctl(mib, cnt, buf, &size, NULL, 0) == -1) { + LogError("Unable to get routing table"); + delete[] buf; + return; + } + + struct rt_msghdr *rtm; + for (char *p = buf; p < buf + size; p += rtm->rtm_msglen) { + rtm = (struct rt_msghdr *)p; + if (rtm->rtm_version != RTM_VERSION) + continue; +#if defined(__OpenBSD__) + struct sockaddr_in *sa = (struct sockaddr_in *)(p + rtm->rtm_hdrlen); +#elif defined(__NetBSD__) + struct sockaddr_in *sa = (struct sockaddr_in *)(rtm + 1); +#endif + if (sa->sin_addr.s_addr == INADDR_ANY) { + ::if_indextoname(rtm->rtm_index, ifname); + break; + } + } + + delete[] buf; + if (::strlen(ifname)) + dflt = ifname; +#endif if (dflt == NULL) { LogError("Unable to find the default route"); return; } + const unsigned int IFLISTSIZ = 25U; char interfacelist[IFLISTSIZ][50+INET6_ADDRSTRLEN]; for (unsigned int n = 0U; n < IFLISTSIZ; n++) interfacelist[n][0] = 0; @@ -144,7 +197,7 @@ void CNetworkInfo::getNetworkInterface(unsigned char* info) } LogInfo(" IP to show: %s", info); -#else +#elif defined(_WIN32) || defined(_WIN64) PMIB_IPFORWARDTABLE pIpForwardTable = (MIB_IPFORWARDTABLE *)::malloc(sizeof(MIB_IPFORWARDTABLE)); if (pIpForwardTable == NULL) { LogError("Error allocating memory"); From f2c399308b58a8b1757075c4381ca79b1cd3ac5e Mon Sep 17 00:00:00 2001 From: SASANO Takayoshi Date: Tue, 6 Oct 2020 06:27:18 +0900 Subject: [PATCH 2/2] CNetworkInfo::getNetworkInterface display IP address is limited to IPv4 Displayed IP address is now IPv4 only due to referring IPv4 routing table to get default route. This feature is used by hotspots which have small LCD or OLED display to show IP address to remote login. No effects to connect other reflectors. If completely disabled IPv4 world will come, the code need to be revised. --- NetworkInfo.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/NetworkInfo.cpp b/NetworkInfo.cpp index e4e57f8..7df2d3c 100644 --- a/NetworkInfo.cpp +++ b/NetworkInfo.cpp @@ -172,12 +172,13 @@ void CNetworkInfo::getNetworkInterface(unsigned char* info) if (family == AF_INET) { ::sprintf(interfacelist[ifnr], "%s:%s", ifa->ifa_name, host); LogInfo(" IPv4: %s", interfacelist[ifnr]); + ifnr++; } else { ::sprintf(interfacelist[ifnr], "%s:%s", ifa->ifa_name, host); LogInfo(" IPv6: %s", interfacelist[ifnr]); + // due to default routing is for IPv4, other + // protocols are not candidate to display. } - - ifnr++; } }