Skip to content

Commit

Permalink
add network information
Browse files Browse the repository at this point in the history
  • Loading branch information
MRsoymilk committed Oct 14, 2024
1 parent 5ca79cd commit 85457e6
Show file tree
Hide file tree
Showing 11 changed files with 323 additions and 2 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ option(HWINFO_RAM "Enable RAM information" ON)
option(HWINFO_GPU "Enable GPU information" ON)
option(HWINFO_GPU_OPENCL "Enable OpenCL for more GPU information" OFF)
option(HWINFO_BATTERY "Enable battery information" ON)
option(HWINFO_NETWORK "Enable network information" ON)

if(NOT HWINFO_STATIC AND HWINFO_SHARED)
set(HWINFO_BUILD SHARED)
Expand Down
27 changes: 27 additions & 0 deletions examples/system_infoMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,5 +179,32 @@ int main(int argc, char** argv) {
} else {
fmt::print("No Disks installed or detected\n");
}

std::vector<hwinfo::Network> networks = hwinfo::getAllNetworks();
fmt::print("--------------------------------- Networks -----------------------------------\n");
if (!networks.empty()) {
int network_counter = 0;
for (const auto& network : networks) {
// clang-format off
if (network.ip4().size() > 0 || network.ip6().size() > 0) {
fmt::print(
"Network {}:\n"
"{:<20} {}\n"
"{:<20} {}\n"
"{:<20} {}\n"
"{:<20} {}\n"
"{:<20} {}\n",
network_counter++,
"description:", network.description(),
"interface index:", network.interfaceIndex(),
"mac:", network.mac(),
"ipv4:", network.ip4(),
"ipv6:", network.ip6());
}
// clang-format on
}
} else {
fmt::print("No Networks installed or detected\n");
}
return EXIT_SUCCESS;
}
1 change: 1 addition & 0 deletions include/hwinfo/hwinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
#include <hwinfo/disk.h>
#include <hwinfo/gpu.h>
#include <hwinfo/mainboard.h>
#include <hwinfo/network.h>
#include <hwinfo/os.h>
#include <hwinfo/ram.h>
34 changes: 34 additions & 0 deletions include/hwinfo/network.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#pragma once

#include <hwinfo/platform.h>

#include <string>
#include <vector>

namespace hwinfo {

class HWINFO_API Network {
friend std::vector<Network> getAllNetworks();

public:
~Network() = default;

HWI_NODISCARD const std::string& interfaceIndex() const;
HWI_NODISCARD const std::string& description() const;
HWI_NODISCARD const std::string& mac() const;
HWI_NODISCARD const std::string& ip4() const;
HWI_NODISCARD const std::string& ip6() const;

private:
Network() = default;

std::string _index;
std::string _description;
std::string _mac;
std::string _ip4;
std::string _ip6;
};

std::vector<Network> getAllNetworks();

} // namespace hwinfo
34 changes: 34 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,40 @@ if (HWINFO_RAM)
endif ()
# ______________________________________________________________________________________________________________________

# ----- NETWORK --------------------------------------------------------------------------------------------------------
if (HWINFO_NETWORK)
set(NETWORK_SRC_FILES
network.cpp
apple/network.cpp
linux/network.cpp
windows/network.cpp

windows/utils/wmi_wrapper.cpp
apple/utils/filesystem.cpp
linux/utils/filesystem.cpp
)

add_library(hwinfo_network ${HWINFO_BUILD} ${NETWORK_SRC_FILES})
if(${HWINFO_SHARED})
target_compile_definitions(hwinfo_network PUBLIC -DHWINFO_EXPORTS)
endif()
target_include_directories(hwinfo_network PUBLIC $<BUILD_INTERFACE:${HWINFO_INCLUDE_DIR}> $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)



target_link_libraries(hwinfo INTERFACE hwinfo_network)

set_target_properties(hwinfo_network PROPERTIES OUTPUT_NAME "hwinfo_network")

install(TARGETS hwinfo_network
EXPORT lfreist-hwinfoTargets
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin)
install(FILES ${HWINFO_INCLUDE_DIR}/hwinfo/network.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hwinfo)
endif ()
# ______________________________________________________________________________________________________________________

install(FILES ${HWINFO_INCLUDE_DIR}/hwinfo/platform.h ${HWINFO_INCLUDE_DIR}/hwinfo/hwinfo.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hwinfo)
install(DIRECTORY ${HWINFO_INCLUDE_DIR}/hwinfo/utils DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/hwinfo)
install(TARGETS hwinfo
Expand Down
12 changes: 12 additions & 0 deletions src/apple/network.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <hwinfo/platform.h>

#ifdef HWINFO_APPLE
#include <vector>
namespace hwinfo {
std::vector<Network> getAllNetworks() {
std::vector<Network> networks;
return networks;
}
} // namespace hwinfo

#endif // HWINFO_APPLE
106 changes: 106 additions & 0 deletions src/linux/network.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#include <hwinfo/platform.h>

#ifdef HWINFO_UNIX
#include <arpa/inet.h>
#include <hwinfo/network.h>
#include <ifaddrs.h>
#include <net/if.h>
#include <netpacket/packet.h>
#include <sys/ioctl.h>

#include <cstring>
#include <fstream>
#include <string>
#include <vector>

namespace hwinfo {

std::string getInterfaceIndex(const std::string& path) {
int index = if_nametoindex(path.c_str());
return (index > 0) ? std::to_string(index) : "<unknown>";
}

std::string getDescription(const std::string& path) { return path; }

std::string getMac(const std::string& path) {
std::ifstream file("/sys/class/net/" + path + "/address");
std::string mac;
if (file.is_open()) {
std::getline(file, mac);
file.close();
}
return mac.empty() ? "<unknown>" : mac;
}

std::string getIp4(const std::string& interface) {
std::string ip4 = "<unknown>";
struct ifaddrs* ifaddr;
if (getifaddrs(&ifaddr) == -1) {
return ip4;
}

for (struct ifaddrs* ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == nullptr) continue;
if (ifa->ifa_addr->sa_family == AF_INET && interface == ifa->ifa_name) {
char ip[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &((struct sockaddr_in*)ifa->ifa_addr)->sin_addr, ip, sizeof(ip));
ip4 = ip;
break;
}
}
freeifaddrs(ifaddr);
return ip4;
}

std::string getIp6(const std::string& interface) {
std::string ip6 = "<unknown>";
struct ifaddrs* ifaddr;
if (getifaddrs(&ifaddr) == -1) {
return ip6;
}

for (struct ifaddrs* ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == nullptr) {
continue;
}
if (ifa->ifa_addr->sa_family == AF_INET6 && interface == ifa->ifa_name) {
char ip[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &((struct sockaddr_in6*)ifa->ifa_addr)->sin6_addr, ip, sizeof(ip));
if (std::strncmp(ip, "fe80", 4) == 0) {
ip6 = ip;
break;
}
}
}
freeifaddrs(ifaddr);
return ip6;
}

std::vector<Network> getAllNetworks() {
std::vector<Network> networks;
struct ifaddrs* ifaddr;
if (getifaddrs(&ifaddr) == -1) {
perror("getifaddrs");
return networks;
}

for (struct ifaddrs* ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == nullptr) continue;
if (ifa->ifa_addr->sa_family != AF_PACKET) continue;

std::string interface = ifa->ifa_name;
Network network;
network._index = getInterfaceIndex(interface);
network._description = getDescription(interface);
network._mac = getMac(interface);
network._ip4 = getIp4(interface);
network._ip6 = getIp6(interface);
networks.push_back(std::move(network));
}
freeifaddrs(ifaddr);
return networks;
}

} // namespace hwinfo

#endif
2 changes: 1 addition & 1 deletion src/linux/os.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ OS::OS() {
}
}
{ // architecture
struct stat buffer {};
struct stat buffer{};
_64bit = stat("/lib64/ld-linux-x86-64.so.2", &buffer) == 0;
_32bit = !_64bit;
}
Expand Down
2 changes: 1 addition & 1 deletion src/linux/utils/filesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace hwinfo {
namespace filesystem {

bool exists(const std::string& path) {
struct stat sb {};
struct stat sb{};
return stat(path.c_str(), &sb) == 0;
}

Expand Down
20 changes: 20 additions & 0 deletions src/network.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

#include <hwinfo/network.h>
namespace hwinfo {

// _____________________________________________________________________________________________________________________
const std::string& Network::interfaceIndex() const { return _index; }

// _____________________________________________________________________________________________________________________
const std::string& Network::description() const { return _description; }

// _____________________________________________________________________________________________________________________
const std::string& Network::mac() const { return _mac; }

// _____________________________________________________________________________________________________________________
const std::string& Network::ip4() const { return _ip4; }

// _____________________________________________________________________________________________________________________
const std::string& Network::ip6() const { return _ip6; }

} // namespace hwinfo
86 changes: 86 additions & 0 deletions src/windows/network.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#include "hwinfo/platform.h"

#ifdef HWINFO_WINDOWS

#include <hwinfo/network.h>
#include <hwinfo/utils/stringutils.h>
#include <hwinfo/utils/wmi_wrapper.h>

namespace hwinfo {

// _____________________________________________________________________________________________________________________
std::vector<Network> getAllNetworks() {
utils::WMI::_WMI wmi;
const std::wstring query_string(
L"SELECT InterfaceIndex, IPAddress, Description, MACAddress "
L"FROM Win32_NetworkAdapterConfiguration");
bool success = wmi.execute_query(query_string);
if (!success) {
return {};
}
std::vector<Network> networks;

ULONG u_return = 0;
IWbemClassObject* obj = nullptr;
int network_id = 0;
while (wmi.enumerator) {
wmi.enumerator->Next(WBEM_INFINITE, 1, &obj, &u_return);
if (!u_return) {
break;
}
Network network;
VARIANT vt_prop;
HRESULT hr;
hr = obj->Get(L"InterfaceIndex", 0, &vt_prop, nullptr, nullptr);
if (SUCCEEDED(hr)) {
network._index = std::to_string(vt_prop.uintVal);
}
hr = obj->Get(L"IPAddress", 0, &vt_prop, nullptr, nullptr);
if (SUCCEEDED(hr)) {
if (vt_prop.vt == (VT_ARRAY | VT_BSTR)) {
LONG lbound, ubound;
SafeArrayGetLBound(vt_prop.parray, 1, &lbound);
SafeArrayGetUBound(vt_prop.parray, 1, &ubound);
std::string ipv4, ipv6;
for (LONG i = lbound; i <= ubound; ++i) {
BSTR bstr;
SafeArrayGetElement(vt_prop.parray, &i, &bstr);
std::wstring ws(bstr, SysStringLen(bstr));
std::string ip = utils::wstring_to_std_string(ws);
if (ip.find(':') != std::string::npos) {
if (ip.find("fe80::") == 0) {
ipv6 = ip;
} else {
ipv6 = "";
}
} else {
ipv4 = ip;
}
SysFreeString(bstr);
}
network._ip4 = ipv4;
network._ip6 = ipv6;
}
}
hr = obj->Get(L"Description", 0, &vt_prop, nullptr, nullptr);
if (SUCCEEDED(hr)) {
if (vt_prop.vt == VT_BSTR) {
network._description = utils::wstring_to_std_string(vt_prop.bstrVal);
}
}
hr = obj->Get(L"MACAddress", 0, &vt_prop, nullptr, nullptr);
if (SUCCEEDED(hr)) {
if (vt_prop.vt == VT_BSTR) {
network._mac = utils::wstring_to_std_string(vt_prop.bstrVal);
}
}
VariantClear(&vt_prop);
obj->Release();
networks.push_back(std::move(network));
}
return networks;
}

} // namespace hwinfo

#endif // HWINFO_WINDOWS

0 comments on commit 85457e6

Please sign in to comment.