From: Martijn van Duren Subject: snmpd: Add support for AGENTX-MIB To: tech@openbsd.org Date: Thu, 16 Jul 2026 12:15:16 +0200 Hello tech@, Right now it's only possible to know which AgentX connections are currently established by parsing the daemon log and hoping the lines haven't rotated out. Diff below implements AGENTX-MIB, and gives a present overview of active AgentX connections and registrations. AGENTX-MIB is defined in RFC 2742, and is omitted from this diff for brevity. It can be found inside the net-snmp package under /usr/local/share/snmp/mibs/AGENTX-MIB.txt. Funny enough, net-snmp doesn't seem to export this information. OK? martijn@ diff refs/heads/master refs/heads/snmpd/mib_agentx commit - 7659da292c89adc3f3c89cc4a96023e23c0ff431 commit + 692d8646c12a477940c047be66dce2de5fda3c8e blob - d10832282ef99d838e2ddb8096c7633205f3f551 blob + 870d9662f4a6a28b6e922d618358816f8b04208a --- share/snmp/Makefile +++ share/snmp/Makefile @@ -7,9 +7,9 @@ FILES+= OPENBSD-CARP-MIB.txt OPENBSD-PF-MIB.txt FILES+= OPENBSD-RELAYD-MIB.txt # IANA/IETF -FILES+= BRIDGE-MIB.txt HOST-RESOURCES-MIB.txt IANA-RTPROTO-MIB.txt -FILES+= IANA-STORAGE-MEDIA-TYPE-MIB.txt IANAifType-MIB.txt IF-MIB.txt -FILES+= INET-ADDRESS-MIB.txt IP-FORWARD-MIB.txt IP-MIB.txt +FILES+= AGENTX-MIB.txt BRIDGE-MIB.txt HOST-RESOURCES-MIB.txt +FILES+= IANA-RTPROTO-MIB.txt IANA-STORAGE-MEDIA-TYPE-MIB.txt IANAifType-MIB.txt +FILES+= IF-MIB.txt INET-ADDRESS-MIB.txt IP-FORWARD-MIB.txt IP-MIB.txt FILES+= SNMP-FRAMEWORK-MIB.txt SNMP-USER-BASED-SM-MIB.txt SNMP-USM-AES-MIB.txt FILES+= SNMP-USM-HMAC-SHA2-MIB.txt SNMPv2-CONF.txt SNMPv2-MIB.txt SNMPv2-SMI.txt FILES+= SNMPv2-TC.txt SNMPv2-TM.txt TRANSPORT-ADDRESS-MIB.txt UUID-TC-MIB.txt blob - 7280c96fcde968f557670fed2043d6f856bc6bea blob + 739daed2e26fa53eae196bc08c1d4c9cb269ae8f --- usr.sbin/snmpd/application.c +++ usr.sbin/snmpd/application.c @@ -247,6 +247,12 @@ appl_context(const char *name, int create) return ctx; } +const char * +appl_context_name(struct appl_context *ctx) +{ + return ctx->ac_name; +} + /* Name from RFC 2741 section 6.2.14 */ enum appl_error appl_addagentcaps(const char *ctxname, struct ber_oid *oid, const char *descr, blob - 03f09b54c38dfa9bb13cd1b612515806e6f30d5f blob + 0e5bc85ecfada8cd37bc82c173b1cd0309c5ab9d --- usr.sbin/snmpd/application.h +++ usr.sbin/snmpd/application.h @@ -123,6 +123,7 @@ void appl(void); void appl_init(void); void appl_shutdown(void); struct appl_context *appl_context(const char *, int); +const char *appl_context_name(struct appl_context *); uint32_t appl_sysuptime(const char *); enum appl_error appl_addagentcaps(const char *, struct ber_oid *, const char *, struct appl_backend *); @@ -149,6 +150,13 @@ void appl_agentx(void); void appl_agentx_init(void); void appl_agentx_shutdown(void); void appl_agentx_backend(int); +struct ber_element *appl_agentx_mib_generic(struct ber_oid *); +struct ber_element *appl_agentx_mib_conntable(struct ber_oid *); +struct ber_element *appl_agentx_mib_conntable_next(int8_t, struct ber_oid *); +struct ber_element *appl_agentx_mib_sessiontable(struct ber_oid *); +struct ber_element *appl_agentx_mib_sessiontable_next(int8_t, struct ber_oid *); +struct ber_element *appl_agentx_mib_registrationtable(struct ber_oid *); +struct ber_element *appl_agentx_mib_registrationtable_next(int8_t, struct ber_oid *); /* application_blocklist.c */ void appl_blocklist_init(void); blob - 967f479f6fc98fb2892e6b860692bb8e83cbecbd blob + 868510ebf9b785e31d2b3a81447cc94b2167d309 --- usr.sbin/snmpd/application_agentx.c +++ usr.sbin/snmpd/application_agentx.c @@ -43,6 +43,7 @@ struct appl_agentx_connection { uint32_t conn_id; + uint32_t conn_opentime; /* * A backend has several overruling properties: * - If it exits, snmpd crashes @@ -60,6 +61,7 @@ struct appl_agentx_connection { struct appl_agentx_session { uint32_t sess_id; + uint32_t sess_opentime; struct appl_agentx_connection *sess_conn; /* * RFC 2741 section 7.1.1: @@ -69,14 +71,31 @@ struct appl_agentx_session { */ enum ax_byte_order sess_byteorder; uint8_t sess_timeout; - struct ax_oid sess_oid; + struct ber_oid sess_oid; struct ax_ostring sess_descr; struct appl_backend sess_backend; - RB_ENTRY(appl_agentx_session) sess_entry; + TAILQ_HEAD(, appl_agentx_registration) sess_registrations; + RB_ENTRY(appl_agentx_session) sess_global_entry; + RB_ENTRY(appl_agentx_session) sess_table_entry; TAILQ_ENTRY(appl_agentx_session) sess_conn_entry; }; +struct appl_agentx_registration { + uint32_t reg_id; + struct appl_agentx_session *reg_session; + struct appl_context *reg_context; + struct ber_oid reg_start; + uint32_t reg_range_subid; + uint32_t reg_upper_bound; + uint32_t reg_priority; + uint8_t reg_timeout; + int reg_instance; + RB_ENTRY(appl_agentx_registration) reg_global_entry; + RB_ENTRY(appl_agentx_registration) reg_table_entry; + TAILQ_ENTRY(appl_agentx_registration) reg_sess_entry; +}; + void appl_agentx_listen(struct agentx_master *); void appl_agentx_accept(int, short, void *); void appl_agentx_free(struct appl_agentx_connection *, enum appl_close_reason); @@ -101,8 +120,14 @@ struct ax_ostring *appl_agentx_string2ostring(const ch struct ax_ostring *); int appl_agentx_cmp(struct appl_agentx_connection *, struct appl_agentx_connection *); -int appl_agentx_session_cmp(struct appl_agentx_session *, +int appl_agentx_session_global_cmp(struct appl_agentx_session *, struct appl_agentx_session *); +int appl_agentx_session_table_cmp(struct appl_agentx_session *, + struct appl_agentx_session *); +int appl_agentx_registration_global_cmp(struct appl_agentx_registration *, + struct appl_agentx_registration *); +int appl_agentx_registration_table_cmp(struct appl_agentx_registration *, + struct appl_agentx_registration *); struct appl_backend_functions appl_agentx_functions = { .ab_close = appl_agentx_forceclose, @@ -113,13 +138,30 @@ struct appl_backend_functions appl_agentx_functions = RB_HEAD(appl_agentx_conns, appl_agentx_connection) appl_agentx_conns = RB_INITIALIZER(&appl_agentx_conns); -RB_HEAD(appl_agentx_sessions, appl_agentx_session) appl_agentx_sessions = - RB_INITIALIZER(&appl_agentx_sessions); +RB_HEAD(appl_agentx_sessions_global, appl_agentx_session) + appl_agentx_sessions_global = RB_INITIALIZER(&appl_agentx_sessions_global); +RB_HEAD(appl_agentx_sessions_table, appl_agentx_session) + appl_agentx_sessions_table = RB_INITIALIZER(&appl_agentx_sessions_table); +RB_HEAD(appl_agentx_registrations_global, appl_agentx_registration) + appl_agentx_registrations_global = + RB_INITIALIZER(&appl_agentx_registrations_global); +RB_HEAD(appl_agentx_registrations_table, appl_agentx_registration) + appl_agentx_registrations_table = + RB_INITIALIZER(&appl_agentx_registrations_table); +static uint32_t appl_agentx_conn_last_change; +static uint32_t appl_agentx_sess_last_change; +static uint32_t appl_agentx_reg_last_change; RB_PROTOTYPE_STATIC(appl_agentx_conns, appl_agentx_connection, conn_entry, appl_agentx_cmp); -RB_PROTOTYPE_STATIC(appl_agentx_sessions, appl_agentx_session, sess_entry, - appl_agentx_session_cmp); +RB_PROTOTYPE_STATIC(appl_agentx_sessions_global, appl_agentx_session, + sess_global_entry, appl_agentx_session_global_cmp); +RB_PROTOTYPE_STATIC(appl_agentx_sessions_table, appl_agentx_session, + sess_table_entry, appl_agentx_session_table_cmp); +RB_PROTOTYPE_STATIC(appl_agentx_registrations_global, appl_agentx_registration, + reg_global_entry, appl_agentx_registration_global_cmp); +RB_PROTOTYPE_STATIC(appl_agentx_registrations_table, appl_agentx_registration, + reg_table_entry, appl_agentx_registration_table_cmp); void appl_agentx(void) @@ -215,6 +257,8 @@ appl_agentx_accept(int masterfd, short event, void *co conn->conn_id = arc4random(); } while (RB_INSERT(appl_agentx_conns, &appl_agentx_conns, conn) != NULL); + conn->conn_opentime = appl_sysuptime(NULL); + appl_agentx_conn_last_change = conn->conn_opentime; event_set(&(conn->conn_rev), fd, EV_READ | EV_PERSIST, appl_agentx_recv, conn); @@ -245,6 +289,8 @@ appl_agentx_backend(int fd) conn->conn_id = arc4random(); } while (RB_INSERT(appl_agentx_conns, &appl_agentx_conns, conn) != NULL); + conn->conn_opentime = appl_sysuptime(NULL); + appl_agentx_conn_last_change = conn->conn_opentime; event_set(&(conn->conn_rev), fd, EV_READ | EV_PERSIST, appl_agentx_recv, conn); @@ -270,6 +316,7 @@ appl_agentx_free(struct appl_agentx_connection *conn, event_del(&(conn->conn_wev)); RB_REMOVE(appl_agentx_conns, &appl_agentx_conns, conn); + appl_agentx_conn_last_change = appl_sysuptime(NULL); if (conn->conn_ax != NULL) (void)ax_send(conn->conn_ax); ax_free(conn->conn_ax); @@ -475,7 +522,6 @@ void appl_agentx_open(struct appl_agentx_connection *conn, struct ax_pdu *pdu) { struct appl_agentx_session *session; - struct ber_oid oid; char oidbuf[1024]; enum appl_error error = APPL_ERROR_NOERROR; @@ -526,7 +572,8 @@ appl_agentx_open(struct appl_agentx_connection *conn, } session->sess_timeout = pdu->ap_payload.ap_open.ap_timeout; - session->sess_oid = pdu->ap_payload.ap_open.ap_oid; + appl_agentx_oid2ber_oid(&pdu->ap_payload.ap_open.ap_oid, + &session->sess_oid); session->sess_descr.aos_slen = pdu->ap_payload.ap_open.ap_descr.aos_slen; if (pdu->ap_payload.ap_open.ap_descr.aos_string != NULL) { session->sess_descr.aos_string = @@ -542,8 +589,12 @@ appl_agentx_open(struct appl_agentx_connection *conn, /* RFC 2742 agentxSessionIndex: chances of reuse, slim to none */ do { session->sess_id = arc4random(); - } while (RB_INSERT(appl_agentx_sessions, - &appl_agentx_sessions, session) != NULL); + } while (RB_INSERT(appl_agentx_sessions_global, + &appl_agentx_sessions_global, session) != NULL); + RB_INSERT(appl_agentx_sessions_table, &appl_agentx_sessions_table, + session); + session->sess_opentime = appl_sysuptime(NULL); + appl_agentx_sess_last_change = session->sess_opentime; if (asprintf(&(session->sess_backend.ab_name), "AgentX(%"PRIu32"/%"PRIu32")", @@ -557,11 +608,12 @@ appl_agentx_open(struct appl_agentx_connection *conn, session->sess_backend.ab_retries = 0; session->sess_backend.ab_fn = &appl_agentx_functions; session->sess_backend.ab_range = 1; + TAILQ_INIT(&session->sess_registrations); RB_INIT(&(session->sess_backend.ab_requests)); TAILQ_INSERT_TAIL(&(conn->conn_sessions), session, sess_conn_entry); - appl_agentx_oid2ber_oid(&(session->sess_oid), &oid); - mib_oid2string(&oid, oidbuf, sizeof(oidbuf), snmpd_env->sc_oidfmt); + mib_oid2string(&session->sess_oid, oidbuf, sizeof(oidbuf), + snmpd_env->sc_oidfmt); log_info("%s: %s %s: Open", session->sess_backend.ab_name, oidbuf, session->sess_descr.aos_string); @@ -633,11 +685,26 @@ void appl_agentx_session_free(struct appl_agentx_session *session) { struct appl_agentx_connection *conn = session->sess_conn; + struct appl_agentx_registration *reg; appl_close(&(session->sess_backend)); - RB_REMOVE(appl_agentx_sessions, &appl_agentx_sessions, session); + while ((reg = TAILQ_FIRST(&session->sess_registrations)) != NULL) { + TAILQ_REMOVE(&session->sess_registrations, reg, reg_sess_entry); + RB_REMOVE(appl_agentx_registrations_global, + &appl_agentx_registrations_global, reg); + RB_REMOVE(appl_agentx_registrations_table, + &appl_agentx_registrations_table, reg); + free(reg); + } + + RB_REMOVE(appl_agentx_sessions_global, &appl_agentx_sessions_global, + session); + RB_REMOVE(appl_agentx_sessions_table, &appl_agentx_sessions_table, + session); TAILQ_REMOVE(&(conn->conn_sessions), session, sess_conn_entry); + appl_agentx_sess_last_change = appl_agentx_reg_last_change = + appl_sysuptime(NULL); free(session->sess_backend.ab_name); free(session->sess_descr.aos_string); @@ -647,8 +714,8 @@ appl_agentx_session_free(struct appl_agentx_session *s void appl_agentx_register(struct appl_agentx_session *session, struct ax_pdu *pdu) { + struct appl_agentx_registration *reg; uint32_t timeout; - struct ber_oid oid; enum appl_error error; int subtree = 0; @@ -661,21 +728,48 @@ appl_agentx_register(struct appl_agentx_session *sessi pdu->ap_payload.ap_register.ap_priority = 1; subtree = 1; } - if (appl_agentx_oid2ber_oid( - &(pdu->ap_payload.ap_register.ap_subtree), &oid) == NULL) { + + if ((reg = malloc(sizeof(*reg))) == NULL) { + log_warn("%s: Failed to register", + session->sess_backend.ab_name); + error = APPL_ERROR_PROCESSINGERROR; + goto fail; + } + reg->reg_session = session; + reg->reg_context = appl_context(pdu->ap_context.aos_string, 0); + if (appl_agentx_oid2ber_oid(&pdu->ap_payload.ap_register.ap_subtree, + ®->reg_start) == NULL) { log_warnx("%s: Failed to register: oid too small", session->sess_backend.ab_name); error = APPL_ERROR_PROCESSINGERROR; goto fail; } + reg->reg_range_subid = pdu->ap_payload.ap_register.ap_range_subid; + reg->reg_upper_bound = pdu->ap_payload.ap_register.ap_upper_bound; + reg->reg_priority = pdu->ap_payload.ap_register.ap_priority; + reg->reg_timeout = pdu->ap_payload.ap_register.ap_timeout; + reg->reg_instance = + pdu->ap_header.aph_flags & AX_PDU_FLAG_INSTANCE_REGISTRATION ? + 1 : 0; error = appl_register(pdu->ap_context.aos_string, timeout, - pdu->ap_payload.ap_register.ap_priority, &oid, - pdu->ap_header.aph_flags & AX_PDU_FLAG_INSTANCE_REGISTRATION, - subtree, pdu->ap_payload.ap_register.ap_range_subid, - pdu->ap_payload.ap_register.ap_upper_bound, + reg->reg_priority, ®->reg_start, reg->reg_instance, + subtree, reg->reg_range_subid, reg->reg_upper_bound, &(session->sess_backend)); + if (error == APPL_ERROR_NOERROR) { + do { + reg->reg_id = arc4random(); + } while (RB_INSERT(appl_agentx_registrations_global, + &appl_agentx_registrations_global, reg) != NULL); + RB_INSERT(appl_agentx_registrations_table, + &appl_agentx_registrations_table, reg); + TAILQ_INSERT_TAIL(&session->sess_registrations, reg, + reg_sess_entry); + appl_agentx_reg_last_change = appl_sysuptime(NULL); + } else + free(reg); + fail: ax_response(session->sess_conn->conn_ax, session->sess_id, pdu->ap_header.aph_transactionid, pdu->ap_header.aph_packetid, @@ -686,6 +780,8 @@ appl_agentx_register(struct appl_agentx_session *sessi void appl_agentx_unregister(struct appl_agentx_session *session, struct ax_pdu *pdu) { + struct appl_context *ctx; + struct appl_agentx_registration *reg; struct ber_oid oid; enum appl_error error; @@ -697,11 +793,40 @@ appl_agentx_unregister(struct appl_agentx_session *ses goto fail; } - error = appl_unregister(pdu->ap_context.aos_string, - pdu->ap_payload.ap_unregister.ap_priority, &oid, - pdu->ap_payload.ap_unregister.ap_range_subid, - pdu->ap_payload.ap_unregister.ap_upper_bound, + /* This is stricter than appl_unregister(), but needed for RFC2742 */ + ctx = appl_context(pdu->ap_context.aos_string, 0); + TAILQ_FOREACH(reg, &session->sess_registrations, reg_sess_entry) { + if (reg->reg_context != ctx || + ober_oid_cmp(®->reg_start, &oid) != 0) + continue; + if (reg->reg_range_subid != + pdu->ap_payload.ap_unregister.ap_range_subid) + continue; + if (reg->reg_upper_bound != + pdu->ap_payload.ap_unregister.ap_upper_bound) + continue; + if (reg->reg_priority != + pdu->ap_payload.ap_unregister.ap_priority) + continue; + break; + } + if (reg == NULL) { + error = APPL_ERROR_UNKNOWNREGISTRATION; + goto fail; + } + + error = appl_unregister(pdu->ap_context.aos_string, reg->reg_priority, + &oid, reg->reg_range_subid, reg->reg_upper_bound, &(session->sess_backend)); + if (error == APPL_ERROR_NOERROR) { + TAILQ_REMOVE(&session->sess_registrations, reg, reg_sess_entry); + RB_REMOVE(appl_agentx_registrations_global, + &appl_agentx_registrations_global, reg); + RB_REMOVE(appl_agentx_registrations_table, + &appl_agentx_registrations_table, reg); + free(reg); + appl_agentx_reg_last_change = appl_sysuptime(NULL); + } fail: ax_response(session->sess_conn->conn_ax, session->sess_id, @@ -1050,13 +1175,358 @@ appl_agentx_cmp(struct appl_agentx_connection *conn1, } int -appl_agentx_session_cmp(struct appl_agentx_session *sess1, +appl_agentx_session_global_cmp(struct appl_agentx_session *sess1, struct appl_agentx_session *sess2) { return sess1->sess_id < sess2->sess_id ? -1 : sess1->sess_id > sess2->sess_id; } +int +appl_agentx_session_table_cmp(struct appl_agentx_session *sess1, + struct appl_agentx_session *sess2) +{ + if (sess1->sess_conn->conn_id != sess2->sess_conn->conn_id) + return sess1->sess_conn->conn_id < sess2->sess_conn->conn_id ? + -1 : 1; + return sess1->sess_id < sess2->sess_id ? -1 : sess1->sess_id > sess2->sess_id; +} + +int +appl_agentx_registration_global_cmp(struct appl_agentx_registration *r1, + struct appl_agentx_registration *r2) +{ + return r1->reg_id < r2->reg_id ? -1 : r1->reg_id > r2->reg_id; +} + +int +appl_agentx_registration_table_cmp(struct appl_agentx_registration *r1, + struct appl_agentx_registration *r2) +{ + struct appl_agentx_session *s1 = r1->reg_session, *s2 = r2->reg_session; + struct appl_agentx_connection *c1 = s1->sess_conn, *c2 = s2->sess_conn; + + if (c1->conn_id != c2->conn_id) + return c1->conn_id < c2->conn_id ? -1 : 1; + if (s1->sess_id != s2->sess_id) + return s1->sess_id < s2->sess_id ? -1 : 1; + return r1->reg_id < r2->reg_id ? -1 : r1->reg_id > r2->reg_id; +} + +struct ber_element * +appl_agentx_mib_generic(struct ber_oid *oid) +{ + struct ber_element *value = NULL; + + if (ober_oid_cmp(&OID(MIB_agentxDefaultTimeout, 0), oid) == 0) + return ober_add_integer(NULL, AGENTX_DEFAULTTIMEOUT); + else if (ober_oid_cmp(&OID(MIB_agentxMasterAgentxVer, 0), oid) == 0) + return ober_add_integer(NULL, 1); + else if (ober_oid_cmp(&OID(MIB_agentxConnTableLastChange, 0), oid) == 0) { + value = ober_add_integer(NULL, appl_agentx_conn_last_change); + ober_set_header(value, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS); + } else if (ober_oid_cmp(&OID(MIB_agentxSessionTableLastChange, 0), oid) == 0) { + value = ober_add_integer(NULL, appl_agentx_sess_last_change); + ober_set_header(value, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS); + } else if (ober_oid_cmp(&OID(MIB_agentxRegistrationTableLastChange, 0), oid) == 0) { + value = ober_add_integer(NULL, appl_agentx_reg_last_change); + ober_set_header(value, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS); + } else + return NULL; + + return value; +} + +struct ber_element * +appl_agentx_mib_conntable(struct ber_oid *oid) +{ + struct appl_agentx_connection *conn, search; + struct ber_element *value = NULL; + + if (oid->bo_n != OID(MIB_agentxConnOpenTime, 0).bo_n) + return appl_exception(APPL_EXC_NOSUCHINSTANCE); + search.conn_id = oid->bo_id[OID(MIB_agentxConnOpenTime).bo_n]; + conn = RB_FIND(appl_agentx_conns, &appl_agentx_conns, &search); + if (conn == NULL) + return appl_exception(APPL_EXC_NOSUCHINSTANCE); + + if (ober_oid_cmp(&OID(MIB_agentxConnOpenTime), oid) == -2) { + value = ober_add_integer(NULL, conn->conn_opentime); + ober_set_header(value, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS); + } else if (ober_oid_cmp(&OID(MIB_agentxConnTransportDomain), oid) == -2) + return ober_add_oid(NULL, &OID(MIB_transportDomainLocal)); + else if (ober_oid_cmp(&OID(MIB_agentxConnTransportAddress), oid) == -2) + return ober_add_string(NULL, ""); + else + return NULL; + + return value; +} + +struct ber_element * +appl_agentx_mib_conntable_next(int8_t include, struct ber_oid *oid) +{ + struct appl_agentx_connection *conn, search; + struct ber_element *value = NULL; + + if (oid->bo_n < OID(MIB_agentxConnOpenTime, 0).bo_n) { + search.conn_id = 0; + include = 1; + } else if (oid->bo_n == OID(MIB_agentxConnOpenTime, 0).bo_n) { + search.conn_id = + oid->bo_id[OID(MIB_agentxConnOpenTime).bo_n]; + } else { + search.conn_id = + oid->bo_id[OID(MIB_agentxConnOpenTime).bo_n]; + include = 0; + } + conn = RB_NFIND(appl_agentx_conns, &appl_agentx_conns, &search); + if (conn != NULL && !include && search.conn_id == conn->conn_id) + conn = RB_NEXT(appl_agentx_conns, &appl_agentx_conns, conn); + if (conn == NULL) + return appl_exception(APPL_EXC_ENDOFMIBVIEW); + + oid->bo_n = OID(MIB_agentxConnOpenTime).bo_n; + oid->bo_id[oid->bo_n++] = conn->conn_id; + if (ober_oid_cmp(&OID(MIB_agentxConnOpenTime), oid) == -2) { + value = ober_add_integer(NULL, conn->conn_opentime); + ober_set_header(value, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS); + } else if (ober_oid_cmp(&OID(MIB_agentxConnTransportDomain), oid) == -2) + return ober_add_oid(NULL, &OID(MIB_transportDomainLocal)); + else if (ober_oid_cmp(&OID(MIB_agentxConnTransportAddress), oid) == -2) + return ober_add_string(NULL, ""); + else + return NULL; + + return value; +} + +struct ber_element * +appl_agentx_mib_sessiontable(struct ber_oid *oid) +{ + struct appl_agentx_connection conn; + struct appl_agentx_session *session, search; + struct ber_element *value = NULL; + + if (oid->bo_n != OID(MIB_agentxSessionObjectID, 0, 0).bo_n) + return appl_exception(APPL_EXC_NOSUCHINSTANCE); + conn.conn_id = oid->bo_id[OID(MIB_agentxSessionObjectID).bo_n]; + search.sess_id = oid->bo_id[OID(MIB_agentxSessionObjectID, 0).bo_n]; + search.sess_conn = &conn; + session = RB_FIND(appl_agentx_sessions_table, + &appl_agentx_sessions_table, &search); + if (session == NULL) + return appl_exception(APPL_EXC_NOSUCHINSTANCE); + + if (ober_oid_cmp(&OID(MIB_agentxSessionObjectID), oid) == -2) + return ober_add_oid(NULL, &session->sess_oid); + else if (ober_oid_cmp(&OID(MIB_agentxSessionDescr), oid) == -2) + return ober_add_nstring(NULL, session->sess_descr.aos_string, + session->sess_descr.aos_slen); + else if (ober_oid_cmp(&OID(MIB_agentxSessionAdminStatus), oid) == -2) + return ober_add_integer(NULL, 1); + else if (ober_oid_cmp(&OID(MIB_agentxSessionOpenTime), oid) == -2) { + value = ober_add_integer(NULL, session->sess_opentime); + ober_set_header(value, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS); + } else if (ober_oid_cmp(&OID(MIB_agentxSessionAgentXVer), oid) == -2) + return ober_add_integer(NULL, 1); + else if (ober_oid_cmp(&OID(MIB_agentxSessionTimeout), oid) == -2) + return ober_add_integer(NULL, session->sess_timeout); + else + return NULL; + + return value; +} + +struct ber_element * +appl_agentx_mib_sessiontable_next(int8_t include, struct ber_oid *oid) +{ + struct appl_agentx_connection conn; + struct appl_agentx_session *session, search; + struct ber_element *value = NULL; + + if (oid->bo_n < OID(MIB_agentxSessionObjectID, 0).bo_n) { + conn.conn_id = 0; + search.sess_id = 0; + include = 1; + } else if (oid->bo_n == OID(MIB_agentxSessionObjectID, 0).bo_n) { + conn.conn_id = oid->bo_id[OID(MIB_agentxSessionObjectID).bo_n]; + search.sess_id = 0; + include = 1; + } else if (oid->bo_n == OID(MIB_agentxSessionObjectID, 0, 0).bo_n) { + conn.conn_id = oid->bo_id[OID(MIB_agentxSessionObjectID).bo_n]; + search.sess_id = + oid->bo_id[OID(MIB_agentxSessionObjectID, 0).bo_n]; + } else { + conn.conn_id = oid->bo_id[OID(MIB_agentxSessionObjectID).bo_n]; + search.sess_id = + oid->bo_id[OID(MIB_agentxSessionObjectID, 0).bo_n]; + include = 0; + } + search.sess_conn = &conn; + session = RB_NFIND(appl_agentx_sessions_table, + &appl_agentx_sessions_table, &search); + if (session != NULL && !include && + appl_agentx_session_table_cmp(&search, session) == 0) + session = RB_NEXT(appl_agentx_sessions_table, + &appl_agentx_sessions_table, session); + if (session == NULL) + return appl_exception(APPL_EXC_ENDOFMIBVIEW); + + oid->bo_n = OID(MIB_agentxSessionObjectID).bo_n; + oid->bo_id[oid->bo_n++] = session->sess_conn->conn_id; + oid->bo_id[oid->bo_n++] = session->sess_id; + if (ober_oid_cmp(&OID(MIB_agentxSessionObjectID), oid) == -2) + return ober_add_oid(NULL, &session->sess_oid); + else if (ober_oid_cmp(&OID(MIB_agentxSessionDescr), oid) == -2) + return ober_add_nstring(NULL, session->sess_descr.aos_string, + session->sess_descr.aos_slen); + else if (ober_oid_cmp(&OID(MIB_agentxSessionAdminStatus), oid) == -2) + return ober_add_integer(NULL, 1); + else if (ober_oid_cmp(&OID(MIB_agentxSessionOpenTime), oid) == -2) { + value = ober_add_integer(NULL, session->sess_opentime); + ober_set_header(value, BER_CLASS_APPLICATION, SNMP_T_TIMETICKS); + } else if (ober_oid_cmp(&OID(MIB_agentxSessionAgentXVer), oid) == -2) + return ober_add_integer(NULL, 1); + else if (ober_oid_cmp(&OID(MIB_agentxSessionTimeout), oid) == -2) + return ober_add_integer(NULL, session->sess_timeout); + else + return NULL; + + return value; +} + +struct ber_element * +appl_agentx_mib_registrationtable(struct ber_oid *oid) +{ + struct appl_agentx_connection conn; + struct appl_agentx_session session; + struct appl_agentx_registration *reg, search; + struct ber_element *value = NULL; + + if (oid->bo_n != OID(MIB_agentxRegContext, 0, 0, 0).bo_n) + return appl_exception(APPL_EXC_NOSUCHINSTANCE); + conn.conn_id = oid->bo_id[OID(MIB_agentxRegContext).bo_n]; + session.sess_id = oid->bo_id[OID(MIB_agentxRegContext, 0).bo_n]; + search.reg_id = oid->bo_id[OID(MIB_agentxRegContext, 0, 0).bo_n]; + search.reg_session = &session; + session.sess_conn = &conn; + + reg = RB_FIND(appl_agentx_registrations_table, + &appl_agentx_registrations_table, &search); + if (reg == NULL) + return appl_exception(APPL_EXC_NOSUCHINSTANCE); + + if (ober_oid_cmp(&OID(MIB_agentxRegContext), oid) == -2) + return ober_add_string( + NULL, appl_context_name(reg->reg_context)); + else if (ober_oid_cmp(&OID(MIB_agentxRegStart), oid) == -2) + return ober_add_oid(NULL, ®->reg_start); + else if (ober_oid_cmp(&OID(MIB_agentxRegRangeSubId), oid) == -2) { + value = ober_add_integer(NULL, reg->reg_range_subid); + ober_set_header( + value, BER_CLASS_APPLICATION, SNMP_T_UNSIGNED32); + } else if (ober_oid_cmp(&OID(MIB_agentxRegUpperBound), oid) == -2) { + value = ober_add_integer(NULL, reg->reg_upper_bound); + ober_set_header( + value, BER_CLASS_APPLICATION, SNMP_T_UNSIGNED32); + } else if (ober_oid_cmp(&OID(MIB_agentxRegPriority), oid) == -2) { + value = ober_add_integer(NULL, reg->reg_priority); + ober_set_header( + value, BER_CLASS_APPLICATION, SNMP_T_UNSIGNED32); + } else if (ober_oid_cmp(&OID(MIB_agentxRegTimeout), oid) == -2) + return ober_add_integer(NULL, reg->reg_timeout); + else if (ober_oid_cmp(&OID(MIB_agentxRegInstance), oid) == -2) + return ober_add_integer(NULL, reg->reg_instance ? 1 : 2); + else + return NULL; + + return value; +} + +struct ber_element * +appl_agentx_mib_registrationtable_next(int8_t include, struct ber_oid *oid) +{ + struct appl_agentx_connection conn; + struct appl_agentx_session session; + struct appl_agentx_registration *reg, search; + struct ber_element *value = NULL; + + if (oid->bo_n < OID(MIB_agentxRegContext, 0).bo_n) { + conn.conn_id = 0; + session.sess_id = 0; + search.reg_id = 0; + include = 1; + } else if (oid->bo_n == OID(MIB_agentxRegContext, 0).bo_n) { + conn.conn_id = oid->bo_id[OID(MIB_agentxRegContext).bo_n]; + session.sess_id = 0; + search.reg_id = 0; + include = 1; + } else if (oid->bo_n == OID(MIB_agentxRegContext, 0, 0).bo_n) { + conn.conn_id = oid->bo_id[OID(MIB_agentxRegContext).bo_n]; + session.sess_id = oid->bo_id[OID(MIB_agentxRegContext, 0).bo_n]; + search.reg_id = 0; + include = 1; + } else if (oid->bo_n == OID(MIB_agentxRegContext, 0, 0, 0).bo_n) { + conn.conn_id = oid->bo_id[OID(MIB_agentxRegContext).bo_n]; + session.sess_id = oid->bo_id[OID(MIB_agentxRegContext, 0).bo_n]; + search.reg_id = + oid->bo_id[OID(MIB_agentxRegContext, 0, 0).bo_n]; + } else { + conn.conn_id = oid->bo_id[OID(MIB_agentxRegContext).bo_n]; + session.sess_id = oid->bo_id[OID(MIB_agentxRegContext, 0).bo_n]; + search.reg_id = + oid->bo_id[OID(MIB_agentxRegContext, 0, 0).bo_n]; + include = 0; + } + session.sess_conn = &conn; + search.reg_session = &session; + reg = RB_NFIND(appl_agentx_registrations_table, + &appl_agentx_registrations_table, &search); + if (reg != NULL && !include && + appl_agentx_registration_table_cmp(&search, reg) == 0) + reg = RB_NEXT(appl_agentx_registrations_table, + &appl_agentx_registrations_table, reg); + if (reg == NULL) + return appl_exception(APPL_EXC_ENDOFMIBVIEW); + oid->bo_n = OID(MIB_agentxRegContext).bo_n; + oid->bo_id[oid->bo_n++] = reg->reg_session->sess_conn->conn_id; + oid->bo_id[oid->bo_n++] = reg->reg_session->sess_id; + oid->bo_id[oid->bo_n++] = reg->reg_id; + + if (ober_oid_cmp(&OID(MIB_agentxRegContext), oid) == -2) + return ober_add_string( + NULL, appl_context_name(reg->reg_context)); + else if (ober_oid_cmp(&OID(MIB_agentxRegStart), oid) == -2) + return ober_add_oid(NULL, ®->reg_start); + else if (ober_oid_cmp(&OID(MIB_agentxRegRangeSubId), oid) == -2) { + value = ober_add_integer(NULL, reg->reg_range_subid); + ober_set_header( + value, BER_CLASS_APPLICATION, SNMP_T_UNSIGNED32); + } else if (ober_oid_cmp(&OID(MIB_agentxRegUpperBound), oid) == -2) { + value = ober_add_integer(NULL, reg->reg_upper_bound); + ober_set_header( + value, BER_CLASS_APPLICATION, SNMP_T_UNSIGNED32); + } else if (ober_oid_cmp(&OID(MIB_agentxRegPriority), oid) == -2) { + value = ober_add_integer(NULL, reg->reg_priority); + ober_set_header( + value, BER_CLASS_APPLICATION, SNMP_T_UNSIGNED32); + } else if (ober_oid_cmp(&OID(MIB_agentxRegTimeout), oid) == -2) + return ober_add_integer(NULL, reg->reg_timeout); + else if (ober_oid_cmp(&OID(MIB_agentxRegInstance), oid) == -2) + return ober_add_integer(NULL, reg->reg_instance ? 1 : 2); + else + return NULL; + + return value; +} + RB_GENERATE_STATIC(appl_agentx_conns, appl_agentx_connection, conn_entry, appl_agentx_cmp); -RB_GENERATE_STATIC(appl_agentx_sessions, appl_agentx_session, sess_entry, - appl_agentx_session_cmp); +RB_GENERATE_STATIC(appl_agentx_sessions_global, appl_agentx_session, + sess_global_entry, appl_agentx_session_global_cmp); +RB_GENERATE_STATIC(appl_agentx_sessions_table, appl_agentx_session, + sess_table_entry, appl_agentx_session_table_cmp); +RB_GENERATE_STATIC(appl_agentx_registrations_global, appl_agentx_registration, + reg_global_entry, appl_agentx_registration_global_cmp); +RB_GENERATE_STATIC(appl_agentx_registrations_table, appl_agentx_registration, + reg_table_entry, appl_agentx_registration_table_cmp); blob - ac3fcb01ced659fa6557cf3fc5b5bc7ae522e029 blob + 877dd40379e225fab5b144f0211bf7451e5381ad --- usr.sbin/snmpd/application_internal.c +++ usr.sbin/snmpd/application_internal.c @@ -200,6 +200,57 @@ appl_internal_init(void) appl_internal_object(&OID(MIB_usmStatsDecryptionErrors), appl_internal_usmstats, NULL); + appl_internal_region(&OID(MIB_agentx)); + appl_internal_object(&OID(MIB_agentxDefaultTimeout), + appl_agentx_mib_generic, NULL); + appl_internal_object(&OID(MIB_agentxMasterAgentxVer), + appl_agentx_mib_generic, NULL); + appl_internal_object(&OID(MIB_agentxConnTableLastChange), + appl_agentx_mib_generic, NULL); + appl_internal_object(&OID(MIB_agentxConnOpenTime), + appl_agentx_mib_conntable, appl_agentx_mib_conntable_next); + appl_internal_object(&OID(MIB_agentxConnTransportDomain), + appl_agentx_mib_conntable, appl_agentx_mib_conntable_next); + appl_internal_object(&OID(MIB_agentxConnTransportAddress), + appl_agentx_mib_conntable, appl_agentx_mib_conntable_next); + appl_internal_object(&OID(MIB_agentxSessionTableLastChange), + appl_agentx_mib_generic, NULL); + appl_internal_object(&OID(MIB_agentxSessionObjectID), + appl_agentx_mib_sessiontable, appl_agentx_mib_sessiontable_next); + appl_internal_object(&OID(MIB_agentxSessionDescr), + appl_agentx_mib_sessiontable, appl_agentx_mib_sessiontable_next); + appl_internal_object(&OID(MIB_agentxSessionAdminStatus), + appl_agentx_mib_sessiontable, appl_agentx_mib_sessiontable_next); + appl_internal_object(&OID(MIB_agentxSessionOpenTime), + appl_agentx_mib_sessiontable, appl_agentx_mib_sessiontable_next); + appl_internal_object(&OID(MIB_agentxSessionAgentXVer), + appl_agentx_mib_sessiontable, appl_agentx_mib_sessiontable_next); + appl_internal_object(&OID(MIB_agentxSessionTimeout), + appl_agentx_mib_sessiontable, appl_agentx_mib_sessiontable_next); + appl_internal_object(&OID(MIB_agentxRegistrationTableLastChange), + appl_agentx_mib_generic, NULL); + appl_internal_object(&OID(MIB_agentxRegContext), + appl_agentx_mib_registrationtable, + appl_agentx_mib_registrationtable_next); + appl_internal_object(&OID(MIB_agentxRegStart), + appl_agentx_mib_registrationtable, + appl_agentx_mib_registrationtable_next); + appl_internal_object(&OID(MIB_agentxRegRangeSubId), + appl_agentx_mib_registrationtable, + appl_agentx_mib_registrationtable_next); + appl_internal_object(&OID(MIB_agentxRegUpperBound), + appl_agentx_mib_registrationtable, + appl_agentx_mib_registrationtable_next); + appl_internal_object(&OID(MIB_agentxRegPriority), + appl_agentx_mib_registrationtable, + appl_agentx_mib_registrationtable_next); + appl_internal_object(&OID(MIB_agentxRegTimeout), + appl_agentx_mib_registrationtable, + appl_agentx_mib_registrationtable_next); + appl_internal_object(&OID(MIB_agentxRegInstance), + appl_agentx_mib_registrationtable, + appl_agentx_mib_registrationtable_next); + while ((obj = RB_MIN(appl_internal_objects, &appl_internal_objects_conf)) != NULL) { RB_REMOVE(appl_internal_objects, blob - fc2a428828de5e9ca1761e25223fc7eeee165e2f blob + 9e2f2a6b2e838b105d140520c01ce51305cff0e7 --- usr.sbin/snmpd/mib.h +++ usr.sbin/snmpd/mib.h @@ -425,6 +425,49 @@ const char *mib_string2oid(const char *, struct ber_oi #define MIB_dot1dTp MIB_dot1dBridge, 4 #define MIB_dot1dStatic MIB_dot1dBridge, 5 +/* AGENTX-MIB */ +#define MIB_agentx MIB_mib_2, 74 +#define MIB_agentxObjects MIB_agentx, 1 +#define MIB_agentxGeneral MIB_agentxObjects, 1 +#define MIB_agentxConnection MIB_agentxObjects, 2 +#define MIB_agentxSession MIB_agentxObjects, 3 +#define MIB_agentxRegistration MIB_agentxObjects, 4 +#define MIB_agentxDefaultTimeout MIB_agentxGeneral, 1 +#define MIB_agentxMasterAgentxVer MIB_agentxGeneral, 2 +#define MIB_agentxConnTableLastChange MIB_agentxConnection, 1 +#define MIB_agentxConnectionTable MIB_agentxConnection, 2 +#define MIB_agentxConnectionEntry MIB_agentxConnectionTable, 1 +#define MIB_agentxConnIndex MIB_agentxConnectionEntry, 1 +#define MIB_agentxConnOpenTime MIB_agentxConnectionEntry, 2 +#define MIB_agentxConnTransportDomain MIB_agentxConnectionEntry, 3 +#define MIB_agentxConnTransportAddress MIB_agentxConnectionEntry, 4 +#define MIB_agentxSessionTableLastChange MIB_agentxSession, 1 +#define MIB_agentxSessionTable MIB_agentxSession, 2 +#define MIB_agentxSessionEntry MIB_agentxSessionTable, 1 +#define MIB_agentxSessionIndex MIB_agentxSessionEntry, 1 +#define MIB_agentxSessionObjectID MIB_agentxSessionEntry, 2 +#define MIB_agentxSessionDescr MIB_agentxSessionEntry, 3 +#define MIB_agentxSessionAdminStatus MIB_agentxSessionEntry, 4 +#define MIB_agentxSessionOpenTime MIB_agentxSessionEntry, 5 +#define MIB_agentxSessionAgentXVer MIB_agentxSessionEntry, 6 +#define MIB_agentxSessionTimeout MIB_agentxSessionEntry, 7 +#define MIB_agentxRegistrationTableLastChange MIB_agentxRegistration, 1 +#define MIB_agentxRegistrationTable MIB_agentxRegistration, 2 +#define MIB_agentxRegistrationEntry MIB_agentxRegistrationTable, 1 +#define MIB_agentxRegIndex MIB_agentxRegistrationEntry, 1 +#define MIB_agentxRegContext MIB_agentxRegistrationEntry, 2 +#define MIB_agentxRegStart MIB_agentxRegistrationEntry, 3 +#define MIB_agentxRegRangeSubId MIB_agentxRegistrationEntry, 4 +#define MIB_agentxRegUpperBound MIB_agentxRegistrationEntry, 5 +#define MIB_agentxRegPriority MIB_agentxRegistrationEntry, 6 +#define MIB_agentxRegTimeout MIB_agentxRegistrationEntry, 7 +#define MIB_agentxRegInstance MIB_agentxRegistrationEntry, 8 + +/* TRANSPORT-ADDRESS-MIB */ +#define MIB_transportAddress MIB_mib_2, 100 +#define MIB_transportDomains MIB_transportAddress, 1 +#define MIB_transportDomainLocal MIB_transportDomains, 13 + /* * PRIVATE ENTERPRISE NUMBERS from * https://www.iana.org/assignments/enterprise-numbers