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 syr...@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 ***
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to