summaryrefslogtreecommitdiffstats
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
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
-rw-r--r--contrib/bsnmp/lib/bsnmplib.338
-rw-r--r--contrib/bsnmp/lib/snmp.c17
-rw-r--r--contrib/bsnmp/lib/snmp.h5
-rw-r--r--contrib/bsnmp/lib/snmpagent.c4
-rw-r--r--contrib/bsnmp/lib/snmpclient.c17
-rw-r--r--contrib/bsnmp/lib/snmppriv.h3
-rwxr-xr-xcontrib/bsnmp/lib/tc.def40
-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
-rwxr-xr-xcontrib/bsnmp/snmp_usm/snmp_usm.32
-rwxr-xr-xcontrib/bsnmp/snmp_usm/usm_tree.def11
-rwxr-xr-xcontrib/bsnmp/snmp_vacm/vacm_tree.def11
-rw-r--r--contrib/bsnmp/snmpd/main.c14
-rw-r--r--contrib/bsnmp/snmpd/snmpmod.3163
-rw-r--r--contrib/bsnmp/snmpd/snmpmod.h75
-rw-r--r--contrib/bsnmp/snmpd/trap.c513
-rw-r--r--contrib/bsnmp/snmpd/tree.def3
-rw-r--r--lib/libbsnmp/libbsnmp/Makefile4
-rw-r--r--usr.sbin/bsnmpd/bsnmpd/Makefile1
-rw-r--r--usr.sbin/bsnmpd/modules/Makefile1
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_bridge/bridge_tree.def11
-rwxr-xr-xusr.sbin/bsnmpd/modules/snmp_target/Makefile20
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_wlan/wlan_tree.def9
24 files changed, 1998 insertions, 100 deletions
diff --git a/contrib/bsnmp/lib/bsnmplib.3 b/contrib/bsnmp/lib/bsnmplib.3
index af36879..fbb956d 100644
--- a/contrib/bsnmp/lib/bsnmplib.3
+++ b/contrib/bsnmp/lib/bsnmplib.3
@@ -37,7 +37,7 @@
.\"
.\" $Begemot: bsnmp/lib/bsnmplib.3,v 1.9 2005/10/04 08:46:51 brandt_h Exp $
.\"
-.Dd September 9, 2010
+.Dd December 19, 2010
.Dt BSNMPLIB 3
.Os
.Sh NAME
@@ -50,6 +50,7 @@
.Nm snmp_pdu_decode_header ,
.Nm snmp_pdu_decode_scoped ,
.Nm snmp_pdu_decode_secmode ,
+.Nm snmp_pdu_init_secparams ,
.Nm snmp_pdu_dump ,
.Nm snmp_passwd_to_keys ,
.Nm snmp_get_local_keys ,
@@ -83,6 +84,8 @@ Begemot SNMP library
.Ft enum snmp_code
.Fn snmp_pdu_decode_secmode "struct asn_buf *buf" "struct snmp_pdu *pdu"
.Ft void
+.Fn snmp_pdu_init_secparams "struct snmp_pdu *pdu"
+.Ft void
.Fn snmp_pdu_dump "const struct snmp_pdu *pdu"
.Ft enum snmp_code
.Fn snmp_passwd_to_keys "struct snmp_user *user" "char *passwd"
@@ -175,12 +178,18 @@ This structure represents an SNMP engine as specified by the SNMP Management
Architecture described in RFC 3411.
.Pp
.Bd -literal -offset indent
-#define SNMP_USM_NAME_SIZ (32 + 1)
+#define SNMP_ADM_STR32_SIZ (32 + 1)
#define SNMP_AUTH_KEY_SIZ 40
#define SNMP_PRIV_KEY_SIZ 32
+enum snmp_usm_level {
+ SNMP_noAuthNoPriv = 1,
+ SNMP_authNoPriv = 2,
+ SNMP_authPriv = 3
+};
+
struct snmp_user {
- char sec_name[SNMP_USM_NAME_SIZ];
+ char sec_name[SNMP_ADM_STR32_SIZ];
enum snmp_authentication auth_proto;
enum snmp_privacy priv_proto;
uint8_t auth_key[SNMP_AUTH_KEY_SIZ];
@@ -230,7 +239,9 @@ contain the authentication and privacy keys for the user.
#define SNMP_MSG_PRIV_FLAG 0x2
#define SNMP_MSG_REPORT_FLAG 0x4
-#define SNMP_SECMODEL_USM 3
+#define SNMP_MPM_SNMP_V1 0
+#define SNMP_MPM_SNMP_V2c 1
+#define SNMP_MPM_SNMP_V3 3
struct snmp_pdu {
char community[SNMP_COMMUNITY_MAXLEN + 1];
@@ -296,7 +307,17 @@ and
is the type of the PDU.
.Fa security_model
is the security model used for SNMPv3 PDUs. The only supported
-value currently is 3 (User-based Security Model).
+value currently is 3 (User-based Security Model). Additional values for any,
+unknown, SNMPv1 and SNMPv2c security models are also enumerated
+.Bd -literal -offset indent
+enum snmp_secmodel {
+ SNMP_SECMODEL_ANY = 0,
+ SNMP_SECMODEL_SNMPv1 = 1,
+ SNMP_SECMODEL_SNMPv2c = 2,
+ SNMP_SECMODEL_USM = 3,
+ SNMP_SECMODEL_UNKNOWN
+};
+.Ed
.Pp
The function
.Fn snmp_value_free
@@ -366,6 +387,13 @@ if the PDU is encrypted, decrypts the PDU contents pointed to by
If successfull, a plain text scoped PDU is stored in the buffer.
.Pp
The function
+.Fn snmp_pdu_init_secparams
+calculates the initialization vector for the privacy protocol in use before
+the PDU pointed to by
+.Fa pdu
+may be encrypted or decrypted.
+.Pp
+The function
.Fn snmp_pdu_dump
dumps the PDU in a human readable form by calling
.Fn snmp_printf .
diff --git a/contrib/bsnmp/lib/snmp.c b/contrib/bsnmp/lib/snmp.c
index 633d10e..744510c 100644
--- a/contrib/bsnmp/lib/snmp.c
+++ b/contrib/bsnmp/lib/snmp.c
@@ -764,6 +764,7 @@ snmp_pdu_encode_header(struct asn_buf *b, struct snmp_pdu *pdu)
if (pdu->type != SNMP_PDU_RESPONSE &&
pdu->type != SNMP_PDU_TRAP &&
+ pdu->type != SNMP_PDU_TRAP2 &&
pdu->type != SNMP_PDU_REPORT)
pdu->flags |= SNMP_MSG_REPORT_FLAG;
@@ -1176,23 +1177,19 @@ snmp_value_copy(struct snmp_value *to, const struct snmp_value *from)
}
void
-snmp_pdu_init_secparams(struct snmp_pdu *pdu, struct snmp_engine *eng,
- struct snmp_user *user)
+snmp_pdu_init_secparams(struct snmp_pdu *pdu)
{
int32_t rval;
- memcpy(&pdu->engine, eng, sizeof(pdu->engine));
- memcpy(&pdu->user, user, sizeof(pdu->user));
-
- if (user->auth_proto != SNMP_AUTH_NOAUTH)
+ if (pdu->user.auth_proto != SNMP_AUTH_NOAUTH)
pdu->flags |= SNMP_MSG_AUTH_FLAG;
- switch (user->priv_proto) {
+ switch (pdu->user.priv_proto) {
case SNMP_PRIV_DES:
- memcpy(pdu->msg_salt, &eng->engine_boots,
- sizeof(eng->engine_boots));
+ memcpy(pdu->msg_salt, &pdu->engine.engine_boots,
+ sizeof(pdu->engine.engine_boots));
rval = random();
- memcpy(pdu->msg_salt + sizeof(eng->engine_boots), &rval,
+ memcpy(pdu->msg_salt + sizeof(pdu->engine.engine_boots), &rval,
sizeof(int32_t));
pdu->flags |= SNMP_MSG_PRIV_FLAG;
break;
diff --git a/contrib/bsnmp/lib/snmp.h b/contrib/bsnmp/lib/snmp.h
index 3a6cec7..631d2f2 100644
--- a/contrib/bsnmp/lib/snmp.h
+++ b/contrib/bsnmp/lib/snmp.h
@@ -89,6 +89,10 @@ enum snmp_version {
SNMP_V3,
};
+#define SNMP_MPM_SNMP_V1 0
+#define SNMP_MPM_SNMP_V2c 1
+#define SNMP_MPM_SNMP_V3 3
+
#define SNMP_ADM_STR32_SIZ (32 + 1)
#define SNMP_AUTH_KEY_SIZ 40
#define SNMP_PRIV_KEY_SIZ 32
@@ -255,6 +259,7 @@ int snmp_value_parse(const char *, enum snmp_syntax, union snmp_values *);
int snmp_value_copy(struct snmp_value *, const struct snmp_value *);
void snmp_pdu_free(struct snmp_pdu *);
+void snmp_pdu_init_secparams(struct snmp_pdu *);
enum snmp_code snmp_pdu_decode(struct asn_buf *b, struct snmp_pdu *pdu, int32_t *);
enum snmp_code snmp_pdu_decode_header(struct asn_buf *, struct snmp_pdu *);
enum snmp_code snmp_pdu_decode_scoped(struct asn_buf *, struct snmp_pdu *, int32_t *);
diff --git a/contrib/bsnmp/lib/snmpagent.c b/contrib/bsnmp/lib/snmpagent.c
index 9cd9676..888d622 100644
--- a/contrib/bsnmp/lib/snmpagent.c
+++ b/contrib/bsnmp/lib/snmpagent.c
@@ -178,7 +178,9 @@ snmp_pdu_create_response(struct snmp_pdu *pdu, struct snmp_pdu *resp)
if (resp->version != SNMP_V3)
return;
- snmp_pdu_init_secparams(resp, &pdu->engine, &pdu->user);
+ memcpy(&resp->engine, &pdu->engine, sizeof(pdu->engine));
+ memcpy(&resp->user, &pdu->user, sizeof(pdu->user));
+ snmp_pdu_init_secparams(resp);
resp->identifier = pdu->identifier;
resp->security_model = pdu->security_model;
resp->context_engine_len = pdu->context_engine_len;
diff --git a/contrib/bsnmp/lib/snmpclient.c b/contrib/bsnmp/lib/snmpclient.c
index 103ea69..8610a4d 100644
--- a/contrib/bsnmp/lib/snmpclient.c
+++ b/contrib/bsnmp/lib/snmpclient.c
@@ -1160,10 +1160,11 @@ snmp_pdu_create(struct snmp_pdu *pdu, u_int op)
pdu->flags = 0;
pdu->security_model = snmp_client.security_model;
- if (snmp_client.security_model == SNMP_SECMODEL_USM)
- snmp_pdu_init_secparams(pdu, &snmp_client.engine,
- &snmp_client.user);
- else
+ if (snmp_client.security_model == SNMP_SECMODEL_USM) {
+ memcpy(&pdu->engine, &snmp_client.engine, sizeof(pdu->engine));
+ memcpy(&pdu->user, &snmp_client.user, sizeof(pdu->user));
+ snmp_pdu_init_secparams(pdu);
+ } else
seterr(&snmp_client, "unknown security model");
if (snmp_client.clen > 0) {
@@ -1440,9 +1441,11 @@ snmp_receive_packet(struct snmp_pdu *pdu, struct timeval *tv)
abuf.asn_len = ret;
memset(pdu, 0, sizeof(*pdu));
- if (snmp_client.security_model == SNMP_SECMODEL_USM)
- snmp_pdu_init_secparams(pdu, &snmp_client.engine,
- &snmp_client.user);
+ if (snmp_client.security_model == SNMP_SECMODEL_USM) {
+ memcpy(&pdu->engine, &snmp_client.engine, sizeof(pdu->engine));
+ memcpy(&pdu->user, &snmp_client.user, sizeof(pdu->user));
+ snmp_pdu_init_secparams(pdu);
+ }
if (SNMP_CODE_OK != (ret = snmp_pdu_decode(&abuf, pdu, &ip))) {
seterr(&snmp_client, "snmp_decode_pdu: failed %d", ret);
diff --git a/contrib/bsnmp/lib/snmppriv.h b/contrib/bsnmp/lib/snmppriv.h
index 56441cc..c0e4479 100644
--- a/contrib/bsnmp/lib/snmppriv.h
+++ b/contrib/bsnmp/lib/snmppriv.h
@@ -38,9 +38,6 @@ enum snmp_code snmp_fix_encoding(struct asn_buf *, struct snmp_pdu *);
enum asn_err snmp_parse_pdus_hdr(struct asn_buf *b, struct snmp_pdu *pdu,
asn_len_t *lenp);
-void snmp_pdu_init_secparams(struct snmp_pdu *, struct snmp_engine *,
- struct snmp_user *);
-
enum snmp_code snmp_pdu_calc_digest(const struct snmp_pdu *, uint8_t *);
enum snmp_code snmp_pdu_encrypt(const struct snmp_pdu *);
enum snmp_code snmp_pdu_decrypt(const struct snmp_pdu *);
diff --git a/contrib/bsnmp/lib/tc.def b/contrib/bsnmp/lib/tc.def
new file mode 100755
index 0000000..65f6972
--- /dev/null
+++ b/contrib/bsnmp/lib/tc.def
@@ -0,0 +1,40 @@
+#-
+# 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$
+#
+
+typedef RowStatus ENUM (
+ 1 active
+ 2 notInService
+ 3 notReady
+ 4 createAndGo
+ 5 createAndWait
+ 6 destroy
+)
+
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)
+ )
+ )
+ )
+ )
+ )
+ )
+)
diff --git a/contrib/bsnmp/snmp_usm/snmp_usm.3 b/contrib/bsnmp/snmp_usm/snmp_usm.3
index 7fd0817..830cacd 100755
--- a/contrib/bsnmp/snmp_usm/snmp_usm.3
+++ b/contrib/bsnmp/snmp_usm/snmp_usm.3
@@ -112,7 +112,7 @@ 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 usmUserStatus
-This column is used to create new USM user entries or delete exsiting ones from
+This column is used to create new USM user entries or delete existing ones from
the table.
.El
.EL
diff --git a/contrib/bsnmp/snmp_usm/usm_tree.def b/contrib/bsnmp/snmp_usm/usm_tree.def
index 8358d7b..41eb557 100755
--- a/contrib/bsnmp/snmp_usm/usm_tree.def
+++ b/contrib/bsnmp/snmp_usm/usm_tree.def
@@ -29,6 +29,8 @@
# $FreeBSD$
#
+include "tc.def"
+
typedef StorageType ENUM (
1 other
2 volatile
@@ -37,15 +39,6 @@ typedef StorageType ENUM (
5 readOnly
)
-typedef RowStatus ENUM (
- 1 active
- 2 notInService
- 3 notReady
- 4 createAndGo
- 5 createAndWait
- 6 destroy
-)
-
(1 internet
(6 snmpV2
(3 snmpModules
diff --git a/contrib/bsnmp/snmp_vacm/vacm_tree.def b/contrib/bsnmp/snmp_vacm/vacm_tree.def
index db70f7d..bd7f70a 100755
--- a/contrib/bsnmp/snmp_vacm/vacm_tree.def
+++ b/contrib/bsnmp/snmp_vacm/vacm_tree.def
@@ -29,6 +29,8 @@
# $FreeBSD$
#
+include "tc.def"
+
typedef StorageType ENUM (
1 other
2 volatile
@@ -37,15 +39,6 @@ typedef StorageType ENUM (
5 readOnly
)
-typedef RowStatus ENUM (
- 1 active
- 2 notInService
- 3 notReady
- 4 createAndGo
- 5 createAndWait
- 6 destroy
-)
-
(1 internet
(6 snmpV2
(3 snmpModules
diff --git a/contrib/bsnmp/snmpd/main.c b/contrib/bsnmp/snmpd/main.c
index e008bf7..c25fff2 100644
--- a/contrib/bsnmp/snmpd/main.c
+++ b/contrib/bsnmp/snmpd/main.c
@@ -5,6 +5,12 @@
*
* Author: Harti Brandt <harti@freebsd.org>
*
+ * Copyright (c) 2010 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were 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:
@@ -98,6 +104,8 @@ struct snmp_engine snmpd_engine;
/* snmpSerialNo */
int32_t snmp_serial_no;
+struct snmpd_target_stats snmpd_target_stats;
+
/* search path for config files */
const char *syspath = PATH_SYSCONFIG;
@@ -361,7 +369,7 @@ snmp_pdu_auth_user(struct snmp_pdu *pdu)
* Check whether access to each of var bindings in the PDU is allowed based
* on the user credentials against the configured User groups & VACM views.
*/
-static enum snmp_code
+enum snmp_code
snmp_pdu_auth_access(struct snmp_pdu *pdu, int32_t *ip)
{
const char *uname;
@@ -1838,14 +1846,14 @@ main(int argc, char *argv[])
exit(1);
}
- snmp_send_trap(&oid_coldStart, (struct snmp_value *)NULL);
-
while ((m = TAILQ_FIRST(&modules_start)) != NULL) {
m->flags &= ~LM_ONSTARTLIST;
TAILQ_REMOVE(&modules_start, m, start);
lm_start(m);
}
+ snmp_send_trap(&oid_coldStart, (struct snmp_value *)NULL);
+
for (;;) {
#ifndef USE_LIBBEGEMOT
evEvent event;
diff --git a/contrib/bsnmp/snmpd/snmpmod.3 b/contrib/bsnmp/snmpd/snmpmod.3
index a142069..38b3cf1 100644
--- a/contrib/bsnmp/snmpd/snmpmod.3
+++ b/contrib/bsnmp/snmpd/snmpmod.3
@@ -31,7 +31,7 @@
.\"
.\" $Begemot: bsnmp/snmpd/snmpmod.3,v 1.14 2005/10/04 13:30:35 brandt_h Exp $
.\"
-.Dd September 9, 2010
+.Dd December 19, 2010
.Dt SNMPMOD 3
.Os
.Sh NAME
@@ -83,6 +83,7 @@
.Nm snmp_output ,
.Nm snmp_send_port ,
.Nm snmp_send_trap ,
+.Nm snmp_pdu_auth_access
.Nm string_save ,
.Nm string_commit ,
.Nm string_rollback ,
@@ -102,6 +103,7 @@
.Nm index_compare_off ,
.Nm index_append ,
.Nm index_append_off,
+.Nm snmpd_usmstats,
.Nm bsnmpd_get_usm_stats,
.Nm bsnmpd_reset_usm_stats,
.Nm usm_first_user,
@@ -111,6 +113,25 @@
.Nm usm_delete_user,
.Nm usm_flush_users,
.Nm usm_user
+.Nm snmpd_target_stat
+.Nm bsnmpd_get_target_stats
+.Nm target_first_address
+.Nm target_next_address
+.Nm target_new_address
+.Nm target_activate_address
+.Nm target_delete_address
+.Nm target_first_param
+.Nm target_next_param
+.Nm target_new_param
+.Nm target_delete_param
+.Nm target_first_notify
+.Nm target_next_notify
+.Nm target_new_notify
+.Nm target_delete_notify
+.Nm target_flush_all
+.Nm target_address
+.Nm target_param
+.Nm target_notify
.Nd "SNMP daemon loadable module interface"
.Sh LIBRARY
Begemot SNMP library
@@ -201,6 +222,8 @@ Begemot SNMP library
.Fc
.Ft void
.Fn snmp_send_trap "const struct asn_oid *oid" "..."
+.Ft enum snmp_code
+.Fn snmp_pdu_auth_access "struct snmp_pdu *pdu" "int32_t *ip"
.Ft int
.Fn string_save "struct snmp_value *val" "struct snmp_context *ctx" "ssize_t req_size" "u_char **strp"
.Ft void
@@ -239,6 +262,7 @@ Begemot SNMP library
.Fn index_append "struct asn_oid *dst" "u_int sub" "const struct asn_oid *src"
.Ft void
.Fn index_append_off "struct asn_oid *dst" "u_int sub" "const struct asn_oid *src" "u_int off"
+.Vt extern struct snmpd_usmstat snmpd_usmstats ;
.Ft struct snmpd_usmstat *
.Fn bsnmpd_get_usm_stats "void"
.Ft void
@@ -256,6 +280,36 @@ Begemot SNMP library
.Ft void
.Fn usm_flush_users "void"
.Vt extern struct usm_user *usm_user;
+.Ft struct snmpd_target_stats *
+.Fn bsnmpd_get_target_stats "void"
+.Ft struct target_address *
+.Fn target_first_address "void"
+.Ft struct target_address *
+.Fn target_next_address "struct target_address *"
+.Ft struct target_address *
+.Fn target_new_address "char *"
+.Ft int
+.Fn target_activate_address "struct target_address *"
+.Ft int
+.Fn target_delete_address "struct target_address *"
+.Ft struct target_param *
+.Fn target_first_param "void"
+.Ft struct target_param *
+.Fn target_next_param "struct target_param *"
+.Ft struct target_param *
+.Fn target_new_param "char *"
+.Ft int
+.Fn target_delete_param "struct target_param *"
+.Ft struct target_notify *
+.Fn target_first_notify "void"
+.Ft struct target_notify *
+.Fn target_next_notify "struct target_notify *"
+.Ft struct target_notify *
+.Fn target_new_notify "char *"
+.Ft int
+.Fn target_delete_notify "struct target_notify *"
+.Ft void
+.Fn target_flush_all "void"
.Vt extern const struct asn_oid oid_usmUnknownEngineIDs;
.Vt extern const struct asn_oid oid_usmNotInTimeWindows;
.Sh DESCRIPTION
@@ -603,7 +657,7 @@ struct usm_user {
struct snmp_user suser;
uint8_t user_engine_id[SNMP_ENGINE_ID_SIZ];
uint32_t user_engine_len;
- char user_public[SNMP_USM_NAME_SIZ];
+ char user_public[SNMP_ADM_STR32_SIZ];
uint32_t user_public_len;
int32_t status;
int32_t type;
@@ -640,6 +694,103 @@ and
or
.Li NULL
if an user with the specified name and engine id is not present in the list.
+.Ss THE MANAGEMENT TARGET GROUP
+The Management Target group holds target address information used when sending
+SNMPv3 notifications.
+.Pp
+The scalar statistics of the Management Target group are held in the global
+variable
+.Va snmpd_target_stats :
+.Bd -literal -offset indent
+struct snmpd_target_stats {
+ uint32_t unavail_contexts;
+ uint32_t unknown_contexts;
+};
+.Ed
+.Fn bsnmpd_get_target_stats
+returns a pointer to the global structure containing the statistics.
+.Pp
+Three global lists of configured management target addresses, parameters and
+notifications respectively are maintained by the daemon.
+.Bd -literal -offset indent
+struct target_address {
+ char name[SNMP_ADM_STR32_SIZ];
+ uint8_t address[SNMP_UDP_ADDR_SIZ];
+ int32_t timeout;
+ int32_t retry;
+ char taglist[SNMP_TAG_SIZ];
+ char paramname[SNMP_ADM_STR32_SIZ];
+ int32_t type;
+ int32_t socket;
+ int32_t status;
+ SLIST_ENTRY(target_address) ta;
+};
+.Ed
+This structure represents a SNMPv3 Management Target address. Each time a SNMP
+TRAP is send the daemon will send the Trap to all active Management Target
+addresses in its global list.
+.Bd -literal -offset indent
+struct target_param {
+ char name[SNMP_ADM_STR32_SIZ];
+ int32_t mpmodel;
+ int32_t sec_model;
+ char secname[SNMP_ADM_STR32_SIZ];
+ enum snmp_usm_level sec_level;
+ int32_t type;
+ int32_t status;
+ SLIST_ENTRY(target_param) tp;
+};
+.Ed
+This structure represents the information used to generate SNMP messages to the
+associated SNMPv3 Management Target addresses.
+.Bd -literal -offset indent
+struct target_notify {
+ char name[SNMP_ADM_STR32_SIZ];
+ char taglist[SNMP_TAG_SIZ];
+ int32_t notify_type;
+ int32_t type;
+ int32_t status;
+ SLIST_ENTRY(target_notify) tn;
+};
+.Ed
+This structure represents Notification Tag entries - SNMP notifications are sent
+to the Target address for each entry in the Management Target Address list that
+has a tag matching the specified tag in this structure.
+.Pp
+The daemon does not create or remove entries in the Management Target group
+lists, it gives an interface to external loadable module(s) to manage the lists.
+.Fn target_new_address
+adds a target address entry, and
+.Fn target_delete_address
+deletes an existing entry from the target address list.
+.Fn target_activate_address
+creates a socket associated with the target address entry so that SNMP
+notifications may actually be send to that target address.
+.Fn target_first_address
+will return a pointer to the first target address entry in the list, while
+.Fn target_next_address
+will return a pointer to the next target address of a given entry if one exists.
+.Fn target_new_param
+adds a target parameters' entry, and
+.Fn target_delete_param
+deletes an existing entry from the target parameters list.
+.Fn target_first_param
+will return a pointer to the first target parameters' entry in the list, while
+.Fn target_next_param
+will return a pointer to the next target parameters of a given entry if one
+exists.
+.Fn target_new_notify
+adds a notification target entry, and
+.Fn target_delete_notify
+deletes an existing entry from the notification target list.
+.Fn target_first_notify
+will return a pointer to the first notification target entry in the list, while
+.Fn target_next_notify
+will return a pointer to the next notification target of a given entry if one
+exists.
+.Fn target_flush_all
+is used to remove all configured data from the three global Management Target
+Group lists.
.Ss WELL KNOWN OIDS
The global variable
.Va oid_zeroDotZero
@@ -840,6 +991,14 @@ The arguments are the
identifying the trap and a NULL-terminated list of
.Vt struct snmp_value
pointers that are to be inserted into the trap binding list.
+.Fn snmp_pdu_auth_access
+verifies whether access to the object IDs contained in the
+.Fa pdu
+ should be granted or denied, according to the configured View-Based Access
+rules.
+.Fa ip
+contains the index of the first varbinding to which access was denied, or 0 if
+access to all varbindings in the PDU is granted.
.Ss SIMPLE ACTION SUPPORT
For simple scalar variables that need no dependencies a number of support
functions is available to handle the set, commit, rollback and get.
diff --git a/contrib/bsnmp/snmpd/snmpmod.h b/contrib/bsnmp/snmpd/snmpmod.h
index 379070c..9025366 100644
--- a/contrib/bsnmp/snmpd/snmpmod.h
+++ b/contrib/bsnmp/snmpd/snmpmod.h
@@ -5,6 +5,12 @@
*
* Author: Harti Brandt <harti@freebsd.org>
*
+ * Copyright (c) 2010 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were 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:
@@ -455,6 +461,74 @@ struct vacm_context *vacm_add_context(char *, int32_t);
void vacm_flush_contexts(int32_t);
/*
+ * RFC 3413 SNMP Management Target & Notification MIB
+ */
+
+struct snmpd_target_stats {
+ uint32_t unavail_contexts;
+ uint32_t unknown_contexts;
+};
+
+#define SNMP_UDP_ADDR_SIZ 6
+#define SNMP_TAG_SIZ (255 + 1)
+
+struct target_address {
+ char name[SNMP_ADM_STR32_SIZ];
+ uint8_t address[SNMP_UDP_ADDR_SIZ];
+ int32_t timeout;
+ int32_t retry;
+ char taglist[SNMP_TAG_SIZ];
+ char paramname[SNMP_ADM_STR32_SIZ];
+ int32_t type;
+ int32_t socket;
+ int32_t status;
+ SLIST_ENTRY(target_address) ta;
+};
+
+SLIST_HEAD(target_addresslist, target_address);
+
+struct target_param {
+ char name[SNMP_ADM_STR32_SIZ];
+ int32_t mpmodel;
+ int32_t sec_model;
+ char secname[SNMP_ADM_STR32_SIZ];
+ enum snmp_usm_level sec_level;
+ int32_t type;
+ int32_t status;
+ SLIST_ENTRY(target_param) tp;
+};
+
+SLIST_HEAD(target_paramlist, target_param);
+
+struct target_notify {
+ char name[SNMP_ADM_STR32_SIZ];
+ char taglist[SNMP_TAG_SIZ];
+ int32_t notify_type;
+ int32_t type;
+ int32_t status;
+ SLIST_ENTRY(target_notify) tn;
+};
+
+SLIST_HEAD(target_notifylist, target_notify);
+
+extern struct snmpd_target_stats snmpd_target_stats;
+struct snmpd_target_stats *bsnmpd_get_target_stats(void);
+struct target_address *target_first_address(void);
+struct target_address *target_next_address(struct target_address *);
+struct target_address *target_new_address(char *);
+int target_activate_address(struct target_address *);
+int target_delete_address(struct target_address *);
+struct target_param *target_first_param(void);
+struct target_param *target_next_param(struct target_param *);
+struct target_param *target_new_param(char *);
+int target_delete_param(struct target_param *);
+struct target_notify *target_first_notify(void);
+struct target_notify *target_next_notify(struct target_notify *);
+struct target_notify *target_new_notify(char *);
+int target_delete_notify (struct target_notify *);
+void target_flush_all(void);
+
+/*
* Well known OIDs
*/
extern const struct asn_oid oid_zeroDotZero;
@@ -515,6 +589,7 @@ enum snmpd_input_err snmp_input_finish(struct snmp_pdu *, const u_char *,
void snmp_output(struct snmp_pdu *, u_char *, size_t *, const char *);
void snmp_send_port(void *, const struct asn_oid *, struct snmp_pdu *,
const struct sockaddr *, socklen_t);
+enum snmp_code snmp_pdu_auth_access(struct snmp_pdu *, int32_t *);
/* sending traps */
void snmp_send_trap(const struct asn_oid *, ...);
diff --git a/contrib/bsnmp/snmpd/trap.c b/contrib/bsnmp/snmpd/trap.c
index 18164cf..d13f902 100644
--- a/contrib/bsnmp/snmpd/trap.c
+++ b/contrib/bsnmp/snmpd/trap.c
@@ -4,7 +4,13 @@
* All rights reserved.
*
* Author: Harti Brandt <harti@freebsd.org>
- *
+ *
+ * Copyright (c) 2010 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * Portions of this software were 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:
@@ -34,6 +40,7 @@
#include <sys/queue.h>
#include <sys/sysctl.h>
#include <sys/un.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
@@ -52,6 +59,18 @@
struct trapsink_list trapsink_list = TAILQ_HEAD_INITIALIZER(trapsink_list);
+/* List of target addresses */
+struct target_addresslist target_addresslist =
+ SLIST_HEAD_INITIALIZER(target_addresslist);
+
+/* List of target parameters */
+struct target_paramlist target_paramlist =
+ SLIST_HEAD_INITIALIZER(target_paramlist);
+
+/* List of notification targets */
+struct target_notifylist target_notifylist =
+ SLIST_HEAD_INITIALIZER(target_notifylist);
+
static const struct asn_oid oid_begemotTrapSinkTable =
OIDX_begemotTrapSinkTable;
static const struct asn_oid oid_sysUpTime = OIDX_sysUpTime;
@@ -398,57 +417,152 @@ op_trapsink(struct snmp_context *ctx, struct snmp_value *value,
return (SNMP_ERR_NOERROR);
}
+static void
+snmp_create_v1_trap(struct snmp_pdu *pdu, char *com,
+ const struct asn_oid *trap_oid)
+{
+ memset(pdu, 0, sizeof(*pdu));
+ strcpy(pdu->community, com);
+
+ pdu->version = SNMP_V1;
+ pdu->type = SNMP_PDU_TRAP;
+ pdu->enterprise = systemg.object_id;
+ memcpy(pdu->agent_addr, snmpd.trap1addr, 4);
+ pdu->generic_trap = trap_oid->subs[trap_oid->len - 1] - 1;
+ pdu->specific_trap = 0;
+ pdu->time_stamp = get_ticks() - start_tick;
+ pdu->nbindings = 0;
+}
+
+static void
+snmp_create_v2_trap(struct snmp_pdu *pdu, char *com,
+ const struct asn_oid *trap_oid)
+{
+ memset(pdu, 0, sizeof(*pdu));
+ strcpy(pdu->community, com);
+
+ pdu->version = SNMP_V2c;
+ pdu->type = SNMP_PDU_TRAP2;
+ pdu->request_id = reqid_next(trap_reqid);
+ pdu->error_index = 0;
+ pdu->error_status = SNMP_ERR_NOERROR;
+
+ pdu->bindings[0].var = oid_sysUpTime;
+ pdu->bindings[0].var.subs[pdu->bindings[0].var.len++] = 0;
+ pdu->bindings[0].syntax = SNMP_SYNTAX_TIMETICKS;
+ pdu->bindings[0].v.uint32 = get_ticks() - start_tick;
+
+ pdu->bindings[1].var = oid_snmpTrapOID;
+ pdu->bindings[1].var.subs[pdu->bindings[1].var.len++] = 0;
+ pdu->bindings[1].syntax = SNMP_SYNTAX_OID;
+ pdu->bindings[1].v.oid = *trap_oid;
+
+ pdu->nbindings = 2;
+}
+
+static void
+snmp_create_v3_trap(struct snmp_pdu *pdu, struct target_param *target,
+ const struct asn_oid *trap_oid)
+{
+ uint64_t etime;
+ struct usm_user *usmuser;
+
+ memset(pdu, 0, sizeof(*pdu));
+
+ pdu->version = SNMP_V3;
+ pdu->type = SNMP_PDU_TRAP2;
+ pdu->request_id = reqid_next(trap_reqid);
+ pdu->error_index = 0;
+ pdu->error_status = SNMP_ERR_NOERROR;
+
+ pdu->bindings[0].var = oid_sysUpTime;
+ pdu->bindings[0].var.subs[pdu->bindings[0].var.len++] = 0;
+ pdu->bindings[0].syntax = SNMP_SYNTAX_TIMETICKS;
+ pdu->bindings[0].v.uint32 = get_ticks() - start_tick;
+
+ pdu->bindings[1].var = oid_snmpTrapOID;
+ pdu->bindings[1].var.subs[pdu->bindings[1].var.len++] = 0;
+ pdu->bindings[1].syntax = SNMP_SYNTAX_OID;
+ pdu->bindings[1].v.oid = *trap_oid;
+
+ pdu->nbindings = 2;
+
+ etime = (get_ticks() - start_tick) / 100ULL;
+ if (etime < INT32_MAX)
+ snmpd_engine.engine_time = etime;
+ else {
+ start_tick = get_ticks();
+ set_snmpd_engine();
+ snmpd_engine.engine_time = start_tick;
+ }
+
+ memcpy(pdu->engine.engine_id, snmpd_engine.engine_id,
+ snmpd_engine.engine_len);
+ pdu->engine.engine_len = snmpd_engine.engine_len;
+ pdu->engine.engine_boots = snmpd_engine.engine_boots;
+ pdu->engine.engine_time = snmpd_engine.engine_time;
+ pdu->engine.max_msg_size = snmpd_engine.max_msg_size;
+ strlcpy(pdu->user.sec_name, target->secname,
+ sizeof(pdu->user.sec_name));
+ pdu->security_model = target->sec_model;
+
+ pdu->context_engine_len = snmpd_engine.engine_len;
+ memcpy(pdu->context_engine, snmpd_engine.engine_id,
+ snmpd_engine.engine_len);
+
+ if (target->sec_model == SNMP_SECMODEL_USM &&
+ target->sec_level != SNMP_noAuthNoPriv) {
+ usmuser = usm_find_user(pdu->engine.engine_id,
+ pdu->engine.engine_len, pdu->user.sec_name);
+ if (usmuser != NULL) {
+ pdu->user.auth_proto = usmuser->suser.auth_proto;
+ pdu->user.priv_proto = usmuser->suser.priv_proto;
+ memcpy(pdu->user.auth_key, usmuser->suser.auth_key,
+ sizeof(pdu->user.auth_key));
+ memcpy(pdu->user.priv_key, usmuser->suser.priv_key,
+ sizeof(pdu->user.priv_key));
+ }
+ snmp_pdu_init_secparams(pdu);
+ }
+}
+
void
snmp_send_trap(const struct asn_oid *trap_oid, ...)
{
struct snmp_pdu pdu;
struct trapsink *t;
const struct snmp_value *v;
+ struct target_notify *n;
+ struct target_address *ta;
+ struct target_param *tp;
+
va_list ap;
u_char *sndbuf;
+ char *tag;
size_t sndlen;
ssize_t len;
+ int32_t ip;
TAILQ_FOREACH(t, &trapsink_list, link) {
if (t->status != TRAPSINK_ACTIVE)
continue;
- memset(&pdu, 0, sizeof(pdu));
- strcpy(pdu.community, t->comm);
- if (t->version == TRAPSINK_V1) {
- pdu.version = SNMP_V1;
- pdu.type = SNMP_PDU_TRAP;
- pdu.enterprise = systemg.object_id;
- memcpy(pdu.agent_addr, snmpd.trap1addr, 4);
- pdu.generic_trap = trap_oid->subs[trap_oid->len - 1] - 1;
- pdu.specific_trap = 0;
- pdu.time_stamp = get_ticks() - start_tick;
-
- pdu.nbindings = 0;
- } else {
- pdu.version = SNMP_V2c;
- pdu.type = SNMP_PDU_TRAP2;
- pdu.request_id = reqid_next(trap_reqid);
- pdu.error_index = 0;
- pdu.error_status = SNMP_ERR_NOERROR;
-
- pdu.bindings[0].var = oid_sysUpTime;
- pdu.bindings[0].var.subs[pdu.bindings[0].var.len++] = 0;
- pdu.bindings[0].syntax = SNMP_SYNTAX_TIMETICKS;
- pdu.bindings[0].v.uint32 = get_ticks() - start_tick;
-
- pdu.bindings[1].var = oid_snmpTrapOID;
- pdu.bindings[1].var.subs[pdu.bindings[1].var.len++] = 0;
- pdu.bindings[1].syntax = SNMP_SYNTAX_OID;
- pdu.bindings[1].v.oid = *trap_oid;
-
- pdu.nbindings = 2;
- }
+
+ if (t->version == TRAPSINK_V1)
+ snmp_create_v1_trap(&pdu, t->comm, trap_oid);
+ else
+ snmp_create_v2_trap(&pdu, t->comm, trap_oid);
va_start(ap, trap_oid);
while ((v = va_arg(ap, const struct snmp_value *)) != NULL)
pdu.bindings[pdu.nbindings++] = *v;
va_end(ap);
+ if (snmp_pdu_auth_access(&pdu, &ip) != SNMP_CODE_OK) {
+ syslog(LOG_DEBUG, "send trap to %s failed: no access",
+ t->comm);
+ continue;
+ }
+
if ((sndbuf = buf_alloc(1)) == NULL) {
syslog(LOG_ERR, "trap send buffer: %m");
return;
@@ -464,4 +578,339 @@ snmp_send_trap(const struct asn_oid *trap_oid, ...)
free(sndbuf);
}
+
+ SLIST_FOREACH(n, &target_notifylist, tn) {
+ if (n->status != RowStatus_active || n->taglist[0] == '\0')
+ continue;
+
+ SLIST_FOREACH(ta, &target_addresslist, ta)
+ if ((tag = strstr(ta->taglist, n->taglist)) != NULL &&
+ (tag[strlen(n->taglist)] == ' ' ||
+ tag[strlen(n->taglist)] == '\0' ||
+ tag[strlen(n->taglist)] == '\t' ||
+ tag[strlen(n->taglist)] == '\r' ||
+ tag[strlen(n->taglist)] == '\n') &&
+ ta->status == RowStatus_active)
+ break;
+ if (ta == NULL)
+ continue;
+
+ SLIST_FOREACH(tp, &target_paramlist, tp)
+ if (strcmp(tp->name, ta->paramname) == 0 &&
+ tp->status == 1)
+ break;
+ if (tp == NULL)
+ continue;
+
+ switch (tp->mpmodel) {
+ case SNMP_MPM_SNMP_V1:
+ snmp_create_v1_trap(&pdu, tp->secname, trap_oid);
+ break;
+
+ case SNMP_MPM_SNMP_V2c:
+ snmp_create_v2_trap(&pdu, tp->secname, trap_oid);
+ break;
+
+ case SNMP_MPM_SNMP_V3:
+ snmp_create_v3_trap(&pdu, tp, trap_oid);
+ break;
+
+ default:
+ continue;
+ }
+
+ va_start(ap, trap_oid);
+ while ((v = va_arg(ap, const struct snmp_value *)) != NULL)
+ pdu.bindings[pdu.nbindings++] = *v;
+ va_end(ap);
+
+ if (snmp_pdu_auth_access(&pdu, &ip) != SNMP_CODE_OK) {
+ syslog(LOG_DEBUG, "send trap to %s failed: no access",
+ t->comm);
+ continue;
+ }
+
+ if ((sndbuf = buf_alloc(1)) == NULL) {
+ syslog(LOG_ERR, "trap send buffer: %m");
+ return;
+ }
+
+ snmp_output(&pdu, sndbuf, &sndlen, "TRAP");
+
+ if ((len = send(ta->socket, sndbuf, sndlen, 0)) == -1)
+ syslog(LOG_ERR, "send: %m");
+ else if ((size_t)len != sndlen)
+ syslog(LOG_ERR, "send: short write %zu/%zu",
+ sndlen, (size_t)len);
+
+ free(sndbuf);
+ }
+}
+
+/*
+ * RFC 3413 SNMP Management Target MIB
+ */
+struct snmpd_target_stats *
+bsnmpd_get_target_stats(void)
+{
+ return (&snmpd_target_stats);
+}
+
+struct target_address *
+target_first_address(void)
+{
+ return (SLIST_FIRST(&target_addresslist));
+}
+
+struct target_address *
+target_next_address(struct target_address *addrs)
+{
+ if (addrs == NULL)
+ return (NULL);
+
+ return (SLIST_NEXT(addrs, ta));
+}
+
+struct target_address *
+target_new_address(char *aname)
+{
+ int cmp;
+ struct target_address *addrs, *temp, *prev;
+
+ SLIST_FOREACH(addrs, &target_addresslist, ta)
+ if (strcmp(aname, addrs->name) == 0)
+ return (NULL);
+
+ if ((addrs = (struct target_address *)malloc(sizeof(*addrs))) == NULL)
+ return (NULL);
+
+ memset(addrs, 0, sizeof(*addrs));
+ strlcpy(addrs->name, aname, sizeof(addrs->name));
+ addrs->timeout = 150;
+ addrs->retry = 3; /* XXX */
+
+ if ((prev = SLIST_FIRST(&target_addresslist)) == NULL ||
+ strcmp(aname, prev->name) < 0) {
+ SLIST_INSERT_HEAD(&target_addresslist, addrs, ta);
+ return (addrs);
+ }
+
+ SLIST_FOREACH(temp, &target_addresslist, ta) {
+ if ((cmp = strcmp(aname, temp->name)) <= 0)
+ break;
+ prev = temp;
+ }
+
+ if (temp == NULL || cmp < 0)
+ SLIST_INSERT_AFTER(prev, addrs, ta);
+ else if (cmp > 0)
+ SLIST_INSERT_AFTER(temp, addrs, ta);
+ else {
+ syslog(LOG_ERR, "Target address %s exists", addrs->name);
+ free(addrs);
+ return (NULL);
+ }
+
+ return (addrs);
+}
+
+int
+target_activate_address(struct target_address *addrs)
+{
+ struct sockaddr_in sa;
+
+ if ((addrs->socket = socket(PF_INET, SOCK_DGRAM, 0)) == -1) {
+ syslog(LOG_ERR, "socket(UDP): %m");
+ return (SNMP_ERR_RES_UNAVAIL);
+ }
+
+ (void)shutdown(addrs->socket, SHUT_RD);
+ sa.sin_len = sizeof(sa);
+ sa.sin_family = AF_INET;
+
+ sa.sin_addr.s_addr = htonl((addrs->address[0] << 24) |
+ (addrs->address[1] << 16) | (addrs->address[2] << 8) |
+ (addrs->address[3] << 0));
+ sa.sin_port = htons(addrs->address[4]) << 8 |
+ htons(addrs->address[5]) << 0;
+
+ if (connect(addrs->socket, (struct sockaddr *)&sa, sa.sin_len) == -1) {
+ syslog(LOG_ERR, "connect(%s,%u): %m",
+ inet_ntoa(sa.sin_addr), ntohs(sa.sin_port));
+ (void)close(addrs->socket);
+ return (SNMP_ERR_GENERR);
+ }
+
+ addrs->status = RowStatus_active;
+
+ return (SNMP_ERR_NOERROR);
+}
+
+int
+target_delete_address(struct target_address *addrs)
+{
+ SLIST_REMOVE(&target_addresslist, addrs, target_address, ta);
+ if (addrs->status == RowStatus_active)
+ close(addrs->socket);
+ free(addrs);
+
+ return (0);
+}
+
+struct target_param *
+target_first_param(void)
+{
+ return (SLIST_FIRST(&target_paramlist));
+}
+
+struct target_param *
+target_next_param(struct target_param *param)
+{
+ if (param == NULL)
+ return (NULL);
+
+ return (SLIST_NEXT(param, tp));
+}
+
+struct target_param *
+target_new_param(char *pname)
+{
+ int cmp;
+ struct target_param *param, *temp, *prev;
+
+ SLIST_FOREACH(param, &target_paramlist, tp)
+ if (strcmp(pname, param->name) == 0)
+ return (NULL);
+
+ if ((param = (struct target_param *)malloc(sizeof(*param))) == NULL)
+ return (NULL);
+
+ memset(param, 0, sizeof(*param));
+ strlcpy(param->name, pname, sizeof(param->name));
+
+ if ((prev = SLIST_FIRST(&target_paramlist)) == NULL ||
+ strcmp(pname, prev->name) < 0) {
+ SLIST_INSERT_HEAD(&target_paramlist, param, tp);
+ return (param);
+ }
+
+ SLIST_FOREACH(temp, &target_paramlist, tp) {
+ if ((cmp = strcmp(pname, temp->name)) <= 0)
+ break;
+ prev = temp;
+ }
+
+ if (temp == NULL || cmp < 0)
+ SLIST_INSERT_AFTER(prev, param, tp);
+ else if (cmp > 0)
+ SLIST_INSERT_AFTER(temp, param, tp);
+ else {
+ syslog(LOG_ERR, "Target parameter %s exists", param->name);
+ free(param);
+ return (NULL);
+ }
+
+ return (param);
+}
+
+int
+target_delete_param(struct target_param *param)
+{
+ SLIST_REMOVE(&target_paramlist, param, target_param, tp);
+ free(param);
+
+ return (0);
+}
+
+struct target_notify *
+target_first_notify(void)
+{
+ return (SLIST_FIRST(&target_notifylist));
+}
+
+struct target_notify *
+target_next_notify(struct target_notify *notify)
+{
+ if (notify == NULL)
+ return (NULL);
+
+ return (SLIST_NEXT(notify, tn));
+}
+
+struct target_notify *
+target_new_notify(char *nname)
+{
+ int cmp;
+ struct target_notify *notify, *temp, *prev;
+
+ SLIST_FOREACH(notify, &target_notifylist, tn)
+ if (strcmp(nname, notify->name) == 0)
+ return (NULL);
+
+ if ((notify = (struct target_notify *)malloc(sizeof(*notify))) == NULL)
+ return (NULL);
+
+ memset(notify, 0, sizeof(*notify));
+ strlcpy(notify->name, nname, sizeof(notify->name));
+
+ if ((prev = SLIST_FIRST(&target_notifylist)) == NULL ||
+ strcmp(nname, prev->name) < 0) {
+ SLIST_INSERT_HEAD(&target_notifylist, notify, tn);
+ return (notify);
+ }
+
+ SLIST_FOREACH(temp, &target_notifylist, tn) {
+ if ((cmp = strcmp(nname, temp->name)) <= 0)
+ break;
+ prev = temp;
+ }
+
+ if (temp == NULL || cmp < 0)
+ SLIST_INSERT_AFTER(prev, notify, tn);
+ else if (cmp > 0)
+ SLIST_INSERT_AFTER(temp, notify, tn);
+ else {
+ syslog(LOG_ERR, "Notification target %s exists", notify->name);
+ free(notify);
+ return (NULL);
+ }
+
+ return (notify);
+}
+
+int
+target_delete_notify(struct target_notify *notify)
+{
+ SLIST_REMOVE(&target_notifylist, notify, target_notify, tn);
+ free(notify);
+
+ return (0);
+}
+
+void
+target_flush_all(void)
+{
+ struct target_address *addrs;
+ struct target_param *param;
+ struct target_notify *notify;
+
+ while ((addrs = SLIST_FIRST(&target_addresslist)) != NULL) {
+ SLIST_REMOVE_HEAD(&target_addresslist, ta);
+ if (addrs->status == RowStatus_active)
+ close(addrs->socket);
+ free(addrs);
+ }
+ SLIST_INIT(&target_addresslist);
+
+ while ((param = SLIST_FIRST(&target_paramlist)) != NULL) {
+ SLIST_REMOVE_HEAD(&target_paramlist, tp);
+ free(param);
+ }
+ SLIST_INIT(&target_paramlist);
+
+ while ((notify = SLIST_FIRST(&target_notifylist)) != NULL) {
+ SLIST_REMOVE_HEAD(&target_notifylist, tn);
+ free(notify);
+ }
+ SLIST_INIT(&target_notifylist);
}
diff --git a/contrib/bsnmp/snmpd/tree.def b/contrib/bsnmp/snmpd/tree.def
index 00672eb..f4d8579 100644
--- a/contrib/bsnmp/snmpd/tree.def
+++ b/contrib/bsnmp/snmpd/tree.def
@@ -30,6 +30,9 @@
#
# System group and private Begemot SNMPd MIB.
#
+
+include "tc.def"
+
(1 internet
(2 mgmt
(1 mibII
diff --git a/lib/libbsnmp/libbsnmp/Makefile b/lib/libbsnmp/libbsnmp/Makefile
index d33808d..7057816 100644
--- a/lib/libbsnmp/libbsnmp/Makefile
+++ b/lib/libbsnmp/libbsnmp/Makefile
@@ -10,6 +10,10 @@ CONTRIB= ${.CURDIR}/../../../contrib/bsnmp/lib
LIB= bsnmp
SHLIBDIR?= /lib
+FILESGROUPS+= DEFS
+DEFSDIR?= ${SHAREDIR}/snmp/defs
+DEFS= tc.def
+
CFLAGS+= -I${CONTRIB} -DHAVE_ERR_H -DHAVE_GETADDRINFO -DHAVE_STRLCPY
CFLAGS+= -DHAVE_STDINT_H -DHAVE_INTTYPES_H -DQUADFMT='"llu"' -DQUADXFMT='"llx"'
diff --git a/usr.sbin/bsnmpd/bsnmpd/Makefile b/usr.sbin/bsnmpd/bsnmpd/Makefile
index 80b14e2..3e6df47 100644
--- a/usr.sbin/bsnmpd/bsnmpd/Makefile
+++ b/usr.sbin/bsnmpd/bsnmpd/Makefile
@@ -25,6 +25,7 @@ BMIBSDIR= ${SHAREDIR}/snmp/mibs
DEFS= tree.def
DEFSDIR= ${SHAREDIR}/snmp/defs
+CFLAGS+= -DSNMPTREE_TYPES
CFLAGS+= -I${CONTRIB}/lib -I${CONTRIB}/snmpd -I. -DUSE_LIBBEGEMOT
CFLAGS+= -DUSE_TCPWRAPPERS -DQUADFMT='"llu"' -DQUADXFMT='"llx"'
CFLAGS+= -DHAVE_STDINT_H -DHAVE_INTTYPES_H -DHAVE_ERR_H -DHAVE_STRLCPY
diff --git a/usr.sbin/bsnmpd/modules/Makefile b/usr.sbin/bsnmpd/modules/Makefile
index f7deb77..ab378f0 100644
--- a/usr.sbin/bsnmpd/modules/Makefile
+++ b/usr.sbin/bsnmpd/modules/Makefile
@@ -13,6 +13,7 @@ SUBDIR= ${_snmp_atm} \
snmp_hostres \
snmp_mibII \
snmp_pf \
+ snmp_target \
snmp_usm \
snmp_vacm \
snmp_wlan
diff --git a/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_tree.def b/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_tree.def
index cbebda0..a8f30c8 100644
--- a/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_tree.def
+++ b/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_tree.def
@@ -26,22 +26,13 @@
# $FreeBSD$
#
-#include "tc.def"
+include "tc.def"
typedef TruthValue ENUM (
1 true
2 false
)
-typedef RowStatus ENUM (
- 1 active
- 2 notInService
- 3 notReady
- 4 createAndGo
- 5 createAndWait
- 6 destroy
-)
-
typedef StpPortState ENUM (
1 disabled
2 blocking
diff --git a/usr.sbin/bsnmpd/modules/snmp_target/Makefile b/usr.sbin/bsnmpd/modules/snmp_target/Makefile
new file mode 100755
index 0000000..10141e5
--- /dev/null
+++ b/usr.sbin/bsnmpd/modules/snmp_target/Makefile
@@ -0,0 +1,20 @@
+# $FreeBSD$
+#
+# Author: Shteryana Shopova <syrinx@freebsd.org>
+
+CONTRIB= ${.CURDIR}/../../../../contrib/bsnmp
+.PATH: ${CONTRIB}/snmp_target
+
+MOD= target
+SRCS= target_snmp.c
+XSYM= snmpTargetMIB snmpNotificationMIB snmpUDPDomain
+
+MAN= snmp_target.3
+
+CFLAGS+= -I${CONTRIB}/lib -I${CONTRIB}/snmpd -DSNMPTREE_TYPES
+CFLAGS+= -DHAVE_ERR_H -DHAVE_GETADDRINFO -DHAVE_STRLCPY -DHAVE_SYS_TREE_H
+
+DEFS= ${MOD}_tree.def
+BMIBS=
+
+.include <bsd.snmpmod.mk>
diff --git a/usr.sbin/bsnmpd/modules/snmp_wlan/wlan_tree.def b/usr.sbin/bsnmpd/modules/snmp_wlan/wlan_tree.def
index f267f76..bc89d56 100644
--- a/usr.sbin/bsnmpd/modules/snmp_wlan/wlan_tree.def
+++ b/usr.sbin/bsnmpd/modules/snmp_wlan/wlan_tree.def
@@ -29,14 +29,7 @@
# $FreeBSD$
#
-typedef RowStatus ENUM (
- 1 active
- 2 notInService
- 3 notReady
- 4 createAndGo
- 5 createAndWait
- 6 destroy
-)
+include "tc.def"
typedef TruthValue ENUM (
1 true
OpenPOWER on IntegriCloud