svn commit: r216594 - in head: contrib/bsnmp/lib contrib/bsnmp/snmp_target contrib/bsnmp/snmp_usm contrib/bsnmp/snmp_vacm contrib/bsnmp/snmpd lib/libbsnmp/libbsnmp usr.sbin/bsnmpd/bsnmpd usr.sbin/b...

Shteryana Shopova syrinx at FreeBSD.org
Mon Dec 20 17:13:15 UTC 2010


Author: syrinx
Date: Mon Dec 20 17:13:14 2010
New Revision: 216594
URL: http://svn.freebsd.org/changeset/base/216594

Log:
  Bring in a SNMP module that allows configuration of SNMPv3 Notification targets.
  
  Sponsored by:	The FreeBSD Foundation
  Reviewed by:	philip
  Approved by:	philip

Added:
  head/contrib/bsnmp/lib/tc.def   (contents, props changed)
  head/contrib/bsnmp/snmp_target/
  head/contrib/bsnmp/snmp_target/snmp_target.3   (contents, props changed)
  head/contrib/bsnmp/snmp_target/target_snmp.c   (contents, props changed)
  head/contrib/bsnmp/snmp_target/target_tree.def   (contents, props changed)
  head/usr.sbin/bsnmpd/modules/snmp_target/
  head/usr.sbin/bsnmpd/modules/snmp_target/Makefile   (contents, props changed)
Modified:
  head/contrib/bsnmp/lib/bsnmplib.3
  head/contrib/bsnmp/lib/snmp.c
  head/contrib/bsnmp/lib/snmp.h
  head/contrib/bsnmp/lib/snmpagent.c
  head/contrib/bsnmp/lib/snmpclient.c
  head/contrib/bsnmp/lib/snmppriv.h
  head/contrib/bsnmp/snmp_usm/snmp_usm.3
  head/contrib/bsnmp/snmp_usm/usm_tree.def
  head/contrib/bsnmp/snmp_vacm/vacm_tree.def
  head/contrib/bsnmp/snmpd/main.c
  head/contrib/bsnmp/snmpd/snmpmod.3
  head/contrib/bsnmp/snmpd/snmpmod.h
  head/contrib/bsnmp/snmpd/trap.c
  head/contrib/bsnmp/snmpd/tree.def
  head/lib/libbsnmp/libbsnmp/Makefile
  head/usr.sbin/bsnmpd/bsnmpd/Makefile
  head/usr.sbin/bsnmpd/modules/Makefile
  head/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_tree.def
  head/usr.sbin/bsnmpd/modules/snmp_wlan/wlan_tree.def

Modified: head/contrib/bsnmp/lib/bsnmplib.3
==============================================================================
--- head/contrib/bsnmp/lib/bsnmplib.3	Mon Dec 20 17:08:22 2010	(r216593)
+++ head/contrib/bsnmp/lib/bsnmplib.3	Mon Dec 20 17:13:14 2010	(r216594)
@@ -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
 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 k
 #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 PD
 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 .

Modified: head/contrib/bsnmp/lib/snmp.c
==============================================================================
--- head/contrib/bsnmp/lib/snmp.c	Mon Dec 20 17:08:22 2010	(r216593)
+++ head/contrib/bsnmp/lib/snmp.c	Mon Dec 20 17:13:14 2010	(r216594)
@@ -764,6 +764,7 @@ snmp_pdu_encode_header(struct asn_buf *b
 
 		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, c
 }
 
 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;

Modified: head/contrib/bsnmp/lib/snmp.h
==============================================================================
--- head/contrib/bsnmp/lib/snmp.h	Mon Dec 20 17:08:22 2010	(r216593)
+++ head/contrib/bsnmp/lib/snmp.h	Mon Dec 20 17:13:14 2010	(r216594)
@@ -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 
 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 *);

Modified: head/contrib/bsnmp/lib/snmpagent.c
==============================================================================
--- head/contrib/bsnmp/lib/snmpagent.c	Mon Dec 20 17:08:22 2010	(r216593)
+++ head/contrib/bsnmp/lib/snmpagent.c	Mon Dec 20 17:13:14 2010	(r216594)
@@ -178,7 +178,9 @@ snmp_pdu_create_response(struct snmp_pdu
 	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;

Modified: head/contrib/bsnmp/lib/snmpclient.c
==============================================================================
--- head/contrib/bsnmp/lib/snmpclient.c	Mon Dec 20 17:08:22 2010	(r216593)
+++ head/contrib/bsnmp/lib/snmpclient.c	Mon Dec 20 17:13:14 2010	(r216594)
@@ -1160,10 +1160,11 @@ snmp_pdu_create(struct snmp_pdu *pdu, u_
 	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
 	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);

Modified: head/contrib/bsnmp/lib/snmppriv.h
==============================================================================
--- head/contrib/bsnmp/lib/snmppriv.h	Mon Dec 20 17:08:22 2010	(r216593)
+++ head/contrib/bsnmp/lib/snmppriv.h	Mon Dec 20 17:13:14 2010	(r216594)
@@ -38,9 +38,6 @@ enum snmp_code snmp_fix_encoding(struct 
 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 *);

Added: head/contrib/bsnmp/lib/tc.def
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/contrib/bsnmp/lib/tc.def	Mon Dec 20 17:13:14 2010	(r216594)
@@ -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
+)
+

Added: head/contrib/bsnmp/snmp_target/snmp_target.3
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/contrib/bsnmp/snmp_target/snmp_target.3	Mon Dec 20 17:13:14 2010	(r216594)
@@ -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 at FreeBSD.org

Added: head/contrib/bsnmp/snmp_target/target_snmp.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/contrib/bsnmp/snmp_target/target_snmp.c	Mon Dec 20 17:13:14 2010	(r216594)
@@ -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);

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list