Download raw body.
snmpd: move smi_getticks to appl_sysuptime
ping
On Wed, 2025-10-08 at 12:27 +0200, Martijn van Duren wrote:
> ping
>
> On Mon, 2024-03-18 at 18:22 +0100, Martijn van Duren wrote:
> > smi_getticks is snmpd's current way of supplying the sysUpTime. SMI
> > doesn't define the sysUpTime (that would be SNMPv2-MIB), so this
> > placing is wrong. Another issue with it is that it uses gettimeofday,
> > where CLOCK_MONOTONIC would be a better fit.
> >
> > The definition of sysUpTime is:
> > "The time (in hundredths of a second) since the
> > network management portion of the system was last
> > re-initialized."
> > Where I wasn't able to find a clear definition of "network management
> > portion". However, the AgentX RFC2741 states in section 6.2.16:
> > res.sysUpTime
> >
> > This field contains the current value of sysUpTime for the
> > context indicated within the PDU to which this PDU is a
> > response.
> > Implying that the sysUpTime is at the very least on a per context basis.
> > For this reason I went with placing the information in appl_context.
> >
> > Because of this the start time should be set when the context is
> > created, implying that the context should be created during appl_init,
> > instead of relying on a random query creating it (either AgentX setup,
> > or an SNMP packet).
> >
> > As for the 'struct appl_context *' vs 'const char *', I've stuck
> > with 'const char *' for consistency and keep things a bit more in
> > line with the SNMP/AgentX protocol point of view.
> >
> > While here fix the types of sysORLastChange and sysORUpTime.
> >
> > OK?
> >
> > martijn@
> >
>
Index: application.c
===================================================================
RCS file: /cvs/src/usr.sbin/snmpd/application.c,v
diff -u -r1.43 application.c
--- application.c 8 Feb 2024 17:34:09 -0000 1.43
+++ application.c 28 Oct 2025 08:10:38 -0000
@@ -28,6 +28,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <time.h>
#include "application.h"
#include "log.h"
@@ -48,7 +49,7 @@
uint32_t aa_index;
struct ber_oid aa_oid;
char aa_descr[256];
- int aa_uptime;
+ uint32_t aa_uptime;
TAILQ_ENTRY(appl_agentcap) aa_entry;
};
@@ -57,9 +58,12 @@
char ac_name[APPL_CONTEXTNAME_MAX + 1];
RB_HEAD(appl_regions, appl_region) ac_regions;
+
TAILQ_HEAD(, appl_agentcap) ac_agentcaps;
int ac_agentcap_lastid;
- int ac_agentcap_lastchange;
+ uint32_t ac_agentcap_lastchange;
+
+ struct timespec ac_starttime;
TAILQ_ENTRY(appl_context) ac_entries;
};
@@ -179,6 +183,8 @@
void
appl_init(void)
{
+ if (appl_context(NULL, 1) == NULL)
+ fatal("Failed to create default context");
appl_blocklist_init();
appl_internal_init();
appl_agentx_init();
@@ -220,7 +226,7 @@
}
/* Always allow the default namespace */
- if (!create && name[0] != '\0') {
+ if (!create) {
errno = ENOENT;
return NULL;
}
@@ -235,6 +241,9 @@
ctx->ac_agentcap_lastchange = 0;
TAILQ_INSERT_TAIL(&contexts, ctx, ac_entries);
+
+ if (clock_gettime(CLOCK_MONOTONIC, &ctx->ac_starttime) == -1)
+ fatal("clock_gettime");
return ctx;
}
@@ -271,7 +280,7 @@
cap->aa_context = ctx;
cap->aa_index = ++ctx->ac_agentcap_lastid;
cap->aa_oid = *oid;
- cap->aa_uptime = smi_getticks();
+ cap->aa_uptime = appl_sysuptime(ctxname);
if (strlcpy(cap->aa_descr, descr,
sizeof(cap->aa_descr)) >= sizeof(cap->aa_descr)) {
log_info("%s: Can't add agent capabilities %s: "
@@ -331,8 +340,25 @@
appl_agentcap_free(struct appl_agentcap *cap)
{
TAILQ_REMOVE(&(cap->aa_context->ac_agentcaps), cap, aa_entry);
- cap->aa_context->ac_agentcap_lastchange = smi_getticks();
+ cap->aa_context->ac_agentcap_lastchange =
+ appl_sysuptime(cap->aa_context->ac_name);
free(cap);
+}
+
+uint32_t
+appl_sysuptime(const char *ctxname)
+{
+ struct appl_context *ctx;
+ struct timespec now, uptime;
+
+ if ((ctx = appl_context(ctxname, 0)) == NULL)
+ return 0;
+
+ if (clock_gettime(CLOCK_MONOTONIC, &now) == -1)
+ fatal("clock_gettime");
+
+ timespecsub(&now, &ctx->ac_starttime, &uptime);
+ return uptime.tv_sec * 100 + uptime.tv_nsec / 10000000;
}
struct ber_element *
Index: application.h
===================================================================
RCS file: /cvs/src/usr.sbin/snmpd/application.h,v
diff -u -r1.13 application.h
--- application.h 12 Nov 2023 16:07:34 -0000 1.13
+++ application.h 28 Oct 2025 08:10:38 -0000
@@ -123,6 +123,7 @@
void appl_init(void);
void appl_shutdown(void);
struct appl_context *appl_context(const char *, int);
+uint32_t appl_sysuptime(const char *);
enum appl_error appl_addagentcaps(const char *, struct ber_oid *, const char *,
struct appl_backend *);
enum appl_error appl_removeagentcaps(const char *, struct ber_oid *,
Index: application_agentx.c
===================================================================
RCS file: /cvs/src/usr.sbin/snmpd/application_agentx.c,v
diff -u -r1.16 application_agentx.c
--- application_agentx.c 6 Feb 2024 12:44:27 -0000 1.16
+++ application_agentx.c 28 Oct 2025 08:10:38 -0000
@@ -423,7 +423,8 @@
case AX_PDU_TYPE_PING:
ax_response(conn->conn_ax, pdu->ap_header.aph_sessionid,
pdu->ap_header.aph_transactionid,
- pdu->ap_header.aph_packetid, smi_getticks(),
+ pdu->ap_header.aph_packetid,
+ appl_sysuptime(pdu->ap_context.aos_string),
APPL_ERROR_NOERROR, 0, NULL, 0);
event_add(&(conn->conn_wev), NULL);
break;
@@ -433,7 +434,8 @@
ax_pdutype2string(pdu->ap_header.aph_type));
ax_response(conn->conn_ax, pdu->ap_header.aph_sessionid,
pdu->ap_header.aph_transactionid,
- pdu->ap_header.aph_packetid, smi_getticks(),
+ pdu->ap_header.aph_packetid,
+ appl_sysuptime(pdu->ap_context.aos_string),
APPL_ERROR_PROCESSINGERROR, 1,
pdu->ap_payload.ap_vbl.ap_varbind,
pdu->ap_payload.ap_vbl.ap_nvarbind);
@@ -455,8 +457,8 @@
fail:
ax_response(conn->conn_ax, pdu->ap_header.aph_sessionid,
pdu->ap_header.aph_transactionid,
- pdu->ap_header.aph_packetid, smi_getticks(),
- error, 0, NULL, 0);
+ pdu->ap_header.aph_packetid,
+ appl_sysuptime(pdu->ap_context.aos_string), error, 0, NULL, 0);
event_add(&(conn->conn_wev), NULL);
ax_pdu_free(pdu);
@@ -565,13 +567,14 @@
ax_response(conn->conn_ax, session->sess_id,
pdu->ap_header.aph_transactionid, pdu->ap_header.aph_packetid,
- smi_getticks(), APPL_ERROR_NOERROR, 0, NULL, 0);
+ appl_sysuptime(NULL), APPL_ERROR_NOERROR, 0, NULL, 0);
event_add(&(conn->conn_wev), NULL);
return;
fail:
ax_response(conn->conn_ax, 0, pdu->ap_header.aph_transactionid,
- pdu->ap_header.aph_packetid, 0, error, 0, NULL, 0);
+ pdu->ap_header.aph_packetid, appl_sysuptime(NULL),
+ error, 0, NULL, 0);
event_add(&(conn->conn_wev), NULL);
if (session != NULL)
free(session->sess_descr.aos_string);
@@ -597,7 +600,7 @@
ax_response(conn->conn_ax, pdu->ap_header.aph_sessionid,
pdu->ap_header.aph_transactionid, pdu->ap_header.aph_packetid,
- smi_getticks(), error, 0, NULL, 0);
+ appl_sysuptime(NULL), error, 0, NULL, 0);
event_add(&(conn->conn_wev), NULL);
if (error == APPL_ERROR_NOERROR)
return;
@@ -676,7 +679,7 @@
fail:
ax_response(session->sess_conn->conn_ax, session->sess_id,
pdu->ap_header.aph_transactionid, pdu->ap_header.aph_packetid,
- smi_getticks(), error, 0, NULL, 0);
+ appl_sysuptime(pdu->ap_context.aos_string), error, 0, NULL, 0);
event_add(&(session->sess_conn->conn_wev), NULL);
}
@@ -703,7 +706,7 @@
fail:
ax_response(session->sess_conn->conn_ax, session->sess_id,
pdu->ap_header.aph_transactionid, pdu->ap_header.aph_packetid,
- smi_getticks(), error, 0, NULL, 0);
+ appl_sysuptime(pdu->ap_context.aos_string), error, 0, NULL, 0);
event_add(&(session->sess_conn->conn_wev), NULL);
}
@@ -835,7 +838,7 @@
fail:
ax_response(session->sess_conn->conn_ax, session->sess_id,
pdu->ap_header.aph_transactionid, pdu->ap_header.aph_packetid,
- smi_getticks(), error, 0, NULL, 0);
+ appl_sysuptime(pdu->ap_context.aos_string), error, 0, NULL, 0);
event_add(&(session->sess_conn->conn_wev), NULL);
}
@@ -860,7 +863,7 @@
fail:
ax_response(session->sess_conn->conn_ax, session->sess_id,
pdu->ap_header.aph_transactionid, pdu->ap_header.aph_packetid,
- smi_getticks(), error, 0, NULL, 0);
+ appl_sysuptime(pdu->ap_context.aos_string), error, 0, NULL, 0);
event_add(&(session->sess_conn->conn_wev), NULL);
}
Index: application_internal.c
===================================================================
RCS file: /cvs/src/usr.sbin/snmpd/application_internal.c,v
diff -u -r1.12 application_internal.c
--- application_internal.c 6 Feb 2024 12:44:27 -0000 1.12
+++ application_internal.c 28 Oct 2025 08:10:39 -0000
@@ -577,7 +577,7 @@
else if (ober_oid_cmp(&OID(MIB_sysOID, 0), oid) == 0)
return ober_add_oid(NULL, &s->sys_oid);
else if (ober_oid_cmp(&OID(MIB_sysUpTime, 0), oid) == 0) {
- value = ober_add_integer(NULL, smi_getticks());
+ value = ober_add_integer(NULL, appl_sysuptime(NULL));
ober_set_header(value, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS);
} else if (ober_oid_cmp(&OID(MIB_sysContact, 0), oid) == 0)
return ober_add_string(NULL, s->sys_contact);
Index: smi.c
===================================================================
RCS file: /cvs/src/usr.sbin/snmpd/smi.c,v
diff -u -r1.40 smi.c
--- smi.c 6 Feb 2024 12:44:27 -0000 1.40
+++ smi.c 28 Oct 2025 08:10:39 -0000
@@ -62,23 +62,6 @@
RB_PROTOTYPE(keytree, oid, o_keyword, smi_key_cmp);
struct keytree smi_keytree;
-u_long
-smi_getticks(void)
-{
- struct timeval now, run;
- u_long ticks;
-
- gettimeofday(&now, NULL);
- if (timercmp(&now, &snmpd_env->sc_starttime, <=))
- return (0);
- timersub(&now, &snmpd_env->sc_starttime, &run);
- ticks = run.tv_sec * 100;
- if (run.tv_usec)
- ticks += run.tv_usec / 10000;
-
- return (ticks);
-}
-
char *
smi_oid2string(struct ber_oid *o, char *buf, size_t len, size_t skip)
{
Index: smi.h
===================================================================
RCS file: /cvs/src/usr.sbin/snmpd/smi.h,v
diff -u -r1.4 smi.h
--- smi.h 21 Dec 2023 12:43:31 -0000 1.4
+++ smi.h 28 Oct 2025 08:10:39 -0000
@@ -22,6 +22,5 @@
struct ber_oid;
char *smi_oid2string(struct ber_oid *, char *, size_t, size_t);
-u_long smi_getticks(void);
char *smi_print_element(struct ber_element *);
char *smi_print_element_legacy(struct ber_element *);
Index: snmpd.c
===================================================================
RCS file: /cvs/src/usr.sbin/snmpd/snmpd.c,v
diff -u -r1.52 snmpd.c
--- snmpd.c 12 Apr 2024 14:17:42 -0000 1.52
+++ snmpd.c 28 Oct 2025 08:10:39 -0000
@@ -218,7 +218,6 @@
log_init(debug, LOG_DAEMON);
log_setverbose(verbose);
- gettimeofday(&env->sc_starttime, NULL);
env->sc_engine_boots = 0;
proc_init(ps, procs, nitems(procs), debug, argc0, argv0, proc_id);
Index: snmpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/snmpd/snmpd.h,v
diff -u -r1.120 snmpd.h
--- snmpd.h 21 May 2024 05:00:48 -0000 1.120
+++ snmpd.h 28 Oct 2025 08:10:39 -0000
@@ -22,7 +22,6 @@
#include <sys/queue.h>
#include <sys/socket.h>
-#include <sys/time.h>
#include <sys/tree.h>
#include <sys/types.h>
#include <sys/un.h>
@@ -402,7 +401,6 @@
const char *sc_confpath;
struct addresslist sc_addresses;
struct axmasterlist sc_agentx_masters;
- struct timeval sc_starttime;
u_int32_t sc_engine_boots;
char sc_rdcommunity[SNMPD_MAXCOMMUNITYLEN];
Index: trap.c
===================================================================
RCS file: /cvs/src/usr.sbin/snmpd/trap.c,v
diff -u -r1.43 trap.c
--- trap.c 6 Feb 2024 15:36:11 -0000 1.43
+++ trap.c 28 Oct 2025 08:10:39 -0000
@@ -24,9 +24,9 @@
#include <stdlib.h>
#include <string.h>
+#include "application.h"
#include "log.h"
#include "mib.h"
-#include "smi.h"
#include "snmp.h"
#include "snmpd.h"
@@ -60,7 +60,7 @@
/* Add mandatory varbind elements */
trap = ober_add_sequence(NULL);
vblist = ober_printf_elements(trap, "{Odt}{OO}",
- &uptime, smi_getticks(),
+ &uptime, appl_sysuptime(NULL),
BER_CLASS_APPLICATION, SNMP_T_TIMETICKS,
&trapoid, oid);
if (elm != NULL)
snmpd: move smi_getticks to appl_sysuptime