diff options
author | Bret Lambert <blambert@cvs.openbsd.org> | 2014-11-19 10:19:01 +0000 |
---|---|---|
committer | Bret Lambert <blambert@cvs.openbsd.org> | 2014-11-19 10:19:01 +0000 |
commit | ff01fb2a97a4878f33c682a1e5148449d815102c (patch) | |
tree | e7802db249a7db6747d2f14843eb12da49e9b3d5 /usr.sbin/snmpd/util.c | |
parent | 5df5cffb8baae7d93397602aec987c965354dd8f (diff) |
add support for AgentX subagents in snmpd
snmp requests are now packaged into pseudo-continuations
to allow for being dispatched to seperate processes;
lightly tested for interoperability with NetSNMP, but
doesn't implement the complete set of AgentX messages
while here, clean up return types of mps_get* functions,
and make smi_insert refuse to insert duplicate OIDs
okay benno@ reyk@
Diffstat (limited to 'usr.sbin/snmpd/util.c')
-rw-r--r-- | usr.sbin/snmpd/util.c | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/usr.sbin/snmpd/util.c b/usr.sbin/snmpd/util.c new file mode 100644 index 00000000000..e744be40a10 --- /dev/null +++ b/usr.sbin/snmpd/util.c @@ -0,0 +1,139 @@ +/* $OpenBSD */ +/* + * Copyright (c) 2014 Bret Stephen Lambert <blambert@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/queue.h> +#include <sys/socket.h> + +#include <net/if.h> + +#include <event.h> + +#include "ber.h" +#include "snmp.h" +#include "snmpd.h" + +/* + * Convert variable bindings from AgentX to SNMP dialect. + */ +int +varbind_convert(struct agentx_pdu *pdu, struct agentx_varbind_hdr *vbhdr, + struct ber_element **varbind, struct ber_element **iter) +{ + struct ber_oid oid; + u_int32_t d; + u_int64_t l; + int slen; + char *str; + struct ber_element *a; + int ret = AGENTX_ERR_NONE; + + if (snmp_agentx_read_oid(pdu, (struct snmp_oid *)&oid) == -1) { + ret = AGENTX_ERR_PARSE_ERROR; + goto done; + } + + *iter = ber_add_sequence(*iter); + if (*varbind == NULL) + *varbind = *iter; + + a = ber_add_oid(*iter, &oid); + + switch (vbhdr->type) { + case AGENTX_NO_SUCH_OBJECT: + case AGENTX_NO_SUCH_INSTANCE: + case AGENTX_END_OF_MIB_VIEW: + case AGENTX_NULL: + a = ber_add_null(a); + break; + + case AGENTX_IP_ADDRESS: + case AGENTX_OPAQUE: + case AGENTX_OCTET_STRING: + str = snmp_agentx_read_octetstr(pdu, &slen); + if (str == NULL) { + ret = AGENTX_ERR_PARSE_ERROR; + goto done; + } + a = ber_add_nstring(a, str, slen); + break; + + case AGENTX_OBJECT_IDENTIFIER: + if (snmp_agentx_read_oid(pdu, + (struct snmp_oid *)&oid) == -1) { + ret = AGENTX_ERR_PARSE_ERROR; + goto done; + } + a = ber_add_oid(a, &oid); + break; + + case AGENTX_INTEGER: + case AGENTX_COUNTER32: + case AGENTX_GAUGE32: + case AGENTX_TIME_TICKS: + if (snmp_agentx_read_int(pdu, &d) == -1) { + ret = AGENTX_ERR_PARSE_ERROR; + goto done; + } + a = ber_add_integer(a, d); + break; + + case AGENTX_COUNTER64: + if (snmp_agentx_read_int64(pdu, &l) == -1) { + ret = AGENTX_ERR_PARSE_ERROR; + goto done; + } + a = ber_add_integer(a, l); + break; + + default: + log_debug("unknown data type '%i'", vbhdr->type); + ret = AGENTX_ERR_PARSE_ERROR; + goto done; + } + + /* AgentX types correspond to BER types */ + switch (vbhdr->type) { + case BER_TYPE_INTEGER: + case BER_TYPE_BITSTRING: + case BER_TYPE_OCTETSTRING: + case BER_TYPE_NULL: + case BER_TYPE_OBJECT: + /* universal types */ + break; + + /* Convert AgentX error types to SNMP error types */ + case AGENTX_NO_SUCH_OBJECT: + ber_set_header(a, BER_CLASS_CONTEXT, 0); + break; + case AGENTX_NO_SUCH_INSTANCE: + ber_set_header(a, BER_CLASS_CONTEXT, 1); + break; + + case AGENTX_COUNTER64: + ber_set_header(a, BER_CLASS_APPLICATION, SNMP_COUNTER64); + break; + + default: + /* application-specific types */ + ber_set_header(a, BER_CLASS_APPLICATION, vbhdr->type); + break; + } + done: + return (ret); +} |