diff options
-rw-r--r-- | usr.sbin/snmpd/snmpd.h | 10 | ||||
-rw-r--r-- | usr.sbin/snmpd/snmpe.c | 20 |
2 files changed, 28 insertions, 2 deletions
diff --git a/usr.sbin/snmpd/snmpd.h b/usr.sbin/snmpd/snmpd.h index c490ed2fd46..40f08748d4b 100644 --- a/usr.sbin/snmpd/snmpd.h +++ b/usr.sbin/snmpd/snmpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: snmpd.h,v 1.93 2021/01/28 20:45:14 martijn Exp $ */ +/* $OpenBSD: snmpd.h,v 1.94 2021/02/05 10:30:45 martijn Exp $ */ /* * Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org> @@ -399,6 +399,8 @@ struct snmp_message { u_int8_t sm_data[READ_BUF_SIZE]; size_t sm_datalen; + uint32_t sm_transactionid; + u_int sm_version; /* V1, V2c */ @@ -436,7 +438,11 @@ struct snmp_message { struct ber_element *sm_varbind; struct ber_element *sm_varbindresp; + + RB_ENTRY(snmp_message) sm_entry; }; +RB_HEAD(snmp_messages, snmp_message); +extern struct snmp_messages snmp_messages; /* Defined in SNMPv2-MIB.txt (RFC 3418) */ struct snmp_stats { @@ -642,6 +648,8 @@ struct kif_arp *karp_getaddr(struct sockaddr *, u_short, int); void snmpe(struct privsep *, struct privsep_proc *); void snmpe_shutdown(void); void snmpe_dispatchmsg(struct snmp_message *); +int snmp_messagecmp(struct snmp_message *, struct snmp_message *); +RB_PROTOTYPE(snmp_messages, snmp_message, sm_entry, snmp_messagecmp) /* trap.c */ void trap_init(void); diff --git a/usr.sbin/snmpd/snmpe.c b/usr.sbin/snmpd/snmpe.c index 4aea2d5c2b1..9d063206854 100644 --- a/usr.sbin/snmpd/snmpe.c +++ b/usr.sbin/snmpd/snmpe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: snmpe.c,v 1.68 2021/01/22 06:33:27 martijn Exp $ */ +/* $OpenBSD: snmpe.c,v 1.69 2021/02/05 10:30:45 martijn Exp $ */ /* * Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org> @@ -58,6 +58,8 @@ void snmp_msgfree(struct snmp_message *); struct imsgev *iev_parent; static const struct timeval snmpe_tcp_timeout = { 10, 0 }; /* 10s */ +struct snmp_messages snmp_messages = RB_INITIALIZER(&snmp_messages); + static struct privsep_proc procs[] = { { "parent", PROC_PARENT } }; @@ -210,6 +212,11 @@ snmpe_parse(struct snmp_message *msg) msg->sm_errstr = "invalid message"; + do { + msg->sm_transactionid = arc4random(); + } while (msg->sm_transactionid == 0 || + RB_INSERT(snmp_messages, &snmp_messages, msg) != NULL); + if (ober_scanf_elements(root, "{ie", &ver, &a) != 0) goto parsefail; @@ -834,6 +841,8 @@ snmpe_response(struct snmp_message *msg) void snmp_msgfree(struct snmp_message *msg) { + if (msg->sm_transactionid != 0) + RB_REMOVE(snmp_messages, &snmp_messages, msg); event_del(&msg->sm_sockev); ober_free(&msg->sm_ber); if (msg->sm_req != NULL) @@ -896,3 +905,12 @@ snmpe_encode(struct snmp_message *msg) #endif return 0; } + +int +snmp_messagecmp(struct snmp_message *m1, struct snmp_message *m2) +{ + return (m1->sm_transactionid < m2->sm_transactionid ? -1 : + m1->sm_transactionid > m2->sm_transactionid); +} + +RB_GENERATE(snmp_messages, snmp_message, sm_entry, snmp_messagecmp) |