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