pkgsrc-WIP-changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

zabbix50-proxy: Use sysctl interface for network statistics



Module Name:	pkgsrc-wip
Committed By:	Juraj Lutter <otis%NetBSD.org@localhost>
Pushed By:	otis
Date:		Mon Sep 14 12:12:19 2020 +0200
Changeset:	5f18dc9a121630220988b14bc98c2e68b82ac116

Modified Files:
	zabbix50-proxy/distinfo
Added Files:
	zabbix50-proxy/patches/patch-src_libs_zbxsysinfo_netbsd_net.c

Log Message:
zabbix50-proxy: Use sysctl interface for network statistics

To see a diff of this commit:
https://wip.pkgsrc.org/cgi-bin/gitweb.cgi?p=pkgsrc-wip.git;a=commitdiff;h=5f18dc9a121630220988b14bc98c2e68b82ac116

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

diffstat:
 zabbix50-proxy/distinfo                            |   1 +
 .../patches/patch-src_libs_zbxsysinfo_netbsd_net.c | 203 +++++++++++++++++++++
 2 files changed, 204 insertions(+)

diffs:
diff --git a/zabbix50-proxy/distinfo b/zabbix50-proxy/distinfo
index fcb68e1bec..260bfb9553 100644
--- a/zabbix50-proxy/distinfo
+++ b/zabbix50-proxy/distinfo
@@ -5,4 +5,5 @@ RMD160 (zabbix-5.0.3.tar.gz) = a1d122b71549a230f21f9d85dbc28042b40ec7ea
 SHA512 (zabbix-5.0.3.tar.gz) = d08a031b334f531320f6b695af3ed7e3514c802ea28e0cec75040c518409e16ab4c591b389091aa12c07129f9b758d050c958967e3e86e725f4595f3b3a90d97
 Size (zabbix-5.0.3.tar.gz) = 18893485 bytes
 SHA1 (patch-configure) = cf647b9ee52a96882d31f8783ac19b66e3e65105
+SHA1 (patch-src_libs_zbxsysinfo_netbsd_net.c) = 468f2112a3d65b0a73f371194ae15ce0df0ad71c
 SHA1 (patch-src_zabbix__proxy_Makefile.in) = 222264bb6145dcd180657e657899aa960fba6d2e
diff --git a/zabbix50-proxy/patches/patch-src_libs_zbxsysinfo_netbsd_net.c b/zabbix50-proxy/patches/patch-src_libs_zbxsysinfo_netbsd_net.c
new file mode 100644
index 0000000000..1591a5c8c4
--- /dev/null
+++ b/zabbix50-proxy/patches/patch-src_libs_zbxsysinfo_netbsd_net.c
@@ -0,0 +1,203 @@
+$NetBSD$
+
+Rework interface statistics code from using kvm to using sysctl interface.
+
+--- src/libs/zbxsysinfo/netbsd/net.c.orig	2020-08-24 09:42:55.000000000 +0000
++++ src/libs/zbxsysinfo/netbsd/net.c
+@@ -22,6 +22,9 @@
+ #include "zbxjson.h"
+ #include "log.h"
+ 
++#include <net/route.h>
++#include <net/if_dl.h>
++
+ static struct nlist kernel_symbols[] =
+ {
+ 	{"_ifnet", N_UNDF, 0, 0, 0},
+@@ -31,43 +34,91 @@ static struct nlist kernel_symbols[] =
+ 
+ #define IFNET_ID 0
+ 
++static void
++get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
++{
++    int i;
++
++    for (i = 0; i < RTAX_MAX; i++) {
++        if (addrs & (1 << i)) {
++            rti_info[i] = sa;
++            sa = (struct sockaddr *)((char *)(sa) +
++                RT_ROUNDUP(sa->sa_len));
++        } else
++            rti_info[i] = NULL;
++    }
++}
++
++
+ static int	get_ifdata(const char *if_name,
+ 		zbx_uint64_t *ibytes, zbx_uint64_t *ipackets, zbx_uint64_t *ierrors, zbx_uint64_t *idropped,
+ 		zbx_uint64_t *obytes, zbx_uint64_t *opackets, zbx_uint64_t *oerrors,
+ 		zbx_uint64_t *tbytes, zbx_uint64_t *tpackets, zbx_uint64_t *terrors,
+ 		zbx_uint64_t *icollisions, char **error)
+ {
+-	struct ifnet_head	head;
+-	struct ifnet		*ifp;
+-	struct ifnet		v;
+-
+-	kvm_t	*kp;
+-	int	len = 0;
+-	int	ret = SYSINFO_RET_FAIL;
++	struct	if_msghdr *ifm;
++	int		mib[6] = { CTL_NET, AF_ROUTE, 0, 0, NET_RT_IFLIST, 0 };
++	char	*buf = NULL;
++	char	*lim, *next;
++	struct	rt_msghdr *rtm;
++	struct	if_data *ifd = NULL;
++	struct	sockaddr *sa, *rti_info[RTAX_MAX];
++	struct	sockaddr_dl *sdl;
++
++	size_t	len = 0;
++	size_t	olen = 0;
++	int		ret = SYSINFO_RET_FAIL;
++
++	static char name[IFNAMSIZ];
+ 
+ 	if (NULL == if_name || '\0' == *if_name)
+ 	{
+ 		*error = zbx_strdup(NULL, "Network interface name cannot be empty.");
+-		return FAIL;
++		ret = FAIL;
++		goto out;
+ 	}
+ 
+-	if (NULL == (kp = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL))) /* requires root privileges */
+-	{
+-		*error = zbx_strdup(NULL, "Cannot obtain a descriptor to access kernel virtual memory.");
+-		return FAIL;
+-	}
+-
+-	if (N_UNDF == kernel_symbols[IFNET_ID].n_type)
+-		if (0 != kvm_nlist(kp, &kernel_symbols[0]))
+-			kernel_symbols[IFNET_ID].n_type = N_UNDF;
+-
+-	if (N_UNDF != kernel_symbols[IFNET_ID].n_type)
+-	{
+-		len = sizeof(struct ifnet_head);
+-
+-		if (kvm_read(kp, kernel_symbols[IFNET_ID].n_value, &head, len) >= len)
+-		{
+-			len = sizeof(struct ifnet);
++    if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1) {
++        *error = zbx_strdup(NULL, "Failed to read network interfaces data");
++		ret = FAIL;
++		goto out;
++	}
++
++    if (len > olen) {
++        free(buf);
++        if ((buf = zbx_malloc(NULL, len)) == NULL) {
++			*error = zbx_strdup(NULL, "Failed to allocate buffer for network interfaces data");
++			ret = FAIL;
++			goto out;
++		}
++        olen = len;
++    }
++    if (sysctl(mib, 6, buf, &len, NULL, 0) == -1) {
++		*error = zbx_strdup(NULL, "Failed to allocate buffer for network interfaces data");
++		ret = FAIL;
++		goto out;
++	}
++
++	lim = buf + len;
++    for (next = buf; next < lim; next += rtm->rtm_msglen) {
++        rtm = (struct rt_msghdr *)next;
++        if ((rtm->rtm_version == RTM_VERSION) &&
++                (rtm->rtm_type == RTM_IFINFO)) {
++            ifm = (struct if_msghdr *)next;
++            ifd = &ifm->ifm_data;
++
++            sa = (struct sockaddr *)(ifm + 1);
++            get_rtaddrs(ifm->ifm_addrs, sa, rti_info);
++
++            sdl = (struct sockaddr_dl *)rti_info[RTAX_IFP];
++            if (sdl == NULL || sdl->sdl_family != AF_LINK) {
++                continue;
++            }
++            bzero(name, sizeof(name));
++            if (sdl->sdl_nlen >= IFNAMSIZ)
++                memcpy(name, sdl->sdl_data, IFNAMSIZ - 1);
++            else if (sdl->sdl_nlen > 0)
++                memcpy(name, sdl->sdl_data, sdl->sdl_nlen);
+ 
+ 			/* if_ibytes;		total number of octets received */
+ 			/* if_ipackets;		packets received on interface */
+@@ -101,42 +152,38 @@ static int	get_ifdata(const char *if_nam
+ 			if (icollisions)
+ 				*icollisions = 0;
+ 
+-			for (ifp = head.tqh_first; ifp; ifp = v.if_list.tqe_next)
++			if (0 == strcmp(if_name, name))
+ 			{
+-				if (kvm_read(kp, (u_long)ifp, &v, len) < len)
+-					break;
+-
+-				if (0 == strcmp(if_name, v.if_xname))
+-				{
+-					if (ibytes)
+-						*ibytes += v.if_ibytes;
+-					if (ipackets)
+-						*ipackets += v.if_ipackets;
+-					if (ierrors)
+-						*ierrors += v.if_ierrors;
+-					if (idropped)
+-						*idropped += v.if_iqdrops;
+-					if (obytes)
+-						*obytes += v.if_obytes;
+-					if (opackets)
+-						*opackets += v.if_opackets;
+-					if (oerrors)
+-						*oerrors += v.if_oerrors;
+-					if (tbytes)
+-						*tbytes += v.if_ibytes + v.if_obytes;
+-					if (tpackets)
+-						*tpackets += v.if_ipackets + v.if_opackets;
+-					if (terrors)
+-						*terrors += v.if_ierrors + v.if_oerrors;
+-					if (icollisions)
+-						*icollisions += v.if_collisions;
+-					ret = SYSINFO_RET_OK;
+-				}
++				if (ibytes)
++					*ibytes += ifd->ifi_ibytes;
++				if (ipackets)
++					*ipackets += ifd->ifi_ipackets;
++				if (ierrors)
++					*ierrors += ifd->ifi_ierrors;
++				if (idropped)
++					*idropped += ifd->ifi_iqdrops;
++				if (obytes)
++					*obytes += ifd->ifi_obytes;
++				if (opackets)
++					*opackets += ifd->ifi_opackets;
++				if (oerrors)
++					*oerrors += ifd->ifi_oerrors;
++				if (tbytes)
++					*tbytes += ifd->ifi_ibytes + ifd->ifi_obytes;
++				if (tpackets)
++					*tpackets += ifd->ifi_ipackets + ifd->ifi_opackets;
++				if (terrors)
++					*terrors += ifd->ifi_ierrors + ifd->ifi_oerrors;
++				if (icollisions)
++					*icollisions += ifd->ifi_collisions;
++				ret = SYSINFO_RET_OK;
++				goto out;
+ 			}
+ 		}
+ 	}
+ 
+-	kvm_close(kp);
++out:
++	free(buf);
+ 
+ 	if (SYSINFO_RET_FAIL == ret)
+ 	{


Home | Main Index | Thread Index | Old Index