diff --git a/src/libs/zbxsysinfo/linux/net.c b/src/libs/zbxsysinfo/linux/net.c index 75b31e9f2cf..a26c6326527 100644 --- a/src/libs/zbxsysinfo/linux/net.c +++ b/src/libs/zbxsysinfo/linux/net.c @@ -1255,6 +1255,107 @@ static void get_wifi_info(const char *interface, struct zbx_json *j) close(sockfd); } +#include +#include + +static int parse_bdf_from_path(const char *p, unsigned *domain, + unsigned *bus, unsigned *slot, unsigned *func) +{ + while (*p) + { + unsigned d, b, s, f; + + /* scan for first domain:bus:slot.func pattern */ + if (4 == sscanf(p, "%4x:%2x:%2x.%1x", &d, &b, &s, &f)) + { + *domain = d; + *bus = b; + *slot = s; + *func = f; + return 1; + } + + p++; + } + + return 0; +} + + +static void foo(const char *inerface, char *resolved_path, struct zbx_json *j) { + struct pci_access *pacc; + struct pci_dev *dev; + char namebuf[1024]; + int device_count = 0; + + char buf[MAX_STRING_LEN]; + + unsigned domain, bus, slot, func; + if (0 == parse_bdf_from_path(basename(resolved_path), &domain, &bus, &slot, &func)) + { + zabbix_log(LOG_LEVEL_INFORMATION, "[owl] %s():%d cannot parse path", __func__, __LINE__); + return; + } + + pacc = pci_alloc(); + pci_init(pacc); + pci_scan_bus(pacc); + + // printf("DEBUG: Scanning devices...\n"); + + for (dev = pacc->devices; dev; dev = dev->next) { + device_count++; + pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_CLASS); + + // printf("DEBUG: Device %02x:%02x.%x class=0x%06x\n", + // dev->bus, dev->dev, dev->func, dev->device_class); + + if (dev->domain_16 != domain || dev->bus != bus || dev->dev != slot || dev->func != func) + continue; + + // Network controllers: base class == 0x02 + // if ((dev->device_class >> 16) == 0x02) { + //if ((dev->device_class >> 8) == 0x02) { + // printf("%02x:%02x.%x ", dev->bus, dev->dev, dev->func); + + pci_lookup_name(pacc, namebuf, sizeof(namebuf), + PCI_LOOKUP_VENDOR | PCI_LOOKUP_DEVICE, + dev->vendor_id, dev->device_id); + + u8 rev = pci_read_byte(dev, PCI_REVISION_ID); + // printf("Network controller: %s (rev %02x)\n", namebuf, rev); + + // zbx_snprintf(buf, sizeof(buf), "%s %02x:%02x.%x Network controller: %s (rev %02x)\n", inerface, dev->bus, dev->dev, dev->func, namebuf, rev); + zbx_snprintf(buf, sizeof(buf), "inerface = '%s' name = '%s'", inerface, namebuf); + + zabbix_log(LOG_LEVEL_INFORMATION, "[owl] %s():%d description = '%s'", __func__, __LINE__, buf); + zbx_json_addstring(j, "description", buf, ZBX_JSON_TYPE_STRING); + //} + } + + // printf("DEBUG: Total devices scanned: %d\n", device_count); + pci_cleanup(pacc); +// return 0; +} + +static void get_description(const char *interface, struct zbx_json *j) +{ + char path[256]; + char resolved_path[PATH_MAX]; + + zbx_snprintf(path, sizeof(path), "/sys/class/net/%s/device", interface); + + + if (realpath(path, resolved_path)) { + zabbix_log(LOG_LEVEL_INFORMATION, "[owl] %s():%d interface = '%s' path = '%s' resolved_path = '%s'", __func__, __LINE__, interface, path, resolved_path); + foo(interface, resolved_path, j); + } + else { + zbx_json_addstring(j, "description", "failed to get realpath", ZBX_JSON_TYPE_STRING); + } +} + + static void get_link_settings(const char *interface, struct zbx_json *j) { int sock; @@ -1453,6 +1554,7 @@ int net_if_get(AGENT_REQUEST *request, AGENT_RESULT *result) fill_net_if_get_params(if_name, "speed", NULL, 1, &jval); fill_net_if_get_params(if_name, "duplex", NULL, 0, &jval); get_link_settings(if_name, &jval); + get_description(if_name, &jval); get_wifi_info(if_name, &jval); zbx_json_close(&jval); diff --git a/src/zabbix_agent/Makefile.am b/src/zabbix_agent/Makefile.am index b217fb57a05..f47f8b238a8 100644 --- a/src/zabbix_agent/Makefile.am +++ b/src/zabbix_agent/Makefile.am @@ -56,7 +56,9 @@ zabbix_agentd_LDADD = \ $(top_builddir)/src/libs/zbxexpr/libzbxexpr.a \ $(top_builddir)/src/libs/zbxcurl/libzbxcurl.a \ $(top_builddir)/src/libs/zbxbincommon/libzbxbincommon.a \ - $(AGENT_LIBS) + $(AGENT_LIBS) \ + -lpci + zabbix_agentd_LDFLAGS = $(AGENT_LDFLAGS)