--- src/data_provider/src/sysInfoFreeBSD.cpp 2024-04-25 03:44:26.000000000 -0500 +++ src/data_provider/src/sysInfoFreeBSD.cpp 2024-05-10 03:48:12.219475000 -0500 @@ -11,6 +11,7 @@ #include "sysInfo.hpp" #include "cmdHelper.h" #include "stringHelper.h" +#include "timeHelper.h" #include "osinfo/sysOsParsers.h" #include #include @@ -19,12 +20,13 @@ static void getMemory(nlohmann::json& info) { + constexpr auto vmFree{"vm.stats.vm.v_free_count"}; + constexpr auto vmInactive{"vm.stats.vm.v_inactive_count"}; constexpr auto vmPageSize{"vm.stats.vm.v_page_size"}; - constexpr auto vmTotal{"vm.vmtotal"}; + constexpr auto vmTotal{"hw.physmem"}; uint64_t ram{0}; - const std::vector mib{CTL_HW, HW_PHYSMEM}; size_t len{sizeof(ram)}; - auto ret{sysctl(const_cast(mib.data()), mib.size(), &ram, &len, nullptr, 0)}; + auto ret{sysctlbyname(vmTotal, &ram, &len, nullptr, 0)}; if (ret) { @@ -52,11 +54,23 @@ }; } - struct vmtotal vmt {}; + uint64_t freeMem{0}; + len = sizeof(freeMem); + ret = sysctlbyname(vmFree, &freeMem, &len, nullptr, 0); - len = sizeof(vmt); + if (ret) + { + throw std::system_error + { + ret, + std::system_category(), + "Error reading free memory size." + }; + } - ret = sysctlbyname(vmTotal, &vmt, &len, nullptr, 0); + uint64_t inactiveMem{0}; + len = sizeof(inactiveMem); + ret = sysctlbyname(vmInactive, &inactiveMem, &len, nullptr, 0); if (ret) { @@ -64,11 +78,11 @@ { ret, std::system_category(), - "Error reading total memory." + "Error reading inactive memory size." }; } - const auto ramFree{(vmt.t_free * pageSize) / KByte}; + const auto ramFree{(freeMem + inactiveMem) * pageSize / KByte}; info["ram_free"] = ramFree; info["ram_usage"] = 100 - (100 * ramFree / ramTotal); } @@ -184,8 +198,12 @@ nlohmann::json SysInfo::getProcessesInfo() const { - // Currently not supported for this OS - return nlohmann::json {}; + nlohmann::json ret; + getProcessesInfo([&ret](nlohmann::json & data) + { + ret.push_back(data); + }); + return ret; } nlohmann::json SysInfo::getOsInfo() const @@ -196,11 +214,12 @@ if (!spParser->parseUname(Utils::exec("uname -r"), ret)) { - ret["os_name"] = "BSD"; ret["os_platform"] = "bsd"; ret["os_version"] = UNKNOWN_VALUE; } + ret["os_name"] = "FreeBSD"; + if (uname(&uts) >= 0) { ret["sysname"] = uts.sysname; @@ -215,18 +234,137 @@ nlohmann::json SysInfo::getPorts() const { - // Currently not supported for this OS. - return nlohmann::json {}; + const auto query{Utils::exec(R"(sockstat -46qs)")}; + nlohmann::json ports {}; + + if (!query.empty()) + { + const auto lines{Utils::split(Utils::trimToOneSpace(query), '\n')}; + + for (const auto& line : lines) + { + std::string localip = ""; + std::string localport = ""; + std::string remoteip = ""; + std::string remoteport = ""; + std::string statedata = ""; + const auto data{Utils::split(line, ' ')}; + auto localdata{Utils::split(data[5], ':')}; + auto remotedata{Utils::split(data[6], ':')}; + + localip = localdata[0]; + localport = localdata[1]; + remoteip = remotedata[0]; + remoteport = remotedata[1]; + + if((data[4] != "udp4") && (data[4] != "udp6")) { + statedata = Utils::toLowerCase(data[7]); + } + + if(statedata == "listen") { + statedata = "listening"; + } + + if(localdata.size() == 4) { + localip = localdata[0] + ":"+ localdata[1] + ":" + localdata[2]; + localport = localdata[3]; + } else if(localip == "*") { + if((data[4] == "tcp6") || (data[4] == "udp6")) { + localip = "0:0:0:0:0:0:0:0"; + } else { + localip = "0.0.0.0"; + } + } + + if(localport == "*") { + localport = "0"; + } + + if(remotedata.size() == 4) { + remoteip = remotedata[0] + ":"+ remotedata[1] + ":" + remotedata[2]; + remoteport = remotedata[3]; + } else if(remoteport == "*") { + remoteip = ""; + remoteport = "0"; + } + + if(data[0] != "?") { + nlohmann::json port {}; + port["protocol"] = data[4]; + port["local_ip"] = localip; + port["local_port"] = localport; + port["remote_ip"] = remoteip; + port["remote_port"] = remoteport; + port["tx_queue"] = 0; + port["rx_queue"] = 0; + port["inode"] = data[3]; + port["state"] = statedata; + port["pid"] = data[2]; + port["process"] = data[1]; + + ports.push_back(port); + } + } + } + + return ports; } -void SysInfo::getProcessesInfo(std::function /*callback*/) const +void SysInfo::getProcessesInfo(std::function callback) const { - // Currently not supported for this OS. + const auto query{Utils::exec(R"(ps -ax -w -o pid,comm,state,ppid,usertime,systime,user,ruser,svuid,group,rgroup,svgid,pri,nice,ssiz,vsz,rss,pmem,etimes,sid,pgid,tpgid,tty,cpu,nlwp,args --libxo json)")}; + + if (!query.empty()) + { + nlohmann::json psjson; + psjson = nlohmann::json::parse(query); + auto &processes = psjson["process-information"]["process"]; + + for(auto &process : processes) { + std::string user_time{""}; + std::string system_time{""}; + + user_time = process["user-time"].get(); + system_time = process["system-time"].get(); + + nlohmann::json jsProcessInfo{}; + jsProcessInfo["pid"] = process["pid"].get(); + jsProcessInfo["name"] = process["command"].get(); + jsProcessInfo["state"] = process["state"].get(); + jsProcessInfo["ppid"] = process["ppid"].get(); + jsProcessInfo["utime"] = Utils::timeToSeconds(user_time); + jsProcessInfo["stime"] = Utils::timeToSeconds(system_time); + jsProcessInfo["cmd"] = process["command"].get(); + jsProcessInfo["argvs"] = process["arguments"].get(); + jsProcessInfo["euser"] = process["user"].get(); + jsProcessInfo["ruser"] = process["real-user"].get(); + jsProcessInfo["suser"] = process["saved-uid"].get(); + jsProcessInfo["egroup"] = process["group"].get(); + jsProcessInfo["rgroup"] = process["real-group"].get(); + jsProcessInfo["sgroup"] = process["saved-gid"].get(); + jsProcessInfo["fgroup"] = process["group"].get(); + jsProcessInfo["priority"] = process["priority"].get(); + jsProcessInfo["nice"] = process["nice"].get(); + jsProcessInfo["size"] = process["stack-size"].get(); + jsProcessInfo["vm_size"] = process["virtual-size"].get(); + jsProcessInfo["resident"] = process["rss"].get(); + //jsProcessInfo["share"] = process["percent-memory"].get(); + jsProcessInfo["start_time"] = process["elapsed-times"].get(); + jsProcessInfo["pgrp"] = process["process-group"].get(); + jsProcessInfo["session"] = process["sid"].get(); + jsProcessInfo["tgid"] = process["terminal-process-gid"].get(); + //jsProcessInfo["tty"] = process["tty"].get(); // this field should be TEXT into local.db + jsProcessInfo["processor"] = process["on-cpu"].get(); + jsProcessInfo["nlwp"] = process["threads"].get(); + + callback(jsProcessInfo); + } + } } void SysInfo::getPackages(std::function callback) const { - const auto query{Utils::exec(R"(pkg query -a "%n|%m|%v|%q|%c")")}; + const auto query{Utils::exec(R"(pkg query -a "%n|%m|%v|%q|%c|%sb|%t|%R|%o")")}; if (!query.empty()) { @@ -235,18 +373,22 @@ for (const auto& line : lines) { const auto data{Utils::split(line, '|')}; + const auto archdata{Utils::split(data[3], ':')}; + const auto sectiondata{Utils::split(data[8], '/')}; + nlohmann::json package; package["name"] = data[0]; package["vendor"] = data[1]; package["version"] = data[2]; - package["install_time"] = UNKNOWN_VALUE; + package["install_time"] = data[6]; package["location"] = UNKNOWN_VALUE; - package["architecture"] = data[3]; + package["architecture"] = archdata[2]; package["groups"] = UNKNOWN_VALUE; package["description"] = data[4]; - package["size"] = 0; + package["size"] = data[5]; package["priority"] = UNKNOWN_VALUE; - package["source"] = UNKNOWN_VALUE; + package["source"] = data[7]; + package["section"] = sectiondata[0]; package["format"] = "pkg"; // The multiarch field won't have a default value