From: martijn Date: Tue, 24 Oct 2023 14:34:40 +0000 (+0000) Subject: Add a new regression framework for snmpd. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=84417368516739962f4394e4429151db254e9416;p=openbsd Add a new regression framework for snmpd. There are still many test cases left to write, so leave snmpd.sh in place to test for cases not yet implemented by the new code. --- diff --git a/regress/usr.sbin/snmpd/Makefile b/regress/usr.sbin/snmpd/Makefile index c8c575e8f57..dfdb717d78c 100644 --- a/regress/usr.sbin/snmpd/Makefile +++ b/regress/usr.sbin/snmpd/Makefile @@ -1,17 +1,248 @@ -# $OpenBSD: Makefile,v 1.4 2021/10/23 17:56:31 bluhm Exp $ +# $OpenBSD: Makefile,v 1.5 2023/10/24 14:34:40 martijn Exp $ # Regress tests for snmpd -REGRESS_SETUP_ONCE = setup -REGRESS_CLEANUP = cleanup -REGRESS_TARGETS = run-snmpd +PROG = snmpd_regress +SRCS = snmpd_regress.c agentx.c backend.c snmp.c + +LDADD= -lutil +DPADD= ${LIBUTIL} + +SNMPD ?= /usr/sbin/snmpd +SNMPD_START = ${SUDO} ${SNMPD} -Nvvdf ${.CURDIR}/snmpd.conf >> snmpd.log 2>&1 & + +REGRESS_CLEANUP = cleanup +REGRESS_SETUP_ONCE = setup +CLEANFILES = snmpd.log setup: - ${SUDO} /etc/rc.d/snmpd stop + -${SUDO} /etc/rc.d/snmpd stop + > snmpd.log cleanup: - -${SUDO} /etc/rc.d/snmpd restart || true + -${SUDO} pkill -f ${SNMPD} + @sleep 1 + -${SUDO} rcctl restart snmpd +REGRESS_TARGETS += run-snmpd run-snmpd: + -${SUDO} pkill -f ${SNMPD} + @sleep 1 ${SUDO} env OBJDIR=${.OBJDIR} sh ${.CURDIR}/snmpd.sh +# AgentX administrative commands: application_agentx.c +AGENTX_TARGETS = agentx_open_nnbo +AGENTX_TARGETS+= agentx_open_nbo +AGENTX_TARGETS+= agentx_open_invalidversion +AGENTX_TARGETS+= agentx_open_ignore_sessionid +AGENTX_TARGETS+= agentx_open_invalid_oid +AGENTX_TARGETS+= agentx_open_descr_too_long +AGENTX_TARGETS+= agentx_open_descr_invalid +AGENTX_TARGETS+= agentx_open_context +AGENTX_TARGETS+= agentx_open_instance_registration +AGENTX_TARGETS+= agentx_open_new_index +AGENTX_TARGETS+= agentx_open_any_index +AGENTX_TARGETS+= agentx_ping_notopen +AGENTX_TARGETS+= agentx_ping_invalid_sessionid +AGENTX_TARGETS+= agentx_ping_default +AGENTX_TARGETS+= agentx_ping_context +AGENTX_TARGETS+= agentx_ping_invalid_version +AGENTX_TARGETS+= agentx_ping_instance_registration +AGENTX_TARGETS+= agentx_ping_new_index +AGENTX_TARGETS+= agentx_ping_any_index +AGENTX_TARGETS+= agentx_ping_nbo_nnbo +AGENTX_TARGETS+= agentx_ping_nnbo_nbo +AGENTX_TARGETS+= agentx_close_notopen +AGENTX_TARGETS+= agentx_close_reasonother +AGENTX_TARGETS+= agentx_close_reasonparseerror +AGENTX_TARGETS+= agentx_close_reasonprotocolerror +AGENTX_TARGETS+= agentx_close_reasontimouts +AGENTX_TARGETS+= agentx_close_reasonshutdown +AGENTX_TARGETS+= agentx_close_reasonbymanager +AGENTX_TARGETS+= agentx_close_reasoninvalid +AGENTX_TARGETS+= agentx_close_single +AGENTX_TARGETS+= agentx_close_notowned +AGENTX_TARGETS+= agentx_close_invalid_sessionid +AGENTX_TARGETS+= agentx_close_context +AGENTX_TARGETS+= agentx_close_invalid_version +AGENTX_TARGETS+= agentx_close_instance_registration +AGENTX_TARGETS+= agentx_close_new_index +AGENTX_TARGETS+= agentx_close_any_index +AGENTX_TARGETS+= agentx_close_nnbo_nbo +AGENTX_TARGETS+= agentx_register_notopen +AGENTX_TARGETS+= agentx_register_invalid_sessionid +AGENTX_TARGETS+= agentx_register_default +AGENTX_TARGETS+= agentx_register_context +AGENTX_TARGETS+= agentx_register_invalid_version +AGENTX_TARGETS+= agentx_register_instance_registration +AGENTX_TARGETS+= agentx_register_new_index +AGENTX_TARGETS+= agentx_register_duplicate_self +AGENTX_TARGETS+= agentx_register_duplicate_twocon +AGENTX_TARGETS+= agentx_register_duplicate_priority +AGENTX_TARGETS+= agentx_register_range +AGENTX_TARGETS+= agentx_register_range_invalidupperbound +AGENTX_TARGETS+= agentx_register_range_single +AGENTX_TARGETS+= agentx_register_range_overlap_single +AGENTX_TARGETS+= agentx_register_single_overlap_range +AGENTX_TARGETS+= agentx_register_range_overlap_range +AGENTX_TARGETS+= agentx_register_below +AGENTX_TARGETS+= agentx_register_above +AGENTX_TARGETS+= agentx_register_restricted +AGENTX_TARGETS+= agentx_unregister_notopen +AGENTX_TARGETS+= agentx_unregister_invalid_sessionid +AGENTX_TARGETS+= agentx_unregister_notregistered +AGENTX_TARGETS+= agentx_unregister_notregistered +AGENTX_TARGETS+= agentx_unregister_single +AGENTX_TARGETS+= agentx_unregister_single_notowned +AGENTX_TARGETS+= agentx_unregister_range +AGENTX_TARGETS+= agentx_unregister_range_single +# Final choice on if this is the desired behaviour pending on tech@ +REGRESS_EXPECTED_FAILURES+= agentx_unregister_range_subset +AGENTX_TARGETS+= agentx_unregister_range_subset +AGENTX_TARGETS+= agentx_unregister_range_extra +AGENTX_TARGETS+= agentx_unregister_range_priority +AGENTX_TARGETS+= agentx_unregister_range_notowned + +REGRESS_TARGETS+= ${AGENTX_TARGETS} +agentx: ${AGENTX_TARGETS} + +# SNMP application core logic: application.c +BACKEND_TARGETS+= backend_get_integer +BACKEND_TARGETS+= backend_get_octetstring +BACKEND_TARGETS+= backend_get_objectidentifier +BACKEND_TARGETS+= backend_get_ipaddress +BACKEND_TARGETS+= backend_get_counter32 +BACKEND_TARGETS+= backend_get_gauge32 +BACKEND_TARGETS+= backend_get_timeticks +BACKEND_TARGETS+= backend_get_opaque +BACKEND_TARGETS+= backend_get_counter64 +BACKEND_TARGETS+= backend_get_nosuchobject +BACKEND_TARGETS+= backend_get_nosuchinstance +BACKEND_TARGETS+= backend_get_endofmibview +BACKEND_TARGETS+= backend_get_two_single_backend +BACKEND_TARGETS+= backend_get_two_double_backend +BACKEND_TARGETS+= backend_get_wrongorder +BACKEND_TARGETS+= backend_get_toofew +BACKEND_TARGETS+= backend_get_toomany +BACKEND_TARGETS+= backend_get_instance +BACKEND_TARGETS+= backend_get_instance_below +BACKEND_TARGETS+= backend_get_timeout_default +REGRESS_SLOW_TARGETS+= backend_get_timeout_default +BACKEND_TARGETS+= backend_get_timeout_session_lower +REGRESS_SLOW_TARGETS+= backend_get_timeout_session_lower +BACKEND_TARGETS+= backend_get_timeout_session_higher +REGRESS_SLOW_TARGETS+= backend_get_timeout_session_higher +BACKEND_TARGETS+= backend_get_timeout_region_lower +REGRESS_SLOW_TARGETS+= backend_get_timeout_region_lower +BACKEND_TARGETS+= backend_get_timeout_region_higher +REGRESS_SLOW_TARGETS+= backend_get_timeout_region_higher +BACKEND_TARGETS+= backend_get_priority_lower +BACKEND_TARGETS+= backend_get_priority_higher +BACKEND_TARGETS+= backend_get_priority_below_lower +BACKEND_TARGETS+= backend_get_priority_below_higher +BACKEND_TARGETS+= backend_get_close +BACKEND_TARGETS+= backend_get_close_overlap +BACKEND_TARGETS+= backend_get_disappear +BACKEND_TARGETS+= backend_get_disappear_overlap +BACKEND_TARGETS+= backend_get_disappear_doublesession +BACKEND_TARGETS+= backend_getnext_selfbound +BACKEND_TARGETS+= backend_getnext_lowerbound +BACKEND_TARGETS+= backend_getnext_lowerbound_self +BACKEND_TARGETS+= backend_getnext_lowerbound_highprio +BACKEND_TARGETS+= backend_getnext_lowerbound_lowprio +BACKEND_TARGETS+= backend_getnext_sibling +BACKEND_TARGETS+= backend_getnext_child_gap +BACKEND_TARGETS+= backend_getnext_nosuchobject +BACKEND_TARGETS+= backend_getnext_nosuchinstance +BACKEND_TARGETS+= backend_getnext_endofmibview +BACKEND_TARGETS+= backend_getnext_inclusive +BACKEND_TARGETS+= backend_getnext_jumpnext +BACKEND_TARGETS+= backend_getnext_jumpnext_endofmibview +BACKEND_TARGETS+= backend_getnext_jump_up +BACKEND_TARGETS+= backend_getnext_two_single_backend +BACKEND_TARGETS+= backend_getnext_two_double_backend +BACKEND_TARGETS+= backend_getnext_instance_below +BACKEND_TARGETS+= backend_getnext_instance +BACKEND_TARGETS+= backend_getnext_instance_exact +BACKEND_TARGETS+= backend_getnext_instance_ignore +BACKEND_TARGETS+= backend_getnext_backwards +BACKEND_TARGETS+= backend_getnext_stale +BACKEND_TARGETS+= backend_getnext_inclusive_backwards +BACKEND_TARGETS+= backend_getnext_toofew +BACKEND_TARGETS+= backend_getnext_toomany +BACKEND_TARGETS+= backend_getbulk_nonrep_zero_maxrep_one +BACKEND_TARGETS+= backend_getbulk_nonrep_zero_maxrep_two +BACKEND_TARGETS+= backend_getbulk_nonrep_one_maxrep_one +BACKEND_TARGETS+= backend_getbulk_nonrep_one_maxrep_two +BACKEND_TARGETS+= backend_getbulk_nonrep_two_maxrep_two +BACKEND_TARGETS+= backend_getbulk_nonrep_negative +BACKEND_TARGETS+= backend_error_get_toobig +BACKEND_TARGETS+= backend_error_get_nosuchname +BACKEND_TARGETS+= backend_error_get_badvalue +BACKEND_TARGETS+= backend_error_get_readonly +BACKEND_TARGETS+= backend_error_get_generr +BACKEND_TARGETS+= backend_error_get_wrongtype +BACKEND_TARGETS+= backend_error_get_wronglength +BACKEND_TARGETS+= backend_error_get_wrongvalue +BACKEND_TARGETS+= backend_error_get_nocreation +BACKEND_TARGETS+= backend_error_get_inconsistentvalue +BACKEND_TARGETS+= backend_error_get_commitfailed +BACKEND_TARGETS+= backend_error_get_undofailed +BACKEND_TARGETS+= backend_error_get_authorizationerror +BACKEND_TARGETS+= backend_error_get_notwritable +BACKEND_TARGETS+= backend_error_get_inconsistentname +BACKEND_TARGETS+= backend_error_get_openfailed +BACKEND_TARGETS+= backend_error_get_notopen +BACKEND_TARGETS+= backend_error_get_indexwrongtype +BACKEND_TARGETS+= backend_error_get_indexalreadyallocated +BACKEND_TARGETS+= backend_error_get_indexnonavailable +BACKEND_TARGETS+= backend_error_get_indexnotallocated +BACKEND_TARGETS+= backend_error_get_duplicateregistration +BACKEND_TARGETS+= backend_error_get_requestdenied +BACKEND_TARGETS+= backend_error_get_processingerror +BACKEND_TARGETS+= backend_error_get_nonstandard +BACKEND_TARGETS+= backend_error_getnext_toobig +BACKEND_TARGETS+= backend_error_getnext_nosuchname +BACKEND_TARGETS+= backend_error_getnext_badvalue +BACKEND_TARGETS+= backend_error_getnext_readonly +BACKEND_TARGETS+= backend_error_getnext_generr +BACKEND_TARGETS+= backend_error_getnext_noaccess +BACKEND_TARGETS+= backend_error_getnext_wrongtype +BACKEND_TARGETS+= backend_error_getnext_wronglength +BACKEND_TARGETS+= backend_error_getnext_wrongencoding +BACKEND_TARGETS+= backend_error_getnext_wrongvalue +BACKEND_TARGETS+= backend_error_getnext_nocreation +BACKEND_TARGETS+= backend_error_getnext_inconsistentvalue +BACKEND_TARGETS+= backend_error_getnext_resourceunavailable +BACKEND_TARGETS+= backend_error_getnext_commitfailed +BACKEND_TARGETS+= backend_error_getnext_undofailed +BACKEND_TARGETS+= backend_error_getnext_notwritable +BACKEND_TARGETS+= backend_error_getnext_inconsistentname +BACKEND_TARGETS+= backend_error_getnext_openfailed +BACKEND_TARGETS+= backend_error_getnext_notopen +BACKEND_TARGETS+= backend_error_getnext_indexwrongtype +BACKEND_TARGETS+= backend_error_getnext_indexalreadyallocated +BACKEND_TARGETS+= backend_error_getnext_indexnonavailable +BACKEND_TARGETS+= backend_error_getnext_indexnotallocated +BACKEND_TARGETS+= backend_error_getnext_unsupportedcontext +BACKEND_TARGETS+= backend_error_getnext_duplicateregistration +BACKEND_TARGETS+= backend_error_getnext_unknownregistration +BACKEND_TARGETS+= backend_error_getnext_parseerror +BACKEND_TARGETS+= backend_error_getnext_requestdenied +BACKEND_TARGETS+= backend_error_getnext_processingerror +BACKEND_TARGETS+= backend_error_getnext_nonstandard + +REGRESS_TARGETS+= ${BACKEND_TARGETS} +backend: ${BACKEND_TARGETS} + +.PHONY: agentx backend + +${REGRESS_TARGETS}: snmpd_regress +# Always start snmpd if it's not running + @pgrep -q snmpd || \ + (printf "%s\n" "${SNMPD_START}"; ${SNMPD_START} sleep 0.5) + ./snmpd_regress ${SNMPD_REGRESS_FLAGS} $@ +# Make sure that snmpd hasn't crashed in the meantime. + @sleep 0.01 + @pgrep -q snmpd + .include diff --git a/regress/usr.sbin/snmpd/agentx.c b/regress/usr.sbin/snmpd/agentx.c new file mode 100644 index 00000000000..ade5dd814e5 --- /dev/null +++ b/regress/usr.sbin/snmpd/agentx.c @@ -0,0 +1,3146 @@ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "regress.h" + +#define AGENTX_SOCKET "/tmp/agentx" + +#define SUBAGENT_DESCR(name) name, strlen(name) + +#define AGENTX_OPEN_PDU 1 +#define AGENTX_CLOSE_PDU 2 +#define AGENTX_REGISTER_PDU 3 +#define AGENTX_UNREGISTER_PDU 4 +#define AGENTX_GET_PDU 5 +#define AGENTX_GETNEXT_PDU 6 +#define AGENTX_GETBULK_PDU 7 +#define AGENTX_TESTSET_PDU 8 +#define AGENTX_COMMITSET_PDU 9 +#define AGENTX_UNDOSET_PDU 10 +#define AGENTX_CLEANUPSET_PDU 11 +#define AGENTX_NOTIFY_PDU 12 +#define AGENTX_PING_PDU 13 +#define AGENTX_INDEXALLOCATE_PDU 14 +#define AGENTX_INDEXDEALLOCATE_PDU 15 +#define AGENTX_ADDAGENTCAPS_PDU 16 +#define AGENTX_REMOVEAGENTCAPS_PDU 17 +#define AGENTX_RESPONSE_PDU 18 + +#define NOAGENTXERROR 0 +#define OPENFAILED 256 +#define NOTOPEN 257 +#define INDEXWRONGTYPE 258 +#define INDEXALREADYALLOCATED 259 +#define INDEXNONEAVAILABLE 260 +#define INDEXNOTALLOCATED 261 +#define UNSUPPORTEDCONTEXT 262 +#define DUPLICATEREGISTRATION 263 +#define UNKNOWNREGISTRATION 264 +#define UNKNOWNAGENTCAPS 265 +#define PARSEERROR 266 +#define REQUESTDENIED 267 +#define PROCESSINGERROR 268 + +#define INSTANCE_REGISTRATION (1 << 0) +#define NEW_INDEX (1 << 1) +#define ANY_INDEX (1 << 2) +#define NON_DEFAULT_CONTEXT (1 << 3) +#define NETWORK_BYTE_ORDER (1 << 4) + +#define INTEGER 2 +#define OCTETSTRING 4 +#define AXNULL 5 +#define OBJECTIDENTIFIER 6 +#define IPADDRESS 64 +#define COUNTER32 65 +#define GAUGE32 66 +#define TIMETICKS 67 +#define OPAQUE 68 +#define COUNTER64 70 +#define NOSUCHOBJECT 128 +#define NOSUCHINSTANCE 129 +#define ENDOFMIBVIEW 130 + +#define MESSAGE_NBO(msg) (((const char *)msg->buf)[2] & NETWORK_BYTE_ORDER) + +#define p16toh(header, value) (uint16_t)(header->flags & NETWORK_BYTE_ORDER ? \ + be16toh(value) : le16toh(value)) +#define p32toh(header, value) (uint32_t)(header->flags & NETWORK_BYTE_ORDER ? \ + be32toh(value) : le32toh(value)) +#define p64toh(header, value) (uint64_t)(header->flags & NETWORK_BYTE_ORDER ? \ + be64toh(value) : le64toh(value)) + +struct header { + uint8_t version; + uint8_t type; + uint8_t flags; + uint8_t reserved; + uint32_t sessionid; + uint32_t transactionid; + uint32_t packetid; + uint32_t payload_length; +} __attribute__ ((packed)); + +struct message { + void *buf; + size_t len; + size_t size; +}; + +void agentx_close_validate(const char *, const void *, + size_t, uint8_t, uint8_t); +static void agentx_response_validate(const char *, const void *, size_t, + uint8_t, uint32_t, enum error, uint16_t, struct varbind *, size_t); +static void message_add_uint8(struct message *, uint8_t); +static void message_add_uint16(struct message *, uint16_t); +static void message_add_uint32(struct message *, uint32_t); +static void message_add_uint64(struct message *, uint64_t); +static void message_add_nstring(struct message *, const void *, uint32_t); +static void message_add_oid(struct message *, const uint32_t[], uint8_t, + uint8_t); +static void message_add_varbind(struct message *, struct varbind *); +static void message_add_header(struct message *, uint8_t, uint8_t, uint8_t, + uint32_t, uint32_t, uint32_t); +static void message_add(struct message *, const void *, size_t); +static void message_release(struct message *); +static size_t poid(const char *, const struct header *, const uint8_t *, size_t, + struct oid *); + +void agentx_write(int, struct message *); + +void +agentx_open_nnbo(void) +{ + int s; + struct message msg = {}; + char zero[3] = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + + s = agentx_connect(axsocket); + message_add_header(&msg, 1, AGENTX_OPEN_PDU, 0, 0, 0, packetid); + message_add_uint8(&msg, 0); + message_add(&msg, zero, 3); + message_add_oid(&msg, OID_ARG(MIB_SUBAGENT_OPEN, 1), 0); + message_add_nstring(&msg, SUBAGENT_DESCR(__func__)); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, NOAGENTXERROR, + 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_open_nbo(void) +{ + int s; + struct message msg = {}; + char zero[3] = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + + s = agentx_connect(axsocket); + message_add_header(&msg, 1, AGENTX_OPEN_PDU, NETWORK_BYTE_ORDER, 0, 0, + packetid); + message_add_uint8(&msg, 0); + message_add(&msg, zero, 3); + message_add_oid(&msg, OID_ARG(MIB_SUBAGENT_OPEN, 2), 0); + message_add_nstring(&msg, SUBAGENT_DESCR(__func__)); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, NETWORK_BYTE_ORDER, + packetid, NOAGENTXERROR, 0, NULL, 0); + message_release(&msg); + close(s); +} + +/* + * The version byte is the only identifier we have to determine if we can + * "trust" the rest of the packet structure. If this doesn't match the server + * can't return a parseError message, because it doesn't know the packetid. + */ +void +agentx_open_invalidversion(void) +{ + int s; + struct message msg = {}; + char zero[3] = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + + s = agentx_connect(axsocket); + message_add_header(&msg, 0xFF, AGENTX_OPEN_PDU, 0, 0, 0, packetid); + message_add_uint8(&msg, 0); + message_add(&msg, zero, 3); + message_add_oid(&msg, OID_ARG(MIB_SUBAGENT_OPEN, 3), 0); + message_add_nstring(&msg, SUBAGENT_DESCR(__func__)); + + agentx_write(s, &msg); + + if (agentx_read(s, repl, sizeof(repl), 1000) != 0) + errx(1, "%s: Unexpected reply", __func__); + close(s); +} + +void +agentx_open_ignore_sessionid(void) +{ + int s1, s2; + struct message msg = {}; + char zero[3] = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + struct header *header = (struct header *)repl; + + s1 = agentx_connect(axsocket); + message_add_header(&msg, 1, AGENTX_OPEN_PDU, 0, 0, 0, packetid); + message_add_uint8(&msg, 0); + message_add(&msg, zero, 3); + message_add_oid(&msg, OID_ARG(MIB_SUBAGENT_OPEN, 4, 1), 0); + message_add_nstring(&msg, + SUBAGENT_DESCR("agentx_open_ignore_sessionid.1")); + + agentx_write(s1, &msg); + + n = agentx_read(s1, repl, sizeof(repl), 1000); + agentx_response_validate(__func__, repl, n, 0, packetid, NOAGENTXERROR, + 0, NULL, 0); + + sessionid = le32toh(header->sessionid); + + s2 = agentx_connect(axsocket); + message_add_header(&msg, 1, AGENTX_OPEN_PDU, 0, sessionid, 0, packetid); + message_add_uint8(&msg, 0); + message_add(&msg, zero, 3); + message_add_oid(&msg, OID_ARG(MIB_SUBAGENT_OPEN, 4, 2), 0); + message_add_nstring(&msg, + SUBAGENT_DESCR("agentx_open_ignore_sessionid.2")); + + agentx_write(s2, &msg); + + n = agentx_read(s2, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, NOAGENTXERROR, + 0, NULL, 0); + if (sessionid == le32toh(header->sessionid)) + errx(1, "%s: sessionid not ignored", __func__); + + message_release(&msg); + close(s1); + close(s2); +} + +void +agentx_open_invalid_oid(void) +{ + int s; + struct message msg = {}; + char zero[3] = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t oid[129]; + + s = agentx_connect(axsocket); + message_add_header(&msg, 1, AGENTX_OPEN_PDU, 0, 0, 0, packetid); + message_add_uint8(&msg, 0); + message_add(&msg, zero, 3); + message_add_oid(&msg, oid, 129, 0); + message_add_nstring(&msg, SUBAGENT_DESCR(__func__)); + + agentx_write(s, &msg); + + if ((n = agentx_read(s, repl, sizeof(repl), 1000)) != 0) + errx(1, "unexpected reply"); + + message_release(&msg); + close(s); +} + +void +agentx_open_descr_too_long(void) +{ + int s; + struct message msg = {}; + char zero[3] = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + char descr[256]; + + s = agentx_connect(axsocket); + message_add_header(&msg, 1, AGENTX_OPEN_PDU, 0, 0, 0, packetid); + message_add_uint8(&msg, 0); + message_add(&msg, zero, 3); + message_add_oid(&msg, OID_ARG(MIB_SUBAGENT_OPEN, 6), 0); + memset(descr, 'a', sizeof(descr)); + message_add_nstring(&msg, descr, sizeof(descr)); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, PARSEERROR, 0, + NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_open_descr_invalid(void) +{ + int s; + struct message msg = {}; + char zero[3] = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + + s = agentx_connect(axsocket); + message_add_header(&msg, 1, AGENTX_OPEN_PDU, 0, 0, 0, packetid); + message_add_uint8(&msg, 0); + message_add(&msg, zero, 3); + message_add_oid(&msg, OID_ARG(MIB_SUBAGENT_OPEN, 7), 0); + /* Too long start-byte (5 ones instead of max 4) followed by ascii */ + message_add_nstring(&msg, SUBAGENT_DESCR("a\373a")); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, PARSEERROR, 0, + NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_open_context(void) +{ + int s; + struct message msg = {}; + char zero[3] = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + + s = agentx_connect(axsocket); + message_add_header(&msg, 1, AGENTX_OPEN_PDU, NON_DEFAULT_CONTEXT, 0, 0, + packetid); + message_add_nstring(&msg, "ctx", 3); + message_add_uint8(&msg, 0); + message_add(&msg, zero, 3); + message_add_oid(&msg, OID_ARG(MIB_SUBAGENT_OPEN, 8), 0); + message_add_nstring(&msg, SUBAGENT_DESCR(__func__)); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, PARSEERROR, 0, + NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_open_instance_registration(void) +{ + int s; + struct message msg = {}; + char zero[3] = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + + s = agentx_connect(axsocket); + message_add_header(&msg, 1, AGENTX_OPEN_PDU, INSTANCE_REGISTRATION, 0, + 0, packetid); + message_add_uint8(&msg, 0); + message_add(&msg, zero, 3); + message_add_oid(&msg, OID_ARG(MIB_SUBAGENT_OPEN, 9), 0); + message_add_nstring(&msg, SUBAGENT_DESCR(__func__)); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, PARSEERROR, 0, + NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_open_new_index(void) +{ + int s; + struct message msg = {}; + char zero[3] = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + + s = agentx_connect(axsocket); + message_add_header(&msg, 1, AGENTX_OPEN_PDU, NEW_INDEX, 0, + 0, packetid); + message_add_uint8(&msg, 0); + message_add(&msg, zero, 3); + message_add_oid(&msg, OID_ARG(MIB_SUBAGENT_OPEN, 10), 0); + message_add_nstring(&msg, SUBAGENT_DESCR(__func__)); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, PARSEERROR, 0, + NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_open_any_index(void) +{ + int s; + struct message msg = {}; + char zero[3] = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + + s = agentx_connect(axsocket); + message_add_header(&msg, 1, AGENTX_OPEN_PDU, ANY_INDEX, 0, + 0, packetid); + message_add_uint8(&msg, 0); + message_add(&msg, zero, 3); + message_add_oid(&msg, OID_ARG(MIB_SUBAGENT_OPEN, 11), 0); + message_add_nstring(&msg, SUBAGENT_DESCR(__func__)); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, PARSEERROR, 0, + NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_ping_notopen(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + + s = agentx_connect(axsocket); + message_add_header(&msg, 1, AGENTX_PING_PDU, 0, 0, 0, packetid); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, NOTOPEN, 0, + NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_ping_invalid_sessionid(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_PING, 2), __func__); + message_add_header(&msg, 1, AGENTX_PING_PDU, 0, + sessionid + 1, 0, packetid); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, NOTOPEN, 0, + NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_ping_default(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_PING, 3), __func__); + message_add_header(&msg, 1, AGENTX_PING_PDU, 0, + sessionid, 0, packetid); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, + packetid, NOAGENTXERROR, 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_ping_context(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_PING, 4), __func__); + message_add_header(&msg, 1, AGENTX_PING_PDU, NON_DEFAULT_CONTEXT, + sessionid, 0, packetid); + message_add_nstring(&msg, "ctx", 3); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, + packetid, UNSUPPORTEDCONTEXT, 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_ping_invalid_version(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_PING, 5), __func__); + message_add_header(&msg, 0xFF, AGENTX_PING_PDU, INSTANCE_REGISTRATION, + sessionid, 0, packetid); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_close_validate(__func__, repl, n, 0, REASONPROTOCOLERROR); + message_release(&msg); + close(s); +} + +void +agentx_ping_instance_registration(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_PING, 6), __func__); + message_add_header(&msg, 1, AGENTX_PING_PDU, INSTANCE_REGISTRATION, + sessionid, 0, packetid); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, + packetid, PARSEERROR, 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_ping_new_index(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_PING, 7), __func__); + message_add_header(&msg, 1, AGENTX_PING_PDU, NEW_INDEX, + sessionid, 0, packetid); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, + packetid, PARSEERROR, 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_ping_any_index(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_PING, 8), __func__); + message_add_header(&msg, 1, AGENTX_PING_PDU, ANY_INDEX, + sessionid, 0, packetid); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, + packetid, PARSEERROR, 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_ping_nbo_nnbo(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_PING, 9), __func__); + message_add_header(&msg, 1, AGENTX_PING_PDU, 0, + sessionid, 0, packetid); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, + packetid, NOAGENTXERROR, 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_ping_nnbo_nbo(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_PING, 9), __func__); + message_add_header(&msg, 1, AGENTX_PING_PDU, NETWORK_BYTE_ORDER, + sessionid, 0, packetid); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, NETWORK_BYTE_ORDER, + packetid, NOAGENTXERROR, 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_close_notopen(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + const uint8_t reason = REASONOTHER, zero[3] = {0}; + + s = agentx_connect(axsocket); + message_add_header(&msg, 1, AGENTX_CLOSE_PDU, 0, 0, 0, packetid); + message_add(&msg, &reason, sizeof(reason)); + message_add(&msg, zero, sizeof(zero)); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, NOTOPEN, 0, + NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_close_reasonother(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + const uint8_t reason = REASONOTHER, zero[3] = {0}; + + s = agentx_connect(axsocket); + + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_CLOSE, 2), __func__); + message_add_header(&msg, 1, AGENTX_CLOSE_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &reason, sizeof(reason)); + message_add(&msg, zero, sizeof(zero)); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, NOAGENTXERROR, + 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_close_reasonparseerror(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + const uint8_t reason = REASONPARSEERROR, zero[3] = {0}; + + s = agentx_connect(axsocket); + + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_CLOSE, 3), __func__); + message_add_header(&msg, 1, AGENTX_CLOSE_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &reason, sizeof(reason)); + message_add(&msg, zero, sizeof(zero)); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, NOAGENTXERROR, + 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_close_reasonprotocolerror(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + const uint8_t reason = REASONPROTOCOLERROR, zero[3] = {0}; + + s = agentx_connect(axsocket); + + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_CLOSE, 4), __func__); + message_add_header(&msg, 1, AGENTX_CLOSE_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &reason, sizeof(reason)); + message_add(&msg, zero, sizeof(zero)); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, NOAGENTXERROR, + 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_close_reasontimouts(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + const uint8_t reason = REASONTIMEOUTS, zero[3] = {0}; + + s = agentx_connect(axsocket); + + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_CLOSE, 5), __func__); + message_add_header(&msg, 1, AGENTX_CLOSE_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &reason, sizeof(reason)); + message_add(&msg, zero, sizeof(zero)); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, NOAGENTXERROR, + 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_close_reasonshutdown(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + const uint8_t reason = REASONSHUTDOWN, zero[3] = {0}; + + s = agentx_connect(axsocket); + + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_CLOSE, 6), __func__); + message_add_header(&msg, 1, AGENTX_CLOSE_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &reason, sizeof(reason)); + message_add(&msg, zero, sizeof(zero)); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, NOAGENTXERROR, + 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_close_reasonbymanager(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + const uint8_t reason = REASONBYMANAGER, zero[3] = {0}; + + s = agentx_connect(axsocket); + + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_CLOSE, 7), __func__); + message_add_header(&msg, 1, AGENTX_CLOSE_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &reason, sizeof(reason)); + message_add(&msg, zero, sizeof(zero)); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, PARSEERROR, + 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_close_reasoninvalid(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + const uint8_t reason = 0xFF, zero[3] = {0}; + + s = agentx_connect(axsocket); + + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_CLOSE, 8), __func__); + message_add_header(&msg, 1, AGENTX_CLOSE_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &reason, sizeof(reason)); + message_add(&msg, zero, sizeof(zero)); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_close_validate(__func__, repl, n, 0, REASONPROTOCOLERROR); + message_release(&msg); + close(s); +} + +void +agentx_close_single(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid1, sessionid2; + const uint8_t reason = REASONOTHER, zero[3] = {0}; + + s = agentx_connect(axsocket); + + sessionid1 = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_CLOSE, 9, 1), "agentx_close_single.1"); + sessionid2 = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_CLOSE, 9, 2), "agentx_close_single.2"); + message_add_header(&msg, 1, AGENTX_CLOSE_PDU, 0, sessionid1, 0, packetid); + message_add(&msg, &reason, sizeof(reason)); + message_add(&msg, zero, sizeof(zero)); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, NOAGENTXERROR, + 0, NULL, 0); + + /* Test that only the second session is still open */ + packetid = arc4random(); + message_add_header(&msg, 1, AGENTX_PING_PDU, 0, sessionid2, 0, packetid); + agentx_write(s, &msg); + n = agentx_read(s, repl, sizeof(repl), 1000); + agentx_response_validate(__func__, repl, n, 0, + packetid, NOAGENTXERROR, 0, NULL, 0); + + packetid = arc4random(); + message_add_header(&msg, 1, AGENTX_PING_PDU, 0, sessionid1, 0, packetid); + agentx_write(s, &msg); + n = agentx_read(s, repl, sizeof(repl), 1000); + agentx_response_validate(__func__, repl, n, 0, + packetid, NOTOPEN, 0, NULL, 0); + + message_release(&msg); + close(s); +} + +void +agentx_close_notowned(void) +{ + int s1, s2; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid1, sessionid2; + const uint8_t reason = REASONOTHER, zero[3] = {0}; + + s1 = agentx_connect(axsocket); + s2 = agentx_connect(axsocket); + + sessionid1 = agentx_open(s1, 0, 0, + OID_ARG(MIB_SUBAGENT_CLOSE, 10, 1), "agentx_close_notowned.1"); + sessionid2 = agentx_open(s2, 0, 0, + OID_ARG(MIB_SUBAGENT_CLOSE, 10, 2), "agentx_close_notowned.2"); + message_add_header(&msg, 1, AGENTX_CLOSE_PDU, 0, sessionid1, 0, packetid); + message_add(&msg, &reason, sizeof(reason)); + message_add(&msg, zero, sizeof(zero)); + + agentx_write(s2, &msg); + + n = agentx_read(s2, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, NOTOPEN, + 0, NULL, 0); + + /* Test that both sessions are still open */ + packetid = arc4random(); + message_add_header(&msg, 1, AGENTX_PING_PDU, 0, sessionid1, 0, packetid); + agentx_write(s1, &msg); + n = agentx_read(s1, repl, sizeof(repl), 1000); + agentx_response_validate(__func__, repl, n, 0, + packetid, NOAGENTXERROR, 0, NULL, 0); + + packetid = arc4random(); + message_add_header(&msg, 1, AGENTX_PING_PDU, 0, sessionid2, 0, packetid); + agentx_write(s2, &msg); + n = agentx_read(s2, repl, sizeof(repl), 1000); + agentx_response_validate(__func__, repl, n, 0, + packetid, NOAGENTXERROR, 0, NULL, 0); + + message_release(&msg); + close(s1); + close(s2); +} + +void +agentx_close_invalid_sessionid(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + const uint8_t reason = REASONOTHER, zero[3] = {0}; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_CLOSE, 11), __func__); + message_add_header(&msg, 1, AGENTX_CLOSE_PDU, 0, sessionid + 1, 0, packetid); + message_add(&msg, &reason, sizeof(reason)); + message_add(&msg, zero, sizeof(zero)); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, NOTOPEN, 0, + NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_close_context(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + const uint8_t reason = REASONOTHER, zero[3] = {0}; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_CLOSE, 12), __func__); + message_add_header(&msg, 1, AGENTX_CLOSE_PDU, NON_DEFAULT_CONTEXT, + sessionid, 0, packetid); + message_add_nstring(&msg, "ctx", 3); + message_add(&msg, &reason, sizeof(reason)); + message_add(&msg, zero, sizeof(zero)); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, PARSEERROR, 0, + NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_close_invalid_version(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + const uint8_t reason = REASONOTHER, zero[3] = {0}; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_CLOSE, 13), __func__); + message_add_header(&msg, 0xFF, AGENTX_CLOSE_PDU, 0, sessionid, 0, packetid); + message_add(&msg, &reason, sizeof(reason)); + message_add(&msg, zero, sizeof(zero)); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + agentx_close_validate(__func__, repl, n, 0, REASONPROTOCOLERROR); + + message_release(&msg); + close(s); +} + +void +agentx_close_instance_registration(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + const uint8_t reason = REASONOTHER, zero[3] = {0}; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_CLOSE, 14), __func__); + message_add_header(&msg, 1, AGENTX_CLOSE_PDU, INSTANCE_REGISTRATION, + sessionid, 0, packetid); + message_add(&msg, &reason, sizeof(reason)); + message_add(&msg, zero, sizeof(zero)); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, + packetid, PARSEERROR, 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_close_new_index(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + const uint8_t reason = REASONOTHER, zero[3] = {0}; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_CLOSE, 15), __func__); + message_add_header(&msg, 1, AGENTX_CLOSE_PDU, NEW_INDEX, + sessionid, 0, packetid); + message_add(&msg, &reason, sizeof(reason)); + message_add(&msg, zero, sizeof(zero)); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, + packetid, PARSEERROR, 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_close_any_index(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + const uint8_t reason = REASONOTHER, zero[3] = {0}; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_CLOSE, 16), __func__); + message_add_header(&msg, 1, AGENTX_CLOSE_PDU, ANY_INDEX, + sessionid, 0, packetid); + message_add(&msg, &reason, sizeof(reason)); + message_add(&msg, zero, sizeof(zero)); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, + packetid, PARSEERROR, 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_close_nnbo_nbo(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + const uint8_t reason = REASONOTHER, zero[3] = {0}; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_CLOSE, 17), __func__); + message_add_header(&msg, 1, AGENTX_CLOSE_PDU, NETWORK_BYTE_ORDER, + sessionid, 0, packetid); + message_add(&msg, &reason, sizeof(reason)); + message_add(&msg, zero, sizeof(zero)); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, NETWORK_BYTE_ORDER, + packetid, NOAGENTXERROR, 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_register_notopen(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0; + + s = agentx_connect(axsocket); + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, 0, 0, packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 1, 0), 0); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, NOTOPEN, 0, + NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_register_invalid_sessionid(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_REGISTER, 2), __func__); + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid + 1, 0, + packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 2, 0), 0); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, NOTOPEN, 0, + NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_register_default(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_REGISTER, 3), __func__); + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 3, 0), 0); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, NOAGENTXERROR, 0, + NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_register_context(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_REGISTER, 4), __func__); + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, NON_DEFAULT_CONTEXT, + sessionid, 0, packetid); + message_add_nstring(&msg, "ctx", 3); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 4, 0), 0); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, + UNSUPPORTEDCONTEXT, 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_register_invalid_version(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_REGISTER, 5), __func__); + message_add_header(&msg, 0xFF, AGENTX_REGISTER_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 5, 0), 0); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_close_validate(__func__, repl, n, 0, REASONPROTOCOLERROR); + message_release(&msg); + close(s); +} + +void +agentx_register_instance_registration(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_REGISTER, 6), __func__); + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, INSTANCE_REGISTRATION, + sessionid, 0, packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 6, 0), 0); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, + NOAGENTXERROR, 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_register_new_index(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_REGISTER, 7), __func__); + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, NEW_INDEX, + sessionid, 0, packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 7, 0), 0); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, + PARSEERROR, 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_register_any_index(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_REGISTER, 8), __func__); + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, NEW_INDEX, + sessionid, 0, packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 8, 0), 0); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, + PARSEERROR, 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_register_duplicate_self(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_REGISTER, 9), __func__); + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 9, 0), 0); + agentx_write(s, &msg); + n = agentx_read(s, repl, sizeof(repl), 1000); + agentx_response_validate(__func__, repl, n, 0, packetid, + NOAGENTXERROR, 0, NULL, 0); + + packetid = arc4random(); + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 9, 0), 0); + agentx_write(s, &msg); + n = agentx_read(s, repl, sizeof(repl), 1000); + agentx_response_validate(__func__, repl, n, 0, packetid, + DUPLICATEREGISTRATION, 0, NULL, 0); + + message_release(&msg); + close(s); +} + +void +agentx_register_duplicate_twocon(void) +{ + int s1, s2; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid1, sessionid2; + uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0; + + s1 = agentx_connect(axsocket); + s2 = agentx_connect(axsocket); + sessionid1 = agentx_open(s1, 0, 0, + OID_ARG(MIB_SUBAGENT_REGISTER, 10, 1), + "agentx_register_duplicate_twocon.1"); + sessionid2 = agentx_open(s2, 0, 0, + OID_ARG(MIB_SUBAGENT_REGISTER, 10, 2), + "agentx_register_duplicate_twocon.2"); + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid1, 0, + packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 10, 0), 0); + agentx_write(s1, &msg); + n = agentx_read(s1, repl, sizeof(repl), 1000); + agentx_response_validate(__func__, repl, n, 0, packetid, + NOAGENTXERROR, 0, NULL, 0); + + packetid = arc4random(); + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid2, 0, + packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 10, 0), 0); + agentx_write(s2, &msg); + n = agentx_read(s2, repl, sizeof(repl), 1000); + agentx_response_validate(__func__, repl, n, 0, packetid, + DUPLICATEREGISTRATION, 0, NULL, 0); + + message_release(&msg); + close(s1); + close(s2); +} + +void +agentx_register_duplicate_priority(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_REGISTER, 11), __func__); + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 11, 0), 0); + agentx_write(s, &msg); + n = agentx_read(s, repl, sizeof(repl), 1000); + agentx_response_validate(__func__, repl, n, 0, packetid, + NOAGENTXERROR, 0, NULL, 0); + + packetid = arc4random(); + priority = 1; + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 11, 0), 0); + agentx_write(s, &msg); + n = agentx_read(s, repl, sizeof(repl), 1000); + agentx_response_validate(__func__, repl, n, 0, packetid, + NOAGENTXERROR, 0, NULL, 0); + + message_release(&msg); + close(s); +} + +void +agentx_register_range(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid, upperbound = 10; + uint8_t timeout = 0, priority = 127, range_subid = 11, reserved = 0; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_REGISTER, 12), __func__); + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 12, 1), 0); + message_add_uint32(&msg, upperbound); + agentx_write(s, &msg); + n = agentx_read(s, repl, sizeof(repl), 1000); + agentx_response_validate(__func__, repl, n, 0, packetid, + NOAGENTXERROR, 0, NULL, 0); + + message_release(&msg); + close(s); +} + +void +agentx_register_range_invalidupperbound(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid, upperbound = 1; + uint8_t timeout = 0, priority = 127, range_subid = 11, reserved = 0; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_REGISTER, 13), __func__); + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 13, 2), 0); + message_add_uint32(&msg, upperbound); + agentx_write(s, &msg); + n = agentx_read(s, repl, sizeof(repl), 1000); + agentx_response_validate(__func__, repl, n, 0, packetid, + PARSEERROR, 0, NULL, 0); + + message_release(&msg); + close(s); +} + +void +agentx_register_range_single(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid, upperbound = 1; + uint8_t timeout = 0, priority = 127, range_subid = 11, reserved = 0; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_REGISTER, 14), __func__); + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 14, 1), 0); + message_add_uint32(&msg, upperbound); + agentx_write(s, &msg); + n = agentx_read(s, repl, sizeof(repl), 1000); + agentx_response_validate(__func__, repl, n, 0, packetid, + NOAGENTXERROR, 0, NULL, 0); + + message_release(&msg); + close(s); +} + +void +agentx_register_range_overlap_single(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid, upperbound = 10; + uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_REGISTER, 15), __func__); + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 15, 1), 0); + agentx_write(s, &msg); + n = agentx_read(s, repl, sizeof(repl), 1000); + agentx_response_validate(__func__, repl, n, 0, packetid, + NOAGENTXERROR, 0, NULL, 0); + + packetid = arc4random(); + range_subid = 11; + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 15, 1), 0); + message_add_uint32(&msg, upperbound); + agentx_write(s, &msg); + n = agentx_read(s, repl, sizeof(repl), 1000); + agentx_response_validate(__func__, repl, n, 0, packetid, + DUPLICATEREGISTRATION, 0, NULL, 0); + + message_release(&msg); + close(s); +} + +void +agentx_register_single_overlap_range(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid, upperbound = 10; + uint8_t timeout = 0, priority = 127, range_subid = 11, reserved = 0; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_REGISTER, 16), __func__); + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 16, 1), 0); + message_add_uint32(&msg, upperbound); + agentx_write(s, &msg); + n = agentx_read(s, repl, sizeof(repl), 1000); + agentx_response_validate(__func__, repl, n, 0, packetid, + NOAGENTXERROR, 0, NULL, 0); + + packetid = arc4random(); + range_subid = 0; + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 16, 1), 0); + agentx_write(s, &msg); + n = agentx_read(s, repl, sizeof(repl), 1000); + agentx_response_validate(__func__, repl, n, 0, packetid, + DUPLICATEREGISTRATION, 0, NULL, 0); + + message_release(&msg); + close(s); +} + +void +agentx_register_range_overlap_range(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid, upperbound = 10; + uint8_t timeout = 0, priority = 127, range_subid = 11, reserved = 0; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_REGISTER, 17), __func__); + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 17, 1), 0); + message_add_uint32(&msg, upperbound); + agentx_write(s, &msg); + n = agentx_read(s, repl, sizeof(repl), 1000); + agentx_response_validate(__func__, repl, n, 0, packetid, + NOAGENTXERROR, 0, NULL, 0); + + packetid = arc4random(); + upperbound = 15; + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 17, 6), 0); + message_add_uint32(&msg, upperbound); + agentx_write(s, &msg); + n = agentx_read(s, repl, sizeof(repl), 1000); + agentx_response_validate(__func__, repl, n, 0, packetid, + DUPLICATEREGISTRATION, 0, NULL, 0); + + message_release(&msg); + close(s); +} + +void +agentx_register_below(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_REGISTER, 18), __func__); + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 18, 1), 0); + agentx_write(s, &msg); + n = agentx_read(s, repl, sizeof(repl), 1000); + agentx_response_validate(__func__, repl, n, 0, packetid, + NOAGENTXERROR, 0, NULL, 0); + + packetid = arc4random(); + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 18, 1, 0), 0); + agentx_write(s, &msg); + n = agentx_read(s, repl, sizeof(repl), 1000); + agentx_response_validate(__func__, repl, n, 0, packetid, + NOAGENTXERROR, 0, NULL, 0); + + message_release(&msg); + close(s); +} + +void +agentx_register_above(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_REGISTER, 19), __func__); + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 19, 1, 1), 0); + agentx_write(s, &msg); + n = agentx_read(s, repl, sizeof(repl), 1000); + agentx_response_validate(__func__, repl, n, 0, packetid, + NOAGENTXERROR, 0, NULL, 0); + + packetid = arc4random(); + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_REGISTER, 19, 1), 0); + agentx_write(s, &msg); + n = agentx_read(s, repl, sizeof(repl), 1000); + agentx_response_validate(__func__, repl, n, 0, packetid, + NOAGENTXERROR, 0, NULL, 0); + + message_release(&msg); + close(s); +} + +void +agentx_register_restricted(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + uint8_t timeout = 0, priority = 127, range_subid = 0, reserved = 0; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_REGISTER, 20), __func__); + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(SYSORTABLE, 1, 1), 0); + agentx_write(s, &msg); + n = agentx_read(s, repl, sizeof(repl), 1000); + agentx_response_validate(__func__, repl, n, 0, packetid, + REQUESTDENIED, 0, NULL, 0); + + message_release(&msg); + close(s); +} + +void +agentx_unregister_notopen(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint8_t priority = 127, range_subid = 0, reserved = 0; + + s = agentx_connect(axsocket); + message_add_header(&msg, 1, AGENTX_UNREGISTER_PDU, 0, 0, 0, packetid); + message_add(&msg, &reserved, sizeof(reserved)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_UNREGISTER, 1, 0), 0); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, NOTOPEN, 0, + NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_unregister_invalid_sessionid(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + uint8_t priority = 127, range_subid = 0, reserved = 0; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_UNREGISTER, 2), __func__); + message_add_header(&msg, 1, AGENTX_UNREGISTER_PDU, 0, sessionid + 1, 0, + packetid); + message_add(&msg, &reserved, sizeof(reserved)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_UNREGISTER, 2, 0), 0); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, NOTOPEN, 0, + NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_unregister_notregistered(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + uint8_t priority = 127, range_subid = 0, reserved = 0; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_UNREGISTER, 3), __func__); + message_add_header(&msg, 1, AGENTX_UNREGISTER_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &reserved, sizeof(reserved)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_UNREGISTER, 3), 0); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, + UNKNOWNREGISTRATION, 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_unregister_single(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + uint8_t priority = 127, range_subid = 0, reserved = 0; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_UNREGISTER, 4), __func__); + agentx_register(s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_UNREGISTER, 4), 0); + message_add_header(&msg, 1, AGENTX_UNREGISTER_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &reserved, sizeof(reserved)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_UNREGISTER, 4), 0); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, + NOAGENTXERROR, 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_unregister_single_notowned(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid1, sessionid2; + uint8_t priority = 127, range_subid = 0, reserved = 0; + + s = agentx_connect(axsocket); + sessionid1 = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_UNREGISTER, 5, 1), + "agentx_unregister_single_notowned.1"); + sessionid2 = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_UNREGISTER, 5, 2), + "agentx_unregister_single_notowned.2"); + agentx_register(s, sessionid1, 0, 0, 127, 0, + OID_ARG(MIB_UNREGISTER, 5, 1), 0); + message_add_header(&msg, 1, AGENTX_UNREGISTER_PDU, 0, sessionid2, 0, + packetid); + message_add(&msg, &reserved, sizeof(reserved)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_UNREGISTER, 5, 1), 0); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, + UNKNOWNREGISTRATION, 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_unregister_range(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + uint8_t priority = 127, range_subid = 11, reserved = 0; + uint32_t upperbound = 10; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_UNREGISTER, 6), __func__); + agentx_register(s, sessionid, 0, 0, 127, 11, + OID_ARG(MIB_UNREGISTER, 6, 1), 10); + message_add_header(&msg, 1, AGENTX_UNREGISTER_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &reserved, sizeof(reserved)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_UNREGISTER, 6, 1), 0); + message_add_uint32(&msg, upperbound); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, + NOAGENTXERROR, 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_unregister_range_single(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + uint8_t priority = 127, range_subid = 0, reserved = 0; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_UNREGISTER, 7), __func__); + agentx_register(s, sessionid, 0, 0, 127, 11, + OID_ARG(MIB_UNREGISTER, 6, 1), 10); + message_add_header(&msg, 1, AGENTX_UNREGISTER_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &reserved, sizeof(reserved)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_UNREGISTER, 7, 1), 0); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, + UNKNOWNREGISTRATION, 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_unregister_range_subset(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + uint8_t priority = 127, range_subid = 11, reserved = 0; + uint32_t upperbound = 5; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_UNREGISTER, 8), __func__); + agentx_register(s, sessionid, 0, 0, 127, 11, + OID_ARG(MIB_UNREGISTER, 8, 1), 10); + message_add_header(&msg, 1, AGENTX_UNREGISTER_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &reserved, sizeof(reserved)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_UNREGISTER, 8, 1), 0); + message_add_uint32(&msg, upperbound); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, + UNKNOWNREGISTRATION, 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_unregister_range_extra(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + uint8_t priority = 127, range_subid = 11, reserved = 0; + uint32_t upperbound = 10; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_UNREGISTER, 9), __func__); + agentx_register(s, sessionid, 0, 0, 127, 11, + OID_ARG(MIB_UNREGISTER, 9, 1), upperbound); + upperbound = 15; + message_add_header(&msg, 1, AGENTX_UNREGISTER_PDU, 0, sessionid, 0, + packetid); + message_add(&msg, &reserved, sizeof(reserved)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_UNREGISTER, 9, 1), 0); + message_add_uint32(&msg, upperbound); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, + UNKNOWNREGISTRATION, 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_unregister_range_priority(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid; + uint8_t priority = 127, range_subid = 11, reserved = 0; + uint32_t upperbound = 10; + + s = agentx_connect(axsocket); + sessionid = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_UNREGISTER, 10), __func__); + agentx_register(s, sessionid, 0, 0, priority, 11, + OID_ARG(MIB_UNREGISTER, 10, 1), upperbound); + message_add_header(&msg, 1, AGENTX_UNREGISTER_PDU, 0, sessionid, 0, + packetid); + priority = 128; + message_add(&msg, &reserved, sizeof(reserved)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_UNREGISTER, 10, 1), 0); + message_add_uint32(&msg, upperbound); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, + UNKNOWNREGISTRATION, 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_unregister_range_notowned(void) +{ + int s; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint32_t sessionid1, sessionid2; + uint8_t priority = 127, range_subid = 11, reserved = 0; + uint32_t upperbound = 10; + + s = agentx_connect(axsocket); + sessionid1 = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_UNREGISTER, 11, 1), + "agentx_unregister_range_notowned.1"); + sessionid2 = agentx_open(s, 0, 0, + OID_ARG(MIB_SUBAGENT_UNREGISTER, 11, 2), + "agentx_unregister_range_notowned.2"); + agentx_register(s, sessionid1, 0, 0, priority, 11, + OID_ARG(MIB_UNREGISTER, 11, 1), upperbound); + message_add_header(&msg, 1, AGENTX_UNREGISTER_PDU, 0, sessionid2, 0, + packetid); + priority = 128; + message_add(&msg, &reserved, sizeof(reserved)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, OID_ARG(MIB_UNREGISTER, 10, 1), 0); + message_add_uint32(&msg, upperbound); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, + UNKNOWNREGISTRATION, 0, NULL, 0); + message_release(&msg); + close(s); +} + +void +agentx_get_handle(const char *test, const void *buf, size_t len, + uint8_t flags, uint32_t sessionid, struct varbind *varbind, + size_t nvarbind) +{ + const struct header *header = buf; + struct oid start, end, zero = {0}; + const uint8_t *u8; + uint32_t u32; + uint16_t u16; + size_t sublen, i, j; + char oid1[512], oid2[512]; + struct varbind *pool; + + if (len < sizeof(*header)) + errx(1, "%s: unexpected pdu message size received: %zu", test, len); + if (header->version != 1) + errx(1, "%s: invalid pdu version", test); + if (header->type != AGENTX_GET_PDU) + errx(1, "%s: invalid pdu type received (%hhu/5)", test, header->type); + if (header->flags != flags) + errx(1, "%s: invalid get pdu flags received (%hhu/%hhu)", + test, header->flags, flags); + if (header->reserved != 0) + errx(1, "%s: invalid get pdu reserved received", test); + if (p32toh(header, header->sessionid) != sessionid) + errx(1, "%s: unexpected get pdu sessionid (%u/%u)", test, + p32toh(header, header->sessionid), sessionid); + if (p32toh(header, header->payload_length) > len - sizeof(*header)) + errx(1, "%s: unexpected get pdu payload length received", + test); + + buf += sizeof(*header); + len = p32toh(header, header->payload_length); + + if ((pool = calloc(nvarbind, sizeof(*pool))) == NULL) + err(1, NULL); + memcpy(pool, varbind, nvarbind * sizeof(*pool)); + + for (i = 0; len > 0; i++) { + sublen = poid(test, header, buf, len, &start); + buf += sublen; + len -= sublen; + sublen = poid(test, header, buf, len, &end); + buf += sublen; + len -= sublen; + + if (oid_cmp(&end, &zero) != 0) + errx(1, "%s: unexpected searchrange end: (%s/%s)", test, + oid_print(&end, oid1, sizeof(oid1)), + oid_print(&zero, oid2, sizeof(oid2))); + if (start.include != 0 || end.include != 0) + errx(1, "%s: unexpected searchrange include: (%s)", + test, oid_print(&start, oid1, sizeof(oid1))); + for (j = 0; j < nvarbind; j++) { + if (oid_cmp(&pool[j].name, &start) == 0) + break; + } + if (j == nvarbind) + warnx("%s: unexpected searchrange start: " "(%s)", test, + oid_print(&start, oid1, sizeof(oid1))); + + varbind[i] = pool[j]; + pool[j].name.n_subid = 0; + } + free(pool); +} + +void +agentx_getnext_handle(const char *test, const void *buf, size_t len, + uint8_t flags, uint32_t sessionid, struct searchrange *searchrange, + struct varbind *varbind, size_t nvarbind) +{ + const struct header *header = buf; + struct oid start, end, zero = {0}; + const uint8_t *u8; + uint32_t u32; + uint16_t u16; + size_t sublen, i, j, match; + char oid1[512], oid2[512], oid3[512], oid4[512]; + struct varbind *pool; + + if (len < sizeof(*header)) + errx(1, "%s: unexpected pdu message size received: %zu", test, len); + if (header->version != 1) + errx(1, "%s: invalid pdu version", test); + if (header->type != AGENTX_GETNEXT_PDU) + errx(1, "%s: invalid pdu type received (%hhu/6)", test, header->type); + if (header->flags != flags) + errx(1, "%s: invalid get pdu flags received (%hhu/%hhu)", + test, header->flags, flags); + if (header->reserved != 0) + errx(1, "%s: invalid get pdu reserved received", test); + if (p32toh(header, header->sessionid) != sessionid) + errx(1, "%s: unexpected get pdu sessionid (%u/%u)", test, + p32toh(header, header->sessionid), sessionid); + if (p32toh(header, header->payload_length) > len - sizeof(*header)) + errx(1, "%s: unexpected get pdu payload length received", + test); + + buf += sizeof(*header); + len = p32toh(header, header->payload_length); + + if ((pool = calloc(nvarbind, sizeof(*pool))) == NULL) + err(1, NULL); + memcpy(pool, varbind, nvarbind * sizeof(*pool)); + + for (i = 0; len > 0; i++) { + sublen = poid(test, header, buf, len, &start); + buf += sublen; + len -= sublen; + sublen = poid(test, header, buf, len, &end); + buf += sublen; + len -= sublen; + + if ((start.include != 1 && start.include != 0) || + end.include != 0) + errx(1, "%s: unexpected searchrange include: (%s-%s)", + test, oid_print(&start, oid1, sizeof(oid1)), + oid_print(&end, oid2, sizeof(oid2))); + + match = (size_t)-1; + for (j = 0; j < nvarbind; j++) { + if (oid_cmp(&pool[j].name, &start) == 0 && + pool[j].type == TYPE_ENDOFMIBVIEW) { + match = j; + } else if (oid_cmp(&pool[j].name, &start) < 0 || + (!start.include && + oid_cmp(&pool[j].name, &start) == 0) || + oid_cmp(&pool[j].name, &end) >= 0) + continue; + if (match == (size_t)-1) + match = j; + else { + if (oid_cmp(&pool[j].name, + &pool[match].name) < 0) + match = j; + } + } + if (match == (size_t)-1) + errx(1, "%s: unexpected searchrange start: " "(%s-%s)", + test, + oid_print(&start, oid1, sizeof(oid1)), + oid_print(&end, oid2, sizeof(oid2))); + if (searchrange != NULL) { + if (oid_cmp(&searchrange[match].start, &start) != 0 || + oid_cmp(&searchrange[match].end, &end) != 0 || + searchrange[match].end.include != end.include || + searchrange[match].start.include != start.include) + errx(1, "%s: searchrange did not match " + "(%s-%s/%s-%s)", test, + oid_print(&start, oid1, sizeof(oid1)), + oid_print(&end, oid2, sizeof(oid2)), + oid_print(&searchrange[match].start, oid3, + sizeof(oid3)), + oid_print(&searchrange[match].end, oid4, + sizeof(oid4))); + } + + varbind[i] = pool[match]; + pool[match].name.n_subid = 0; + } + free(pool); +} + +/* + * Don't assume a specific sequence of requests here so we can more easily + * migrate to getbulk in agentx. + */ +size_t +agentx_getbulk_handle(const char *test, const void *buf, size_t len, + uint8_t flags, int32_t sessionid, struct varbind *varbind, size_t nvarbind, + struct varbind *outvarbind) +{ + const struct header *header = buf; + struct oid start, end, zero = {0}; + const uint8_t *u8; + uint16_t nonrep, maxrep; + uint32_t u32; + uint16_t u16; + size_t sublen, i, j, match; + size_t nout = 0; + char oid1[512], oid2[512], oid3[512], oid4[512]; + + if (len < sizeof(*header)) + errx(1, "%s: unexpected pdu message size received: %zu", test, len); + if (header->version != 1) + errx(1, "%s: invalid pdu version", test); + if (header->type != AGENTX_GETNEXT_PDU && + header->type != AGENTX_GETBULK_PDU) + errx(1, "%s: invalid pdu type received (%hhu/[67])", + test, header->type); + if (header->flags != flags) + errx(1, "%s: invalid get pdu flags received (%hhu/%hhu)", + test, header->flags, flags); + if (header->reserved != 0) + errx(1, "%s: invalid get pdu reserved received", test); + if (p32toh(header, header->sessionid) != sessionid) + errx(1, "%s: unexpected get pdu sessionid (%u/%u)", test, + p32toh(header, header->sessionid), sessionid); + if (p32toh(header, header->payload_length) > len - sizeof(*header)) + errx(1, "%s: unexpected get pdu payload length received", + test); + + buf += sizeof(*header); + len = p32toh(header, header->payload_length); + + if (header->type == AGENTX_GETBULK_PDU) { + if (len < 4) + errx(1, "%s: missing non_repeaters/max_repititions", + __func__); + memcpy(&u16, buf, sizeof(u16)); + nonrep = p16toh(header, u16); + memcpy(&u16, buf + sizeof(u16), sizeof(u16)); + maxrep = p16toh(header, u16); + buf += 4; + } else { + nonrep = 0; + maxrep = 1; + } + for (i = 0; len > 0; i++) { + sublen = poid(test, header, buf, len, &start); + buf += sublen; + len -= sublen; + sublen = poid(test, header, buf, len, &end); + buf += sublen; + len -= sublen; + + if ((start.include != 1 && start.include != 0) || + end.include != 0) + errx(1, "%s: unexpected searchrange include: (%s-%s)", + test, oid_print(&start, oid1, sizeof(oid1)), + oid_print(&end, oid2, sizeof(oid2))); + + match = (size_t)-1; + for (j = 0; j < nvarbind; j++) { + if (oid_cmp(&varbind[j].name, &start) == 0 && + varbind[j].type == TYPE_ENDOFMIBVIEW) { + match = j; + } else if (oid_cmp(&varbind[j].name, &start) < 0 || + (!start.include && + oid_cmp(&varbind[j].name, &start) == 0) || + oid_cmp(&varbind[j].name, &end) >= 0) + continue; + if (match == (size_t)-1) + match = j; + else { + if (oid_cmp(&varbind[j].name, + &varbind[match].name) < 0) + match = j; + } + } + if (match == (size_t)-1) + errx(1, "%s: unexpected searchrange start: " "(%s-%s)", + test, + oid_print(&start, oid1, sizeof(oid1)), + oid_print(&end, oid2, sizeof(oid2))); + outvarbind[nout++] = varbind[match]; + varbind[match] = varbind[--nvarbind]; + varbind[nvarbind] = (struct varbind){}; + } + return nout; +} + +void +agentx_close_validate(const char *test, const void *buf, size_t len, + uint8_t flags, uint8_t reason) +{ + const struct header *header = buf; + const uint8_t *u8; + uint32_t u32; + uint16_t u16; + + if (len != sizeof(*header) + 4) + errx(1, "%s: unexpected pdu message size received: %zu", test, len); + if (header->version != 1) + errx(1, "%s: invalid pdu version", test); + if (header->type != AGENTX_CLOSE_PDU) + errx(1, "%s: invalid pdu type received (%hhu/2)", test, header->type); + if (header->flags != flags) + errx(1, "%s: invalid close pdu flags received (%hhu/%hhu)", + test, header->flags, flags); + if (header->reserved != 0) + errx(1, "%s: invalid close pdu reserved received", test); + if (p32toh(header, header->payload_length) != 4) + errx(1, "%s: unexpected response pdu payload length received", + test); + + u8 = buf + sizeof(*header); + if (u8[0] != reason) + errx(1, "%s: unexpected close reason (%hhu/%hhu)", + test, u8[0], reason); + if (u8[1] != 0 || u8[2] != 0 || u8[3] != 0) + errx(1, "%s: invalid close pdu reserved received", test); +} + +void +agentx_response_validate(const char *test, const void *buf, size_t len, + uint8_t flags, uint32_t packetid, enum error error, uint16_t index, + struct varbind *varbindlist, size_t nvarbind) +{ + const struct header *header = buf; + struct oid name, oid; + int32_t i32; + uint32_t u32; + uint16_t u16, type; + size_t i, sublen; + + if (len < sizeof(*header) + 8) + errx(1, "%s: unexpected pdu message size received: %zu", test, len); + if (header->version != 1) + errx(1, "%s: invalid pdu version", test); + if (header->type != AGENTX_RESPONSE_PDU) + errx(1, "%s: invalid pdu type received (%hhu/18)", test, header->type); + if (header->flags != flags) + errx(1, "%s: invalid response pdu flags received (%hhu/%hhu)", + test, header->flags, flags); + if (header->reserved != 0) + errx(1, "%s: invalid response pdu reserved received", test); + if (p32toh(header, header->packetid) != packetid) + errx(1, "%s: invalid response pdu packetid received", test); + /* + * Needs to be changed once we start validating responses with varbinds. + */ + if (p32toh(header, header->payload_length) < 8 || + p32toh(header, header->payload_length) > len - sizeof(*header)) + errx(1, "%s: unexpected response pdu payload length received", + test); + + buf += sizeof(*header); + len = p32toh(header, header->payload_length); + memcpy(&u32, buf, sizeof(u32)); + if ((p32toh(header, u32) & 0xF0000000) != 0) + errx(1, "%s: unexpected response pdu sysUptime received", + test); + buf += sizeof(u32); + memcpy(&u16, buf, sizeof(u16)); + if (p16toh(header, u16) != error) + errx(1, "%s: unexpected response pdu error (%hu/%u)", + test, p16toh(header, u16), error); + buf += sizeof(u16); + memcpy(&u16, buf, sizeof(u16)); + if (p16toh(header, u16) != index) + errx(1, "%s: unexpected response pdu index (%hu/%hu)", + test, p16toh(header, u16), index); + buf += sizeof(u16); + len -= 8; + + for (i = 0; len > 0; i++) { + if (len < 4) + errx(1, + "%s: invalid response pdu varbind length", test); + memcpy(&type, buf, sizeof(type)); + type = p16toh(header, type); + if (i < nvarbind && type != varbindlist[i].type % 1000) + errx(1, "%s: invalid response pdu varbind type", test); + buf += sizeof(type); + len -= sizeof(type); + memcpy(&u16, buf, sizeof(u16)); + if (u16 != 0) + errx(1, "%s: invalid response pdu varbind reserved", + test); + buf += sizeof(u16); + len -= sizeof(u16); + sublen = poid(test, header, buf, len, &name); + if (i < nvarbind && oid_cmp(&varbindlist[i].name, &name) != 0) + errx(1, "%s: invalid response pdu varbind name", test); + buf += sublen; + len -= sublen; + switch (type % 1000) { + case TYPE_INTEGER: + if (len < sizeof(i32)) + errx(1, + "%s: invalid response pdu varbind length", + test); + if (i < nvarbind && varbindlist[i].type / 1000 == 0) { + memcpy(&i32, buf, sizeof(i32)); + i32 = p32toh(header, i32); + if (i32 != varbindlist[i].data.int32) + errx(1, "%s: invalid response pdu " + "varbind integer", test); + } + break; + default: + errx(1, "%s: Regress test not implemented: %d", test, type); + } + } + + if (i != nvarbind) + errx(1, "%s: unexpected response pdu nvarbind: (%zu/%zu)", + test, i, nvarbind); +} + +int +agentx_connect(const char *path) +{ + struct sockaddr_un sun; + int s; + + if (path == NULL) + path = AGENTX_SOCKET; + + sun.sun_len = sizeof(sun); + sun.sun_family = AF_UNIX; + strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); + + if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + err(1, "%s: socket", __func__); + if (connect(s, (struct sockaddr *)&sun, sizeof(sun)) == -1) + err(1, "%s: connect", __func__); + + return s; +} + +uint32_t +agentx_open(int s, int nbo, uint8_t timeout, uint32_t oid[], size_t oidlen, + const char *descr) +{ + struct message msg ={}; + char zero[3] = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + struct header *header = (struct header *)repl; + + message_add_header(&msg, 1, AGENTX_OPEN_PDU, + nbo ? NETWORK_BYTE_ORDER : 0, 0, 0, packetid); + message_add_uint8(&msg, timeout); + message_add(&msg, zero, 3); + message_add_oid(&msg, oid, oidlen, 0); + message_add_nstring(&msg, descr, strlen(descr)); + + agentx_write(s, &msg); + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, + nbo ? NETWORK_BYTE_ORDER : 0, packetid, 0, 0, NULL, 0); + + message_release(&msg); + + return p32toh(header, header->sessionid); +} + +void +agentx_close(int s, uint32_t sessionid, enum close_reason reason) +{ + struct message msg ={}; + char zero[3] = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + struct header *header = (struct header *)repl; + + message_add_header(&msg, 1, AGENTX_CLOSE_PDU, 0, sessionid, 0, + packetid); + message_add_uint8(&msg, reason); + message_add(&msg, zero, 3); + + agentx_write(s, &msg); + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, 0, 0, NULL, 0); + + message_release(&msg); +} + +void +agentx_register(int s, uint32_t sessionid, uint8_t instance, uint8_t timeout, + uint8_t priority, uint8_t range_subid, uint32_t oid[], size_t oidlen, + uint32_t upperbound) +{ + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t packetid = arc4random(); + uint8_t reserved = 0; + + message_add_header(&msg, 1, AGENTX_REGISTER_PDU, + instance ? INSTANCE_REGISTRATION : 0, sessionid, 0, packetid); + message_add(&msg, &timeout, sizeof(timeout)); + message_add(&msg, &priority, sizeof(priority)); + message_add(&msg, &range_subid, sizeof(range_subid)); + message_add(&msg, &reserved, sizeof(reserved)); + message_add_oid(&msg, oid, oidlen, 0); + if (range_subid != 0) + message_add_uint32(&msg, upperbound); + + agentx_write(s, &msg); + + n = agentx_read(s, repl, sizeof(repl), 1000); + + agentx_response_validate(__func__, repl, n, 0, packetid, NOAGENTXERROR, 0, + NULL, 0); + message_release(&msg); +} + +void +agentx_response(int s, void *buf, enum error error, uint16_t index, + struct varbind *varbindlist, size_t nvarbind) +{ + struct header *header = buf; + struct message msg = {}; + char repl[1024]; + size_t n; + uint32_t sysuptime = 0; + uint16_t reserved = 0; + size_t i; + + message_add_header(&msg, 1, AGENTX_RESPONSE_PDU, 0, + p32toh(header, header->sessionid), + p32toh(header, header->transactionid), + p32toh(header, header->packetid)); + message_add_uint32(&msg, sysuptime); + message_add_uint16(&msg, error); + message_add_uint16(&msg, index); + + for (i = 0; i < nvarbind; i++) + message_add_varbind(&msg, varbindlist + i); + + agentx_write(s, &msg); + message_release(&msg); +} + +static void +message_add_uint8(struct message *msg, uint8_t n) +{ + message_add(msg, &n, 1); +} + +static void +message_add_uint16(struct message *msg, uint16_t n) +{ + if (MESSAGE_NBO(msg)) + n = htobe16(n); + else + n = htole16(n); + + message_add(msg, &n, sizeof(n)); +} + +static void +message_add_uint32(struct message *msg, uint32_t n) +{ + if (MESSAGE_NBO(msg)) + n = htobe32(n); + else + n = htole32(n); + + message_add(msg, &n, sizeof(n)); +} + +static void +message_add_uint64(struct message *msg, uint64_t n) +{ + if (MESSAGE_NBO(msg)) + n = htobe64(n); + else + n = htole64(n); + + message_add(msg, &n, sizeof(n)); +} + +static void +message_add_nstring(struct message *msg, const void *src, uint32_t len) +{ + char zero[3] = {}; + + message_add_uint32(msg, len); + if (len == 0) + return; + message_add(msg, src, len); + message_add(msg, zero, (4 - (len % 4)) % 4); +} + +static void +message_add_oid(struct message *msg, const uint32_t oid[], uint8_t n_subid, + uint8_t include) +{ + uint8_t prefix = 0; + uint8_t i; + + if (n_subid > 5 && oid[0] == 1 && oid[1] == 3 && oid[2] == 6 && + oid[3] == 1 && oid[4] < UINT8_MAX) { + prefix = oid[4]; + oid += 5; + n_subid -= 5; + } + + message_add_uint8(msg, n_subid); + message_add_uint8(msg, prefix); + message_add_uint8(msg, include); + message_add_uint8(msg, 0); + for (i = 0; i < n_subid; i++) + message_add_uint32(msg, oid[i]); +} + +static void +message_add_varbind(struct message *msg, struct varbind *varbind) +{ + uint64_t u64; + uint32_t u32; + size_t len; + va_list ap; + + message_add_uint16(msg, varbind->type); + message_add_uint16(msg, 0); + message_add_oid(msg, varbind->name.subid, varbind->name.n_subid, 0); + switch (varbind->type) { + case INTEGER: + message_add_uint32(msg, varbind->data.int32); + break; + case COUNTER32: + case GAUGE32: + case TIMETICKS: + message_add_uint32(msg, varbind->data.uint32); + break; + case OCTETSTRING: + case IPADDRESS: + case OPAQUE: + message_add_nstring(msg, varbind->data.octetstring.string, + varbind->data.octetstring.len); + break; + case OBJECTIDENTIFIER: + message_add_oid(msg, varbind->data.oid.subid, + varbind->data.oid.n_subid, 0); + break; + case COUNTER64: + message_add_uint64(msg, varbind->data.uint64); + break; + case AXNULL: + case NOSUCHOBJECT: + case NOSUCHINSTANCE: + case ENDOFMIBVIEW: + break; + default: + errx(1, "%s: unsupported data type: %d", __func__, + varbind->type); + } +} + +static void +message_add_header(struct message *msg, uint8_t version, uint8_t type, + uint8_t flags, uint32_t sessionid, uint32_t transactionid, + uint32_t packetid) +{ + if (msg->len != 0) + errx(1, "%s: message not new", __func__); + message_add_uint8(msg, version); + message_add_uint8(msg, type); + message_add_uint8(msg, flags); + message_add_uint8(msg, 0); + message_add_uint32(msg, sessionid); + message_add_uint32(msg, transactionid); + message_add_uint32(msg, packetid); + message_add_uint32(msg, 0); /* payload_length tbt */ +} + +static void +message_add(struct message *msg, const void *src, size_t len) +{ + if (len == 0) + return; + if (msg->len + len > msg->size) { + if ((msg->buf = recallocarray(msg->buf, msg->size, + (((msg->len + len) % 4096) + 1) * 4096, 1)) == NULL) + err(1, NULL); + msg->size = (((msg->len + len) % 4096) + 1) * 4096; + } + memcpy(msg->buf + msg->len, src, len); + msg->len += len; +} + +static void +message_release(struct message *msg) +{ + free(msg->buf); +} + +static size_t +poid(const char *test, const struct header *header, const uint8_t *buf, size_t len, + struct oid *oid) +{ + uint8_t n_subid, i; + uint32_t subid; + + if (len < 4) + errx(1, "%s: incomplete oid", test); + n_subid = buf[0]; + if (buf[1] != 0) { + *oid = OID_STRUCT(1, 3, 6, 1, buf[1]); + } else + *oid = OID_STRUCT(); + oid->include = buf[2]; + if (buf[3] != 0) + errx(1, "%s: invalid oid reserved (%hhx)", test, buf[3]); + buf += 4; + len -= 4; + if (oid->n_subid + n_subid > 128) + errx(1, "%s: too many n_subid in oid", test); + if (len < n_subid * sizeof(oid->subid[0])) + errx(1, "%s: incomplete oid: (%zu/%zu)", test, + n_subid * sizeof(oid->subid[0]), len); + for (i = 0; i < n_subid; i++) { + memcpy(&subid, buf, sizeof(subid)); + buf += 4; + oid->subid[oid->n_subid++] = p32toh(header, subid); + } + + return 4 * (n_subid + 1); +} + +size_t +agentx_read(int s, void *buf, size_t len, int timeout) +{ + ssize_t n; + size_t i; + int ret; + struct pollfd pfd = { + .fd = s, + .events = POLLIN + }; + + if ((ret = poll(&pfd, 1, timeout)) == -1) + err(1, "poll"); + if (ret == 0) + errx(1, "%s: timeout", __func__); + if ((n = read(s, buf, len)) == -1) + err(1, "agentx read"); + + if (verbose && n != 0) { + printf("AgentX received(%d):\n", s); + for (i = 0; i < n; i++) { + printf("%s%02hhx", i % 4 == 0 ? "" : " ", + ((char *)buf)[i]); + if (i % 4 == 3) + printf("\n"); + } + if (i % 4 != 0) + printf("\n"); + } + return n; +} + +void +agentx_timeout(int s, int timeout) +{ + int ret; + struct pollfd pfd = { + .fd = s, + .events = POLLIN + }; + + if ((ret = poll(&pfd, 1, timeout)) == -1) + err(1, "poll"); + if (ret != 0) + errx(1, "%s: unexpected agentx data", __func__); +} + +void +agentx_write(int s, struct message *msg) +{ + ssize_t n; + char *buf = msg->buf; + size_t len = msg->len; + struct header *header = msg->buf; + size_t i; + + msg->len = 16; + message_add_uint32(msg, len - sizeof(*header)); + + if (verbose) { + printf("AgentX sending(%d):\n", s); + for (i = 0; i < len; i++) { + printf("%s%02hhx", i % 4 == 0 ? "" : " ", buf[i]); + if (i % 4 == 3) + printf("\n"); + } + if (i % 4 != 0) + printf("\n"); + } + + while (len > 0) { + if ((n = write(s, buf, len)) == -1) + err(1, "agentx write"); + buf += n; + len -= n; + } + msg->len = 0; +} diff --git a/regress/usr.sbin/snmpd/backend.c b/regress/usr.sbin/snmpd/backend.c new file mode 100644 index 00000000000..52f19e49b01 --- /dev/null +++ b/regress/usr.sbin/snmpd/backend.c @@ -0,0 +1,5152 @@ +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "regress.h" + +#define MIB_BACKEND_GET MIB_BACKEND, 1 +#define MIB_BACKEND_GETNEXT MIB_BACKEND, 2 +#define MIB_BACKEND_GETBULK MIB_BACKEND, 3 +#define MIB_BACKEND_ERROR MIB_BACKEND, 4 + +#define MIB_SUBAGENT_BACKEND_GET MIB_SUBAGENT_BACKEND, 1 +#define MIB_SUBAGENT_BACKEND_GETNEXT MIB_SUBAGENT_BACKEND, 2 +#define MIB_SUBAGENT_BACKEND_GETBULK MIB_SUBAGENT_BACKEND, 3 +#define MIB_SUBAGENT_BACKEND_ERROR MIB_SUBAGENT_BACKEND, 4 + +#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) + +void +backend_get_integer(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 1, 0), + .data.int32 = 1 + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 1), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 1), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + varbind.type = TYPE_INTEGER; + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_get_octetstring(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 2, 0), + .data.octetstring.string = "test", + .data.octetstring.len = 4 + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 2), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 2), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + varbind.type = TYPE_OCTETSTRING; + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_get_objectidentifier(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 3, 0), + .data.oid = OID_STRUCT(MIB_BACKEND_GET, 3, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 3), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 3), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + varbind.type = TYPE_OBJECTIDENTIFIER; + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_get_ipaddress(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 4, 0), + .data.octetstring.string = "\0\0\0\0", + .data.octetstring.len = 4 + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 4), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 4), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + varbind.type = TYPE_IPADDRESS; + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_get_counter32(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 5, 0), + .data.uint32 = 1 + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 5), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 5), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + varbind.type = TYPE_COUNTER32; + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_get_gauge32(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 6, 0), + .data.uint32 = 1 + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 6), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 6), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + varbind.type = TYPE_GAUGE32; + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_get_timeticks(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 7, 0), + .data.uint32 = 1 + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 7), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 7), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + varbind.type = TYPE_TIMETICKS; + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_get_opaque(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 8, 0), + .data.octetstring.string = "\1", + .data.octetstring.len = 1 + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 8), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 8), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + varbind.type = TYPE_OPAQUE; + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_get_counter64(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 9, 0), + .data.uint64 = 1 + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 9), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 9), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + varbind.type = TYPE_COUNTER64; + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_get_nosuchobject(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 10, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 10), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 10), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + varbind.type = TYPE_NOSUCHOBJECT; + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_get_nosuchinstance(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 11, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 11), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 11), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + varbind.type = TYPE_NOSUCHINSTANCE; + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_get_endofmibview(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 12, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 12), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 12), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + varbind.type = TYPE_ENDOFMIBVIEW; + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + varbind.type = TYPE_NULL; + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_get_two_single_backend(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind[] = { + { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 13, 1), + .data.int32 = 1 + }, + { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 13, 2), + .data.int32 = 2 + } + }; + struct varbind varbind_ax[] = { + { + .type = TYPE_INTEGER, + .name = OID_STRUCT(MIB_BACKEND_GET, 13, 1), + .data.int32 = 1 + }, + { + .type = TYPE_INTEGER, + .name = OID_STRUCT(MIB_BACKEND_GET, 13, 2), + .data.int32 = 2 + } + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 13), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 13), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, varbind, 2); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, varbind_ax, 2); + + agentx_response(ax_s, buf, NOERROR, 0, varbind_ax, 2); + + varbind[0].type = varbind[1].type = TYPE_INTEGER; + snmpv2_response_validate(snmp_s, 1000, community, requestid, NOERROR, 0, + varbind, 2); +} + +void +backend_get_two_double_backend(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s1, ax_s2; + uint32_t sessionid1, sessionid2; + struct varbind varbind[] = { + { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 14, 1), + .data.int32 = 1 + }, + { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 14, 2), + .data.int32 = 2 + } + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s1 = agentx_connect(axsocket); + ax_s2 = agentx_connect(axsocket); + sessionid1 = agentx_open(ax_s1, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 14, 1), + "backend_get_two_double_backend.1"); + sessionid2 = agentx_open(ax_s2, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 14, 2), + "backend_get_two_double_backend.2"); + agentx_register(ax_s1, sessionid1, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 14, 1), 0); + agentx_register(ax_s2, sessionid2, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 14, 2), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, varbind, 2); + + varbind[0].type = varbind[1].type = TYPE_INTEGER; + n = agentx_read(ax_s1, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid1, varbind, 1); + agentx_response(ax_s1, buf, NOERROR, 0, varbind, 1); + + n = agentx_read(ax_s2, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid2, varbind + 1, 1); + agentx_response(ax_s2, buf, NOERROR, 0, varbind + 1, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, NOERROR, 0, + varbind, 2); +} + +void +backend_get_wrongorder(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind[] = { + { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 15, 1), + }, + { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 15, 2), + } + }; + struct varbind varbind_ax[] = { + { + .type = TYPE_INTEGER, + .name = OID_STRUCT(MIB_BACKEND_GET, 15, 1), + .data.int32 = 1 + }, + { + .type = TYPE_INTEGER, + .name = OID_STRUCT(MIB_BACKEND_GET, 15, 2), + .data.int32 = 2 + } + }, tmpvarbind; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 15), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 15), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, varbind, 2); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, varbind_ax, 2); + tmpvarbind = varbind_ax[0]; + varbind_ax[0] = varbind_ax[1]; + varbind_ax[1] = tmpvarbind; + + agentx_response(ax_s, buf, NOERROR, 0, varbind_ax, 2); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 2, + varbind, 2); +} + +void +backend_get_toofew(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind[] = { + { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 16, 1), + }, + { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 16, 2), + } + }; + struct varbind varbind_ax[] = { + { + .type = TYPE_INTEGER, + .name = OID_STRUCT(MIB_BACKEND_GET, 16, 1), + .data.int32 = 1 + }, + { + .type = TYPE_INTEGER, + .name = OID_STRUCT(MIB_BACKEND_GET, 16, 2), + .data.int32 = 2 + } + }, tmpvarbind; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 16), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 16), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, varbind, 2); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, varbind_ax, 2); + + agentx_response(ax_s, buf, NOERROR, 0, varbind_ax, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 2, + varbind, 2); +} + +void +backend_get_toomany(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind[] = { + { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 17, 1), + }, + { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 17, 2), + } + }; + struct varbind varbind_ax[] = { + { + .type = TYPE_INTEGER, + .name = OID_STRUCT(MIB_BACKEND_GET, 17, 1), + .data.int32 = 1 + }, + { + .type = TYPE_INTEGER, + .name = OID_STRUCT(MIB_BACKEND_GET, 17, 2), + .data.int32 = 2 + }, + { + .type = TYPE_INTEGER, + .name = OID_STRUCT(MIB_BACKEND_GET, 17, 3), + .data.int32 = 3 + } + }, tmpvarbind; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 17), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 17), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, varbind, 2); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, varbind_ax, 2); + + agentx_response(ax_s, buf, NOERROR, 0, varbind_ax, 3); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 2, + varbind, 2); +} + +void +backend_get_instance(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 18, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 18), __func__); + agentx_register(ax_s, sessionid, 1, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 18, 0), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + varbind.type = TYPE_INTEGER; + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_get_instance_below(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 19, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 19), __func__); + agentx_register(ax_s, sessionid, 1, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 19), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + varbind.type = TYPE_NOSUCHINSTANCE; + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_get_timeout_default(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 20, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + struct timespec start, end, diff; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 20), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 20), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + if (clock_gettime(CLOCK_MONOTONIC, &start) == -1) + err(1, "clock_gettime"); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 6000, community, requestid, GENERR, 1, + &varbind, 1); + if (clock_gettime(CLOCK_MONOTONIC, &end) == -1) + err(1, "clock_gettime"); + timespecsub(&end, &start, &diff); + if (diff.tv_sec != 5) + errx(1, "%s: unexpected timeout (%lld.%09ld/5)", __func__, + diff.tv_sec, diff.tv_nsec); +} + +void +backend_get_timeout_session_lower(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 21, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + struct timespec start, end, diff; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 1, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 21), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 21), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + if (clock_gettime(CLOCK_MONOTONIC, &start) == -1) + err(1, "clock_gettime"); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 6000, community, requestid, GENERR, 1, + &varbind, 1); + if (clock_gettime(CLOCK_MONOTONIC, &end) == -1) + err(1, "clock_gettime"); + timespecsub(&end, &start, &diff); + if (diff.tv_sec != 1) + errx(1, "%s: unexpected timeout (%lld.%09ld/1)", __func__, + diff.tv_sec, diff.tv_nsec); +} + +void +backend_get_timeout_session_higher(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 22, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + struct timespec start, end, diff; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 6, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 22), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 22), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + if (clock_gettime(CLOCK_MONOTONIC, &start) == -1) + err(1, "clock_gettime"); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 7000, community, requestid, GENERR, 1, + &varbind, 1); + if (clock_gettime(CLOCK_MONOTONIC, &end) == -1) + err(1, "clock_gettime"); + timespecsub(&end, &start, &diff); + if (diff.tv_sec != 6) + errx(1, "%s: unexpected timeout (%lld.%09ld/6)", __func__, + diff.tv_sec, diff.tv_nsec); +} + +void +backend_get_timeout_region_lower(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 23, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + struct timespec start, end, diff; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 4, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 23), __func__); + agentx_register(ax_s, sessionid, 0, 1, 127, 0, + OID_ARG(MIB_BACKEND_GET, 23), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + if (clock_gettime(CLOCK_MONOTONIC, &start) == -1) + err(1, "clock_gettime"); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 6000, community, requestid, GENERR, 1, + &varbind, 1); + if (clock_gettime(CLOCK_MONOTONIC, &end) == -1) + err(1, "clock_gettime"); + timespecsub(&end, &start, &diff); + if (diff.tv_sec != 1) + errx(1, "%s: unexpected timeout (%lld.%09ld/1)", __func__, + diff.tv_sec, diff.tv_nsec); +} + +void +backend_get_timeout_region_higher(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 24, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + struct timespec start, end, diff; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 7, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 24), __func__); + agentx_register(ax_s, sessionid, 0, 6, 127, 0, + OID_ARG(MIB_BACKEND_GET, 24), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + if (clock_gettime(CLOCK_MONOTONIC, &start) == -1) + err(1, "clock_gettime"); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 8000, community, requestid, GENERR, 1, + &varbind, 1); + if (clock_gettime(CLOCK_MONOTONIC, &end) == -1) + err(1, "clock_gettime"); + timespecsub(&end, &start, &diff); + if (diff.tv_sec != 6) + errx(1, "%s: unexpected timeout (%lld.%09ld/6)", __func__, + diff.tv_sec, diff.tv_nsec); +} + +void +backend_get_priority_lower(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid1, sessionid2; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 25, 0), + .data.int32 = 1 + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid1 = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 25, 1), "backend_get_priority.1"); + sessionid2 = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 25, 2), "backend_get_priority.2"); + agentx_register(ax_s, sessionid1, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 25), 0); + agentx_register(ax_s, sessionid2, 0, 0, 126, 0, + OID_ARG(MIB_BACKEND_GET, 25), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid2, &varbind, 1); + + varbind.type = TYPE_INTEGER; + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_get_priority_higher(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid1, sessionid2; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 26, 0), + .data.int32 = 1 + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid1 = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 26, 1), + "backend_get_priority_higher.1"); + sessionid2 = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 26, 2), + "backend_get_priority_higher.2"); + agentx_register(ax_s, sessionid1, 0, 0, 126, 0, + OID_ARG(MIB_BACKEND_GET, 26), 0); + agentx_register(ax_s, sessionid2, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 26), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid1, &varbind, 1); + + varbind.type = TYPE_INTEGER; + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_get_priority_below_lower(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid1, sessionid2; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 27, 0), + .data.int32 = 1 + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid1 = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 27, 1), + "backend_get_priority_below_lower.1"); + sessionid2 = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 27, 2), + "backend_get_priority_below_lower.2"); + agentx_register(ax_s, sessionid1, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 27), 0); + agentx_register(ax_s, sessionid2, 0, 0, 126, 0, + OID_ARG(MIB_BACKEND_GET, 27, 0), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid2, &varbind, 1); + + varbind.type = TYPE_INTEGER; + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_get_priority_below_higher(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid1, sessionid2; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 28, 0), + .data.int32 = 1 + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid1 = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 28, 1), + "backend_get_priority_below_higher.1"); + sessionid2 = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 28, 2), + "backend_get_priority_below_higher.2"); + agentx_register(ax_s, sessionid1, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 28), 0); + agentx_register(ax_s, sessionid2, 0, 0, 128, 0, + OID_ARG(MIB_BACKEND_GET, 28, 0), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid2, &varbind, 1); + + varbind.type = TYPE_INTEGER; + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_get_close(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 29, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 29), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 29), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_close(ax_s, sessionid, REASONOTHER); + + varbind.type = TYPE_NOSUCHOBJECT; + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_get_close_overlap(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s1, ax_s2; + uint32_t sessionid1, sessionid2; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 30, 0), + .data.int32 = 1 + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s1 = agentx_connect(axsocket); + ax_s2 = agentx_connect(axsocket); + sessionid1 = agentx_open(ax_s1, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 30, 1), + "backend_get_close_overlap.1"); + sessionid2 = agentx_open(ax_s2, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 30, 1), + "backend_get_close_overlap.2"); + agentx_register(ax_s1, sessionid1, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 30), 0); + agentx_register(ax_s2, sessionid2, 0, 0, 128, 0, + OID_ARG(MIB_BACKEND_GET, 30), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s1, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid1, &varbind, 1); + agentx_close(ax_s1, sessionid1, REASONOTHER); + + varbind.type = TYPE_INTEGER; + n = agentx_read(ax_s2, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid2, &varbind, 1); + agentx_response(ax_s2, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_get_disappear(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 31, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 31), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 31), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + close(ax_s); + + varbind.type = TYPE_NOSUCHOBJECT; + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_get_disappear_overlap(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s1, ax_s2; + uint32_t sessionid1, sessionid2; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 32, 0), + .data.int32 = 1 + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s1 = agentx_connect(axsocket); + ax_s2 = agentx_connect(axsocket); + sessionid1 = agentx_open(ax_s1, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 32, 1), + "backend_get_close_overlap.1"); + sessionid2 = agentx_open(ax_s2, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 32, 1), + "backend_get_close_overlap.2"); + agentx_register(ax_s1, sessionid1, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 32), 0); + agentx_register(ax_s2, sessionid2, 0, 0, 128, 0, + OID_ARG(MIB_BACKEND_GET, 32), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s1, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid1, &varbind, 1); + close(ax_s1); + + varbind.type = TYPE_INTEGER; + n = agentx_read(ax_s2, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid2, &varbind, 1); + agentx_response(ax_s2, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_get_disappear_doublesession(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid1, sessionid2; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GET, 33, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid1 = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 33, 1), + "backend_get_disappear_doublesession.1"); + sessionid2 = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GET, 33, 2), + "backend_get_disappear_doublesession.2"); + agentx_register(ax_s, sessionid1, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GET, 33), 0); + agentx_register(ax_s, sessionid2, 0, 0, 128, 0, + OID_ARG(MIB_BACKEND_GET, 33), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid1, &varbind, 1); + close(ax_s); + + varbind.type = TYPE_NOSUCHOBJECT; + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_getnext_selfbound(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 1), + .data.int32 = 1 + }; + struct searchrange searchrange = { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 1), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 2) + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 1), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 1), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + varbind.type = TYPE_INTEGER; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, &searchrange, + &varbind, 1); + + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_getnext_lowerbound(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid1, sessionid2; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 2), + .data.int32 = 1 + }; + struct searchrange searchrange = { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 2), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 2, 1) + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid1 = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 2, 1), + "backend_getnext_lowerbound.1"); + sessionid2 = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 2, 2), + "backend_getnext_lowerbound.2"); + agentx_register(ax_s, sessionid1, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 2), 0); + agentx_register(ax_s, sessionid2, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 2, 1), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + varbind.type = TYPE_INTEGER; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid1, &searchrange, + &varbind, 1); + + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_getnext_lowerbound_self(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 3), + .data.int32 = 1 + }; + struct searchrange searchrange = { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 3), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 4) + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 3), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 3), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + varbind.type = TYPE_INTEGER; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, &searchrange, + &varbind, 1); + + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_getnext_lowerbound_highprio(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid1, sessionid2; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 4), + .data.int32 = 1 + }; + struct searchrange searchrange = { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 4), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 4, 1) + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid1 = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 4, 1), + "backend_getnext_lowerbound_highprio.1"); + sessionid2 = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 4, 2), + "backend_getnext_lowerbound_highprio.2"); + agentx_register(ax_s, sessionid1, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 4), 0); + agentx_register(ax_s, sessionid2, 0, 0, 128, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 4, 1), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + varbind.type = TYPE_INTEGER; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid1, &searchrange, + &varbind, 1); + + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_getnext_lowerbound_lowprio(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid1, sessionid2; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 5), + .data.int32 = 1 + }; + struct searchrange searchrange = { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 5), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 5, 1) + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid1 = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 5, 1), + "backend_getnext_lowerbound_lowprio.1"); + sessionid2 = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 5, 2), + "backend_getnext_lowerbound_lowprio.2"); + agentx_register(ax_s, sessionid1, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 5), 0); + agentx_register(ax_s, sessionid2, 0, 0, 128, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 5, 1), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + varbind.type = TYPE_INTEGER; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid1, &searchrange, + &varbind, 1); + + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_getnext_sibling(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 6), + .data.int32 = 1 + }; + struct searchrange searchrange = { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 6), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 8) + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 6), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 6), 0); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 7), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + varbind.type = TYPE_INTEGER; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, &searchrange, + &varbind, 1); + + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_getnext_child_gap(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid1, sessionid2; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 7), + .data.int32 = 1 + }; + struct searchrange searchrange = { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 7), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 7, 2) + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid1 = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 6, 1), + "backend_getnext_child_gap.1"); + sessionid2 = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 6, 2), + "backend_getnext_child_gap.2"); + agentx_register(ax_s, sessionid1, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 7), 0); + agentx_register(ax_s, sessionid2, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 7, 2), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + varbind.type = TYPE_INTEGER; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid1, &searchrange, + &varbind, 1); + + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_getnext_nosuchobject(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 8), + }; + struct searchrange searchrange = { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 8), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 9) + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 8), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 8), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + varbind.type = TYPE_NOSUCHOBJECT; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, &searchrange, + &varbind, 1); + varbind.name.n_subid--; + varbind.type = TYPE_NULL; + + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_getnext_nosuchinstance(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 9), + }; + struct searchrange searchrange = { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 9), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 10) + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 9), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 9), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + varbind.type = TYPE_NOSUCHINSTANCE; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, &searchrange, + &varbind, 1); + varbind.name.n_subid--; + varbind.type = TYPE_NULL; + + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +/* Assume that everything is registered under 1.3.* */ +void +backend_getnext_endofmibview(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(2, 0), + }; + struct searchrange searchrange = { + .start = OID_STRUCT(2, 0), + .end = OID_STRUCT(2, 1) + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 10), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(2, 0), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + varbind.type = TYPE_ENDOFMIBVIEW; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, &searchrange, + &varbind, 1); + varbind.name.n_subid--; + + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, NOERROR, 0, + &varbind, 1); +} + +void +backend_getnext_inclusive(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 11), + .data.int32 = 1 + }; + struct searchrange searchrange = { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 11, 0), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 11, 1) + }; + int32_t requestid; + char buf[1024]; + size_t n; + + searchrange.start.include = 1; + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 11), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 11, 0), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + varbind.type = TYPE_INTEGER; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, &searchrange, + &varbind, 1); + + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind, 1); +} + +void +backend_getnext_jumpnext(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid1, sessionid2; + struct varbind varbind1 = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 12) + }, varbind2 = { + .type = TYPE_INTEGER, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 12, 1), + .data.int32 = 1 + }; + struct searchrange searchrange1 = { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 12), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 12, 1) + }, searchrange2 = { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 12, 1), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 12, 2) + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid1 = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 12, 1), + "backend_getnext_jumpnext.1"); + sessionid2 = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 12, 2), + "backend_getnext_jumpnext.2"); + agentx_register(ax_s, sessionid1, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 12), 0); + agentx_register(ax_s, sessionid2, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 12, 1), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind1, 1); + + varbind1.type = TYPE_ENDOFMIBVIEW; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid1, &searchrange1, + &varbind1, 1); + agentx_response(ax_s, buf, NOERROR, 0, &varbind1, 1); + + searchrange2.start.include = 1; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid2, &searchrange2, + &varbind2, 1); + agentx_response(ax_s, buf, NOERROR, 0, &varbind2, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind2, 1); +} + +/* Assume that everything is registered under 1.3.* */ +void +backend_getnext_jumpnext_endofmibview(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid1, sessionid2; + struct varbind varbind1 = { + .type = TYPE_NULL, + .name = OID_STRUCT(2, 0) + }, varbind2 = { + .type = TYPE_ENDOFMIBVIEW, + .name = OID_STRUCT(2, 1), + }; + struct searchrange searchrange1 = { + .start = OID_STRUCT(2, 0), + .end = OID_STRUCT(2, 1) + }, searchrange2 = { + .start = OID_STRUCT(2, 1), + .end = OID_STRUCT(2, 2) + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid1 = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 13, 1), + "backend_getnext_jumpnext_endofmibview.1"); + sessionid2 = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 13, 2), + "backend_getnext_jumpnext_endofmibview.2"); + agentx_register(ax_s, sessionid1, 0, 0, 127, 0, + OID_ARG(2, 0), 0); + agentx_register(ax_s, sessionid2, 0, 0, 127, 0, + OID_ARG(2, 1), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind1, 1); + + varbind1.type = TYPE_ENDOFMIBVIEW; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid1, &searchrange1, + &varbind1, 1); + agentx_response(ax_s, buf, NOERROR, 0, &varbind1, 1); + + searchrange2.start.include = 1; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid2, &searchrange2, + &varbind2, 1); + agentx_response(ax_s, buf, NOERROR, 0, &varbind2, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind1, 1); +} + +void +backend_getnext_jump_up(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid1, sessionid2; + struct varbind varbind1 = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 14, 1) + }, varbind2 = { + .type = TYPE_INTEGER, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 14, 2), + .data.int32 = 1 + }; + struct searchrange searchrange1 = { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 14, 1), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 14, 2) + }, searchrange2 = { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 14, 2), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 15) + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid1 = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 14, 1), + "backend_getnext_jump_up.1"); + sessionid2 = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 14, 2), + "backend_getnext_jump_up.2"); + agentx_register(ax_s, sessionid1, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 14), 0); + agentx_register(ax_s, sessionid2, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 14, 1), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind1, 1); + + varbind1.type = TYPE_ENDOFMIBVIEW; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid2, &searchrange1, + &varbind1, 1); + agentx_response(ax_s, buf, NOERROR, 0, &varbind1, 1); + + searchrange2.start.include = 1; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid1, &searchrange2, + &varbind2, 1); + agentx_response(ax_s, buf, NOERROR, 0, &varbind2, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, 0, 0, + &varbind2, 1); +} + +void +backend_getnext_two_single_backend(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind[] = { + { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 15, 0), + .data.int32 = 1 + }, + { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 15, 1), + .data.int32 = 2 + } + }; + struct varbind varbind_ax[] = { + { + .type = TYPE_INTEGER, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 15, 1), + .data.int32 = 1 + }, + { + .type = TYPE_INTEGER, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 15, 2), + .data.int32 = 2 + } + }; + struct searchrange searchrange[] = { + { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 15, 0), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 16) + }, + { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 15, 1), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 16) + } + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 15), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 15), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, varbind, 2); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, searchrange, + varbind_ax, 2); + + agentx_response(ax_s, buf, NOERROR, 0, varbind_ax, 2); + + varbind[0].type = varbind[1].type = TYPE_INTEGER; + varbind[0].name.subid[varbind[0].name.n_subid -1]++; + varbind[1].name.subid[varbind[1].name.n_subid - 1]++; + snmpv2_response_validate(snmp_s, 1000, community, requestid, NOERROR, 0, + varbind, 2); +} + +void +backend_getnext_two_double_backend(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s1, ax_s2; + uint32_t sessionid1, sessionid2; + struct varbind varbind[] = { + { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 16, 1), + .data.int32 = 1 + }, + { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 16, 2), + .data.int32 = 2 + } + }; + struct searchrange searchrange1 = { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 16, 1), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 16, 2) + }, searchrange2 = { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 16, 2), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 16, 3) + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s1 = agentx_connect(axsocket); + ax_s2 = agentx_connect(axsocket); + sessionid1 = agentx_open(ax_s1, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 16, 1), + "backend_getnext_two_double_backend.1"); + sessionid2 = agentx_open(ax_s2, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 16, 2), + "backend_getnext_two_double_backend.2"); + agentx_register(ax_s1, sessionid1, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 16, 1), 0); + agentx_register(ax_s2, sessionid2, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 16, 2), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, varbind, 2); + + varbind[0].name.subid[varbind[0].name.n_subid++] = 0; + varbind[1].name.subid[varbind[1].name.n_subid++] = 0; + varbind[0].type = varbind[1].type = TYPE_INTEGER; + n = agentx_read(ax_s1, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid1, &searchrange1, + varbind + 0, 1); + agentx_response(ax_s1, buf, NOERROR, 0, varbind + 0, 1); + + n = agentx_read(ax_s2, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid2, &searchrange2, + varbind + 1, 1); + agentx_response(ax_s2, buf, NOERROR, 0, varbind + 1, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, NOERROR, 0, + varbind, 2); +} + +void +backend_getnext_instance_below(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 17, 1, 1), + .data.int32 = 1 + }; + struct searchrange searchrange = { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 17, 2), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 17, 3) + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 17), __func__); + agentx_register(ax_s, sessionid, 1, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 17, 1), 0); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 17, 2), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.type = TYPE_INTEGER; + varbind.name = OID_STRUCT(MIB_BACKEND_GETNEXT, 17, 2); + searchrange.start.include = 1; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, &searchrange, + &varbind, 1); + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, NOERROR, 0, + &varbind, 1); +} + +void +backend_getnext_instance(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 18), + .data.int32 = 1 + }; + struct searchrange searchrange = { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 18, 1), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 18, 2) + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 18), __func__); + agentx_register(ax_s, sessionid, 1, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 18, 1), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.type = TYPE_INTEGER; + varbind.name = OID_STRUCT(MIB_BACKEND_GETNEXT, 18, 1); + searchrange.start.include = 1; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, &searchrange, + &varbind, 1); + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, NOERROR, 0, + &varbind, 1); +} + +void +backend_getnext_instance_exact(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 19, 1), + .data.int32 = 1 + }; + struct searchrange searchrange = { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 19, 2), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 19, 3) + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 19), __func__); + agentx_register(ax_s, sessionid, 1, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 19, 1), 0); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 19, 2), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.type = TYPE_INTEGER; + varbind.name = OID_STRUCT(MIB_BACKEND_GETNEXT, 19, 2); + searchrange.start.include = 1; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, &searchrange, + &varbind, 1); + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, NOERROR, 0, + &varbind, 1); +} + +void +backend_getnext_instance_ignore(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 20), + .data.int32 = 1 + }; + struct searchrange searchrange = { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 20, 1), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 20, 2) + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 20), __func__); + agentx_register(ax_s, sessionid, 1, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 20, 1), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.type = TYPE_INTEGER; + varbind.name = OID_STRUCT(MIB_BACKEND_GETNEXT, 20, 1, 0); + searchrange.start.include = 1; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, &searchrange, + &varbind, 1); + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + varbind.type = TYPE_NULL; + varbind.name.n_subid -= 2; + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_getnext_backwards(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 21), + .data.int32 = 1 + }; + struct searchrange searchrange = { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 21), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 22) + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 21), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 21), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.type = TYPE_INTEGER; + varbind.name = OID_STRUCT(MIB_BACKEND_GETNEXT, 21, 1); + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, &searchrange, + &varbind, 1); + varbind.name = OID_STRUCT(MIB_BACKEND_GETNEXT, 20); + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + varbind.type = TYPE_NULL; + varbind.name = OID_STRUCT(MIB_BACKEND_GETNEXT, 21); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_getnext_stale(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 22), + .data.int32 = 1 + }; + struct searchrange searchrange = { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 22), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 23) + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 22), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 22), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.type = TYPE_INTEGER; + varbind.name = OID_STRUCT(MIB_BACKEND_GETNEXT, 22, 1); + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, &searchrange, + &varbind, 1); + varbind.name = OID_STRUCT(MIB_BACKEND_GETNEXT, 22); + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + varbind.type = TYPE_NULL; + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_getnext_inclusive_backwards(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 23), + .data.int32 = 1 + }; + struct searchrange searchrange = { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 23, 1), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 23, 2) + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 23), __func__); + agentx_register(ax_s, sessionid, 1, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 23, 1), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.type = TYPE_INTEGER; + varbind.name = OID_STRUCT(MIB_BACKEND_GETNEXT, 23, 1); + searchrange.start.include = 1; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, &searchrange, + &varbind, 1); + varbind.name = OID_STRUCT(MIB_BACKEND_GETNEXT, 22); + agentx_response(ax_s, buf, NOERROR, 0, &varbind, 1); + varbind.type = TYPE_NULL; + varbind.name = OID_STRUCT(MIB_BACKEND_GETNEXT, 23); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_getnext_toofew(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind[] = { + { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 24, 0), + .data.int32 = 1 + }, + { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 24, 1), + .data.int32 = 2 + } + }; + struct searchrange searchrange[] = { + { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 24, 0), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 25) + }, + { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 24, 1), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 25) + } + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 24), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 24), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, varbind, 2); + + varbind[0].name.subid[varbind[0].name.n_subid - 1]++; + varbind[1].name.subid[varbind[1].name.n_subid - 1]++; + varbind[0].type = varbind[1].type = TYPE_INTEGER; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, searchrange, + varbind, 2); + agentx_response(ax_s, buf, NOERROR, 0, varbind, 1); + varbind[0].type = varbind[1].type = TYPE_NULL; + varbind[0].name = OID_STRUCT(MIB_BACKEND_GETNEXT, 24, 0), + varbind[1].name = OID_STRUCT(MIB_BACKEND_GETNEXT, 24, 1), + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 2, + varbind, 2); +} + +void +backend_getnext_toomany(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind[] = { + { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 25, 0), + .data.int32 = 1 + }, + { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 25, 1), + .data.int32 = 2 + }, + { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETNEXT, 25, 3), + .data.int32 = 3 + } + }; + struct searchrange searchrange[] = { + { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 25, 0), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 26) + }, + { + .start = OID_STRUCT(MIB_BACKEND_GETNEXT, 25, 1), + .end = OID_STRUCT(MIB_BACKEND_GETNEXT, 26) + } + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETNEXT, 25), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETNEXT, 25), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, varbind, 2); + + varbind[0].name.subid[varbind[0].name.n_subid - 1]++; + varbind[1].name.subid[varbind[1].name.n_subid - 1]++; + varbind[0].type = varbind[1].type = TYPE_INTEGER; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, searchrange, + varbind, 2); + agentx_response(ax_s, buf, NOERROR, 0, varbind, 3); + varbind[0].type = varbind[1].type = TYPE_NULL; + varbind[0].name = OID_STRUCT(MIB_BACKEND_GETNEXT, 25, 0), + varbind[1].name = OID_STRUCT(MIB_BACKEND_GETNEXT, 25, 1), + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 2, + varbind, 2); +} + +void +backend_getbulk_nonrep_zero_maxrep_one(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind request = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETBULK, 1) + }, ax_request[] = { + { + .type = TYPE_INTEGER, + .name = OID_STRUCT(MIB_BACKEND_GETBULK, 1, 0), + .data.int32 = 1 + } + }, ax_response[nitems(ax_request)], response[nitems(ax_request)]; + int32_t requestid; + char buf[1024]; + size_t n, nvarbind = nitems(ax_request), nout; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETBULK, 1), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETBULK, 1), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getbulk(snmp_s, community, 0, 0, 1, &request, 1); + + memcpy(response, ax_request, sizeof(ax_request)); + while (nvarbind > 0) { + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + nout = agentx_getbulk_handle(__func__, buf, n, 0, + sessionid, ax_request, nvarbind, ax_response); + agentx_response(ax_s, buf, NOERROR, 0, ax_response, nout); + nvarbind -= nout; + } + + snmpv2_response_validate(snmp_s, 1000, community, requestid, NOERROR, 0, + response, nitems(response)); +} + +void +backend_getbulk_nonrep_zero_maxrep_two(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind request = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETBULK, 2) + }, ax_request[] = { + { + .type = TYPE_INTEGER, + .name = OID_STRUCT(MIB_BACKEND_GETBULK, 2, 1), + .data.int32 = 1 + }, + { + .type = TYPE_INTEGER, + .name = OID_STRUCT(MIB_BACKEND_GETBULK, 2, 2), + .data.int32 = 2 + } + }, ax_response[nitems(ax_request)], response[nitems(ax_request)]; + int32_t requestid; + char buf[1024]; + size_t n, nvarbind = nitems(ax_request), nout; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETBULK, 2), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETBULK, 2), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getbulk(snmp_s, community, 0, 0, 2, &request, 1); + + memcpy(response, ax_request, sizeof(ax_request)); + while (nvarbind > 0) { + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + nout = agentx_getbulk_handle(__func__, buf, n, 0, + sessionid, ax_request, nvarbind, ax_response); + agentx_response(ax_s, buf, NOERROR, 0, ax_response, nout); + nvarbind -= nout; + } + + snmpv2_response_validate(snmp_s, 1000, community, requestid, NOERROR, 0, + response, nitems(response)); +} + +void +backend_getbulk_nonrep_one_maxrep_one(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind request[] = { + { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETBULK, 3, 1) + }, + { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETBULK, 3, 2) + } + }, ax_request[] = { + { + .type = TYPE_INTEGER, + .name = OID_STRUCT(MIB_BACKEND_GETBULK, 3, 1, 0), + .data.int32 = 1 + }, + { + .type = TYPE_INTEGER, + .name = OID_STRUCT(MIB_BACKEND_GETBULK, 3, 2, 0), + .data.int32 = 2 + } + }, ax_response[nitems(ax_request)], response[nitems(ax_request)]; + int32_t requestid; + char buf[1024]; + size_t n, nvarbind = nitems(ax_request), nout; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETBULK, 3), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETBULK, 3), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getbulk(snmp_s, community, 0, 1, 1, request, 2); + + memcpy(response, ax_request, sizeof(ax_request)); + while (nvarbind > 0) { + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + nout = agentx_getbulk_handle(__func__, buf, n, 0, + sessionid, ax_request, nvarbind, ax_response); + agentx_response(ax_s, buf, NOERROR, 0, ax_response, nout); + nvarbind -= nout; + } + + snmpv2_response_validate(snmp_s, 1000, community, requestid, NOERROR, 0, + response, nitems(response)); +} + +void +backend_getbulk_nonrep_one_maxrep_two(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind request[] = { + { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETBULK, 4, 1) + }, + { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETBULK, 4, 2) + } + }, ax_request[] = { + { + .type = TYPE_INTEGER, + .name = OID_STRUCT(MIB_BACKEND_GETBULK, 4, 1, 0), + .data.int32 = 1 + }, + { + .type = TYPE_INTEGER, + .name = OID_STRUCT(MIB_BACKEND_GETBULK, 4, 2, 2), + .data.int32 = 2 + }, + { + .type = TYPE_INTEGER, + .name = OID_STRUCT(MIB_BACKEND_GETBULK, 4, 2, 3), + .data.int32 = 3 + } + }, ax_response[nitems(ax_request)], response[nitems(ax_request)]; + int32_t requestid; + char buf[1024]; + size_t n, nvarbind = nitems(ax_request), nout; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETBULK, 4), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETBULK, 4), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getbulk(snmp_s, community, 0, 1, 2, request, 2); + + memcpy(response, ax_request, sizeof(ax_request)); + while (nvarbind > 0) { + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + nout = agentx_getbulk_handle(__func__, buf, n, 0, + sessionid, ax_request, nvarbind, ax_response); + agentx_response(ax_s, buf, NOERROR, 0, ax_response, nout); + nvarbind -= nout; + } + + snmpv2_response_validate(snmp_s, 1000, community, requestid, NOERROR, 0, + response, nitems(response)); +} + +void +backend_getbulk_nonrep_two_maxrep_two(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind request[] = { + { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETBULK, 5, 1) + }, + { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETBULK, 5, 2) + }, + { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETBULK, 5, 3) + } + }, ax_request[] = { + { + .type = TYPE_INTEGER, + .name = OID_STRUCT(MIB_BACKEND_GETBULK, 5, 1, 0), + .data.int32 = 1 + }, + { + .type = TYPE_INTEGER, + .name = OID_STRUCT(MIB_BACKEND_GETBULK, 5, 2, 0), + .data.int32 = 2 + }, + { + .type = TYPE_INTEGER, + .name = OID_STRUCT(MIB_BACKEND_GETBULK, 5, 3, 3), + .data.int32 = 3 + }, + { + .type = TYPE_INTEGER, + .name = OID_STRUCT(MIB_BACKEND_GETBULK, 5, 3, 4), + .data.int32 = 4 + } + }, ax_response[nitems(ax_request)], response[nitems(ax_request)]; + int32_t requestid; + char buf[1024]; + size_t n, nvarbind = nitems(ax_request), nout; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETBULK, 5), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETBULK, 5), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getbulk(snmp_s, community, 0, 2, 2, request, 3); + + memcpy(response, ax_request, sizeof(ax_request)); + while (nvarbind > 0) { + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + nout = agentx_getbulk_handle(__func__, buf, n, 0, + sessionid, ax_request, nvarbind, ax_response); + agentx_response(ax_s, buf, NOERROR, 0, ax_response, nout); + nvarbind -= nout; + } + + snmpv2_response_validate(snmp_s, 1000, community, requestid, NOERROR, 0, + response, nitems(response)); +} + +void +backend_getbulk_nonrep_negative(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind request = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_GETBULK, 6) + }, ax_request[] = { + { + .type = TYPE_INTEGER, + .name = OID_STRUCT(MIB_BACKEND_GETBULK, 6), + .data.int32 = 1 + } + }, ax_response[nitems(ax_request)], response[nitems(ax_request)]; + int32_t requestid; + char buf[1024]; + size_t n, nvarbind = nitems(ax_request), nout; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_GETBULK, 6), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_GETBULK, 6), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getbulk(snmp_s, community, 0, -1, 1, &request, 1); + + agentx_timeout(ax_s, 1000); + snmp_timeout(snmp_s, 1); +} + +void +backend_error_get_toobig(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 1, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 1), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 1), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, TOOBIG, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, TOOBIG, 1, + &varbind, 1); +} + +void +backend_error_get_nosuchname(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 2, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 2), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 2), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, NOSUCHNAME, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, NOSUCHNAME, 1, + &varbind, 1); +} + +void +backend_error_get_badvalue(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 3, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 3), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 3), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, BADVALUE, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_readonly(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 4, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 4), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 4), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, READONLY, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_generr(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 5, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 5), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 5), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, GENERR, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_noaccess(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 6, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 6), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 5), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, NOACCESS, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_wrongtype(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 7, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 7), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 7), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, WRONGTYPE, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_wronglength(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 8, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 8), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 8), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, WRONGLENGTH, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_wrongencoding(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 9, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 9), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 9), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, WRONGENCODING, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_wrongvalue(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 10, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 10), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 10), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, WRONGVALUE, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_nocreation(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 11, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 11), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 11), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, NOCREATION, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_inconsistentvalue(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 12, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 12), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 12), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, INCONSISTENTVALUE, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_resourceunavailable(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 13, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 13), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 13), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, WRONGVALUE, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_commitfailed(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 14, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 14), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 14), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, COMMITFAILED, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_undofailed(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 15, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 15), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 15), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, UNDOFAILED, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_authorizationerror(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 16, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 16), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 16), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, AUTHORIZATIONERROR, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, AUTHORIZATIONERROR, 1, + &varbind, 1); +} + +void +backend_error_get_notwritable(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 17, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 17), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 17), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, NOTWRITABLE, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_inconsistentname(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 18, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 18), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 18), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, INCONSISTENTNAME, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_openfailed(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 19, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 19), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 19), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, OPENFAILED, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_notopen(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 20, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 20), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 20), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, NOTOPEN, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_indexwrongtype(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 21, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 21), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 21), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, INDEXWRONGTYPE, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_indexalreadyallocated(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 22, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 22), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 22), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, INDEXALREADYALLOCATED, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_indexnonavailable(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 23, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 23), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 23), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, INDEXNONEAVAILABLE, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_indexnotallocated(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 24, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 24), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 24), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, INDEXNOTALLOCATED, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_unsupportedcontext(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 25, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 25), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 25), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, UNSUPPORTEDCONTEXT, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_duplicateregistration(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 26, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 26), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 26), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, DUPLICATEREGISTRATION, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_unknownregistration(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 27, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 27), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 27), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, UNKNOWNREGISTRATION, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_parseerror(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 28, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 28), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 28), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, PARSEERROR, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_requestdenied(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 29, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 29), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 29), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, REQUESTDENIED, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_processingerror(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 30, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 30), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 30), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, PROCESSINGERROR, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_get_nonstandard(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 31, 0), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 31), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 31), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_get(snmp_s, community, 0, &varbind, 1); + + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_get_handle(__func__, buf, n, 0, sessionid, &varbind, 1); + + agentx_response(ax_s, buf, 0xFFFF, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_toobig(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 32), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 32), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 32), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, TOOBIG, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, TOOBIG, 1, + &varbind, 1); +} + +void +backend_error_getnext_nosuchname(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 33), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 33), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 33), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, NOSUCHNAME, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, NOSUCHNAME, 1, + &varbind, 1); +} + +void +backend_error_getnext_badvalue(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 34), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 34), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 34), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, BADVALUE, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_readonly(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 35), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 35), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 35), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, READONLY, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_generr(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 36), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 36), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 36), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, GENERR, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_noaccess(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 37), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 37), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 37), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, NOACCESS, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_wrongtype(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 38), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 38), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 38), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, WRONGTYPE, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_wronglength(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 39), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 39), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 39), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, WRONGLENGTH, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_wrongencoding(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 40), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 40), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 40), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, WRONGENCODING, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_wrongvalue(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 41), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 41), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 41), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, WRONGVALUE, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_nocreation(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 42), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 42), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 42), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, NOCREATION, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_inconsistentvalue(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 43), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 43), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 43), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, INCONSISTENTVALUE, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_resourceunavailable(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 44), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 44), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 44), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, RESOURCEUNAVAILABLE, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_commitfailed(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 45), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 45), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 45), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, COMMITFAILED, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_undofailed(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 46), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 46), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 46), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, UNDOFAILED, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_authorizationerror(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 47), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 47), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 47), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, AUTHORIZATIONERROR, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_notwritable(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 48), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 48), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 48), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, NOTWRITABLE, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_inconsistentname(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 49), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 49), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 49), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, INCONSISTENTNAME, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_openfailed(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 50), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 50), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 50), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, OPENFAILED, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_notopen(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 51), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 51), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 51), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, NOTOPEN, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_indexwrongtype(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 52), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 52), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 52), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, INDEXWRONGTYPE, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_indexalreadyallocated(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 53), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 53), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 53), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, INDEXALREADYALLOCATED, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_indexnonavailable(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 54), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 54), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 54), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, INDEXNONEAVAILABLE, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_indexnotallocated(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 55), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 55), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 55), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, INDEXNOTALLOCATED, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_unsupportedcontext(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 56), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 56), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 56), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, UNSUPPORTEDCONTEXT, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_duplicateregistration(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 57), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 57), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 57), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, DUPLICATEREGISTRATION, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_unknownregistration(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 58), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 58), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 58), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, UNKNOWNREGISTRATION, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_parseerror(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 59), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 59), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 59), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, PARSEERROR, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_requestdenied(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 60), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 60), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 60), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, REQUESTDENIED, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_processingerror(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 61), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 61), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 61), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, PROCESSINGERROR, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} + +void +backend_error_getnext_nonstandard(void) +{ + struct sockaddr_storage ss; + struct sockaddr *sa = (struct sockaddr *)&ss; + socklen_t salen; + int snmp_s, ax_s; + uint32_t sessionid; + struct varbind varbind = { + .type = TYPE_NULL, + .name = OID_STRUCT(MIB_BACKEND_ERROR, 62), + }; + int32_t requestid; + char buf[1024]; + size_t n; + + ax_s = agentx_connect(axsocket); + sessionid = agentx_open(ax_s, 0, 0, + OID_ARG(MIB_SUBAGENT_BACKEND_ERROR, 62), __func__); + agentx_register(ax_s, sessionid, 0, 0, 127, 0, + OID_ARG(MIB_BACKEND_ERROR, 62), 0); + + salen = snmp_resolve(SOCK_DGRAM, hostname, servname, sa); + snmp_s = snmp_connect(SOCK_DGRAM, sa, salen); + requestid = snmpv2_getnext(snmp_s, community, 0, &varbind, 1); + + varbind.name.subid[varbind.name.n_subid++] = 0; + n = agentx_read(ax_s, buf, sizeof(buf), 1000); + agentx_getnext_handle(__func__, buf, n, 0, sessionid, NULL, &varbind, 1); + varbind.name.n_subid--; + agentx_response(ax_s, buf, 0xFFFF, 1, &varbind, 1); + + snmpv2_response_validate(snmp_s, 1000, community, requestid, GENERR, 1, + &varbind, 1); +} diff --git a/regress/usr.sbin/snmpd/regress.h b/regress/usr.sbin/snmpd/regress.h new file mode 100644 index 00000000000..ef496112708 --- /dev/null +++ b/regress/usr.sbin/snmpd/regress.h @@ -0,0 +1,356 @@ +/* + * Generic + */ +#define OID_MAX 128 + +struct oid { + uint32_t subid[OID_MAX]; + size_t n_subid; + int include; +}; + +struct searchrange { + struct oid start; + struct oid end; +}; + +enum type { + TYPE_INTEGER = 2, + TYPE_OCTETSTRING = 4, + TYPE_NULL = 5, + TYPE_OBJECTIDENTIFIER = 6, + TYPE_IPADDRESS = 64, + TYPE_COUNTER32 = 65, + TYPE_GAUGE32 = 66, + TYPE_TIMETICKS = 67, + TYPE_OPAQUE = 68, + TYPE_COUNTER64 = 70, + TYPE_NOSUCHOBJECT = 128, + TYPE_NOSUCHINSTANCE = 129, + TYPE_ENDOFMIBVIEW = 130, + /* Don't expect a specific value: mod 1000 */ + TYPE_INTEGER_UNKNOWN = 1002, + TYPE_OCTETSTRING_UNKNOWN = 1004, + TYPE_OBJECTIDENTIFIER_UNKNOWN = 1006, + TYPE_IPADDRESS_UNKNOWN = 1064 +}; + +enum error { + NOERROR = 0, + NOAGENTXERROR = 0, + TOOBIG = 1, + NOSUCHNAME = 2, + BADVALUE = 3, + READONLY = 4, + GENERR = 5, + NOACCESS = 6, + WRONGTYPE = 7, + WRONGLENGTH = 8, + WRONGENCODING = 9, + WRONGVALUE = 10, + NOCREATION = 11, + INCONSISTENTVALUE = 12, + RESOURCEUNAVAILABLE = 13, + COMMITFAILED = 14, + UNDOFAILED = 15, + AUTHORIZATIONERROR = 16, + NOTWRITABLE = 17, + INCONSISTENTNAME = 18, + OPENFAILED = 256, + NOTOPEN = 257, + INDEXWRONGTYPE = 258, + INDEXALREADYALLOCATED = 259, + INDEXNONEAVAILABLE = 260, + INDEXNOTALLOCATED = 261, + UNSUPPORTEDCONTEXT = 262, + DUPLICATEREGISTRATION = 263, + UNKNOWNREGISTRATION = 264, + UNKNOWNAGENTCAPS = 265, + PARSEERROR = 266, + REQUESTDENIED = 267, + PROCESSINGERROR = 268 +}; + +enum close_reason { + REASONOTHER = 1, + REASONPARSEERROR = 2, + REASONPROTOCOLERROR = 3, + REASONTIMEOUTS = 4, + REASONSHUTDOWN = 5, + REASONBYMANAGER = 6 +}; + +struct varbind { + enum type type; + struct oid name; + union data { + int32_t int32; + uint32_t uint32; + uint64_t uint64; + struct oid oid; + struct octetstring { + char *string; + size_t len; + } octetstring; + } data; +}; + +extern int verbose; +extern char *axsocket; +extern char *hostname; +extern char *servname; +extern char *community; + +int oid_cmp(struct oid *, struct oid *); +char *oid_print(struct oid *, char *, size_t); + +#define OID_STRUCT(...) (struct oid){ \ + .subid = { __VA_ARGS__ }, \ + .n_subid = (sizeof((uint32_t []) { __VA_ARGS__ }) / sizeof(uint32_t)) \ +} + +#define OID_ARG(...) (uint32_t []) { __VA_ARGS__ }, \ + (sizeof((uint32_t []) { __VA_ARGS__ }) / sizeof(uint32_t)) + +/* + * AgentX + */ +#define MIB_OPENBSD_REGRESS 1, 3, 6, 1, 4, 1, 30155, 42 +/* Subagent names */ +#define MIB_SUBAGENTS MIB_OPENBSD_REGRESS, 1 +#define MIB_SUBAGENT_OPEN MIB_SUBAGENTS, 1 +#define MIB_SUBAGENT_PING MIB_SUBAGENTS, 2 +#define MIB_SUBAGENT_CLOSE MIB_SUBAGENTS, 3 +#define MIB_SUBAGENT_REGISTER MIB_SUBAGENTS, 4 +#define MIB_SUBAGENT_UNREGISTER MIB_SUBAGENTS, 4 +#define MIB_SUBAGENT_BACKEND MIB_SUBAGENTS, 5 +/* Region used for registration testing */ +#define MIB_REGISTER MIB_OPENBSD_REGRESS, 2 +#define MIB_UNREGISTER MIB_OPENBSD_REGRESS, 3 +#define MIB_BACKEND MIB_OPENBSD_REGRESS, 4 + +#define SYSORTABLE 1, 3, 6, 1, 2, 1, 1, 9 + +int agentx_connect(const char *); +uint32_t agentx_open(int, int, uint8_t, uint32_t[], size_t, const char *); +void agentx_close(int, uint32_t, enum close_reason); +void agentx_register(int, uint32_t, uint8_t, uint8_t, uint8_t, uint8_t, + uint32_t[], size_t, uint32_t); +void agentx_response(int, void *, enum error, uint16_t, struct varbind *, + size_t); +void agentx_get_handle(const char *, const void *, size_t, uint8_t, uint32_t, + struct varbind *, size_t); +void agentx_getnext_handle(const char *, const void *, size_t, uint8_t, + uint32_t, struct searchrange *, struct varbind *, size_t); +size_t agentx_getbulk_handle(const char *, const void *, size_t, uint8_t, int32_t, + struct varbind *, size_t, struct varbind *); +size_t agentx_read(int, void *, size_t, int); +void agentx_timeout(int, int); + + +/* Tests */ +void agentx_open_nnbo(void); +void agentx_open_nbo(void); +void agentx_open_invalidversion(void); +void agentx_open_ignore_sessionid(void); +void agentx_open_invalid_oid(void); +void agentx_open_descr_too_long(void); +void agentx_open_descr_invalid(void); +void agentx_open_context(void); +void agentx_open_instance_registration(void); +void agentx_open_new_index(void); +void agentx_open_any_index(void); +void agentx_ping_notopen(void); +void agentx_ping_invalid_sessionid(void); +void agentx_ping_default(void); +void agentx_ping_context(void); +void agentx_ping_invalid_version(void); +void agentx_ping_instance_registration(void); +void agentx_ping_new_index(void); +void agentx_ping_any_index(void); +void agentx_ping_nbo_nnbo(void); +void agentx_ping_nnbo_nbo(void); +void agentx_close_notopen(void); +void agentx_close_reasonother(void); +void agentx_close_reasonparseerror(void); +void agentx_close_reasonprotocolerror(void); +void agentx_close_reasontimouts(void); +void agentx_close_reasonshutdown(void); +void agentx_close_reasonbymanager(void); +void agentx_close_reasoninvalid(void); +void agentx_close_single(void); +void agentx_close_notowned(void); +void agentx_close_invalid_sessionid(void); +void agentx_close_context(void); +void agentx_close_invalid_version(void); +void agentx_close_instance_registration(void); +void agentx_close_new_index(void); +void agentx_close_any_index(void); +void agentx_close_nnbo_nbo(void); +void agentx_register_notopen(void); +void agentx_register_invalid_sessionid(void); +void agentx_register_default(void); +void agentx_register_context(void); +void agentx_register_invalid_version(void); +void agentx_register_instance_registration(void); +void agentx_register_new_index(void); +void agentx_register_any_index(void); +void agentx_register_duplicate_self(void); +void agentx_register_duplicate_twocon(void); +void agentx_register_duplicate_priority(void); +void agentx_register_range(void); +void agentx_register_range_invalidupperbound(void); +void agentx_register_range_single(void); +void agentx_register_range_overlap_single(void); +void agentx_register_single_overlap_range(void); +void agentx_register_range_overlap_range(void); +void agentx_register_below(void); +void agentx_register_above(void); +void agentx_register_restricted(void); +void agentx_unregister_notopen(void); +void agentx_unregister_invalid_sessionid(void); +void agentx_unregister_notregistered(void); +void agentx_unregister_single(void); +void agentx_unregister_single_notowned(void); +void agentx_unregister_range(void); +void agentx_unregister_range_single(void); +void agentx_unregister_range_subset(void); +void agentx_unregister_range_extra(void); +void agentx_unregister_range_priority(void); +void agentx_unregister_range_notowned(void); + +/* + * SNMP + */ +socklen_t snmp_resolve(int, const char *, const char *, struct sockaddr *); +int snmp_connect(int, struct sockaddr *, socklen_t); +int32_t snmpv2_get(int, const char *, int32_t, struct varbind *, size_t); +int32_t snmpv2_getnext(int, const char *, int32_t, struct varbind *, size_t); +int32_t snmpv2_getbulk(int, const char *, int32_t, int32_t, int32_t, + struct varbind *, size_t); +void snmpv2_response_validate(int, int, const char *, int32_t, int32_t, int32_t, + struct varbind *, size_t); +void snmp_timeout(int, int); + +void backend_get_integer(void); +void backend_get_octetstring(void); +void backend_get_objectidentifier(void); +void backend_get_ipaddress(void); +void backend_get_counter32(void); +void backend_get_gauge32(void); +void backend_get_timeticks(void); +void backend_get_opaque(void); +void backend_get_counter64(void); +void backend_get_nosuchobject(void); +void backend_get_nosuchinstance(void); +void backend_get_endofmibview(void); +void backend_get_two_single_backend(void); +void backend_get_two_double_backend(void); +void backend_get_wrongorder(void); +void backend_get_toofew(void); +void backend_get_toomany(void); +void backend_get_instance(void); +void backend_get_instance_below(void); +void backend_get_timeout_default(void); +void backend_get_timeout_session_lower(void); +void backend_get_timeout_session_higher(void); +void backend_get_timeout_region_lower(void); +void backend_get_timeout_region_higher(void); +void backend_get_priority_lower(void); +void backend_get_priority_higher(void); +void backend_get_priority_below_lower(void); +void backend_get_priority_below_higher(void); +void backend_get_close(void); +void backend_get_close_overlap(void); +void backend_get_disappear(void); +void backend_get_disappear_overlap(void); +void backend_get_disappear_doublesession(void); +void backend_getnext_selfbound(void); +void backend_getnext_lowerbound(void); +void backend_getnext_lowerbound_self(void); +void backend_getnext_lowerbound_highprio(void); +void backend_getnext_lowerbound_lowprio(void); +void backend_getnext_sibling(void); +void backend_getnext_child_gap(void); +void backend_getnext_nosuchobject(void); +void backend_getnext_nosuchinstance(void); +void backend_getnext_endofmibview(void); +void backend_getnext_inclusive(void); +void backend_getnext_jumpnext(void); +void backend_getnext_jumpnext_endofmibview(void); +void backend_getnext_jump_up(void); +void backend_getnext_jump_up(void); +void backend_getnext_two_single_backend(void); +void backend_getnext_two_double_backend(void); +void backend_getnext_instance_below(void); +void backend_getnext_instance(void); +void backend_getnext_instance_exact(void); +void backend_getnext_instance_ignore(void); +void backend_getnext_instance_ignore(void); +void backend_getnext_backwards(void); +void backend_getnext_stale(void); +void backend_getnext_inclusive_backwards(void); +void backend_getnext_toofew(void); +void backend_getnext_toomany(void); +void backend_getbulk_nonrep_zero_maxrep_one(void); +void backend_getbulk_nonrep_zero_maxrep_two(void); +void backend_getbulk_nonrep_one_maxrep_one(void); +void backend_getbulk_nonrep_one_maxrep_two(void); +void backend_getbulk_nonrep_two_maxrep_two(void); +void backend_getbulk_nonrep_negative(void); +void backend_error_get_toobig(void); +void backend_error_get_nosuchname(void); +void backend_error_get_badvalue(void); +void backend_error_get_readonly(void); +void backend_error_get_generr(void); +void backend_error_get_wrongtype(void); +void backend_error_get_wronglength(void); +void backend_error_get_wrongencoding(void); +void backend_error_get_wrongvalue(void); +void backend_error_get_nocreation(void); +void backend_error_get_inconsistentvalue(void); +void backend_error_get_commitfailed(void); +void backend_error_get_undofailed(void); +void backend_error_get_authorizationerror(void); +void backend_error_get_notwritable(void); +void backend_error_get_inconsistentname(void); +void backend_error_get_openfailed(void); +void backend_error_get_notopen(void); +void backend_error_get_indexwrongtype(void); +void backend_error_get_indexalreadyallocated(void); +void backend_error_get_indexnonavailable(void); +void backend_error_get_indexnotallocated(void); +void backend_error_get_duplicateregistration(void); +void backend_error_get_requestdenied(void); +void backend_error_get_processingerror(void); +void backend_error_get_nonstandard(void); +void backend_error_getnext_toobig(void); +void backend_error_getnext_nosuchname(void); +void backend_error_getnext_badvalue(void); +void backend_error_getnext_readonly(void); +void backend_error_getnext_generr(void); +void backend_error_getnext_noaccess(void); +void backend_error_getnext_wrongtype(void); +void backend_error_getnext_wronglength(void); +void backend_error_getnext_wrongencoding(void); +void backend_error_getnext_wrongvalue(void); +void backend_error_getnext_nocreation(void); +void backend_error_getnext_inconsistentvalue(void); +void backend_error_getnext_resourceunavailable(void); +void backend_error_getnext_commitfailed(void); +void backend_error_getnext_undofailed(void); +void backend_error_getnext_notwritable(void); +void backend_error_getnext_inconsistentname(void); +void backend_error_getnext_openfailed(void); +void backend_error_getnext_notopen(void); +void backend_error_getnext_indexwrongtype(void); +void backend_error_getnext_indexalreadyallocated(void); +void backend_error_getnext_indexnonavailable(void); +void backend_error_getnext_indexnotallocated(void); +void backend_error_getnext_unsupportedcontext(void); +void backend_error_getnext_duplicateregistration(void); +void backend_error_getnext_unknownregistration(void); +void backend_error_getnext_parseerror(void); +void backend_error_getnext_requestdenied(void); +void backend_error_getnext_processingerror(void); +void backend_error_getnext_nonstandard(void); diff --git a/regress/usr.sbin/snmpd/snmp.c b/regress/usr.sbin/snmpd/snmp.c new file mode 100644 index 00000000000..63f0bb6ef14 --- /dev/null +++ b/regress/usr.sbin/snmpd/snmp.c @@ -0,0 +1,855 @@ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "regress.h" + +#include + +#define SNMP_HOSTNAME "127.0.0.1" +#define SNMP_PORT "161" + +#define SNMP_R_COMMUNITY "public" + +enum snmp_application { + APPLICATION_IPADDR = 0, + APPLICATION_COUNTER32 = 1, + APPLICATION_GAUGE32 = 2, + APPLICATION_UNSIGNED32 = 2, + APPLICATION_TIMETICKS = 3, + APPLICATION_OPAQUE = 4, + APPLICATION_NSAPADDR = 5, + APPLICATION_COUNTER64 = 6, +}; + +enum snmp_exception { + EXCEPTION_NOSUCHOBJECT = 0, + EXCEPTION_NOSUCHINSTANCE = 1, + EXCEPTION_ENDOFMIBVIEW = 2 +}; + +enum snmp_request { + REQUEST_GET = 0, + REQUEST_GETNEXT = 1, + REQUEST_RESPONSE = 2, + REQUEST_SET = 3, + REQUEST_TRAP = 4, + REQUEST_GETBULK = 5, + REQUEST_INFORM = 6, + REQUEST_TRAPV2 = 7, + REQUEST_REPORT = 8 +}; + +int32_t snmpv2_send(int, const char *, enum snmp_request, int32_t, int32_t, + int32_t, struct varbind *, size_t); +struct ber_element *snmp_v2_recv(int, int); +struct ber_element *snmp_pdu(enum snmp_request, int32_t, int32_t, int32_t, + struct varbind *, size_t); +struct ber_element *snmp_varbindlist(struct varbind *, size_t); +struct ber_oid *snmp_oid2ber_oid(struct oid *, struct ber_oid *); +struct ber_element *snmp_data2ber_element(enum type, union data *); +unsigned int smi_application(struct ber_element *); +char *smi_oid2string(struct ber_oid *, char *, size_t); +char *smi_print_element(struct ber_element *); +void smi_debug_elements(struct ber_element *); +struct ber_element *v2cmps(struct ber_element *, const char *); +void snmp_pdu_validate(struct ber_element *, enum snmp_request, int32_t, + int32_t, int32_t, struct varbind *, size_t); + +socklen_t +snmp_resolve(int type, const char *hostname, const char *servname, struct sockaddr *sa) +{ + struct addrinfo hints, *res; + socklen_t salen; + int error; + + if (hostname == NULL) + hostname = SNMP_HOSTNAME; + if (servname == NULL) + servname = SNMP_PORT; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = type; + + if ((error = getaddrinfo(hostname, servname, &hints, &res)) != 0) + errx(1, "getaddrinfo(%s, %s): %s", hostname, servname, + gai_strerror(error)); + + memcpy(sa, res->ai_addr, res->ai_addrlen); + salen = res->ai_addrlen; + + freeaddrinfo(res); + return salen; +} + +int +snmp_connect(int type, struct sockaddr *sa, socklen_t salen) +{ + int s; + + if ((s = socket(sa->sa_family, type, 0)) == -1) + err(1, "socket"); + if (connect(s, sa, salen) == -1) + err(1, "connect"); + return s; +} + +int32_t +snmpv2_get(int s, const char *community, int32_t requestid, + struct varbind *varbindlist, size_t nvarbind) +{ + return snmpv2_send(s, community, REQUEST_GET, requestid, 0, 0, + varbindlist, nvarbind); +} + +int32_t +snmpv2_getnext(int s, const char *community, int32_t requestid, + struct varbind *varbindlist, size_t nvarbind) +{ + return snmpv2_send(s, community, REQUEST_GETNEXT, requestid, 0, 0, + varbindlist, nvarbind); +} + +int32_t +snmpv2_getbulk(int s, const char *community, int32_t requestid, int32_t nonrep, + int32_t maxrep, struct varbind *varbindlist, size_t nvarbind) +{ + return snmpv2_send(s, community, REQUEST_GETBULK, requestid, nonrep, + maxrep, varbindlist, nvarbind); +} + +int32_t +snmpv2_send(int s, const char *community, enum snmp_request request, + int32_t requestid, int32_t error, int32_t index, + struct varbind *varbindlist, size_t nvarbind) +{ + struct ber_element *message; + struct ber ber = {}; + void *buf; + ssize_t buflen, writelen; + + if (community == NULL) + community = SNMP_R_COMMUNITY; + while (requestid == 0) + requestid = arc4random(); + message = ober_printf_elements(NULL, "{dse}", 1, community, + snmp_pdu(request, requestid, error, index, varbindlist, nvarbind)); + if (message == NULL) + err(1, NULL); + + if (ober_write_elements(&ber, message) == -1) + err(1, "ober_write_elements"); + + buflen = ober_get_writebuf(&ber, &buf); + if ((writelen = write(s, buf, buflen)) == -1) + err(1, "write"); + if (writelen != buflen) + errx(1, "write: short write"); + + if (verbose) { + printf("SNMP send(%d):\n", s); + smi_debug_elements(message); + } + ober_free_elements(message); + ober_free(&ber); + + return requestid; +} + +void +snmpv2_response_validate(int s, int timeout, const char *community, + int32_t requestid, int32_t error, int32_t index, + struct varbind *varbindlist, size_t nvarbind) +{ + struct ber_element *message, *pdu; + + message = snmp_v2_recv(s, timeout); + + if (community == NULL) + community = SNMP_R_COMMUNITY; + snmp_pdu_validate(v2cmps(message, community), REQUEST_RESPONSE, + requestid, error, index, varbindlist, nvarbind); + + ober_free_elements(message); +} + +struct ber_element * +snmp_v2_recv(int s, int timeout) +{ + struct pollfd pfd = { + .fd = s, + .events = POLLIN + }; + char buf[1024]; + struct ber ber = {}; + struct ber_element *message; + ssize_t n; + int ret; + + if ((ret = poll(&pfd, 1, timeout)) == -1) + err(1, "poll"); + if (ret == 0) + errx(1, "%s: timeout", __func__); + if ((n = read(s, buf, sizeof(buf))) == -1) + err(1, "agentx read"); + + ober_set_application(&ber, smi_application); + ober_set_readbuf(&ber, buf, n); + + message = ober_read_elements(&ber, NULL); + if (verbose) { + printf("SNMP received(%d):\n", s); + smi_debug_elements(message); + } + + ober_free(&ber); + + return message; +} + +void +snmp_timeout(int s, int timeout) +{ + int ret; + struct pollfd pfd = { + .fd = s, + .events = POLLIN + }; + + if ((ret = poll(&pfd, 1, timeout)) == -1) + err(1, "poll"); + if (ret != 0) + errx(1, "%s: unexpected snmp data", __func__); +} + +struct ber_element * +snmp_pdu(enum snmp_request request, int32_t requestid, int32_t error, + int32_t index, struct varbind *varbindlist, size_t nvarbind) +{ + struct ber_element *pdu; + + if ((pdu = ober_printf_elements(NULL, "{tddde}", BER_CLASS_CONTEXT, + request, requestid, error, index, + snmp_varbindlist(varbindlist, nvarbind))) == NULL) + err(1, NULL); + return pdu; +} + +struct ber_element * +snmp_varbindlist(struct varbind *varbindlist, size_t nvarbind) +{ + struct ber_element *vblist, *prev = NULL; + struct ber_oid oid; + size_t i; + + if ((vblist = prev = ober_add_sequence(NULL)) == NULL) + err(1, NULL); + for (i = 0; i < nvarbind; i++) { + if ((prev = ober_printf_elements(prev, "{Oe}", + snmp_oid2ber_oid(&varbindlist[i].name, &oid), + snmp_data2ber_element(varbindlist[i].type, + &varbindlist[i].data))) == NULL) + err(1, NULL); + } + + return vblist; +} + +struct ber_oid * +snmp_oid2ber_oid(struct oid *oid, struct ber_oid *boid) +{ + size_t i; + + for (i = 0; i < oid->n_subid; i++) + boid->bo_id[i] = oid->subid[i]; + boid->bo_n = oid->n_subid; + + return boid; +} + +struct ber_element * +snmp_data2ber_element(enum type type, union data *data) +{ + struct ber_element *elm; + struct ber_oid oid; + + switch (type) { + case TYPE_INTEGER: + elm = ober_add_integer(NULL, data->int32); + break; + case TYPE_OCTETSTRING: + elm = ober_add_nstring(NULL, data->octetstring.string, + data->octetstring.len); + break; + case TYPE_NULL: + elm = ober_add_null(NULL); + break; + case TYPE_OBJECTIDENTIFIER: + elm = ober_add_oid(NULL, snmp_oid2ber_oid(&data->oid, &oid)); + break; + case TYPE_IPADDRESS: + if ((elm = ober_add_nstring(NULL, data->octetstring.string, + data->octetstring.len)) == NULL) + err(1, NULL); + ober_set_header(elm, BER_CLASS_APPLICATION, APPLICATION_IPADDR); + break; + case TYPE_COUNTER32: + if ((elm = ober_add_integer(NULL, data->uint32)) == NULL) + err(1, NULL); + ober_set_header(elm, BER_CLASS_APPLICATION, + APPLICATION_COUNTER32); + break; + case TYPE_GAUGE32: + if ((elm = ober_add_integer(NULL, data->uint32)) == NULL) + err(1, NULL); + ober_set_header(elm, BER_CLASS_APPLICATION, + APPLICATION_GAUGE32); + break; + case TYPE_TIMETICKS: + if ((elm = ober_add_integer(NULL, data->uint32)) == NULL) + err(1, NULL); + ober_set_header(elm, BER_CLASS_APPLICATION, + APPLICATION_TIMETICKS); + break; + case TYPE_OPAQUE: + if ((elm = ober_add_nstring(NULL, data->octetstring.string, + data->octetstring.len)) == NULL) + err(1, NULL); + ober_set_header(elm, BER_CLASS_APPLICATION, APPLICATION_OPAQUE); + break; + case TYPE_COUNTER64: + if ((elm = ober_add_integer(NULL, data->uint64)) == NULL) + err(1, NULL); + ober_set_header(elm, BER_CLASS_APPLICATION, + APPLICATION_COUNTER64); + break; + case TYPE_NOSUCHOBJECT: + if ((elm = ober_add_null(NULL)) == NULL) + err(1, NULL); + ober_set_header(elm, BER_CLASS_CONTEXT, EXCEPTION_NOSUCHOBJECT); + break; + case TYPE_NOSUCHINSTANCE: + if ((elm = ober_add_null(NULL)) == NULL) + err(1, NULL); + ober_set_header(elm, BER_CLASS_CONTEXT, + EXCEPTION_NOSUCHINSTANCE); + break; + case TYPE_ENDOFMIBVIEW: + if ((elm = ober_add_null(NULL)) == NULL) + err(1, NULL); + ober_set_header(elm, BER_CLASS_CONTEXT, EXCEPTION_ENDOFMIBVIEW); + break; + default: + errx(1, "%s: unsupported type: %d", __func__, type); + } + if (elm == NULL) + err(1, NULL); + return elm; +} + +unsigned int +smi_application(struct ber_element *elm) +{ + if (elm->be_class != BER_CLASS_APPLICATION) + return -1; + + switch (elm->be_type) { + case APPLICATION_IPADDR: + case APPLICATION_OPAQUE: + return BER_TYPE_OCTETSTRING; + case APPLICATION_COUNTER32: + case APPLICATION_GAUGE32: + case APPLICATION_TIMETICKS: + case APPLICATION_COUNTER64: + return BER_TYPE_INTEGER; + default: + return -1; + } +} + +char * +smi_oid2string(struct ber_oid *oid, char *buf, size_t len) +{ + char digit[11]; + size_t i; + + buf[0] = '\0'; + for (i = 0; i < oid->bo_n; i++) { + snprintf(digit, sizeof(digit), "%"PRIu32, oid->bo_id[i]); + if (i > 0) + strlcat(buf, ".", len); + strlcat(buf, digit, len); + } + return buf; +} + +char * +smi_print_element(struct ber_element *root) +{ + char *str = NULL, *buf, *p; + long long v; + struct ber_oid o; + char strbuf[BUFSIZ]; + + switch (root->be_class) { + case BER_CLASS_UNIVERSAL: + switch (root->be_type) { + case BER_TYPE_INTEGER: + if (ober_get_integer(root, &v) == -1) + goto fail; + if (asprintf(&str, "%lld", v) == -1) + goto fail; + break; + case BER_TYPE_OBJECT: + if (ober_get_oid(root, &o) == -1) + goto fail; + if (asprintf(&str, "%s", smi_oid2string(&o, strbuf, + sizeof(strbuf))) == -1) + goto fail; + break; + case BER_TYPE_OCTETSTRING: + if (ober_get_string(root, &buf) == -1) + goto fail; + p = reallocarray(NULL, 4, root->be_len + 1); + if (p == NULL) + goto fail; + strvisx(p, buf, root->be_len, VIS_NL); + if (asprintf(&str, "\"%s\"", p) == -1) { + free(p); + goto fail; + } + free(p); + break; + case BER_TYPE_NULL: + if (asprintf(&str, "null") == -1) + goto fail; + break; + default: + /* Should not happen in a valid SNMP packet */ + if (asprintf(&str, "[U/%u]", root->be_type) == -1) + goto fail; + break; + } + break; + case BER_CLASS_APPLICATION: + switch (root->be_type) { + case APPLICATION_IPADDR: + if (ober_get_string(root, &buf) == -1) + goto fail; + if (asprintf(&str, "%s", + inet_ntoa(*(struct in_addr *)buf)) == -1) + goto fail; + break; + case APPLICATION_COUNTER32: + if (ober_get_integer(root, &v) == -1) + goto fail; + if (asprintf(&str, "%lld(c32)", v) == -1) + goto fail; + break; + case APPLICATION_GAUGE32: + if (ober_get_integer(root, &v) == -1) + goto fail; + if (asprintf(&str, "%lld(g32)", v) == -1) + goto fail; + break; + case APPLICATION_TIMETICKS: + if (ober_get_integer(root, &v) == -1) + goto fail; + if (asprintf(&str, "%lld.%llds", v/100, v%100) == -1) + goto fail; + break; + case APPLICATION_OPAQUE: + if (ober_get_string(root, &buf) == -1) + goto fail; + p = reallocarray(NULL, 4, root->be_len + 1); + if (p == NULL) + goto fail; + strvisx(p, buf, root->be_len, VIS_NL); + if (asprintf(&str, "\"%s\"(opaque)", p) == -1) { + free(p); + goto fail; + } + free(p); + break; + case APPLICATION_COUNTER64: + if (ober_get_integer(root, &v) == -1) + goto fail; + if (asprintf(&str, "%lld(c64)", v) == -1) + goto fail; + break; + default: + /* Should not happen in a valid SNMP packet */ + if (asprintf(&str, "[A/%u]", root->be_type) == -1) + goto fail; + break; + } + break; + case BER_CLASS_CONTEXT: + switch (root->be_type) { + case EXCEPTION_NOSUCHOBJECT: + str = strdup("noSuchObject"); + break; + case EXCEPTION_NOSUCHINSTANCE: + str = strdup("noSuchInstance"); + break; + case EXCEPTION_ENDOFMIBVIEW: + str = strdup("endOfMibView"); + break; + default: + /* Should not happen in a valid SNMP packet */ + if (asprintf(&str, "[C/%u]", root->be_type) == -1) + goto fail; + break; + } + break; + default: + /* Should not happen in a valid SNMP packet */ + if (asprintf(&str, "[%hhu/%u]", root->be_class, + root->be_type) == -1) + goto fail; + break; + } + + return (str); + + fail: + free(str); + return (NULL); +} + +void +smi_debug_elements(struct ber_element *root) +{ + static int indent = 0; + char *value; + int constructed; + + /* calculate lengths */ + ober_calc_len(root); + + switch (root->be_encoding) { + case BER_TYPE_SEQUENCE: + case BER_TYPE_SET: + constructed = root->be_encoding; + break; + default: + constructed = 0; + break; + } + + fprintf(stderr, "%*slen %lu ", indent, "", root->be_len); + switch (root->be_class) { + case BER_CLASS_UNIVERSAL: + fprintf(stderr, "class: universal(%u) type: ", root->be_class); + switch (root->be_type) { + case BER_TYPE_EOC: + fprintf(stderr, "end-of-content"); + break; + case BER_TYPE_INTEGER: + fprintf(stderr, "integer"); + break; + case BER_TYPE_BITSTRING: + fprintf(stderr, "bit-string"); + break; + case BER_TYPE_OCTETSTRING: + fprintf(stderr, "octet-string"); + break; + case BER_TYPE_NULL: + fprintf(stderr, "null"); + break; + case BER_TYPE_OBJECT: + fprintf(stderr, "object"); + break; + case BER_TYPE_ENUMERATED: + fprintf(stderr, "enumerated"); + break; + case BER_TYPE_SEQUENCE: + fprintf(stderr, "sequence"); + break; + case BER_TYPE_SET: + fprintf(stderr, "set"); + break; + } + break; + case BER_CLASS_APPLICATION: + fprintf(stderr, "class: application(%u) type: ", + root->be_class); + switch (root->be_type) { + case APPLICATION_IPADDR: + fprintf(stderr, "ipaddr"); + break; + case APPLICATION_COUNTER32: + fprintf(stderr, "counter32"); + break; + case APPLICATION_GAUGE32: + fprintf(stderr, "gauge32"); + break; + case APPLICATION_TIMETICKS: + fprintf(stderr, "timeticks"); + break; + case APPLICATION_OPAQUE: + fprintf(stderr, "opaque"); + break; + case APPLICATION_COUNTER64: + fprintf(stderr, "counter64"); + break; + } + break; + case BER_CLASS_CONTEXT: + fprintf(stderr, "class: context(%u) type: ", + root->be_class); + switch (root->be_type) { + case REQUEST_GET: + fprintf(stderr, "getreq"); + break; + case REQUEST_GETNEXT: + fprintf(stderr, "getnextreq"); + break; + case REQUEST_RESPONSE: + fprintf(stderr, "response"); + break; + case REQUEST_SET: + fprintf(stderr, "setreq"); + break; + case REQUEST_TRAP: + fprintf(stderr, "trap"); + break; + case REQUEST_GETBULK: + fprintf(stderr, "getbulkreq"); + break; + case REQUEST_INFORM: + fprintf(stderr, "informreq"); + break; + case REQUEST_TRAPV2: + fprintf(stderr, "trapv2"); + break; + case REQUEST_REPORT: + fprintf(stderr, "report"); + break; + } + break; + case BER_CLASS_PRIVATE: + fprintf(stderr, "class: private(%u) type: ", root->be_class); + break; + default: + fprintf(stderr, "class: (%u) type: ", root->be_class); + break; + } + fprintf(stderr, "(%u) encoding %u ", + root->be_type, root->be_encoding); + + if ((value = smi_print_element(root)) == NULL) + goto invalid; + + switch (root->be_encoding) { + case BER_TYPE_INTEGER: + case BER_TYPE_ENUMERATED: + fprintf(stderr, "value %s", value); + break; + case BER_TYPE_BITSTRING: + fprintf(stderr, "hexdump %s", value); + break; + case BER_TYPE_OBJECT: + fprintf(stderr, "oid %s", value); + break; + case BER_TYPE_OCTETSTRING: + if (root->be_class == BER_CLASS_APPLICATION && + root->be_type == APPLICATION_IPADDR) { + fprintf(stderr, "addr %s", value); + } else { + fprintf(stderr, "string %s", value); + } + break; + case BER_TYPE_NULL: /* no payload */ + case BER_TYPE_EOC: + case BER_TYPE_SEQUENCE: + case BER_TYPE_SET: + default: + fprintf(stderr, "%s", value); + break; + } + + invalid: + if (value == NULL) + fprintf(stderr, ""); + else + free(value); + fprintf(stderr, "\n"); + + if (constructed) + root->be_encoding = constructed; + + if (constructed && root->be_sub) { + indent += 2; + smi_debug_elements(root->be_sub); + indent -= 2; + } + if (root->be_next) + smi_debug_elements(root->be_next); +} + +struct ber_element * +v2cmps(struct ber_element *message, const char *community) +{ + int version; + const char *mcommunity; + struct ber_element *pdu; + + if (ober_scanf_elements(message, "{dse}$", &version, &mcommunity, &pdu) == -1) + err(1, "%s: ober_scanf_elements", __func__); + + if (strcmp(mcommunity, community) != 0) + errx(1, "%s: invalid community (%s/%s)", __func__, mcommunity, + community); + + return pdu; +} + +void +snmp_pdu_validate(struct ber_element *pdu, enum snmp_request request, + int32_t requestid, int32_t error, int32_t index, struct varbind *varbindlist, + size_t nvarbind) +{ + int32_t mrequestid, merror, mindex; + int class; + unsigned int type; + struct ber_element *mvarbindlist, *varbind; + struct ber_oid moid, oid; + struct ber_element *value; + char oidbuf1[512], oidbuf2[512]; + size_t i; + + if (ober_scanf_elements(pdu, "t{ddd{e}$}$", &class, &type, &mrequestid, + &merror, &mindex, &varbind) == -1) + err(1, "%s: ober_scanf_elementsi", __func__); + + if (class != BER_CLASS_CONTEXT || type != request) + errx(1, "%s: unexpected pdu type", __func__); + if (mrequestid != requestid) + errx(1, "%s: unexpected pdu requestid (%d/%d)", + __func__, mrequestid, requestid); + if (error != merror) + errx(1, "%s: unexpected pdu error (%d/%d)", + __func__, merror, error); + if (index != mindex) + errx(1, "%s: unepxected pdu index (%d/%d)", + __func__, mindex, index); + + for (i = 0; varbind != NULL; varbind = varbind->be_next, i++) { + if (ober_scanf_elements(varbind, "{oeS$}", &moid, &value) == -1) + err(1, "%s: ober_scanf_elements", __func__); + if (i >= nvarbind) + continue; + snmp_oid2ber_oid(&varbindlist[i].name, &oid); + if (ober_oid_cmp(&moid, &oid) != 0) + errx(1, "%s: unexpected oid (%s/%s)", __func__, + smi_oid2string(&moid, oidbuf1, sizeof(oidbuf1)), + smi_oid2string(&oid, oidbuf2, sizeof(oidbuf2))); + switch (varbindlist[i].type) { + case TYPE_INTEGER: + if (value->be_class != BER_CLASS_UNIVERSAL || + value->be_type != BER_TYPE_INTEGER || + value->be_numeric != varbindlist[i].data.int32) + errx(1, "%s: unexpected value", __func__); + break; + case TYPE_OCTETSTRING: + if (value->be_class != BER_CLASS_UNIVERSAL || + value->be_type != BER_TYPE_OCTETSTRING || + value->be_len != + varbindlist[i].data.octetstring.len || + memcmp(varbindlist[i].data.octetstring.string, + value->be_val, value->be_len) != 0) + errx(1, "%s: unexpected value", __func__); + break; + case TYPE_NULL: + if (value->be_class != BER_CLASS_UNIVERSAL || + value->be_type != BER_TYPE_NULL) + errx(1, "%s: unexpected value", __func__); + break; + case TYPE_OBJECTIDENTIFIER: + if (value->be_class != BER_CLASS_UNIVERSAL || + value->be_type != BER_TYPE_OBJECT) + errx(1, "%s: unexpected value", __func__); + if (ober_get_oid(value, &moid) == -1) + errx(1, "%s: unexpected value", __func__); + snmp_oid2ber_oid(&varbindlist[i].data.oid, &oid); + if (ober_oid_cmp(&oid, &moid) != 0) + errx(1, "%s: unexpected value", __func__); + break; + case TYPE_IPADDRESS: + if (value->be_class != BER_CLASS_APPLICATION || + value->be_type != APPLICATION_IPADDR || + value->be_len != + varbindlist[i].data.octetstring.len || + memcmp(varbindlist[i].data.octetstring.string, + value->be_val, value->be_len) != 0) + errx(1, "%s: unexpected value", __func__); + break; + case TYPE_COUNTER32: + if (value->be_class != BER_CLASS_APPLICATION || + value->be_type != APPLICATION_COUNTER32 || + value->be_numeric != varbindlist[i].data.uint32) + errx(1, "%s: unexpected value", __func__); + break; + case TYPE_GAUGE32: + if (value->be_class != BER_CLASS_APPLICATION || + value->be_type != APPLICATION_GAUGE32 || + value->be_numeric != varbindlist[i].data.uint32) + errx(1, "%s: unexpected value", __func__); + break; + case TYPE_TIMETICKS: + if (value->be_class != BER_CLASS_APPLICATION || + value->be_type != APPLICATION_TIMETICKS || + value->be_numeric != varbindlist[i].data.uint32) + errx(1, "%s: unexpected value", __func__); + break; + case TYPE_OPAQUE: + if (value->be_class != BER_CLASS_APPLICATION || + value->be_type != APPLICATION_OPAQUE || + value->be_len != + varbindlist[i].data.octetstring.len || + memcmp(varbindlist[i].data.octetstring.string, + value->be_val, value->be_len) != 0) + errx(1, "%s: unexpected value", __func__); + break; + case TYPE_COUNTER64: + if (value->be_class != BER_CLASS_APPLICATION || + value->be_type != APPLICATION_COUNTER64 || + value->be_numeric != varbindlist[i].data.uint64) + errx(1, "%s: unexpected value", __func__); + break; + case TYPE_NOSUCHOBJECT: + if (value->be_class != BER_CLASS_CONTEXT || + value->be_type != EXCEPTION_NOSUCHOBJECT) + errx(1, "%s: unexpected value", __func__); + break; + case TYPE_NOSUCHINSTANCE: + if (value->be_class != BER_CLASS_CONTEXT || + value->be_type != EXCEPTION_NOSUCHINSTANCE) + errx(1, "%s: unexpected value", __func__); + break; + case TYPE_ENDOFMIBVIEW: + if (value->be_class != BER_CLASS_CONTEXT || + value->be_type != EXCEPTION_ENDOFMIBVIEW) + errx(1, "%s: unexpected value", __func__); + break; + default: + errx(1, "%s: unexpected type", __func__); + } + } + if (i != nvarbind) + errx(1, "%s: unexpected amount of varbind (%zu/%zu)", __func__, + i, nvarbind); +} diff --git a/regress/usr.sbin/snmpd/snmpd.conf b/regress/usr.sbin/snmpd/snmpd.conf new file mode 100644 index 00000000000..0bbea076733 --- /dev/null +++ b/regress/usr.sbin/snmpd/snmpd.conf @@ -0,0 +1,35 @@ +## Generic config to test internals + +# Assume snmp ports are available +listen on 127.0.0.1 snmpv1 snmpv2c snmpv3 +listen on tcp 127.0.0.1 snmpv1 snmpv2c snmpv3 + +agentx path "/tmp/agentx" mode 222 + +system contact "regress@openbsd.org" + +# SNMPv1/SNMPv2c +read-only community public +trap community private + +# SNMPv3 +seclevel none +user noauthpriv +user auth_md5 authkey testpass auth hmac-md5 +user auth_sha1 authkey testpass auth hmac-sha1 +user auth_sha224 authkey testpass auth hmac-sha224 +user auth_sha256 authkey testpass auth hmac-sha256 +user auth_sha384 authkey testpass auth hmac-sha384 +user auth_sha512 authkey testpass auth hmac-sha512 +user authpriv_md5_des authkey testpass auth hmac-md5 enckey testpass enc des +user authpriv_md5_aes authkey testpass auth hmac-md5 enckey testpass enc aes +user authpriv_sha1_des authkey testpass auth hmac-sha1 enckey testpass enc des +user authpriv_sha1_aes authkey testpass auth hmac-sha1 enckey testpass enc aes +user authpriv_sha224_des authkey testpass auth hmac-sha224 enckey testpass enc des +user authpriv_sha224_aes authkey testpass auth hmac-sha224 enckey testpass enc aes +user authpriv_sha256_des authkey testpass auth hmac-sha256 enckey testpass enc des +user authpriv_sha256_aes authkey testpass auth hmac-sha256 enckey testpass enc aes +user authpriv_sha384_des authkey testpass auth hmac-sha384 enckey testpass enc des +user authpriv_sha384_aes authkey testpass auth hmac-sha384 enckey testpass enc aes +user authpriv_sha512_des authkey testpass auth hmac-sha512 enckey testpass enc des +user authpriv_sha512_aes authkey testpass auth hmac-sha512 enckey testpass enc aes diff --git a/regress/usr.sbin/snmpd/snmpd_regress.c b/regress/usr.sbin/snmpd/snmpd_regress.c new file mode 100644 index 00000000000..a4decb6480f --- /dev/null +++ b/regress/usr.sbin/snmpd/snmpd_regress.c @@ -0,0 +1,309 @@ +#include + +#include +#include +#include +#include +#include +#include + +#include "regress.h" + +__dead void usage(void); + +const struct { + char *target; + void (*function)(void); +} targets[] = { + { "agentx_open_nnbo", agentx_open_nnbo }, + { "agentx_open_nbo", agentx_open_nbo }, + { "agentx_open_invalidversion", agentx_open_invalidversion }, + { "agentx_open_ignore_sessionid", agentx_open_ignore_sessionid }, + { "agentx_open_invalid_oid", agentx_open_invalid_oid }, + { "agentx_open_descr_too_long", agentx_open_descr_too_long }, + { "agentx_open_descr_invalid", agentx_open_descr_invalid }, + { "agentx_open_context", agentx_open_context }, + { "agentx_open_instance_registration", agentx_open_instance_registration }, + { "agentx_open_new_index", agentx_open_new_index }, + { "agentx_open_any_index", agentx_open_any_index }, + { "agentx_ping_notopen", agentx_ping_notopen }, + { "agentx_ping_invalid_sessionid", agentx_ping_invalid_sessionid }, + { "agentx_ping_default", agentx_ping_default }, + { "agentx_ping_context", agentx_ping_context }, + { "agentx_ping_invalid_version", agentx_ping_invalid_version }, + { "agentx_ping_instance_registration", agentx_ping_instance_registration }, + { "agentx_ping_new_index", agentx_ping_new_index }, + { "agentx_ping_any_index", agentx_ping_any_index }, + { "agentx_ping_nbo_nnbo", agentx_ping_nbo_nnbo }, + { "agentx_ping_nnbo_nbo", agentx_ping_nnbo_nbo }, + { "agentx_close_notopen", agentx_close_notopen }, + { "agentx_close_reasonother", agentx_close_reasonother }, + { "agentx_close_reasonparseerror", agentx_close_reasonparseerror }, + { "agentx_close_reasonprotocolerror", agentx_close_reasonprotocolerror }, + { "agentx_close_reasontimouts", agentx_close_reasontimouts }, + { "agentx_close_reasonshutdown", agentx_close_reasonshutdown }, + { "agentx_close_reasonbymanager", agentx_close_reasonbymanager }, + { "agentx_close_reasoninvalid", agentx_close_reasoninvalid }, + { "agentx_close_single", agentx_close_single }, + { "agentx_close_notowned", agentx_close_notowned }, + { "agentx_close_invalid_sessionid", agentx_close_invalid_sessionid }, + { "agentx_close_context", agentx_close_context }, + { "agentx_close_invalid_version", agentx_close_invalid_version }, + { "agentx_close_instance_registration", agentx_close_instance_registration }, + { "agentx_close_new_index", agentx_close_new_index }, + { "agentx_close_any_index", agentx_close_any_index }, + { "agentx_close_nnbo_nbo", agentx_close_nnbo_nbo }, + { "agentx_register_notopen", agentx_register_notopen }, + { "agentx_register_invalid_sessionid", agentx_register_invalid_sessionid }, + { "agentx_register_default", agentx_register_default }, + { "agentx_register_context", agentx_register_context }, + { "agentx_register_invalid_version", agentx_register_invalid_version }, + { "agentx_register_instance_registration", agentx_register_instance_registration }, + { "agentx_register_new_index", agentx_register_new_index }, + { "agentx_register_any_index", agentx_register_any_index }, + { "agentx_register_duplicate_self", agentx_register_duplicate_self }, + { "agentx_register_duplicate_twocon", agentx_register_duplicate_twocon }, + { "agentx_register_duplicate_priority", agentx_register_duplicate_priority }, + { "agentx_register_range", agentx_register_range }, + { "agentx_register_range_invalidupperbound", agentx_register_range_invalidupperbound }, + { "agentx_register_range_single", agentx_register_range_single }, + { "agentx_register_range_overlap_single", agentx_register_range_overlap_single }, + { "agentx_register_single_overlap_range", agentx_register_single_overlap_range }, + { "agentx_register_range_overlap_range", agentx_register_range_overlap_range }, + { "agentx_register_below", agentx_register_below }, + { "agentx_register_above", agentx_register_above }, + { "agentx_register_restricted", agentx_register_restricted }, + { "agentx_unregister_notopen", agentx_unregister_notopen }, + { "agentx_unregister_invalid_sessionid", agentx_unregister_invalid_sessionid }, + { "agentx_unregister_notregistered", agentx_unregister_notregistered }, + { "agentx_unregister_single", agentx_unregister_single }, + { "agentx_unregister_single_notowned", agentx_unregister_single_notowned }, + { "agentx_unregister_range", agentx_unregister_range }, + { "agentx_unregister_range_single", agentx_unregister_range_single }, + { "agentx_unregister_range_subset", agentx_unregister_range_subset }, + { "agentx_unregister_range_extra", agentx_unregister_range_extra }, + { "agentx_unregister_range_priority", agentx_unregister_range_priority }, + { "agentx_unregister_range_notowned", agentx_unregister_range_notowned }, + { "backend_get_integer", backend_get_integer }, + { "backend_get_octetstring", backend_get_octetstring }, + { "backend_get_objectidentifier", backend_get_objectidentifier }, + { "backend_get_ipaddress", backend_get_ipaddress }, + { "backend_get_counter32", backend_get_counter32 }, + { "backend_get_gauge32", backend_get_gauge32 }, + { "backend_get_timeticks", backend_get_timeticks }, + { "backend_get_opaque", backend_get_opaque }, + { "backend_get_counter64", backend_get_counter64 }, + { "backend_get_nosuchobject", backend_get_nosuchobject }, + { "backend_get_nosuchinstance", backend_get_nosuchinstance }, + { "backend_get_endofmibview", backend_get_endofmibview }, + { "backend_get_two_single_backend", backend_get_two_single_backend }, + { "backend_get_two_double_backend", backend_get_two_double_backend }, + { "backend_get_wrongorder", backend_get_wrongorder }, + { "backend_get_toofew", backend_get_toofew }, + { "backend_get_toomany", backend_get_toomany }, + { "backend_get_instance", backend_get_instance }, + { "backend_get_instance_below", backend_get_instance_below }, + { "backend_get_timeout_default", backend_get_timeout_default }, + { "backend_get_timeout_session_lower", backend_get_timeout_session_lower }, + { "backend_get_timeout_session_higher", backend_get_timeout_session_higher }, + { "backend_get_timeout_region_lower", backend_get_timeout_region_lower }, + { "backend_get_timeout_region_higher", backend_get_timeout_region_higher }, + { "backend_get_priority_lower", backend_get_priority_lower }, + { "backend_get_priority_higher", backend_get_priority_higher }, + { "backend_get_priority_below_lower", backend_get_priority_below_lower }, + { "backend_get_priority_below_higher", backend_get_priority_below_higher }, + { "backend_get_close", backend_get_close }, + { "backend_get_close_overlap", backend_get_close_overlap }, + { "backend_get_disappear", backend_get_disappear }, + { "backend_get_disappear_overlap", backend_get_disappear_overlap }, + { "backend_get_disappear_doublesession", backend_get_disappear_doublesession }, + { "backend_getnext_selfbound", backend_getnext_selfbound }, + { "backend_getnext_lowerbound", backend_getnext_lowerbound }, + { "backend_getnext_lowerbound_self", backend_getnext_lowerbound_self }, + { "backend_getnext_lowerbound_highprio", backend_getnext_lowerbound_highprio }, + { "backend_getnext_lowerbound_lowprio", backend_getnext_lowerbound_lowprio }, + { "backend_getnext_sibling", backend_getnext_sibling }, + { "backend_getnext_child_gap", backend_getnext_child_gap }, + { "backend_getnext_nosuchobject", backend_getnext_nosuchobject }, + { "backend_getnext_nosuchinstance", backend_getnext_nosuchinstance }, + { "backend_getnext_endofmibview", backend_getnext_endofmibview }, + { "backend_getnext_inclusive", backend_getnext_inclusive }, + { "backend_getnext_jumpnext", backend_getnext_jumpnext }, + { "backend_getnext_jumpnext_endofmibview", backend_getnext_jumpnext_endofmibview }, + { "backend_getnext_jump_up", backend_getnext_jump_up }, + { "backend_getnext_two_single_backend", backend_getnext_two_single_backend }, + { "backend_getnext_two_double_backend", backend_getnext_two_double_backend }, + { "backend_getnext_instance_below", backend_getnext_instance_below }, + { "backend_getnext_instance", backend_getnext_instance }, + { "backend_getnext_instance_exact", backend_getnext_instance_exact }, + { "backend_getnext_instance_ignore", backend_getnext_instance_ignore }, + { "backend_getnext_backwards", backend_getnext_backwards }, + { "backend_getnext_stale", backend_getnext_stale }, + { "backend_getnext_inclusive_backwards", backend_getnext_inclusive_backwards }, + { "backend_getnext_toofew", backend_getnext_toofew }, + { "backend_getnext_toomany", backend_getnext_toomany }, + { "backend_getbulk_nonrep_zero_maxrep_one", backend_getbulk_nonrep_zero_maxrep_one }, + { "backend_getbulk_nonrep_zero_maxrep_two", backend_getbulk_nonrep_zero_maxrep_two }, + { "backend_getbulk_nonrep_one_maxrep_one", backend_getbulk_nonrep_one_maxrep_one }, + { "backend_getbulk_nonrep_one_maxrep_two", backend_getbulk_nonrep_one_maxrep_two }, + { "backend_getbulk_nonrep_two_maxrep_two", backend_getbulk_nonrep_two_maxrep_two }, + { "backend_getbulk_nonrep_negative", backend_getbulk_nonrep_negative }, + { "backend_error_get_toobig", backend_error_get_toobig }, + { "backend_error_get_nosuchname", backend_error_get_nosuchname }, + { "backend_error_get_badvalue", backend_error_get_badvalue }, + { "backend_error_get_readonly", backend_error_get_readonly }, + { "backend_error_get_generr", backend_error_get_generr }, + { "backend_error_get_wrongtype", backend_error_get_wrongtype }, + { "backend_error_get_wronglength", backend_error_get_wronglength }, + { "backend_error_get_wrongvalue", backend_error_get_wrongvalue }, + { "backend_error_get_nocreation", backend_error_get_nocreation }, + { "backend_error_get_inconsistentvalue", backend_error_get_inconsistentvalue }, + { "backend_error_get_commitfailed", backend_error_get_commitfailed }, + { "backend_error_get_undofailed", backend_error_get_undofailed }, + { "backend_error_get_authorizationerror", backend_error_get_authorizationerror }, + { "backend_error_get_notwritable", backend_error_get_notwritable }, + { "backend_error_get_inconsistentname", backend_error_get_inconsistentname }, + { "backend_error_get_openfailed", backend_error_get_openfailed }, + { "backend_error_get_notopen", backend_error_get_notopen }, + { "backend_error_get_indexwrongtype", backend_error_get_indexwrongtype }, + { "backend_error_get_indexalreadyallocated", backend_error_get_indexalreadyallocated }, + { "backend_error_get_indexnonavailable", backend_error_get_indexnonavailable }, + { "backend_error_get_indexnotallocated", backend_error_get_indexnotallocated }, + { "backend_error_get_duplicateregistration", backend_error_get_duplicateregistration }, + { "backend_error_get_requestdenied", backend_error_get_requestdenied }, + { "backend_error_get_processingerror", backend_error_get_processingerror }, + { "backend_error_get_nonstandard", backend_error_get_nonstandard }, + { "backend_error_getnext_toobig", backend_error_getnext_toobig }, + { "backend_error_getnext_nosuchname", backend_error_getnext_nosuchname }, + { "backend_error_getnext_badvalue", backend_error_getnext_badvalue }, + { "backend_error_getnext_readonly", backend_error_getnext_readonly }, + { "backend_error_getnext_generr", backend_error_getnext_generr }, + { "backend_error_getnext_noaccess", backend_error_getnext_noaccess }, + { "backend_error_getnext_wrongtype", backend_error_getnext_wrongtype }, + { "backend_error_getnext_wronglength", backend_error_getnext_wronglength }, + { "backend_error_getnext_wrongencoding", backend_error_getnext_wrongencoding }, + { "backend_error_getnext_wrongvalue", backend_error_getnext_wrongvalue }, + { "backend_error_getnext_nocreation", backend_error_getnext_nocreation }, + { "backend_error_getnext_inconsistentvalue", backend_error_getnext_inconsistentvalue }, + { "backend_error_getnext_resourceunavailable", backend_error_getnext_resourceunavailable }, + { "backend_error_getnext_commitfailed", backend_error_getnext_commitfailed }, + { "backend_error_getnext_undofailed", backend_error_getnext_undofailed }, + { "backend_error_getnext_notwritable", backend_error_getnext_notwritable }, + { "backend_error_getnext_inconsistentname", backend_error_getnext_inconsistentname }, + { "backend_error_getnext_openfailed", backend_error_getnext_openfailed }, + { "backend_error_getnext_notopen", backend_error_getnext_notopen }, + { "backend_error_getnext_indexwrongtype", backend_error_getnext_indexwrongtype }, + { "backend_error_getnext_indexalreadyallocated", backend_error_getnext_indexalreadyallocated }, + { "backend_error_getnext_indexnonavailable", backend_error_getnext_indexnonavailable }, + { "backend_error_getnext_indexnotallocated", backend_error_getnext_indexnotallocated }, + { "backend_error_getnext_unsupportedcontext", backend_error_getnext_unsupportedcontext }, + { "backend_error_getnext_duplicateregistration", backend_error_getnext_duplicateregistration }, + { "backend_error_getnext_unknownregistration", backend_error_getnext_unknownregistration }, + { "backend_error_getnext_parseerror", backend_error_getnext_parseerror }, + { "backend_error_getnext_requestdenied", backend_error_getnext_requestdenied }, + { "backend_error_getnext_processingerror", backend_error_getnext_processingerror }, + { "backend_error_getnext_nonstandard", backend_error_getnext_nonstandard }, + { NULL, NULL } +}; + +int verbose = 0; +char *axsocket = NULL; + +char *hostname = NULL; +char *servname = NULL; + +char *community = NULL; + +int +main(int argc, char *argv[]) +{ + size_t i, j; + int c; + + while ((c = getopt(argc, argv, "a:h:p:v")) != -1) { + switch (c) { + case 'a': + axsocket = optarg; + break; + case 'c': + community = optarg; + break; + case 'h': + hostname = optarg; + break; + case 'p': + servname = optarg; + break; + case 'v': + verbose = 1; + break; + default: + usage(); + } + } + argc -= optind; + argv += optind; + + if (argc != 1) + usage(); + + for (i = 0; i < argc; i++) { + for (j = 0; targets[j].target != NULL; j++) { + if (strcmp(argv[i], targets[j].target) == 0) { + targets[j].function(); + return 0; + } + } + } + + errx(1, "Unknown target: %s", argv[1]); +} + +__dead void +usage(void) +{ + fprintf(stderr, "%s: [-v] [-a axsocket] test\n", getprogname()); + exit(1); +} + +int +oid_cmp(struct oid *a, struct oid *b) +{ + size_t i, min; + + min = a->n_subid < b->n_subid ? a->n_subid : b->n_subid; + for (i = 0; i < min; i++) { + if (a->subid[i] < b->subid[i]) + return (-1); + if (a->subid[i] > b->subid[i]) + return (1); + } + /* a is parent of b */ + if (a->n_subid < b->n_subid) + return (-2); + /* a is child of b */ + if (a->n_subid > b->n_subid) + return 2; + return (0); +} + +char * +oid_print(struct oid *oid, char *buf, size_t len) +{ + char digit[11]; + size_t i; + + buf[0] = '\0'; + for (i = 0; i < oid->n_subid; i++) { + snprintf(digit, sizeof(digit), "%"PRIu32, oid->subid[i]); + if (i > 0) + strlcat(buf, ".", len); + strlcat(buf, digit, len); + } + if (oid->include) { + strlcat(buf, "incl", len); + snprintf(digit, sizeof(digit), "(%d)", oid->include); + strlcat(buf, digit, len); + } + return buf; +}