summaryrefslogtreecommitdiffstats
path: root/contrib/bsnmp/snmp_target
diff options
context:
space:
mode:
authorsyrinx <syrinx@FreeBSD.org>2010-12-20 17:13:14 +0000
committersyrinx <syrinx@FreeBSD.org>2010-12-20 17:13:14 +0000
commitcdf73327e5ede68524c23f9fb281bbbd7c771b07 (patch)
tree5b7dd1db00389b1d0504f34a299b48339c9b9aac /contrib/bsnmp/snmp_target
parent0f810ef0a25b4d64ffe05b47b5dfd30d73167b71 (diff)
downloadFreeBSD-src-cdf73327e5ede68524c23f9fb281bbbd7c771b07.zip
FreeBSD-src-cdf73327e5ede68524c23f9fb281bbbd7c771b07.tar.gz
Bring in a SNMP module that allows configuration of SNMPv3 Notification targets.
Sponsored by: The FreeBSD Foundation Reviewed by: philip Approved by: philip
Diffstat (limited to 'contrib/bsnmp/snmp_target')
-rwxr-xr-xcontrib/bsnmp/snmp_target/snmp_target.3204
-rwxr-xr-xcontrib/bsnmp/snmp_target/target_snmp.c837
-rwxr-xr-xcontrib/bsnmp/snmp_target/target_tree.def95
3 files changed, 1136 insertions, 0 deletions
diff --git a/contrib/bsnmp/snmp_target/snmp_target.3 b/contrib/bsnmp/snmp_target/snmp_target.3
new file mode 100755
index 0000000..03071b5
--- /dev/null
+++ b/contrib/bsnmp/snmp_target/snmp_target.3
@@ -0,0 +1,204 @@
+.\"-
+.\" Copyright (C) 2010 The FreeBSD Foundation
+.\" All rights reserved.
+.\"
+.\" This documentation was written by Shteryana Sotirova Shopova under
+.\" sponsorship from the FreeBSD Foundation.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd December 16, 2010
+.Dt SNMP_TARGET 3
+.Os
+.Sh NAME
+.Nm snmp_target
+.Nd "Target addresses and notifications module for
+.Xr bsnmpd 1
+.Sh LIBRARY
+.Pq begemotSnmpdModulePath."target" = "/usr/lib/snmp_target.so"
+.Sh DESCRIPTION
+The
+.Nm snmp_target
+module implements SNMPv3 Management Target MIB and basic functionality from
+Notification MIB as defined in RFC 3413. The module is used to manage the
+internal list of SNMPv3 notification target addresses in
+.Nm bsnmpd
+and their associated transport and encapsulation parameters.
+The module must be loaded for
+.Nm bsnmpd
+to send SNMPv3 Trap-PDUs to the configured notification target addresses.
+.Sh IMPLEMENTATION NOTES
+A short description of the objects implemented in the module follows.
+.Bl -tag -width "XXXXXXXXX"
+.It Va snmpTargetSpinLock
+An advisory lock used to coordinate several Command Generator Applications when
+altering the SNMP Target addresses and their associated parameters.
+.It Va snmpTargetAddrTable
+The table contains the transport addresses to be used in generation of SNMP
+messages.
+The table contains the following objects
+.Bl -tag -width ".It Va snmpTargetAddrName"
+.It Va snmpTargetAddrName
+A unique local identifier used as entry key. Not accessible for GET or SET
+operations.
+.It Va snmpTargetAddrTDomain
+The transport domain of the target address. Currently only UDP over IPv4 is
+supported and any attempt to SET the value of this object will return an
+"inconsistentValue" error. Additional transport domains will be supported
+in future via the object definitions in TRANSPORT-ADDRESS-MIB (RFC 3419).
+.It Va snmpTargetAddrTAddress
+The transport address of this entry interpreted within the context of the value
+of
+.Va snmpTargetAddrTDomain .
+For UDP over IPv4, this is a 6-byte long octetstring, with the first 4 bytes
+representing the IPv4 address and the last 2 bytes the UDP port number in
+network-byte order.
+.It Va snmpTargetAddrTimeout
+The value of this object is only relevant when the receiver of the SNMP
+message is to send an acknowledgment that the message was received, i.e
+for SNMP notifications it is relevant if the notification is SNMP Inform
+rather than SNMP Trap. Currently
+.Nm bsnmpd
+supports only SNMP Trap notifications, so the value of this object is
+meaningless.
+.It Va snmpTargetAddrRetryCount
+As with
+.Va snmpTargetAddrTimeout
+the value of this object currently is meaningless.
+.It Va snmpTargetAddrTagList
+A list of human-readable tag values used to select target addresses for a
+particular operation. Recognized ASCII delimiting characters between tags are
+space (0x20), tab (0x20), carriage return (0xOD) and line feed (0x0A).
+.It Va snmpTargetAddrParams
+The value of this object contains the value of a key in snmpTargetParamsTable
+containing SNMP parameters used when generating messages to this transport
+address.
+.It Va snmpTargetAddrStorageType
+This column always has either of two values. Entries created via
+.Nm bsnmpd's
+configuration file always have this column set to readOnly (5) and
+it is not possible to modify those entries. Entries created by Command Generator
+Applications always have this column set to volatile(2) and such entries are
+lost when the module is restarted. A SET operation on this column is not
+allowed.
+.It Va snmpTargetAddrRowStatus
+This column is used to create new target address entries or delete existing ones
+from the table.
+.El
+.It Va snmpTargetParamsTable
+The table contains the target information to be used in generation of SNMP
+messages.
+The table contains the following objects
+.Bl -tag -width ".It Va snmpTargetParamsName"
+.It Va snmpTargetParamsName
+A unique local identifier used as entry key. Not accessible for GET or SET
+operations.
+.It Va snmpTargetParamsMPModel
+The Message Processing Model to be used when generating SNMP PDUs using this
+entry. Supported values are 0 for SNMPv1, 1 for SNMPv2c and 3 for SNMPv3.
+.It Va snmpTargetParamsSecurityModel
+The Security Model to be used when generating SNMP PDUs using this entry.
+Supported values are 1 for SNMPv1, 2 for SNMPv2c and 3 for SNMPv3 User-Based
+Security Model.
+.It Va snmpTargetParamsSecurityName
+The securityName which identifies the Principal on whose behalf SNMP PDUs
+will be generated using this entry. For SNMPv1 and SNMPv2c this is the
+name of a community configured in
+.Nm bsnmpd ,
+and for SNMPv3 USM, this is the name of an existing user configured via the
+.Nm snmp_usm
+module.
+.It Va snmpTargetParamsSecurityLevel
+The Security Level to be used when generating SNMP PDUs using this entry.
+Supported values are noAuthNoPriv(1) for plain-text PDUs with no authentication,
+authNoPriv(2) for authenticated plain-text PDUs and authPriv(3) for encrypted
+PDUs.
+.It Va snmpTargetParamsStorageType
+As with
+.Va snmpTargetAddrStorageType
+this column always has either of two values. Entries created via
+.Nm bsnmpd's
+configuration file always have this column set to readOnly (5), while entries
+created by Command Generator Applications always have this column set to
+volatile(2). A SET operation on this column is not allowed.
+.It Va snmpTargetParamsRowStatus
+This column is used to create new target address parameters entries or delete
+existing ones from the table.
+.El
+.It Va snmpNotifyTable
+The table is used to select the management targets which should receive SNMP
+notifications.
+The table contains the following objects
+.Bl -tag -width ".It Va snmpNotifyName"
+.It Va snmpNotifyName
+A unique local identifier used as entry key. Not accessible for GET or SET
+operations.
+.It Va snmpNotifyTag
+This object contains a single tag value used to select target addresses from
+the
+.Va snmpTargetAddrTable
+to which the notifications will be send.
+.It Va snmpNotifyType
+The type of SNMP notifications that will be send to the target addresses
+matching the corresponding
+.Va snmpNotifyTag .
+Possible values are Trap (1) or Inform (2). Currently only SNMP Traps are
+supported and any attempt to SET the value of this object will return an
+"inconsistentValue" error.
+.It Va snmpNotifyStorageType
+Again this column always has either of two values. Entries created via
+.Nm bsnmpd's
+configuration file always have this column set to readOnly (5), while entries
+created by Command Generator Applications always have this column set to
+volatile(2). A SET operation on this column is not allowed.
+.It Va snmpNotifyRowStatus
+This column is used to create new notification target entries or delete existing
+ones from the table.
+.El
+.El
+.Pp
+The
+.Va snmpNotifyFilterProfileTable
+and
+.Va snmpNotifyFilterTable
+tables from the SNMP-NOTIFICATION-MIB are not supported by the module.
+Notification filtering is supported via the
+.Xr snmp_vacm 3
+module instead.
+.Sh FILES
+.Bl -tag -width "XXXXXXXXX"
+.It Pa /usr/share/snmp/defs/target_tree.def
+The description of the MIB tree implemented by
+.Nm .
+.El
+.Sh SEE ALSO
+.Xr bsnmpd 1 ,
+.Xr gensnmptree 1 ,
+.Xr snmpmod 3 ,
+.Xr snmp_usm 3 ,
+.Xr snmp_vacm 3
+.Sh STANDARDS
+IETF RFC 3413
+.Sh AUTHORS
+.An Shteryana Shopova Aq syrinx@FreeBSD.org
diff --git a/contrib/bsnmp/snmp_target/target_snmp.c b/contrib/bsnmp/snmp_target/target_snmp.c
new file mode 100755
index 0000000..c6f05de
--- /dev/null
+++ b/contrib/bsnmp/snmp_target/target_snmp.c
@@ -0,0 +1,837 @@
+/*-
+ * Copyright (c) 2010 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Shteryana Sotirova Shopova under
+ * sponsorship from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#include <sys/queue.h>
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <syslog.h>
+
+#include "asn1.h"
+#include "snmp.h"
+#include "snmpmod.h"
+
+#include "target_tree.h"
+#include "target_oid.h"
+
+static struct lmodule *target_module;
+/* For the registration. */
+static const struct asn_oid oid_target = OIDX_snmpTargetMIB;
+static const struct asn_oid oid_notification = OIDX_snmpNotificationMIB;
+
+static uint reg_target;
+static uint reg_notification;
+
+static int32_t target_lock;
+
+static const struct asn_oid oid_udp_domain = OIDX_snmpUDPDomain;
+
+/*
+ * Internal datastructures and forward declarations.
+ */
+static void target_append_index(struct asn_oid *, uint,
+ const char *);
+static int target_decode_index(const struct asn_oid *, uint,
+ char *);
+static struct target_address *target_get_address(const struct asn_oid *,
+ uint);
+static struct target_address *target_get_next_address(const struct asn_oid *,
+ uint);
+static struct target_param *target_get_param(const struct asn_oid *,
+ uint);
+static struct target_param *target_get_next_param(const struct asn_oid *,
+ uint);
+static struct target_notify *target_get_notify(const struct asn_oid *,
+ uint);
+static struct target_notify *target_get_next_notify(const struct asn_oid *,
+ uint);
+
+int
+op_snmp_target(struct snmp_context *ctx __unused, struct snmp_value *val,
+ uint32_t sub, uint32_t iidx __unused, enum snmp_op op)
+{
+ struct snmpd_target_stats *ctx_stats;
+
+ if (val->var.subs[sub - 1] == LEAF_snmpTargetSpinLock) {
+ switch (op) {
+ case SNMP_OP_GET:
+ if (++target_lock == INT32_MAX)
+ target_lock = 0;
+ val->v.integer = target_lock;
+ break;
+ case SNMP_OP_GETNEXT:
+ abort();
+ case SNMP_OP_SET:
+ if (val->v.integer != target_lock)
+ return (SNMP_ERR_INCONS_VALUE);
+ break;
+ case SNMP_OP_ROLLBACK:
+ /* FALLTHROUGH */
+ case SNMP_OP_COMMIT:
+ break;
+ }
+ return (SNMP_ERR_NOERROR);
+ } else if (op == SNMP_OP_SET)
+ return (SNMP_ERR_NOT_WRITEABLE);
+
+ if ((ctx_stats = bsnmpd_get_target_stats()) == NULL)
+ return (SNMP_ERR_GENERR);
+
+ if (op == SNMP_OP_GET) {
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_snmpUnavailableContexts:
+ val->v.uint32 = ctx_stats->unavail_contexts;
+ break;
+ case LEAF_snmpUnknownContexts:
+ val->v.uint32 = ctx_stats->unknown_contexts;
+ break;
+ default:
+ return (SNMP_ERR_NOSUCHNAME);
+ }
+ return (SNMP_ERR_NOERROR);
+ }
+ abort();
+}
+
+int
+op_snmp_target_addrs(struct snmp_context *ctx __unused, struct snmp_value *val,
+ uint32_t sub, uint32_t iidx __unused, enum snmp_op op)
+{
+ char aname[SNMP_ADM_STR32_SIZ];
+ struct target_address *addrs;
+
+ switch (op) {
+ case SNMP_OP_GET:
+ if ((addrs = target_get_address(&val->var, sub)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ break;
+
+ case SNMP_OP_GETNEXT:
+ if ((addrs = target_get_next_address(&val->var, sub)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ target_append_index(&val->var, sub, addrs->name);
+ break;
+
+ case SNMP_OP_SET:
+ if ((addrs = target_get_address(&val->var, sub)) == NULL &&
+ (val->var.subs[sub - 1] != LEAF_snmpTargetAddrRowStatus ||
+ val->v.integer != RowStatus_createAndWait))
+ return (SNMP_ERR_NOSUCHNAME);
+
+ if (addrs != NULL) {
+ if (community != COMM_INITIALIZE &&
+ addrs->type == StorageType_readOnly)
+ return (SNMP_ERR_NOT_WRITEABLE);
+ if (addrs->status == RowStatus_active &&
+ val->v.integer != RowStatus_destroy)
+ return (SNMP_ERR_INCONS_VALUE);
+ }
+
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_snmpTargetAddrTDomain:
+ return (SNMP_ERR_INCONS_VALUE);
+ case LEAF_snmpTargetAddrTAddress:
+ if (val->v.octetstring.len != SNMP_UDP_ADDR_SIZ)
+ return (SNMP_ERR_INCONS_VALUE);
+ ctx->scratch->ptr1 = malloc(SNMP_UDP_ADDR_SIZ);
+ if (ctx->scratch->ptr1 == NULL)
+ return (SNMP_ERR_GENERR);
+ memcpy(ctx->scratch->ptr1, addrs->address,
+ SNMP_UDP_ADDR_SIZ);
+ memcpy(addrs->address, val->v.octetstring.octets,
+ SNMP_UDP_ADDR_SIZ);
+ break;
+
+ case LEAF_snmpTargetAddrTagList:
+ if (val->v.octetstring.len >= SNMP_TAG_SIZ)
+ return (SNMP_ERR_INCONS_VALUE);
+ ctx->scratch->int1 = strlen(addrs->taglist) + 1;
+ ctx->scratch->ptr1 = malloc(ctx->scratch->int1);
+ if (ctx->scratch->ptr1 == NULL)
+ return (SNMP_ERR_GENERR);
+ strlcpy(ctx->scratch->ptr1, addrs->taglist,
+ ctx->scratch->int1);
+ memcpy(addrs->taglist, val->v.octetstring.octets,
+ val->v.octetstring.len);
+ addrs->taglist[val->v.octetstring.len] = '\0';
+ break;
+
+ case LEAF_snmpTargetAddrParams:
+ if (val->v.octetstring.len >= SNMP_ADM_STR32_SIZ)
+ return (SNMP_ERR_INCONS_VALUE);
+ ctx->scratch->int1 = strlen(addrs->paramname) + 1;
+ ctx->scratch->ptr1 = malloc(ctx->scratch->int1);
+ if (ctx->scratch->ptr1 == NULL)
+ return (SNMP_ERR_GENERR);
+ strlcpy(ctx->scratch->ptr1, addrs->paramname,
+ ctx->scratch->int1);
+ memcpy(addrs->paramname, val->v.octetstring.octets,
+ val->v.octetstring.len);
+ addrs->paramname[val->v.octetstring.len] = '\0';
+ break;
+
+ case LEAF_snmpTargetAddrRetryCount:
+ ctx->scratch->int1 = addrs->retry;
+ addrs->retry = val->v.integer;
+ break;
+
+ case LEAF_snmpTargetAddrTimeout:
+ ctx->scratch->int1 = addrs->timeout;
+ addrs->timeout = val->v.integer / 10;
+ break;
+
+ case LEAF_snmpTargetAddrStorageType:
+ return (SNMP_ERR_INCONS_VALUE);
+
+ case LEAF_snmpTargetAddrRowStatus:
+ if (addrs != NULL) {
+ if (val->v.integer != RowStatus_active &&
+ val->v.integer != RowStatus_destroy)
+ return (SNMP_ERR_INCONS_VALUE);
+ if (val->v.integer == RowStatus_active &&
+ (addrs->address[0] == 0 ||
+ strlen(addrs->taglist) == 0 ||
+ strlen(addrs->paramname) == 0))
+ return (SNMP_ERR_INCONS_VALUE);
+ ctx->scratch->int1 = addrs->status;
+ addrs->status = val->v.integer;
+ return (SNMP_ERR_NOERROR);
+ }
+ if (val->v.integer != RowStatus_createAndWait ||
+ target_decode_index(&val->var, sub, aname) < 0)
+ return (SNMP_ERR_INCONS_VALUE);
+ if ((addrs = target_new_address(aname)) == NULL)
+ return (SNMP_ERR_GENERR);
+ addrs->status = RowStatus_destroy;
+ if (community != COMM_INITIALIZE)
+ addrs->type = StorageType_volatile;
+ else
+ addrs->type = StorageType_readOnly;
+ break;
+ }
+ return (SNMP_ERR_NOERROR);
+
+ case SNMP_OP_COMMIT:
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_snmpTargetAddrTAddress:
+ case LEAF_snmpTargetAddrTagList:
+ case LEAF_snmpTargetAddrParams:
+ free(ctx->scratch->ptr1);
+ break;
+ case LEAF_snmpTargetAddrRowStatus:
+ if ((addrs = target_get_address(&val->var, sub)) == NULL)
+ return (SNMP_ERR_GENERR);
+ if (val->v.integer == RowStatus_destroy)
+ return (target_delete_address(addrs));
+ else if (val->v.integer == RowStatus_active)
+ return (target_activate_address(addrs));
+ break;
+ default:
+ break;
+ }
+ return (SNMP_ERR_NOERROR);
+
+ case SNMP_OP_ROLLBACK:
+ if ((addrs = target_get_address(&val->var, sub)) == NULL)
+ return (SNMP_ERR_GENERR);
+
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_snmpTargetAddrTAddress:
+ memcpy(addrs->address, ctx->scratch->ptr1,
+ SNMP_UDP_ADDR_SIZ);
+ free(ctx->scratch->ptr1);
+ break;
+
+ case LEAF_snmpTargetAddrTagList:
+ strlcpy(addrs->taglist, ctx->scratch->ptr1,
+ ctx->scratch->int1);
+ free(ctx->scratch->ptr1);
+ break;
+
+ case LEAF_snmpTargetAddrParams:
+ strlcpy(addrs->paramname, ctx->scratch->ptr1,
+ ctx->scratch->int1);
+ free(ctx->scratch->ptr1);
+ break;
+
+ case LEAF_snmpTargetAddrRetryCount:
+ addrs->retry = ctx->scratch->int1;
+ break;
+
+ case LEAF_snmpTargetAddrTimeout:
+ addrs->timeout = ctx->scratch->int1;
+ break;
+
+ case LEAF_snmpTargetAddrRowStatus:
+ if (ctx->scratch->int1 == RowStatus_destroy)
+ return (target_delete_address(addrs));
+ break;
+ default:
+ break;
+ }
+
+ default:
+ abort();
+ }
+
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_snmpTargetAddrTDomain:
+ return (oid_get(val, &oid_udp_domain));
+ case LEAF_snmpTargetAddrTAddress:
+ return (string_get(val, addrs->address, SNMP_UDP_ADDR_SIZ));
+ case LEAF_snmpTargetAddrTimeout:
+ val->v.integer = addrs->timeout;
+ break;
+ case LEAF_snmpTargetAddrRetryCount:
+ val->v.integer = addrs->retry;
+ break;
+ case LEAF_snmpTargetAddrTagList:
+ return (string_get(val, addrs->taglist, -1));
+ case LEAF_snmpTargetAddrParams:
+ return (string_get(val, addrs->paramname, -1));
+ case LEAF_snmpTargetAddrStorageType:
+ val->v.integer = addrs->type;
+ break;
+ case LEAF_snmpTargetAddrRowStatus:
+ val->v.integer = addrs->status;
+ break;
+ default:
+ abort();
+ }
+
+ return (SNMP_ERR_NOERROR);
+}
+
+int
+op_snmp_target_params(struct snmp_context *ctx __unused, struct snmp_value *val,
+ uint32_t sub, uint32_t iidx __unused, enum snmp_op op)
+{
+ char pname[SNMP_ADM_STR32_SIZ];
+ struct target_param *param;
+
+ switch (op) {
+ case SNMP_OP_GET:
+ if ((param = target_get_param(&val->var, sub)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ break;
+
+ case SNMP_OP_GETNEXT:
+ if ((param = target_get_next_param(&val->var, sub)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ target_append_index(&val->var, sub, param->name);
+ break;
+
+ case SNMP_OP_SET:
+ if ((param = target_get_param(&val->var, sub)) == NULL &&
+ (val->var.subs[sub - 1] != LEAF_snmpTargetParamsRowStatus ||
+ val->v.integer != RowStatus_createAndWait))
+ return (SNMP_ERR_NOSUCHNAME);
+
+ if (param != NULL) {
+ if (community != COMM_INITIALIZE &&
+ param->type == StorageType_readOnly)
+ return (SNMP_ERR_NOT_WRITEABLE);
+ if (param->status == RowStatus_active &&
+ val->v.integer != RowStatus_destroy)
+ return (SNMP_ERR_INCONS_VALUE);
+ }
+
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_snmpTargetParamsMPModel:
+ if (val->v.integer != SNMP_MPM_SNMP_V1 &&
+ val->v.integer != SNMP_MPM_SNMP_V2c &&
+ val->v.integer != SNMP_MPM_SNMP_V3)
+ return (SNMP_ERR_INCONS_VALUE);
+ ctx->scratch->int1 = param->mpmodel;
+ param->mpmodel = val->v.integer;
+ break;
+
+ case LEAF_snmpTargetParamsSecurityModel:
+ if (val->v.integer != SNMP_SECMODEL_SNMPv1 &&
+ val->v.integer != SNMP_SECMODEL_SNMPv2c &&
+ val->v.integer != SNMP_SECMODEL_USM)
+ return (SNMP_ERR_INCONS_VALUE);
+ ctx->scratch->int1 = param->sec_model;
+ param->sec_model = val->v.integer;
+ break;
+
+ case LEAF_snmpTargetParamsSecurityName:
+ if (val->v.octetstring.len >= SNMP_ADM_STR32_SIZ)
+ return (SNMP_ERR_INCONS_VALUE);
+ ctx->scratch->int1 = strlen(param->secname) + 1;
+ ctx->scratch->ptr1 = malloc(ctx->scratch->int1);
+ if (ctx->scratch->ptr1 == NULL)
+ return (SNMP_ERR_GENERR);
+ strlcpy(ctx->scratch->ptr1, param->secname,
+ ctx->scratch->int1);
+ memcpy(param->secname, val->v.octetstring.octets,
+ val->v.octetstring.len);
+ param->secname[val->v.octetstring.len] = '\0';
+ break;
+
+ case LEAF_snmpTargetParamsSecurityLevel:
+ if (val->v.integer != SNMP_noAuthNoPriv &&
+ val->v.integer != SNMP_authNoPriv &&
+ val->v.integer != SNMP_authPriv)
+ return (SNMP_ERR_INCONS_VALUE);
+ ctx->scratch->int1 = param->sec_level;
+ param->sec_level = val->v.integer;
+ break;
+
+ case LEAF_snmpTargetParamsStorageType:
+ return (SNMP_ERR_INCONS_VALUE);
+
+ case LEAF_snmpTargetParamsRowStatus:
+ if (param != NULL) {
+ if (val->v.integer != RowStatus_active &&
+ val->v.integer != RowStatus_destroy)
+ return (SNMP_ERR_INCONS_VALUE);
+ if (val->v.integer == RowStatus_active &&
+ (param->sec_model == 0 ||
+ param->sec_level == 0 ||
+ strlen(param->secname) == 0))
+ return (SNMP_ERR_INCONS_VALUE);
+ ctx->scratch->int1 = param->status;
+ param->status = val->v.integer;
+ return (SNMP_ERR_NOERROR);
+ }
+ if (val->v.integer != RowStatus_createAndWait ||
+ target_decode_index(&val->var, sub, pname) < 0)
+ return (SNMP_ERR_INCONS_VALUE);
+ if ((param = target_new_param(pname)) == NULL)
+ return (SNMP_ERR_GENERR);
+ param->status = RowStatus_destroy;
+ if (community != COMM_INITIALIZE)
+ param->type = StorageType_volatile;
+ else
+ param->type = StorageType_readOnly;
+ break;
+ }
+ return (SNMP_ERR_NOERROR);
+
+ case SNMP_OP_COMMIT:
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_snmpTargetParamsSecurityName:
+ free(ctx->scratch->ptr1);
+ break;
+ case LEAF_snmpTargetParamsRowStatus:
+ if ((param = target_get_param(&val->var, sub)) == NULL)
+ return (SNMP_ERR_GENERR);
+ if (val->v.integer == RowStatus_destroy)
+ return (target_delete_param(param));
+ break;
+ default:
+ break;
+ }
+ return (SNMP_ERR_NOERROR);
+
+ case SNMP_OP_ROLLBACK:
+ if ((param = target_get_param(&val->var, sub)) == NULL &&
+ (val->var.subs[sub - 1] != LEAF_snmpTargetParamsRowStatus ||
+ val->v.integer != RowStatus_createAndWait))
+ return (SNMP_ERR_GENERR);
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_snmpTargetParamsMPModel:
+ param->mpmodel = ctx->scratch->int1;
+ break;
+ case LEAF_snmpTargetParamsSecurityModel:
+ param->sec_model = ctx->scratch->int1;
+ break;
+ case LEAF_snmpTargetParamsSecurityName:
+ strlcpy(param->secname, ctx->scratch->ptr1,
+ sizeof(param->secname));
+ free(ctx->scratch->ptr1);
+ break;
+ case LEAF_snmpTargetParamsSecurityLevel:
+ param->sec_level = ctx->scratch->int1;
+ break;
+ case LEAF_snmpTargetParamsRowStatus:
+ if (ctx->scratch->int1 == RowStatus_destroy)
+ return (target_delete_param(param));
+ break;
+ default:
+ break;
+ }
+
+ return (SNMP_ERR_NOERROR);
+
+ default:
+ abort();
+ }
+
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_snmpTargetParamsMPModel:
+ val->v.integer = param->mpmodel;
+ break;
+ case LEAF_snmpTargetParamsSecurityModel:
+ val->v.integer = param->sec_model;
+ break;
+ case LEAF_snmpTargetParamsSecurityName:
+ return (string_get(val, param->secname, -1));
+ case LEAF_snmpTargetParamsSecurityLevel:
+ val->v.integer = param->sec_level;
+ break;
+ case LEAF_snmpTargetParamsStorageType:
+ val->v.integer = param->type;
+ break;
+ case LEAF_snmpTargetParamsRowStatus:
+ val->v.integer = param->status;
+ break;
+ default:
+ abort();
+ }
+
+ return (SNMP_ERR_NOERROR);
+}
+
+int
+op_snmp_notify(struct snmp_context *ctx __unused, struct snmp_value *val,
+ uint32_t sub, uint32_t iidx __unused, enum snmp_op op)
+{
+ char nname[SNMP_ADM_STR32_SIZ];
+ struct target_notify *notify;
+
+ switch (op) {
+ case SNMP_OP_GET:
+ if ((notify = target_get_notify(&val->var, sub)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ break;
+
+ case SNMP_OP_GETNEXT:
+ if ((notify = target_get_next_notify(&val->var, sub)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ target_append_index(&val->var, sub, notify->name);
+ break;
+
+ case SNMP_OP_SET:
+ if ((notify = target_get_notify(&val->var, sub)) == NULL &&
+ (val->var.subs[sub - 1] != LEAF_snmpNotifyRowStatus ||
+ val->v.integer != RowStatus_createAndGo))
+ return (SNMP_ERR_NOSUCHNAME);
+
+ if (notify != NULL) {
+ if (community != COMM_INITIALIZE &&
+ notify->type == StorageType_readOnly)
+ return (SNMP_ERR_NOT_WRITEABLE);
+ }
+
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_snmpNotifyTag:
+ if (val->v.octetstring.len >= SNMP_TAG_SIZ)
+ return (SNMP_ERR_INCONS_VALUE);
+ ctx->scratch->int1 = strlen(notify->taglist) + 1;
+ ctx->scratch->ptr1 = malloc(ctx->scratch->int1);
+ if (ctx->scratch->ptr1 == NULL)
+ return (SNMP_ERR_GENERR);
+ strlcpy(ctx->scratch->ptr1, notify->taglist,
+ ctx->scratch->int1);
+ memcpy(notify->taglist, val->v.octetstring.octets,
+ val->v.octetstring.len);
+ notify->taglist[val->v.octetstring.len] = '\0';
+ break;
+
+ case LEAF_snmpNotifyType:
+ /* FALLTHROUGH */
+ case LEAF_snmpNotifyStorageType:
+ return (SNMP_ERR_INCONS_VALUE);
+ case LEAF_snmpNotifyRowStatus:
+ if (notify != NULL) {
+ if (val->v.integer != RowStatus_active &&
+ val->v.integer != RowStatus_destroy)
+ return (SNMP_ERR_INCONS_VALUE);
+ ctx->scratch->int1 = notify->status;
+ notify->status = val->v.integer;
+ return (SNMP_ERR_NOERROR);
+ }
+ if (val->v.integer != RowStatus_createAndGo ||
+ target_decode_index(&val->var, sub, nname) < 0)
+ return (SNMP_ERR_INCONS_VALUE);
+ if ((notify = target_new_notify(nname)) == NULL)
+ return (SNMP_ERR_GENERR);
+ notify->status = RowStatus_destroy;
+ if (community != COMM_INITIALIZE)
+ notify->type = StorageType_volatile;
+ else
+ notify->type = StorageType_readOnly;
+ break;
+ }
+ return (SNMP_ERR_NOERROR);
+
+ case SNMP_OP_COMMIT:
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_snmpNotifyTag:
+ free(ctx->scratch->ptr1);
+ break;
+ case LEAF_snmpNotifyRowStatus:
+ notify = target_get_notify(&val->var, sub);
+ if (notify == NULL)
+ return (SNMP_ERR_GENERR);
+ if (val->v.integer == RowStatus_destroy)
+ return (target_delete_notify(notify));
+ else
+ notify->status = RowStatus_active;
+ break;
+ default:
+ break;
+ }
+ return (SNMP_ERR_NOERROR);
+
+ case SNMP_OP_ROLLBACK:
+ if ((notify = target_get_notify(&val->var, sub)) == NULL)
+ return (SNMP_ERR_GENERR);
+
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_snmpNotifyTag:
+ strlcpy(notify->taglist, ctx->scratch->ptr1,
+ ctx->scratch->int1);
+ free(ctx->scratch->ptr1);
+ break;
+ case LEAF_snmpNotifyRowStatus:
+ if (ctx->scratch->int1 == RowStatus_destroy)
+ return (target_delete_notify(notify));
+ break;
+ default:
+ break;
+ }
+
+ default:
+ abort();
+ }
+
+
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_snmpNotifyTag:
+ return (string_get(val, notify->taglist, -1));
+ case LEAF_snmpNotifyType:
+ val->v.integer = snmpNotifyType_trap;
+ break;
+ case LEAF_snmpNotifyStorageType:
+ val->v.integer = notify->type;
+ break;
+ case LEAF_snmpNotifyRowStatus:
+ val->v.integer = notify->status;
+ break;
+ default:
+ abort();
+ }
+
+ return (SNMP_ERR_NOERROR);
+}
+
+static void
+target_append_index(struct asn_oid *oid, uint sub, const char *name)
+{
+ uint32_t i;
+
+ oid->len = sub + strlen(name);
+ for (i = 0; i < strlen(name); i++)
+ oid->subs[sub + i] = name[i];
+}
+
+static int
+target_decode_index(const struct asn_oid *oid, uint sub, char *name)
+{
+ uint32_t i, len;
+
+ if ((len = oid->len - sub) >= SNMP_ADM_STR32_SIZ)
+ return (-1);
+
+ for (i = 0; i < len; i++)
+ name[i] = oid->subs[sub + i];
+ name[i] = '\0';
+
+ return (0);
+}
+
+static struct target_address *
+target_get_address(const struct asn_oid *oid, uint sub)
+{
+ char aname[SNMP_ADM_STR32_SIZ];
+ struct target_address *addrs;
+
+ if (target_decode_index(oid, sub, aname) < 0)
+ return (NULL);
+
+ for (addrs = target_first_address(); addrs != NULL;
+ addrs = target_next_address(addrs))
+ if (strcmp(aname, addrs->name) == 0)
+ return (addrs);
+
+ return (NULL);
+}
+
+static struct target_address *
+target_get_next_address(const struct asn_oid * oid, uint sub)
+{
+ char aname[SNMP_ADM_STR32_SIZ];
+ struct target_address *addrs;
+
+ if (oid->len - sub == 0)
+ return (target_first_address());
+
+ if (target_decode_index(oid, sub, aname) < 0)
+ return (NULL);
+
+ for (addrs = target_first_address(); addrs != NULL;
+ addrs = target_next_address(addrs))
+ if (strcmp(aname, addrs->name) == 0)
+ return (target_next_address(addrs));
+
+ return (NULL);
+}
+
+static struct target_param *
+target_get_param(const struct asn_oid *oid, uint sub)
+{
+ char pname[SNMP_ADM_STR32_SIZ];
+ struct target_param *param;
+
+ if (target_decode_index(oid, sub, pname) < 0)
+ return (NULL);
+
+ for (param = target_first_param(); param != NULL;
+ param = target_next_param(param))
+ if (strcmp(pname, param->name) == 0)
+ return (param);
+
+ return (NULL);
+}
+
+static struct target_param *
+target_get_next_param(const struct asn_oid *oid, uint sub)
+{
+ char pname[SNMP_ADM_STR32_SIZ];
+ struct target_param *param;
+
+ if (oid->len - sub == 0)
+ return (target_first_param());
+
+ if (target_decode_index(oid, sub, pname) < 0)
+ return (NULL);
+
+ for (param = target_first_param(); param != NULL;
+ param = target_next_param(param))
+ if (strcmp(pname, param->name) == 0)
+ return (target_next_param(param));
+
+ return (NULL);
+}
+
+static struct target_notify *
+target_get_notify(const struct asn_oid *oid, uint sub)
+{
+ char nname[SNMP_ADM_STR32_SIZ];
+ struct target_notify *notify;
+
+ if (target_decode_index(oid, sub, nname) < 0)
+ return (NULL);
+
+ for (notify = target_first_notify(); notify != NULL;
+ notify = target_next_notify(notify))
+ if (strcmp(nname, notify->name) == 0)
+ return (notify);
+
+ return (NULL);
+}
+
+static struct target_notify *
+target_get_next_notify(const struct asn_oid *oid, uint sub)
+{
+ char nname[SNMP_ADM_STR32_SIZ];
+ struct target_notify *notify;
+
+ if (oid->len - sub == 0)
+ return (target_first_notify());
+
+ if (target_decode_index(oid, sub, nname) < 0)
+ return (NULL);
+
+ for (notify = target_first_notify(); notify != NULL;
+ notify = target_next_notify(notify))
+ if (strcmp(nname, notify->name) == 0)
+ return (target_next_notify(notify));
+
+ return (NULL);
+}
+
+static int
+target_init(struct lmodule *mod, int argc __unused, char *argv[] __unused)
+{
+ target_module = mod;
+ target_lock = random();
+
+ return (0);
+}
+
+
+static int
+target_fini(void)
+{
+ target_flush_all();
+ or_unregister(reg_target);
+ or_unregister(reg_notification);
+
+ return (0);
+}
+
+static void
+target_start(void)
+{
+ reg_target = or_register(&oid_target,
+ "The MIB module for managing SNMP Management Targets.",
+ target_module);
+ reg_notification = or_register(&oid_notification,
+ "The MIB module for configuring generation of SNMP notifications.",
+ target_module);
+}
+
+static void
+target_dump(void)
+{
+ /* XXX: dump the module stats & list of mgmt targets */
+}
+
+const char target_comment[] = \
+"This module implements SNMP Management Target MIB Module defined in RFC 3413.";
+
+const struct snmp_module config = {
+ .comment = target_comment,
+ .init = target_init,
+ .fini = target_fini,
+ .start = target_start,
+ .tree = target_ctree,
+ .dump = target_dump,
+ .tree_size = target_CTREE_SIZE,
+};
diff --git a/contrib/bsnmp/snmp_target/target_tree.def b/contrib/bsnmp/snmp_target/target_tree.def
new file mode 100755
index 0000000..6c77b3f
--- /dev/null
+++ b/contrib/bsnmp/snmp_target/target_tree.def
@@ -0,0 +1,95 @@
+#-
+# Copyright (C) 2010 The FreeBSD Foundation
+# All rights reserved.
+#
+# This software was developed by Shteryana Sotirova Shopova under
+# sponsorship from the FreeBSD Foundation.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+#
+
+include "tc.def"
+
+typedef StorageType ENUM (
+ 1 other
+ 2 volatile
+ 3 nonVolatile
+ 4 permanent
+ 5 readOnly
+)
+
+(1 internet
+ (6 snmpV2
+ (1 snmpDomains
+ (1 snmpUDPDomain
+ )
+ )
+ (3 snmpModules
+ (12 snmpTargetMIB
+ (1 snmpTargetObjects
+ (1 snmpTargetSpinLock INTEGER op_snmp_target GET SET)
+ (2 snmpTargetAddrTable
+ (1 snmpTargetAddrEntry : OCTETSTRING op_snmp_target_addrs
+ (1 snmpTargetAddrName OCTETSTRING)
+ (2 snmpTargetAddrTDomain OID GET SET)
+ (3 snmpTargetAddrTAddress OCTETSTRING | TAddress GET SET)
+ (4 snmpTargetAddrTimeout INTEGER GET SET)
+ (5 snmpTargetAddrRetryCount INTEGER GET SET)
+ (6 snmpTargetAddrTagList OCTETSTRING | SnmpTagList GET SET)
+ (7 snmpTargetAddrParams OCTETSTRING GET SET)
+ (8 snmpTargetAddrStorageType StorageType GET SET)
+ (9 snmpTargetAddrRowStatus RowStatus GET SET)
+ )
+ )
+ (3 snmpTargetParamsTable
+ (1 snmpTargetParamsEntry : OCTETSTRING op_snmp_target_params
+ (1 snmpTargetParamsName OCTETSTRING)
+ (2 snmpTargetParamsMPModel INTEGER GET SET)
+ (3 snmpTargetParamsSecurityModel INTEGER GET SET)
+ (4 snmpTargetParamsSecurityName OCTETSTRING | SnmpAdminString GET SET)
+ (5 snmpTargetParamsSecurityLevel ENUM ( 1 noAuthNoPriv 2 authNoPriv 3 authPriv ) GET SET)
+ (6 snmpTargetParamsStorageType StorageType GET SET)
+ (7 snmpTargetParamsRowStatus RowStatus GET SET)
+ )
+ )
+ (4 snmpUnavailableContexts COUNTER op_snmp_target GET)
+ (5 snmpUnknownContexts COUNTER op_snmp_target GET)
+ )
+ )
+ (13 snmpNotificationMIB
+ (1 snmpNotifyObjects
+ (1 snmpNotifyTable
+ (1 snmpNotifyEntry : OCTETSTRING op_snmp_notify
+ (1 snmpNotifyName OCTETSTRING)
+ (2 snmpNotifyTag OCTETSTRING | SnmpTagValue GET SET)
+ (3 snmpNotifyType ENUM ( 1 trap 2 inform ) GET SET)
+ (4 snmpNotifyStorageType StorageType GET SET)
+ (5 snmpNotifyRowStatus RowStatus GET SET)
+ )
+ )
+ )
+ )
+ )
+ )
+)
OpenPOWER on IntegriCloud