Bring in a SNMP module that allows configuration of SNMPv3 Notification targets.
Sponsored by: The FreeBSD Foundation Reviewed by: philip Approved by: philip
This commit is contained in:
parent
81bd5041a2
commit
72cd7a520d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=216594
@ -37,7 +37,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $Begemot: bsnmp/lib/bsnmplib.3,v 1.9 2005/10/04 08:46:51 brandt_h Exp $
|
.\" $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
|
.Dt BSNMPLIB 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -50,6 +50,7 @@
|
|||||||
.Nm snmp_pdu_decode_header ,
|
.Nm snmp_pdu_decode_header ,
|
||||||
.Nm snmp_pdu_decode_scoped ,
|
.Nm snmp_pdu_decode_scoped ,
|
||||||
.Nm snmp_pdu_decode_secmode ,
|
.Nm snmp_pdu_decode_secmode ,
|
||||||
|
.Nm snmp_pdu_init_secparams ,
|
||||||
.Nm snmp_pdu_dump ,
|
.Nm snmp_pdu_dump ,
|
||||||
.Nm snmp_passwd_to_keys ,
|
.Nm snmp_passwd_to_keys ,
|
||||||
.Nm snmp_get_local_keys ,
|
.Nm snmp_get_local_keys ,
|
||||||
@ -83,6 +84,8 @@ Begemot SNMP library
|
|||||||
.Ft enum snmp_code
|
.Ft enum snmp_code
|
||||||
.Fn snmp_pdu_decode_secmode "struct asn_buf *buf" "struct snmp_pdu *pdu"
|
.Fn snmp_pdu_decode_secmode "struct asn_buf *buf" "struct snmp_pdu *pdu"
|
||||||
.Ft void
|
.Ft void
|
||||||
|
.Fn snmp_pdu_init_secparams "struct snmp_pdu *pdu"
|
||||||
|
.Ft void
|
||||||
.Fn snmp_pdu_dump "const struct snmp_pdu *pdu"
|
.Fn snmp_pdu_dump "const struct snmp_pdu *pdu"
|
||||||
.Ft enum snmp_code
|
.Ft enum snmp_code
|
||||||
.Fn snmp_passwd_to_keys "struct snmp_user *user" "char *passwd"
|
.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.
|
Architecture described in RFC 3411.
|
||||||
.Pp
|
.Pp
|
||||||
.Bd -literal -offset indent
|
.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_AUTH_KEY_SIZ 40
|
||||||
#define SNMP_PRIV_KEY_SIZ 32
|
#define SNMP_PRIV_KEY_SIZ 32
|
||||||
|
|
||||||
|
enum snmp_usm_level {
|
||||||
|
SNMP_noAuthNoPriv = 1,
|
||||||
|
SNMP_authNoPriv = 2,
|
||||||
|
SNMP_authPriv = 3
|
||||||
|
};
|
||||||
|
|
||||||
struct snmp_user {
|
struct snmp_user {
|
||||||
char sec_name[SNMP_USM_NAME_SIZ];
|
char sec_name[SNMP_ADM_STR32_SIZ];
|
||||||
enum snmp_authentication auth_proto;
|
enum snmp_authentication auth_proto;
|
||||||
enum snmp_privacy priv_proto;
|
enum snmp_privacy priv_proto;
|
||||||
uint8_t auth_key[SNMP_AUTH_KEY_SIZ];
|
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_PRIV_FLAG 0x2
|
||||||
#define SNMP_MSG_REPORT_FLAG 0x4
|
#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 {
|
struct snmp_pdu {
|
||||||
char community[SNMP_COMMUNITY_MAXLEN + 1];
|
char community[SNMP_COMMUNITY_MAXLEN + 1];
|
||||||
@ -296,7 +307,17 @@ and
|
|||||||
is the type of the PDU.
|
is the type of the PDU.
|
||||||
.Fa security_model
|
.Fa security_model
|
||||||
is the security model used for SNMPv3 PDUs. The only supported
|
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
|
.Pp
|
||||||
The function
|
The function
|
||||||
.Fn snmp_value_free
|
.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.
|
If successfull, a plain text scoped PDU is stored in the buffer.
|
||||||
.Pp
|
.Pp
|
||||||
The function
|
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
|
.Fn snmp_pdu_dump
|
||||||
dumps the PDU in a human readable form by calling
|
dumps the PDU in a human readable form by calling
|
||||||
.Fn snmp_printf .
|
.Fn snmp_printf .
|
||||||
|
@ -764,6 +764,7 @@ snmp_pdu_encode_header(struct asn_buf *b, struct snmp_pdu *pdu)
|
|||||||
|
|
||||||
if (pdu->type != SNMP_PDU_RESPONSE &&
|
if (pdu->type != SNMP_PDU_RESPONSE &&
|
||||||
pdu->type != SNMP_PDU_TRAP &&
|
pdu->type != SNMP_PDU_TRAP &&
|
||||||
|
pdu->type != SNMP_PDU_TRAP2 &&
|
||||||
pdu->type != SNMP_PDU_REPORT)
|
pdu->type != SNMP_PDU_REPORT)
|
||||||
pdu->flags |= SNMP_MSG_REPORT_FLAG;
|
pdu->flags |= SNMP_MSG_REPORT_FLAG;
|
||||||
|
|
||||||
@ -1176,23 +1177,19 @@ snmp_value_copy(struct snmp_value *to, const struct snmp_value *from)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
snmp_pdu_init_secparams(struct snmp_pdu *pdu, struct snmp_engine *eng,
|
snmp_pdu_init_secparams(struct snmp_pdu *pdu)
|
||||||
struct snmp_user *user)
|
|
||||||
{
|
{
|
||||||
int32_t rval;
|
int32_t rval;
|
||||||
|
|
||||||
memcpy(&pdu->engine, eng, sizeof(pdu->engine));
|
if (pdu->user.auth_proto != SNMP_AUTH_NOAUTH)
|
||||||
memcpy(&pdu->user, user, sizeof(pdu->user));
|
|
||||||
|
|
||||||
if (user->auth_proto != SNMP_AUTH_NOAUTH)
|
|
||||||
pdu->flags |= SNMP_MSG_AUTH_FLAG;
|
pdu->flags |= SNMP_MSG_AUTH_FLAG;
|
||||||
|
|
||||||
switch (user->priv_proto) {
|
switch (pdu->user.priv_proto) {
|
||||||
case SNMP_PRIV_DES:
|
case SNMP_PRIV_DES:
|
||||||
memcpy(pdu->msg_salt, &eng->engine_boots,
|
memcpy(pdu->msg_salt, &pdu->engine.engine_boots,
|
||||||
sizeof(eng->engine_boots));
|
sizeof(pdu->engine.engine_boots));
|
||||||
rval = random();
|
rval = random();
|
||||||
memcpy(pdu->msg_salt + sizeof(eng->engine_boots), &rval,
|
memcpy(pdu->msg_salt + sizeof(pdu->engine.engine_boots), &rval,
|
||||||
sizeof(int32_t));
|
sizeof(int32_t));
|
||||||
pdu->flags |= SNMP_MSG_PRIV_FLAG;
|
pdu->flags |= SNMP_MSG_PRIV_FLAG;
|
||||||
break;
|
break;
|
||||||
|
@ -89,6 +89,10 @@ enum snmp_version {
|
|||||||
SNMP_V3,
|
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_ADM_STR32_SIZ (32 + 1)
|
||||||
#define SNMP_AUTH_KEY_SIZ 40
|
#define SNMP_AUTH_KEY_SIZ 40
|
||||||
#define SNMP_PRIV_KEY_SIZ 32
|
#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 *);
|
int snmp_value_copy(struct snmp_value *, const struct snmp_value *);
|
||||||
|
|
||||||
void snmp_pdu_free(struct snmp_pdu *);
|
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(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_header(struct asn_buf *, struct snmp_pdu *);
|
||||||
enum snmp_code snmp_pdu_decode_scoped(struct asn_buf *, struct snmp_pdu *, int32_t *);
|
enum snmp_code snmp_pdu_decode_scoped(struct asn_buf *, struct snmp_pdu *, int32_t *);
|
||||||
|
@ -178,7 +178,9 @@ snmp_pdu_create_response(struct snmp_pdu *pdu, struct snmp_pdu *resp)
|
|||||||
if (resp->version != SNMP_V3)
|
if (resp->version != SNMP_V3)
|
||||||
return;
|
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->identifier = pdu->identifier;
|
||||||
resp->security_model = pdu->security_model;
|
resp->security_model = pdu->security_model;
|
||||||
resp->context_engine_len = pdu->context_engine_len;
|
resp->context_engine_len = pdu->context_engine_len;
|
||||||
|
@ -1160,10 +1160,11 @@ snmp_pdu_create(struct snmp_pdu *pdu, u_int op)
|
|||||||
pdu->flags = 0;
|
pdu->flags = 0;
|
||||||
pdu->security_model = snmp_client.security_model;
|
pdu->security_model = snmp_client.security_model;
|
||||||
|
|
||||||
if (snmp_client.security_model == SNMP_SECMODEL_USM)
|
if (snmp_client.security_model == SNMP_SECMODEL_USM) {
|
||||||
snmp_pdu_init_secparams(pdu, &snmp_client.engine,
|
memcpy(&pdu->engine, &snmp_client.engine, sizeof(pdu->engine));
|
||||||
&snmp_client.user);
|
memcpy(&pdu->user, &snmp_client.user, sizeof(pdu->user));
|
||||||
else
|
snmp_pdu_init_secparams(pdu);
|
||||||
|
} else
|
||||||
seterr(&snmp_client, "unknown security model");
|
seterr(&snmp_client, "unknown security model");
|
||||||
|
|
||||||
if (snmp_client.clen > 0) {
|
if (snmp_client.clen > 0) {
|
||||||
@ -1440,9 +1441,11 @@ snmp_receive_packet(struct snmp_pdu *pdu, struct timeval *tv)
|
|||||||
abuf.asn_len = ret;
|
abuf.asn_len = ret;
|
||||||
|
|
||||||
memset(pdu, 0, sizeof(*pdu));
|
memset(pdu, 0, sizeof(*pdu));
|
||||||
if (snmp_client.security_model == SNMP_SECMODEL_USM)
|
if (snmp_client.security_model == SNMP_SECMODEL_USM) {
|
||||||
snmp_pdu_init_secparams(pdu, &snmp_client.engine,
|
memcpy(&pdu->engine, &snmp_client.engine, sizeof(pdu->engine));
|
||||||
&snmp_client.user);
|
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))) {
|
if (SNMP_CODE_OK != (ret = snmp_pdu_decode(&abuf, pdu, &ip))) {
|
||||||
seterr(&snmp_client, "snmp_decode_pdu: failed %d", ret);
|
seterr(&snmp_client, "snmp_decode_pdu: failed %d", ret);
|
||||||
|
@ -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,
|
enum asn_err snmp_parse_pdus_hdr(struct asn_buf *b, struct snmp_pdu *pdu,
|
||||||
asn_len_t *lenp);
|
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_calc_digest(const struct snmp_pdu *, uint8_t *);
|
||||||
enum snmp_code snmp_pdu_encrypt(const struct snmp_pdu *);
|
enum snmp_code snmp_pdu_encrypt(const struct snmp_pdu *);
|
||||||
enum snmp_code snmp_pdu_decrypt(const struct snmp_pdu *);
|
enum snmp_code snmp_pdu_decrypt(const struct snmp_pdu *);
|
||||||
|
40
contrib/bsnmp/lib/tc.def
Executable file
40
contrib/bsnmp/lib/tc.def
Executable file
@ -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
|
||||||
|
)
|
||||||
|
|
204
contrib/bsnmp/snmp_target/snmp_target.3
Executable file
204
contrib/bsnmp/snmp_target/snmp_target.3
Executable file
@ -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
|
837
contrib/bsnmp/snmp_target/target_snmp.c
Executable file
837
contrib/bsnmp/snmp_target/target_snmp.c
Executable file
@ -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,
|
||||||
|
};
|
95
contrib/bsnmp/snmp_target/target_tree.def
Executable file
95
contrib/bsnmp/snmp_target/target_tree.def
Executable file
@ -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)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
@ -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
|
lost when the module is restarted. A SET operation on this column is not
|
||||||
allowed.
|
allowed.
|
||||||
.It Va usmUserStatus
|
.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.
|
the table.
|
||||||
.El
|
.El
|
||||||
.EL
|
.EL
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
#
|
#
|
||||||
|
|
||||||
|
include "tc.def"
|
||||||
|
|
||||||
typedef StorageType ENUM (
|
typedef StorageType ENUM (
|
||||||
1 other
|
1 other
|
||||||
2 volatile
|
2 volatile
|
||||||
@ -37,15 +39,6 @@ typedef StorageType ENUM (
|
|||||||
5 readOnly
|
5 readOnly
|
||||||
)
|
)
|
||||||
|
|
||||||
typedef RowStatus ENUM (
|
|
||||||
1 active
|
|
||||||
2 notInService
|
|
||||||
3 notReady
|
|
||||||
4 createAndGo
|
|
||||||
5 createAndWait
|
|
||||||
6 destroy
|
|
||||||
)
|
|
||||||
|
|
||||||
(1 internet
|
(1 internet
|
||||||
(6 snmpV2
|
(6 snmpV2
|
||||||
(3 snmpModules
|
(3 snmpModules
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
#
|
#
|
||||||
|
|
||||||
|
include "tc.def"
|
||||||
|
|
||||||
typedef StorageType ENUM (
|
typedef StorageType ENUM (
|
||||||
1 other
|
1 other
|
||||||
2 volatile
|
2 volatile
|
||||||
@ -37,15 +39,6 @@ typedef StorageType ENUM (
|
|||||||
5 readOnly
|
5 readOnly
|
||||||
)
|
)
|
||||||
|
|
||||||
typedef RowStatus ENUM (
|
|
||||||
1 active
|
|
||||||
2 notInService
|
|
||||||
3 notReady
|
|
||||||
4 createAndGo
|
|
||||||
5 createAndWait
|
|
||||||
6 destroy
|
|
||||||
)
|
|
||||||
|
|
||||||
(1 internet
|
(1 internet
|
||||||
(6 snmpV2
|
(6 snmpV2
|
||||||
(3 snmpModules
|
(3 snmpModules
|
||||||
|
@ -5,6 +5,12 @@
|
|||||||
*
|
*
|
||||||
* Author: Harti Brandt <harti@freebsd.org>
|
* 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
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
* are met:
|
* are met:
|
||||||
@ -98,6 +104,8 @@ struct snmp_engine snmpd_engine;
|
|||||||
/* snmpSerialNo */
|
/* snmpSerialNo */
|
||||||
int32_t snmp_serial_no;
|
int32_t snmp_serial_no;
|
||||||
|
|
||||||
|
struct snmpd_target_stats snmpd_target_stats;
|
||||||
|
|
||||||
/* search path for config files */
|
/* search path for config files */
|
||||||
const char *syspath = PATH_SYSCONFIG;
|
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
|
* 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.
|
* 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)
|
snmp_pdu_auth_access(struct snmp_pdu *pdu, int32_t *ip)
|
||||||
{
|
{
|
||||||
const char *uname;
|
const char *uname;
|
||||||
@ -1838,14 +1846,14 @@ main(int argc, char *argv[])
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
snmp_send_trap(&oid_coldStart, (struct snmp_value *)NULL);
|
|
||||||
|
|
||||||
while ((m = TAILQ_FIRST(&modules_start)) != NULL) {
|
while ((m = TAILQ_FIRST(&modules_start)) != NULL) {
|
||||||
m->flags &= ~LM_ONSTARTLIST;
|
m->flags &= ~LM_ONSTARTLIST;
|
||||||
TAILQ_REMOVE(&modules_start, m, start);
|
TAILQ_REMOVE(&modules_start, m, start);
|
||||||
lm_start(m);
|
lm_start(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
snmp_send_trap(&oid_coldStart, (struct snmp_value *)NULL);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
#ifndef USE_LIBBEGEMOT
|
#ifndef USE_LIBBEGEMOT
|
||||||
evEvent event;
|
evEvent event;
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $Begemot: bsnmp/snmpd/snmpmod.3,v 1.14 2005/10/04 13:30:35 brandt_h Exp $
|
.\" $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
|
.Dt SNMPMOD 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -83,6 +83,7 @@
|
|||||||
.Nm snmp_output ,
|
.Nm snmp_output ,
|
||||||
.Nm snmp_send_port ,
|
.Nm snmp_send_port ,
|
||||||
.Nm snmp_send_trap ,
|
.Nm snmp_send_trap ,
|
||||||
|
.Nm snmp_pdu_auth_access
|
||||||
.Nm string_save ,
|
.Nm string_save ,
|
||||||
.Nm string_commit ,
|
.Nm string_commit ,
|
||||||
.Nm string_rollback ,
|
.Nm string_rollback ,
|
||||||
@ -102,6 +103,7 @@
|
|||||||
.Nm index_compare_off ,
|
.Nm index_compare_off ,
|
||||||
.Nm index_append ,
|
.Nm index_append ,
|
||||||
.Nm index_append_off,
|
.Nm index_append_off,
|
||||||
|
.Nm snmpd_usmstats,
|
||||||
.Nm bsnmpd_get_usm_stats,
|
.Nm bsnmpd_get_usm_stats,
|
||||||
.Nm bsnmpd_reset_usm_stats,
|
.Nm bsnmpd_reset_usm_stats,
|
||||||
.Nm usm_first_user,
|
.Nm usm_first_user,
|
||||||
@ -111,6 +113,25 @@
|
|||||||
.Nm usm_delete_user,
|
.Nm usm_delete_user,
|
||||||
.Nm usm_flush_users,
|
.Nm usm_flush_users,
|
||||||
.Nm usm_user
|
.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"
|
.Nd "SNMP daemon loadable module interface"
|
||||||
.Sh LIBRARY
|
.Sh LIBRARY
|
||||||
Begemot SNMP library
|
Begemot SNMP library
|
||||||
@ -201,6 +222,8 @@ Begemot SNMP library
|
|||||||
.Fc
|
.Fc
|
||||||
.Ft void
|
.Ft void
|
||||||
.Fn snmp_send_trap "const struct asn_oid *oid" "..."
|
.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
|
.Ft int
|
||||||
.Fn string_save "struct snmp_value *val" "struct snmp_context *ctx" "ssize_t req_size" "u_char **strp"
|
.Fn string_save "struct snmp_value *val" "struct snmp_context *ctx" "ssize_t req_size" "u_char **strp"
|
||||||
.Ft void
|
.Ft void
|
||||||
@ -239,6 +262,7 @@ Begemot SNMP library
|
|||||||
.Fn index_append "struct asn_oid *dst" "u_int sub" "const struct asn_oid *src"
|
.Fn index_append "struct asn_oid *dst" "u_int sub" "const struct asn_oid *src"
|
||||||
.Ft void
|
.Ft void
|
||||||
.Fn index_append_off "struct asn_oid *dst" "u_int sub" "const struct asn_oid *src" "u_int off"
|
.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 *
|
.Ft struct snmpd_usmstat *
|
||||||
.Fn bsnmpd_get_usm_stats "void"
|
.Fn bsnmpd_get_usm_stats "void"
|
||||||
.Ft void
|
.Ft void
|
||||||
@ -256,6 +280,36 @@ Begemot SNMP library
|
|||||||
.Ft void
|
.Ft void
|
||||||
.Fn usm_flush_users "void"
|
.Fn usm_flush_users "void"
|
||||||
.Vt extern struct usm_user *usm_user;
|
.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_usmUnknownEngineIDs;
|
||||||
.Vt extern const struct asn_oid oid_usmNotInTimeWindows;
|
.Vt extern const struct asn_oid oid_usmNotInTimeWindows;
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
@ -603,7 +657,7 @@ struct usm_user {
|
|||||||
struct snmp_user suser;
|
struct snmp_user suser;
|
||||||
uint8_t user_engine_id[SNMP_ENGINE_ID_SIZ];
|
uint8_t user_engine_id[SNMP_ENGINE_ID_SIZ];
|
||||||
uint32_t user_engine_len;
|
uint32_t user_engine_len;
|
||||||
char user_public[SNMP_USM_NAME_SIZ];
|
char user_public[SNMP_ADM_STR32_SIZ];
|
||||||
uint32_t user_public_len;
|
uint32_t user_public_len;
|
||||||
int32_t status;
|
int32_t status;
|
||||||
int32_t type;
|
int32_t type;
|
||||||
@ -640,6 +694,103 @@ and
|
|||||||
or
|
or
|
||||||
.Li NULL
|
.Li NULL
|
||||||
if an user with the specified name and engine id is not present in the list.
|
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
|
.Ss WELL KNOWN OIDS
|
||||||
The global variable
|
The global variable
|
||||||
.Va oid_zeroDotZero
|
.Va oid_zeroDotZero
|
||||||
@ -840,6 +991,14 @@ The arguments are the
|
|||||||
identifying the trap and a NULL-terminated list of
|
identifying the trap and a NULL-terminated list of
|
||||||
.Vt struct snmp_value
|
.Vt struct snmp_value
|
||||||
pointers that are to be inserted into the trap binding list.
|
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
|
.Ss SIMPLE ACTION SUPPORT
|
||||||
For simple scalar variables that need no dependencies a number of support
|
For simple scalar variables that need no dependencies a number of support
|
||||||
functions is available to handle the set, commit, rollback and get.
|
functions is available to handle the set, commit, rollback and get.
|
||||||
|
@ -5,6 +5,12 @@
|
|||||||
*
|
*
|
||||||
* Author: Harti Brandt <harti@freebsd.org>
|
* 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
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
* are met:
|
* are met:
|
||||||
@ -454,6 +460,74 @@ struct vacm_context *vacm_next_context(struct vacm_context *);
|
|||||||
struct vacm_context *vacm_add_context(char *, int32_t);
|
struct vacm_context *vacm_add_context(char *, int32_t);
|
||||||
void vacm_flush_contexts(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
|
* Well known OIDs
|
||||||
*/
|
*/
|
||||||
@ -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_output(struct snmp_pdu *, u_char *, size_t *, const char *);
|
||||||
void snmp_send_port(void *, const struct asn_oid *, struct snmp_pdu *,
|
void snmp_send_port(void *, const struct asn_oid *, struct snmp_pdu *,
|
||||||
const struct sockaddr *, socklen_t);
|
const struct sockaddr *, socklen_t);
|
||||||
|
enum snmp_code snmp_pdu_auth_access(struct snmp_pdu *, int32_t *);
|
||||||
|
|
||||||
/* sending traps */
|
/* sending traps */
|
||||||
void snmp_send_trap(const struct asn_oid *, ...);
|
void snmp_send_trap(const struct asn_oid *, ...);
|
||||||
|
@ -4,7 +4,13 @@
|
|||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Author: Harti Brandt <harti@freebsd.org>
|
* 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
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
* are met:
|
* are met:
|
||||||
@ -34,6 +40,7 @@
|
|||||||
#include <sys/queue.h>
|
#include <sys/queue.h>
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@ -52,6 +59,18 @@
|
|||||||
|
|
||||||
struct trapsink_list trapsink_list = TAILQ_HEAD_INITIALIZER(trapsink_list);
|
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 =
|
static const struct asn_oid oid_begemotTrapSinkTable =
|
||||||
OIDX_begemotTrapSinkTable;
|
OIDX_begemotTrapSinkTable;
|
||||||
static const struct asn_oid oid_sysUpTime = OIDX_sysUpTime;
|
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);
|
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
|
void
|
||||||
snmp_send_trap(const struct asn_oid *trap_oid, ...)
|
snmp_send_trap(const struct asn_oid *trap_oid, ...)
|
||||||
{
|
{
|
||||||
struct snmp_pdu pdu;
|
struct snmp_pdu pdu;
|
||||||
struct trapsink *t;
|
struct trapsink *t;
|
||||||
const struct snmp_value *v;
|
const struct snmp_value *v;
|
||||||
|
struct target_notify *n;
|
||||||
|
struct target_address *ta;
|
||||||
|
struct target_param *tp;
|
||||||
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
u_char *sndbuf;
|
u_char *sndbuf;
|
||||||
|
char *tag;
|
||||||
size_t sndlen;
|
size_t sndlen;
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
|
int32_t ip;
|
||||||
|
|
||||||
TAILQ_FOREACH(t, &trapsink_list, link) {
|
TAILQ_FOREACH(t, &trapsink_list, link) {
|
||||||
if (t->status != TRAPSINK_ACTIVE)
|
if (t->status != TRAPSINK_ACTIVE)
|
||||||
continue;
|
continue;
|
||||||
memset(&pdu, 0, sizeof(pdu));
|
|
||||||
strcpy(pdu.community, t->comm);
|
if (t->version == TRAPSINK_V1)
|
||||||
if (t->version == TRAPSINK_V1) {
|
snmp_create_v1_trap(&pdu, t->comm, trap_oid);
|
||||||
pdu.version = SNMP_V1;
|
else
|
||||||
pdu.type = SNMP_PDU_TRAP;
|
snmp_create_v2_trap(&pdu, t->comm, trap_oid);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
va_start(ap, trap_oid);
|
va_start(ap, trap_oid);
|
||||||
while ((v = va_arg(ap, const struct snmp_value *)) != NULL)
|
while ((v = va_arg(ap, const struct snmp_value *)) != NULL)
|
||||||
pdu.bindings[pdu.nbindings++] = *v;
|
pdu.bindings[pdu.nbindings++] = *v;
|
||||||
va_end(ap);
|
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) {
|
if ((sndbuf = buf_alloc(1)) == NULL) {
|
||||||
syslog(LOG_ERR, "trap send buffer: %m");
|
syslog(LOG_ERR, "trap send buffer: %m");
|
||||||
return;
|
return;
|
||||||
@ -464,4 +578,339 @@ snmp_send_trap(const struct asn_oid *trap_oid, ...)
|
|||||||
|
|
||||||
free(sndbuf);
|
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);
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,9 @@
|
|||||||
#
|
#
|
||||||
# System group and private Begemot SNMPd MIB.
|
# System group and private Begemot SNMPd MIB.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
include "tc.def"
|
||||||
|
|
||||||
(1 internet
|
(1 internet
|
||||||
(2 mgmt
|
(2 mgmt
|
||||||
(1 mibII
|
(1 mibII
|
||||||
|
@ -10,6 +10,10 @@ CONTRIB= ${.CURDIR}/../../../contrib/bsnmp/lib
|
|||||||
LIB= bsnmp
|
LIB= bsnmp
|
||||||
SHLIBDIR?= /lib
|
SHLIBDIR?= /lib
|
||||||
|
|
||||||
|
FILESGROUPS+= DEFS
|
||||||
|
DEFSDIR?= ${SHAREDIR}/snmp/defs
|
||||||
|
DEFS= tc.def
|
||||||
|
|
||||||
CFLAGS+= -I${CONTRIB} -DHAVE_ERR_H -DHAVE_GETADDRINFO -DHAVE_STRLCPY
|
CFLAGS+= -I${CONTRIB} -DHAVE_ERR_H -DHAVE_GETADDRINFO -DHAVE_STRLCPY
|
||||||
CFLAGS+= -DHAVE_STDINT_H -DHAVE_INTTYPES_H -DQUADFMT='"llu"' -DQUADXFMT='"llx"'
|
CFLAGS+= -DHAVE_STDINT_H -DHAVE_INTTYPES_H -DQUADFMT='"llu"' -DQUADXFMT='"llx"'
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ BMIBSDIR= ${SHAREDIR}/snmp/mibs
|
|||||||
DEFS= tree.def
|
DEFS= tree.def
|
||||||
DEFSDIR= ${SHAREDIR}/snmp/defs
|
DEFSDIR= ${SHAREDIR}/snmp/defs
|
||||||
|
|
||||||
|
CFLAGS+= -DSNMPTREE_TYPES
|
||||||
CFLAGS+= -I${CONTRIB}/lib -I${CONTRIB}/snmpd -I. -DUSE_LIBBEGEMOT
|
CFLAGS+= -I${CONTRIB}/lib -I${CONTRIB}/snmpd -I. -DUSE_LIBBEGEMOT
|
||||||
CFLAGS+= -DUSE_TCPWRAPPERS -DQUADFMT='"llu"' -DQUADXFMT='"llx"'
|
CFLAGS+= -DUSE_TCPWRAPPERS -DQUADFMT='"llu"' -DQUADXFMT='"llx"'
|
||||||
CFLAGS+= -DHAVE_STDINT_H -DHAVE_INTTYPES_H -DHAVE_ERR_H -DHAVE_STRLCPY
|
CFLAGS+= -DHAVE_STDINT_H -DHAVE_INTTYPES_H -DHAVE_ERR_H -DHAVE_STRLCPY
|
||||||
|
@ -13,6 +13,7 @@ SUBDIR= ${_snmp_atm} \
|
|||||||
snmp_hostres \
|
snmp_hostres \
|
||||||
snmp_mibII \
|
snmp_mibII \
|
||||||
snmp_pf \
|
snmp_pf \
|
||||||
|
snmp_target \
|
||||||
snmp_usm \
|
snmp_usm \
|
||||||
snmp_vacm \
|
snmp_vacm \
|
||||||
snmp_wlan
|
snmp_wlan
|
||||||
|
@ -26,22 +26,13 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
#
|
#
|
||||||
|
|
||||||
#include "tc.def"
|
include "tc.def"
|
||||||
|
|
||||||
typedef TruthValue ENUM (
|
typedef TruthValue ENUM (
|
||||||
1 true
|
1 true
|
||||||
2 false
|
2 false
|
||||||
)
|
)
|
||||||
|
|
||||||
typedef RowStatus ENUM (
|
|
||||||
1 active
|
|
||||||
2 notInService
|
|
||||||
3 notReady
|
|
||||||
4 createAndGo
|
|
||||||
5 createAndWait
|
|
||||||
6 destroy
|
|
||||||
)
|
|
||||||
|
|
||||||
typedef StpPortState ENUM (
|
typedef StpPortState ENUM (
|
||||||
1 disabled
|
1 disabled
|
||||||
2 blocking
|
2 blocking
|
||||||
|
20
usr.sbin/bsnmpd/modules/snmp_target/Makefile
Executable file
20
usr.sbin/bsnmpd/modules/snmp_target/Makefile
Executable file
@ -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>
|
@ -29,14 +29,7 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
#
|
#
|
||||||
|
|
||||||
typedef RowStatus ENUM (
|
include "tc.def"
|
||||||
1 active
|
|
||||||
2 notInService
|
|
||||||
3 notReady
|
|
||||||
4 createAndGo
|
|
||||||
5 createAndWait
|
|
||||||
6 destroy
|
|
||||||
)
|
|
||||||
|
|
||||||
typedef TruthValue ENUM (
|
typedef TruthValue ENUM (
|
||||||
1 true
|
1 true
|
||||||
|
Loading…
Reference in New Issue
Block a user