Virgin import of bsnmp 1.4
This commit is contained in:
commit
f06ca4af18
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/bsnmp/dist/; revision=122394 svn path=/vendor/bsnmp/1.4/; revision=122396; tag=vendor/bsnmp/1.4
43
contrib/bsnmp/NEWS
Normal file
43
contrib/bsnmp/NEWS
Normal file
@ -0,0 +1,43 @@
|
||||
08-Nov-2003
|
||||
WARNS=6 fixed.
|
||||
|
||||
28-Jan-2003
|
||||
WARNS=5 fixes.
|
||||
|
||||
09-Jan-2003
|
||||
snmpd: remove local socket in case of an error to fully initialize it.
|
||||
Use chmod instead of fchmod. The latter seems not really to change
|
||||
the mode of the socket.
|
||||
|
||||
lib: at program exit remove the local socket in the library.
|
||||
|
||||
11-Dec-2002
|
||||
Implement listening on unix domain sockets. The client must bind
|
||||
its socket, or the server cannot send back its response. These
|
||||
sockets are considered to be more secure, because it is much
|
||||
harder for an intruder to listen on them.
|
||||
|
||||
This requires changes in snmpmod.h and snmpclient.h.
|
||||
|
||||
04-Dec-2002
|
||||
Sparc fixes.
|
||||
|
||||
15-Aug-2002
|
||||
Use inttypes.h instead of limits.h to get integer limits. This
|
||||
seems to be the Posix way.
|
||||
|
||||
First drafts of an snmpd, gensnmptree, asn1, bsnmplib,
|
||||
bsnmpclient, bsnmpagent, snmpmod, snmp_mibII, snmp_netgraph man pages.
|
||||
|
||||
snmpd/main.c: reorder getopt options according to style(9). Implement
|
||||
a -h option to print a short help.
|
||||
|
||||
25-Jun-2002
|
||||
Makefiles rewritten to not use bsnmpmod.mk. The BSD makefiles are
|
||||
really hard to use, because a) they are not documented and b) they
|
||||
change much too often.
|
||||
|
||||
Make the patch a context diff instead of a unified one.
|
||||
|
||||
28-Feb-2002
|
||||
Library code for SNMP clients.
|
65
contrib/bsnmp/README
Normal file
65
contrib/bsnmp/README
Normal file
@ -0,0 +1,65 @@
|
||||
Mon Nov 10 09:50:22 CET 2003
|
||||
|
||||
This is a mini-SNMP daemon. The basic daemon implements the system group
|
||||
and a number of private extensions to manage the UDP transport mapping,
|
||||
communities, trap destinations and loadable modules. In this form it can
|
||||
be used to provide remote access to arbitrary data that can be described in
|
||||
the form as required by the SMI. The daemon speaks both SNMPv1 and SNMPv2c.
|
||||
|
||||
One basic loadable module is provided together with the daemon:
|
||||
|
||||
- snmp_mibII provides the information groups for ip, tcp, and udp.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
You need to apply the patch in the patches directory to your system sources.
|
||||
This adds a sysctl to retrieve multicast address information from the kernel.
|
||||
|
||||
As usual by doing:
|
||||
|
||||
make obj ; make depend ; make ; make install
|
||||
|
||||
This does not install a configuration file. The standard location for the
|
||||
configuration is /etc/snmpd.config, but can be overwritten on the command
|
||||
line. An example configuration file is provided.
|
||||
|
||||
Running
|
||||
-------
|
||||
|
||||
snmpd [-m name[=value]] [-p pid-file] [-c config-file] [-d] [-l prefix]
|
||||
[-D debug-flags] [-I path]
|
||||
|
||||
-m defines a configuration macro. If no value is given it
|
||||
is set to the empty string.
|
||||
|
||||
-p specify the file where to store the PID. Default is
|
||||
/var/run/{prefix}.pid.
|
||||
|
||||
-c specify the configuration file. Default is /etc/{prefix}.config.
|
||||
|
||||
-d don't go into daemon mode.
|
||||
|
||||
-l specify the prefix. This is used for the default config and
|
||||
pid file names and for the syslog. Default is "snmpd".
|
||||
|
||||
-D specify debug flags:
|
||||
|
||||
d dump all PDUs.
|
||||
|
||||
e debug event library.
|
||||
|
||||
-I specify the include path for system configuration files.
|
||||
Default is /etc:/usr/etc:/usr/local/etc.
|
||||
|
||||
The directory snmpd contains a snmpd.sh script, which can be copied to
|
||||
/usr/local/etc/rc.d to automatically start and stop the daemon. snmpd.config
|
||||
is an example config script.
|
||||
|
||||
Bug reports:
|
||||
-----------
|
||||
|
||||
Please report bugs to harti@freebsd.org.
|
||||
|
||||
Happy hacking,
|
||||
harti
|
5
contrib/bsnmp/TODO
Normal file
5
contrib/bsnmp/TODO
Normal file
@ -0,0 +1,5 @@
|
||||
snmpd_mibII:
|
||||
- handle HC counters by periodically polling the kernel counters.
|
||||
|
||||
snmpd_netgraph:
|
||||
- make some tables writeable
|
1
contrib/bsnmp/VERSION
Normal file
1
contrib/bsnmp/VERSION
Normal file
@ -0,0 +1 @@
|
||||
1.4
|
190
contrib/bsnmp/gensnmptree/gensnmptree.1
Normal file
190
contrib/bsnmp/gensnmptree/gensnmptree.1
Normal file
@ -0,0 +1,190 @@
|
||||
.\"
|
||||
.\" Copyright (c) 2001-2003
|
||||
.\" Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution of this software and documentation 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 or documentation 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.
|
||||
.\" 3. Neither the name of the Institute nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
.\" AND ITS 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
|
||||
.\" FRAUNHOFER FOKUS OR ITS 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.
|
||||
.\"
|
||||
.\" $Begemot: bsnmp/gensnmptree/gensnmptree.1,v 1.1 2002/08/15 13:27:44 hbb Exp $
|
||||
.\"
|
||||
.\" Author: Harti Brandt <harti@freebsd.org>
|
||||
.\"
|
||||
.Dd October 7, 2003
|
||||
.Dt gensnmptree 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm gensnmptree
|
||||
.Nd "generate C and header files from a MIB description file"
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl hel
|
||||
.Op Fl p Ar prefix
|
||||
.Op Ar name Ar ...
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility is used to either generate C language tables and header files from
|
||||
a MIB description or to numeric OIDs from MIB descriptions. The first form
|
||||
is used only for maintaining the
|
||||
.Xr snmpd 1
|
||||
daemon or for module writers.
|
||||
The second form may be used by SNMP client program writers.
|
||||
.Pp
|
||||
If the
|
||||
.Fl e
|
||||
option is not used
|
||||
.Nm
|
||||
reads a MIB description from its standard input and creates two files: a
|
||||
C-file
|
||||
.Ar prefix Ns tree.c
|
||||
containing a table used by
|
||||
.Xr snmpd 1
|
||||
during PDU processing
|
||||
and a header file
|
||||
.Ar prefix Ns tree.h
|
||||
containing appropriate declarations of the callback functions used in this table
|
||||
and the table itself.
|
||||
.Pp
|
||||
If the
|
||||
.Fl e
|
||||
option is specified
|
||||
.Nm
|
||||
expects MIB variable names (only the last component) on its command line.
|
||||
It reads a MIB specification from standard input and for each MIB variable
|
||||
name emits two C preprocessor defines on its standard output. One define
|
||||
.Va OID_ Ns Ar name
|
||||
can be used as an array initialized to initialize a
|
||||
.Va struct asn_oid .
|
||||
The other define
|
||||
.Va OIDLEN_ Ns Ar name
|
||||
contains the length of the OID.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width ".Fl d Ar argument"
|
||||
.It Fl h
|
||||
Print a short help page.
|
||||
.It Fl e
|
||||
Enter extract mode.
|
||||
.It Fl l
|
||||
Generate local preprocessor includes. This is used for bootstrapping
|
||||
.Xr snmpd 1 .
|
||||
.It Fl p Ar prefix
|
||||
Prefix the file names and the table name with
|
||||
.Ar prefix .
|
||||
.El
|
||||
.Sh MIBS
|
||||
The syntax of the MIB description file can formally be specified as follows:
|
||||
.Bd -unfilled -offset indent
|
||||
tree := head elements ')'
|
||||
|
||||
entry := head ':' index STRING elements ')'
|
||||
|
||||
leaf := head TYPE STRING ACCESS ')'
|
||||
|
||||
column := head TYPE ACCESS ')'
|
||||
|
||||
head := '(' INT STRING
|
||||
|
||||
elements := EMPTY | elements element
|
||||
|
||||
element := tree | leaf
|
||||
|
||||
index := TYPE | index TYPE
|
||||
.Ed
|
||||
.Pp
|
||||
.Ar TYPE
|
||||
specifies a SNMP data type and may be one of
|
||||
.Bl -bullet -offset indent -compact
|
||||
.It
|
||||
NULL
|
||||
.It
|
||||
INTEGER
|
||||
.It
|
||||
INTEGER32 (same as INTEGER)
|
||||
.It
|
||||
UNSIGNED32 (same as GAUGE)
|
||||
.It
|
||||
OCTETSTRING
|
||||
.It
|
||||
IPADDRESS
|
||||
.It
|
||||
OID
|
||||
.It
|
||||
TIMETICKS
|
||||
.It
|
||||
COUNTER
|
||||
.It
|
||||
GAUGE
|
||||
.It
|
||||
COUNTER64
|
||||
.El
|
||||
.Pp
|
||||
.Ar ACCESS
|
||||
specifies the accessibility of the MIB variable (which operation can be
|
||||
performed) and is one of
|
||||
.Bl -bullet -offset indent -compact
|
||||
.It
|
||||
GET
|
||||
.It
|
||||
SET
|
||||
.El
|
||||
.Pp
|
||||
.Ar INT
|
||||
is a decimal integer and
|
||||
.Ar STRING
|
||||
is any string starting with a letter or underscore and consisting of
|
||||
letters, digits and underscores, that is not one of the keywords.
|
||||
.Sh EXAMPLES
|
||||
The following MIB description describes the system group:
|
||||
.Bd -literal -offset indent
|
||||
(1 internet
|
||||
(2 mgmt
|
||||
(1 mibII
|
||||
(1 system
|
||||
(1 sysDescr OCTETSTRING op_system_group GET)
|
||||
(2 sysObjectId OID op_system_group GET)
|
||||
(3 sysUpTime TIMETICKS op_system_group GET)
|
||||
(4 sysContact OCTETSTRING op_system_group GET SET)
|
||||
(5 sysName OCTETSTRING op_system_group GET SET)
|
||||
(6 sysLocation OCTETSTRING op_system_group GET SET)
|
||||
(7 sysServices INTEGER op_system_group GET)
|
||||
(8 sysORLastChange TIMETICKS op_system_group GET)
|
||||
(9 sysORTable
|
||||
(1 sysOREntry : INTEGER op_or_table
|
||||
(1 sysORIndex INTEGER)
|
||||
(2 sysORID OID GET)
|
||||
(3 sysORDescr OCTETSTRING GET)
|
||||
(4 sysORUpTime TIMETICKS GET)
|
||||
))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr snmpd 1
|
||||
.Sh AUTHORS
|
||||
.An Hartmut Brandt Aq harti@freebsd.org
|
770
contrib/bsnmp/gensnmptree/gensnmptree.c
Normal file
770
contrib/bsnmp/gensnmptree/gensnmptree.c
Normal file
@ -0,0 +1,770 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003
|
||||
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Harti Brandt <harti@freebsd.org>
|
||||
*
|
||||
* Redistribution of this software and documentation 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 or documentation 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.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
* AND ITS 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
|
||||
* FRAUNHOFER FOKUS OR ITS 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.
|
||||
*
|
||||
* $Begemot: bsnmp/gensnmptree/gensnmptree.c,v 1.34 2003/01/28 13:44:34 hbb Exp $
|
||||
*
|
||||
* Generate OID table from table description.
|
||||
*
|
||||
* Syntax is:
|
||||
* ---------
|
||||
* tree := head elements ')'
|
||||
*
|
||||
* entry := head ':' index STRING elements ')'
|
||||
*
|
||||
* leaf := head TYPE STRING ACCESS ')'
|
||||
*
|
||||
* column := head TYPE ACCESS ')'
|
||||
*
|
||||
* head := '(' INT STRING
|
||||
*
|
||||
* elements := EMPTY | elements element
|
||||
*
|
||||
* element := tree | leaf
|
||||
*
|
||||
* index := TYPE | index TYPE
|
||||
*
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <sys/queue.h>
|
||||
#include "asn1.h"
|
||||
#include "snmp.h"
|
||||
#include "snmpagent.h"
|
||||
|
||||
/*
|
||||
* Constant prefix for all OIDs
|
||||
*/
|
||||
static const asn_subid_t prefix[] = { 1, 3, 6 };
|
||||
#define PREFIX_LEN (sizeof(prefix) / sizeof(prefix[0]))
|
||||
|
||||
u_int tree_size;
|
||||
static const char *file_prefix = "";
|
||||
static FILE *fp;
|
||||
|
||||
/* if true generate local include paths */
|
||||
static int localincs = 0;
|
||||
|
||||
static const char usgtxt[] = "\
|
||||
Generate SNMP tables. Copyright (c) 2001-2002 Fraunhofer Institute for\n\
|
||||
Open Communication Systems (FhG Fokus). All rights reserved.\n\
|
||||
usage: gensnmptree [-hel] [-p prefix] [name]...\n\
|
||||
options:\n\
|
||||
-h print this info\n\
|
||||
-e extrace the named oids\n\
|
||||
-l generate local include directives\n\
|
||||
-p prefix prepend prefix to file and variable names\n\
|
||||
";
|
||||
|
||||
/*
|
||||
* A node in the OID tree
|
||||
*/
|
||||
enum ntype {
|
||||
NODE_LEAF = 1,
|
||||
NODE_TREE,
|
||||
NODE_ENTRY,
|
||||
NODE_COLUMN
|
||||
};
|
||||
|
||||
enum {
|
||||
FL_GET = 0x01,
|
||||
FL_SET = 0x02,
|
||||
};
|
||||
|
||||
struct node;
|
||||
TAILQ_HEAD(node_list, node);
|
||||
|
||||
struct node {
|
||||
enum ntype type;
|
||||
asn_subid_t id; /* last element of OID */
|
||||
char *name; /* name of node */
|
||||
TAILQ_ENTRY(node) link;
|
||||
u_int lno; /* starting line number */
|
||||
u_int flags; /* allowed operations */
|
||||
|
||||
union {
|
||||
struct tree {
|
||||
struct node_list subs;
|
||||
} tree;
|
||||
|
||||
struct entry {
|
||||
u_int32_t index; /* index for table entry */
|
||||
char *func; /* function for tables */
|
||||
struct node_list subs;
|
||||
} entry;
|
||||
|
||||
struct leaf {
|
||||
enum snmp_syntax syntax; /* syntax for this leaf */
|
||||
char *func; /* function name */
|
||||
} leaf;
|
||||
|
||||
struct column {
|
||||
enum snmp_syntax syntax; /* syntax for this column */
|
||||
} column;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct func {
|
||||
const char *name;
|
||||
LIST_ENTRY(func) link;
|
||||
};
|
||||
|
||||
static LIST_HEAD(, func) funcs = LIST_HEAD_INITIALIZER(funcs);
|
||||
|
||||
/************************************************************
|
||||
*
|
||||
* Allocate memory and panic just in the case...
|
||||
*/
|
||||
static void *
|
||||
xalloc(size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
if ((ptr = malloc(size)) == NULL)
|
||||
err(1, "allocing %u bytes", size);
|
||||
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
*
|
||||
* Parsing input
|
||||
*/
|
||||
enum tok {
|
||||
TOK_EOF = 0200, /* end-of-file seen */
|
||||
TOK_NUM, /* number */
|
||||
TOK_STR, /* string */
|
||||
TOK_ACCESS, /* access operator */
|
||||
TOK_TYPE, /* type operator */
|
||||
};
|
||||
|
||||
static const struct {
|
||||
const char *str;
|
||||
enum tok tok;
|
||||
u_int val;
|
||||
} keywords[] = {
|
||||
{ "GET", TOK_ACCESS, FL_GET },
|
||||
{ "SET", TOK_ACCESS, FL_SET },
|
||||
{ "NULL", TOK_TYPE, SNMP_SYNTAX_NULL },
|
||||
{ "INTEGER", TOK_TYPE, SNMP_SYNTAX_INTEGER },
|
||||
{ "INTEGER32", TOK_TYPE, SNMP_SYNTAX_INTEGER },
|
||||
{ "UNSIGNED32", TOK_TYPE, SNMP_SYNTAX_GAUGE },
|
||||
{ "OCTETSTRING", TOK_TYPE, SNMP_SYNTAX_OCTETSTRING },
|
||||
{ "IPADDRESS", TOK_TYPE, SNMP_SYNTAX_IPADDRESS },
|
||||
{ "OID", TOK_TYPE, SNMP_SYNTAX_OID },
|
||||
{ "TIMETICKS", TOK_TYPE, SNMP_SYNTAX_TIMETICKS },
|
||||
{ "COUNTER", TOK_TYPE, SNMP_SYNTAX_COUNTER },
|
||||
{ "GAUGE", TOK_TYPE, SNMP_SYNTAX_GAUGE },
|
||||
{ "COUNTER64", TOK_TYPE, SNMP_SYNTAX_COUNTER64 },
|
||||
{ NULL, 0, 0 }
|
||||
};
|
||||
|
||||
/* arbitrary upper limit on node names and function names */
|
||||
#define MAXSTR 1000
|
||||
char str[MAXSTR];
|
||||
u_long val; /* integer values */
|
||||
u_int lno = 1; /* current line number */
|
||||
|
||||
static void report(const char *, ...) __dead2 __printflike(1, 2);
|
||||
static void report_node(const struct node *, const char *, ...)
|
||||
__dead2 __printflike(2, 3);
|
||||
|
||||
/*
|
||||
* Report an error and exit.
|
||||
*/
|
||||
static void
|
||||
report(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int c;
|
||||
|
||||
va_start(ap, fmt);
|
||||
fprintf(stderr, "line %u: ", lno);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "context: \"");
|
||||
while ((c = getchar()) != EOF && c != '\n')
|
||||
fprintf(stderr, "%c", c);
|
||||
fprintf(stderr, "\n");
|
||||
va_end(ap);
|
||||
exit(1);
|
||||
}
|
||||
static void
|
||||
report_node(const struct node *np, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
fprintf(stderr, "line %u, node %s: ", np->lno, np->name);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fprintf(stderr, "\n");
|
||||
va_end(ap);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a fresh copy of the string constituting the current token.
|
||||
*/
|
||||
static char *
|
||||
savetok(void)
|
||||
{
|
||||
return (strcpy(xalloc(strlen(str)+1), str));
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the next token from input.
|
||||
*/
|
||||
static int
|
||||
gettoken(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
again:
|
||||
/*
|
||||
* Skip any whitespace before the next token
|
||||
*/
|
||||
while ((c = getchar()) != EOF) {
|
||||
if (c == '\n')
|
||||
lno++;
|
||||
if (!isspace(c))
|
||||
break;
|
||||
}
|
||||
if (c == EOF)
|
||||
return (TOK_EOF);
|
||||
if (!isascii(c))
|
||||
report("unexpected character %#2x", (u_int)c);
|
||||
|
||||
/*
|
||||
* Skip comments
|
||||
*/
|
||||
if (c == '#') {
|
||||
while ((c = getchar()) != EOF) {
|
||||
if (c == '\n') {
|
||||
lno++;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
report("unexpected EOF in comment");
|
||||
}
|
||||
|
||||
/*
|
||||
* Single character tokens
|
||||
*/
|
||||
if (c == ')' || c == '(' || c == ':')
|
||||
return (c);
|
||||
|
||||
/*
|
||||
* Sort out numbers
|
||||
*/
|
||||
if (isdigit(c)) {
|
||||
ungetc(c, stdin);
|
||||
scanf("%lu", &val);
|
||||
return (TOK_NUM);
|
||||
}
|
||||
|
||||
/*
|
||||
* So that has to be a string.
|
||||
*/
|
||||
if (isalpha(c) || c == '_') {
|
||||
size_t n = 0;
|
||||
str[n++] = c;
|
||||
while ((c = getchar()) != EOF) {
|
||||
if (!isalnum(c) && c != '_') {
|
||||
ungetc(c, stdin);
|
||||
break;
|
||||
}
|
||||
if (n == sizeof(str) - 1) {
|
||||
str[n++] = '\0';
|
||||
report("string too long '%s...'", str);
|
||||
}
|
||||
str[n++] = c;
|
||||
}
|
||||
str[n++] = '\0';
|
||||
|
||||
/*
|
||||
* Keywords
|
||||
*/
|
||||
for (c = 0; keywords[c].str != NULL; c++)
|
||||
if (strcmp(keywords[c].str, str) == 0) {
|
||||
val = keywords[c].val;
|
||||
return (keywords[c].tok);
|
||||
}
|
||||
|
||||
return (TOK_STR);
|
||||
}
|
||||
if (isprint(c))
|
||||
errx(1, "%u: unexpected character '%c'", lno, c);
|
||||
else
|
||||
errx(1, "%u: unexpected character 0x%02x", lno, (u_int)c);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the next node (complete with all subnodes)
|
||||
*/
|
||||
static struct node *
|
||||
parse(enum tok tok)
|
||||
{
|
||||
struct node *node;
|
||||
struct node *sub;
|
||||
u_int index_count;
|
||||
|
||||
node = xalloc(sizeof(struct node));
|
||||
node->lno = lno;
|
||||
|
||||
if (tok != '(')
|
||||
report("'(' expected at begin of node");
|
||||
if (gettoken() != TOK_NUM)
|
||||
report("node id expected after opening '('");
|
||||
if (val > ASN_MAXID)
|
||||
report("subid too large '%lu'", val);
|
||||
node->id = (asn_subid_t)val;
|
||||
if (gettoken() != TOK_STR)
|
||||
report("node name expected after '(' ID");
|
||||
node->name = savetok();
|
||||
|
||||
if ((tok = gettoken()) == TOK_TYPE) {
|
||||
/* LEAF or COLUM */
|
||||
u_int syntax = val;
|
||||
|
||||
if ((tok = gettoken()) == TOK_STR) {
|
||||
/* LEAF */
|
||||
node->type = NODE_LEAF;
|
||||
node->u.leaf.func = savetok();
|
||||
node->u.leaf.syntax = syntax;
|
||||
tok = gettoken();
|
||||
} else {
|
||||
/* COLUMN */
|
||||
node->type = NODE_COLUMN;
|
||||
node->u.column.syntax = syntax;
|
||||
}
|
||||
|
||||
while (tok != ')') {
|
||||
if (tok != TOK_ACCESS)
|
||||
report("access keyword or ')' expected");
|
||||
node->flags |= (u_int)val;
|
||||
tok = gettoken();
|
||||
}
|
||||
|
||||
} else if (tok == ':') {
|
||||
/* ENTRY */
|
||||
node->type = NODE_ENTRY;
|
||||
TAILQ_INIT(&node->u.entry.subs);
|
||||
|
||||
index_count = 0;
|
||||
node->u.entry.index = 0;
|
||||
while ((tok = gettoken()) == TOK_TYPE) {
|
||||
if (index_count++ == SNMP_INDEXES_MAX)
|
||||
report("too many table indexes");
|
||||
node->u.entry.index |=
|
||||
val << (SNMP_INDEX_SHIFT * index_count);
|
||||
}
|
||||
node->u.entry.index |= index_count;
|
||||
if (index_count == 0)
|
||||
report("need at least one index");
|
||||
|
||||
if (tok != TOK_STR)
|
||||
report("function name expected");
|
||||
|
||||
node->u.entry.func = savetok();
|
||||
|
||||
tok = gettoken();
|
||||
|
||||
while (tok != ')') {
|
||||
sub = parse(tok);
|
||||
TAILQ_INSERT_TAIL(&node->u.entry.subs, sub, link);
|
||||
tok = gettoken();
|
||||
}
|
||||
|
||||
} else {
|
||||
/* subtree */
|
||||
node->type = NODE_TREE;
|
||||
TAILQ_INIT(&node->u.tree.subs);
|
||||
|
||||
while (tok != ')') {
|
||||
sub = parse(tok);
|
||||
TAILQ_INSERT_TAIL(&node->u.tree.subs, sub, link);
|
||||
tok = gettoken();
|
||||
}
|
||||
}
|
||||
return (node);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate the C-code table part for one node.
|
||||
*/
|
||||
static void
|
||||
gen_node(struct node *np, struct asn_oid *oid, u_int idx, const char *func)
|
||||
{
|
||||
u_int n;
|
||||
struct node *sub;
|
||||
u_int syntax;
|
||||
|
||||
if (oid->len == ASN_MAXOIDLEN)
|
||||
report_node(np, "OID too long");
|
||||
oid->subs[oid->len++] = np->id;
|
||||
|
||||
if (np->type == NODE_TREE) {
|
||||
TAILQ_FOREACH(sub, &np->u.tree.subs, link)
|
||||
gen_node(sub, oid, 0, NULL);
|
||||
oid->len--;
|
||||
return;
|
||||
}
|
||||
if (np->type == NODE_ENTRY) {
|
||||
TAILQ_FOREACH(sub, &np->u.entry.subs, link)
|
||||
gen_node(sub, oid, np->u.entry.index, np->u.entry.func);
|
||||
oid->len--;
|
||||
return;
|
||||
}
|
||||
|
||||
/* leaf or column */
|
||||
if ((np->flags & (FL_GET|FL_SET)) == 0) {
|
||||
oid->len--;
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(fp, " {{ %u, {", oid->len);
|
||||
for (n = 0; n < oid->len; n++)
|
||||
fprintf(fp, " %u,", oid->subs[n]);
|
||||
fprintf(fp, " }}, \"%s\", ", np->name);
|
||||
|
||||
if (np->type == NODE_COLUMN) {
|
||||
syntax = np->u.column.syntax;
|
||||
fprintf(fp, "SNMP_NODE_COLUMN, ");
|
||||
} else {
|
||||
syntax = np->u.leaf.syntax;
|
||||
fprintf(fp, "SNMP_NODE_LEAF, ");
|
||||
}
|
||||
|
||||
switch (syntax) {
|
||||
|
||||
case SNMP_SYNTAX_NULL:
|
||||
fprintf(fp, "SNMP_SYNTAX_NULL, ");
|
||||
break;
|
||||
|
||||
case SNMP_SYNTAX_INTEGER:
|
||||
fprintf(fp, "SNMP_SYNTAX_INTEGER, ");
|
||||
break;
|
||||
|
||||
case SNMP_SYNTAX_OCTETSTRING:
|
||||
fprintf(fp, "SNMP_SYNTAX_OCTETSTRING, ");
|
||||
break;
|
||||
|
||||
case SNMP_SYNTAX_IPADDRESS:
|
||||
fprintf(fp, "SNMP_SYNTAX_IPADDRESS, ");
|
||||
break;
|
||||
|
||||
case SNMP_SYNTAX_OID:
|
||||
fprintf(fp, "SNMP_SYNTAX_OID, ");
|
||||
break;
|
||||
|
||||
case SNMP_SYNTAX_TIMETICKS:
|
||||
fprintf(fp, "SNMP_SYNTAX_TIMETICKS, ");
|
||||
break;
|
||||
|
||||
case SNMP_SYNTAX_COUNTER:
|
||||
fprintf(fp, "SNMP_SYNTAX_COUNTER, ");
|
||||
break;
|
||||
|
||||
case SNMP_SYNTAX_GAUGE:
|
||||
fprintf(fp, "SNMP_SYNTAX_GAUGE, ");
|
||||
break;
|
||||
|
||||
case SNMP_SYNTAX_COUNTER64:
|
||||
fprintf(fp, "SNMP_SYNTAX_COUNTER64, ");
|
||||
break;
|
||||
|
||||
case SNMP_SYNTAX_NOSUCHOBJECT:
|
||||
case SNMP_SYNTAX_NOSUCHINSTANCE:
|
||||
case SNMP_SYNTAX_ENDOFMIBVIEW:
|
||||
abort();
|
||||
}
|
||||
|
||||
if (np->type == NODE_COLUMN)
|
||||
fprintf(fp, "%s, ", func);
|
||||
else
|
||||
fprintf(fp, "%s, ", np->u.leaf.func);
|
||||
|
||||
fprintf(fp, "0");
|
||||
if (np->flags & FL_SET)
|
||||
fprintf(fp, "|SNMP_NODE_CANSET");
|
||||
fprintf(fp, ", %#x, NULL },\n", idx);
|
||||
oid->len--;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate the header file with the function declarations.
|
||||
*/
|
||||
static void
|
||||
gen_header(struct node *np, u_int oidlen, const char *func)
|
||||
{
|
||||
char f[MAXSTR + 4];
|
||||
struct node *sub;
|
||||
struct func *ptr;
|
||||
|
||||
oidlen++;
|
||||
if (np->type == NODE_TREE) {
|
||||
TAILQ_FOREACH(sub, &np->u.tree.subs, link)
|
||||
gen_header(sub, oidlen, NULL);
|
||||
return;
|
||||
}
|
||||
if (np->type == NODE_ENTRY) {
|
||||
TAILQ_FOREACH(sub, &np->u.entry.subs, link)
|
||||
gen_header(sub, oidlen, np->u.entry.func);
|
||||
return;
|
||||
}
|
||||
|
||||
if((np->flags & (FL_GET|FL_SET)) == 0)
|
||||
return;
|
||||
|
||||
if (np->type == NODE_COLUMN)
|
||||
sprintf(f, "%s", func);
|
||||
else
|
||||
sprintf(f, "%s", np->u.leaf.func);
|
||||
|
||||
LIST_FOREACH(ptr, &funcs, link)
|
||||
if (strcmp(ptr->name, f) == 0)
|
||||
break;
|
||||
|
||||
if (ptr == NULL) {
|
||||
ptr = xalloc(sizeof(*ptr));
|
||||
ptr->name = strcpy(xalloc(strlen(f)+1), f);
|
||||
LIST_INSERT_HEAD(&funcs, ptr, link);
|
||||
|
||||
fprintf(fp, "int %s(struct snmp_context *, "
|
||||
"struct snmp_value *, u_int, u_int, "
|
||||
"enum snmp_op);\n", f);
|
||||
}
|
||||
|
||||
fprintf(fp, "# define LEAF_%s %u\n", np->name, np->id);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate the OID table.
|
||||
*/
|
||||
static void
|
||||
gen_table(struct node *node)
|
||||
{
|
||||
struct asn_oid oid;
|
||||
|
||||
fprintf(fp, "#include <sys/types.h>\n");
|
||||
fprintf(fp, "#include <stdio.h>\n");
|
||||
if (localincs) {
|
||||
fprintf(fp, "#include \"asn1.h\"\n");
|
||||
fprintf(fp, "#include \"snmp.h\"\n");
|
||||
fprintf(fp, "#include \"snmpagent.h\"\n");
|
||||
} else {
|
||||
fprintf(fp, "#include <bsnmp/asn1.h>\n");
|
||||
fprintf(fp, "#include <bsnmp/snmp.h>\n");
|
||||
fprintf(fp, "#include <bsnmp/snmpagent.h>\n");
|
||||
}
|
||||
fprintf(fp, "#include \"%stree.h\"\n", file_prefix);
|
||||
fprintf(fp, "\n");
|
||||
|
||||
fprintf(fp, "const struct snmp_node %sctree[] = {\n", file_prefix);
|
||||
|
||||
oid.len = PREFIX_LEN;
|
||||
memcpy(oid.subs, prefix, sizeof(prefix));
|
||||
gen_node(node, &oid, 0, NULL);
|
||||
|
||||
fprintf(fp, "};\n\n");
|
||||
}
|
||||
|
||||
static int
|
||||
extract(const struct node *np, struct asn_oid *oid, const char *obj)
|
||||
{
|
||||
struct node *sub;
|
||||
u_long n;
|
||||
|
||||
if (oid->len == ASN_MAXOIDLEN)
|
||||
report_node(np, "OID too long");
|
||||
oid->subs[oid->len++] = np->id;
|
||||
|
||||
if (strcmp(obj, np->name) == 0) {
|
||||
fprintf(fp, "#define OID_%s\t%u\n", np->name, np->id);
|
||||
fprintf(fp, "#define OIDLEN_%s\t%u\n", np->name, oid->len);
|
||||
fprintf(fp, "#define OIDX_%s\t{ %u, {", np->name, oid->len);
|
||||
for (n = 0; n < oid->len; n++)
|
||||
fprintf(fp, " %u,", oid->subs[n]);
|
||||
fprintf(fp, " } }\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (np->type == NODE_TREE) {
|
||||
TAILQ_FOREACH(sub, &np->u.tree.subs, link)
|
||||
if (!extract(sub, oid, obj))
|
||||
return (0);
|
||||
} else if (np->type == NODE_ENTRY) {
|
||||
TAILQ_FOREACH(sub, &np->u.entry.subs, link)
|
||||
if (!extract(sub, oid, obj))
|
||||
return (0);
|
||||
}
|
||||
oid->len--;
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
gen_extract(const struct node *root, const char *object)
|
||||
{
|
||||
struct asn_oid oid;
|
||||
|
||||
oid.len = PREFIX_LEN;
|
||||
memcpy(oid.subs, prefix, sizeof(prefix));
|
||||
return (extract(root, &oid, object));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
check_sub_order(const struct node *np, const struct node_list *subs)
|
||||
{
|
||||
int first;
|
||||
const struct node *sub;
|
||||
asn_subid_t maxid = 0;
|
||||
|
||||
/* ensure, that subids are ordered */
|
||||
first = 1;
|
||||
TAILQ_FOREACH(sub, subs, link) {
|
||||
if (!first && sub->id <= maxid)
|
||||
report_node(np, "subids not ordered at %s", sub->name);
|
||||
maxid = sub->id;
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Do some sanity checks on the tree definition and do some computations.
|
||||
*/
|
||||
static void
|
||||
check_tree(struct node *np)
|
||||
{
|
||||
struct node *sub;
|
||||
|
||||
if (np->type == NODE_LEAF || np->type == NODE_COLUMN) {
|
||||
if ((np->flags & (FL_GET|FL_SET)) != 0)
|
||||
tree_size++;
|
||||
return;
|
||||
}
|
||||
|
||||
if (np->type == NODE_ENTRY) {
|
||||
check_sub_order(np, &np->u.entry.subs);
|
||||
|
||||
/* ensure all subnodes are columns */
|
||||
TAILQ_FOREACH(sub, &np->u.entry.subs, link) {
|
||||
if (sub->type != NODE_COLUMN)
|
||||
report_node(np, "entry subnode '%s' is not "
|
||||
"a column", sub->name);
|
||||
check_tree(sub);
|
||||
}
|
||||
} else {
|
||||
check_sub_order(np, &np->u.tree.subs);
|
||||
|
||||
TAILQ_FOREACH(sub, &np->u.tree.subs, link)
|
||||
check_tree(sub);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int do_extract = 0;
|
||||
int opt;
|
||||
struct node *root;
|
||||
char fname[MAXPATHLEN + 1];
|
||||
|
||||
while ((opt = getopt(argc, argv, "help:")) != EOF)
|
||||
switch (opt) {
|
||||
|
||||
case 'h':
|
||||
fprintf(stderr, "%s", usgtxt);
|
||||
exit(0);
|
||||
|
||||
case 'e':
|
||||
do_extract = 1;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
localincs = 1;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
file_prefix = optarg;
|
||||
if (strlen(file_prefix) + strlen("tree.c") >
|
||||
MAXPATHLEN)
|
||||
errx(1, "prefix too long");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!do_extract && argc != optind)
|
||||
errx(1, "no arguments allowed");
|
||||
if (do_extract && argc == optind)
|
||||
errx(1, "no objects specified");
|
||||
|
||||
root = parse(gettoken());
|
||||
if (gettoken() != TOK_EOF)
|
||||
report("junk after closing ')'");
|
||||
|
||||
check_tree(root);
|
||||
|
||||
if (do_extract) {
|
||||
fp = stdout;
|
||||
while (optind < argc) {
|
||||
if (gen_extract(root, argv[optind]))
|
||||
errx(1, "object not found: %s", argv[optind]);
|
||||
optind++;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
sprintf(fname, "%stree.h", file_prefix);
|
||||
if ((fp = fopen(fname, "w")) == NULL)
|
||||
err(1, "%s: ", fname);
|
||||
gen_header(root, PREFIX_LEN, NULL);
|
||||
|
||||
fprintf(fp, "#define %sCTREE_SIZE %u\n", file_prefix, tree_size);
|
||||
fprintf(fp, "extern const struct snmp_node %sctree[];\n", file_prefix);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
sprintf(fname, "%stree.c", file_prefix);
|
||||
if ((fp = fopen(fname, "w")) == NULL)
|
||||
err(1, "%s: ", fname);
|
||||
gen_table(root);
|
||||
fclose(fp);
|
||||
|
||||
return (0);
|
||||
}
|
484
contrib/bsnmp/lib/asn1.3
Normal file
484
contrib/bsnmp/lib/asn1.3
Normal file
@ -0,0 +1,484 @@
|
||||
.\"
|
||||
.\" Copyright (c) 2001-2003
|
||||
.\" Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Author: Harti Brandt <harti@freebsd.org>
|
||||
.\"
|
||||
.\" Redistribution of this software and documentation 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 or documentation 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.
|
||||
.\" 3. Neither the name of the Institute nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
.\" AND ITS 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
|
||||
.\" FRAUNHOFER FOKUS OR ITS 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.
|
||||
.\"
|
||||
.\" $Begemot: bsnmp/lib/asn1.3,v 1.2 2002/08/16 10:02:53 hbb Exp $
|
||||
.\"
|
||||
.Dd August 15, 2002
|
||||
.Dt asn1 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm asn_get_header ,
|
||||
.Nm asn_put_header ,
|
||||
.Nm asn_put_temp_header ,
|
||||
.Nm asn_commit_header ,
|
||||
.Nm asn_get_integer_raw ,
|
||||
.Nm asn_get_integer ,
|
||||
.Nm asn_put_integer ,
|
||||
.Nm asn_get_octetstring_raw ,
|
||||
.Nm asn_get_octetstring ,
|
||||
.Nm asn_put_octetstring ,
|
||||
.Nm asn_get_null_raw ,
|
||||
.Nm asn_get_null ,
|
||||
.Nm asn_put_null ,
|
||||
.Nm asn_put_exception ,
|
||||
.Nm asn_get_objid_raw ,
|
||||
.Nm asn_get_objid ,
|
||||
.Nm asn_put_objid ,
|
||||
.Nm asn_get_sequence ,
|
||||
.Nm asn_get_ipaddress_raw ,
|
||||
.Nm asn_get_ipaddress ,
|
||||
.Nm asn_put_ipaddress ,
|
||||
.Nm asn_get_uint32_raw ,
|
||||
.Nm asn_put_uint32 ,
|
||||
.Nm asn_get_counter64_raw ,
|
||||
.Nm asn_put_counter64 ,
|
||||
.Nm asn_get_timeticks ,
|
||||
.Nm asn_put_timeticks ,
|
||||
.Nm asn_skip ,
|
||||
.Nm asn_slice_oid ,
|
||||
.Nm asn_append_oid ,
|
||||
.Nm asn_compare_oid ,
|
||||
.Nm asn_is_suboid ,
|
||||
.Nm asn_oid2str_r ,
|
||||
.Nm asn_oid2str
|
||||
.Nd "ASN.1 library for SNMP"
|
||||
.Sh LIBRARY
|
||||
Begemot SNMP library
|
||||
.Pq libbsnmp, -lbsnmp
|
||||
.Sh SYNOPSIS
|
||||
.In bsnmp/asn1.h
|
||||
.Ft enum asn_err
|
||||
.Fn asn_get_header "struct asn_buf *buf" "u_char *type" "asn_len_t *lenp"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_put_header "struct asn_buf *buf" "u_char type" "asn_len_t len"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_put_temp_header "struct asn_buf *buf" "u_char type" "u_char **ptr"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_commit_header "struct asn_buf *buf" "u_char *ptr"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_get_integer_raw "struct asn_buf *buf" "asn_len_t len" "int32_t *res"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_get_integer "struct asn_buf *buf" "int32_t *res"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_put_integer "struct asn_buf *buf" "int32_t arg"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_get_octetstring_raw "struct asn_buf *buf" "asn_len_t len" "u_char *out" "u_int *outsize"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_get_octetstring "struct asn_buf *buf" "u_char *out" "u_int *outsize"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_put_octetstring "struct asn_buf *buf" "const u_char *str" "u_int strsize"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_get_null_raw "struct asn_buf *buf" "asn_len_t len"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_get_null "struct asn_buf *buf"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_put_null "struct asn_buf *buf"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_put_exception "struct asn_buf *buf" "u_int type"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_get_objid_raw "struct asn_buf *buf" "asn_len_t len" "struct asn_oid *oid"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_get_objid "struct asn_buf *buf" "struct asn_oid *oid"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_put_objid "struct asn_buf *buf" "const struct asn_oid *oid"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_get_sequence "struct asn_buf *buf" "asn_len_t *lenp"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_get_ipaddress_raw "struct asn_buf *buf" "asn_len_t len" "u_char *ipa"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_get_ipaddress "struct asn_buf *buf" "u_char *ipa"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_put_ipaddress "struct asn_buf *buf" "const u_char *ipa"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_get_uint32_raw "struct asn_buf *buf" "asn_len_t len" "u_int32_t *res"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_put_uint32 "struct asn_buf *buf" "u_char type" "u_int32_t val"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_get_counter64_raw "struct asn_buf *buf" "asn_len_t len" "u_int64_t *res"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_put_counter64 "struct asn_buf *buf" "u_int64_t val"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_get_timeticks "struct asn_buf *buf" "u_int32_t *valp"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_put_timeticks "struct asn_buf *buf" "u_int32_t val"
|
||||
.Ft enum asn_err
|
||||
.Fn asn_skip "struct asn_buf *buf" "asn_len_t len"
|
||||
.Ft void
|
||||
.Fn asn_slice_oid "struct asn_oid *dest" "const struct asn_oid *src" "u_int from" "u_int to"
|
||||
.Ft void
|
||||
.Fn asn_append_oid "struct asn_oid *to" "const struct asn_oid *from"
|
||||
.Ft int
|
||||
.Fn asn_compare_oid "const struct asn_oid *oid1" "const struct asn_oid *oid2"
|
||||
.Ft int
|
||||
.Fn asn_is_suboid "const struct asn_oid *oid1" "const struct asn_oid *oid2"
|
||||
.Ft char *
|
||||
.Fn asn_oid2str_r "const struct asn_oid *oid" "char *buf"
|
||||
.Ft char *
|
||||
.Fn asn_oid2str "const struct asn_oid *oid"
|
||||
.Sh DESCRIPTION
|
||||
The ASN.1 library contains routines to handle ASN.1 encoding for SNMP.
|
||||
It supports only the restricted form of ASN.1 as required by SNMP. There
|
||||
are two basic structures used throughout the library:
|
||||
.Bd -literal -offset indent
|
||||
/* these restrictions are in the SMI */
|
||||
#define ASN_MAXID 0xffffffff
|
||||
#define ASN_MAXOIDLEN 128
|
||||
|
||||
/* type of subidentifiers */
|
||||
typedef u_int32_t asn_subid_t;
|
||||
|
||||
struct asn_oid {
|
||||
u_int len;
|
||||
asn_subid_t subs[ASN_MAXOIDLEN];
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
This structure represents an OID with the restrictions defined in the SNMP
|
||||
SMI.
|
||||
.Fa len
|
||||
holds the current length of the OID and
|
||||
.Fa subs
|
||||
holds the elements of the OID.
|
||||
.Bd -literal -offset indent
|
||||
struct asn_buf {
|
||||
union {
|
||||
u_char *ptr;
|
||||
const u_char *cptr;
|
||||
} asn_u;
|
||||
size_t asn_len;
|
||||
};
|
||||
#define asn_cptr asn_u.cptr
|
||||
#define asn_ptr asn_u.ptr
|
||||
.Ed
|
||||
.Pp
|
||||
This structure is used to encode and decode ASN.1. It describes the output
|
||||
buffer for encoding routines and the input buffer for decoding routines.
|
||||
For encoding
|
||||
.Fa asn_len
|
||||
holds the number of remaining free octets in the buffer. The first free byte
|
||||
is pointed to by
|
||||
.Fa asn_ptr .
|
||||
For decoding
|
||||
.Fa asn_len
|
||||
holds the number of remaining bytes to decode. The next byte to decode is pointed
|
||||
to by
|
||||
.Fa asn_cptr .
|
||||
.Pp
|
||||
Most of the functions return an error code
|
||||
.Fa "enum asn_error" :
|
||||
.Bd -literal -offset indent
|
||||
enum asn_err {
|
||||
/* conversion was ok */
|
||||
ASN_ERR_OK = 0,
|
||||
/* conversion failed and stopped */
|
||||
ASN_ERR_FAILED = 1 | 0x1000,
|
||||
/* length field bad, value skipped */
|
||||
ASN_ERR_BADLEN = 2,
|
||||
/* out of buffer, stopped */
|
||||
ASN_ERR_EOBUF = 3 | 0x1000,
|
||||
/* length ok, but value is out of range */
|
||||
ASN_ERR_RANGE = 4,
|
||||
/* not the expected tag, stopped */
|
||||
ASN_ERR_TAG = 5 | 0x1000,
|
||||
};
|
||||
#define ASN_ERR_STOPPED(E) (((E) & 0x1000) != 0)
|
||||
.Ed
|
||||
.Pp
|
||||
If
|
||||
.Fn ASN_ERR_STOPPED
|
||||
returns true, the error was fatal and processing has stopped at the point
|
||||
of error.
|
||||
.Pp
|
||||
The function
|
||||
.Fn asn_get_header
|
||||
reads the next header from the input octet stream. It returns the tag
|
||||
in the variable pointed to by
|
||||
.Fa type
|
||||
(note that only single byte tags are supported) and the decoded length field
|
||||
in the value pointed to by
|
||||
.Fa lenp
|
||||
(this is restricted to a unsigned 32-bit value). All errors in this function
|
||||
are fatal and stop processing.
|
||||
.Pp
|
||||
The function
|
||||
.Fn asn_put_header
|
||||
writes an ASN.1 header.
|
||||
.Fa type
|
||||
is the tag to write and is restricted to one byte tags (i.e. tags
|
||||
lesser or equal than 0x30).
|
||||
.Fa len
|
||||
is the length of the value and is restricted to 16-bit.
|
||||
.Pp
|
||||
The functions
|
||||
.Fn asn_put_temp_header
|
||||
and
|
||||
.Fn asn_commit_header
|
||||
are used to write a header when the length of the value is not known in
|
||||
advance, for example, for sequences.
|
||||
.Fn asn_put_temp_header
|
||||
writes a header with the given tag
|
||||
.Fa type
|
||||
and space for the maximum supported length field and sets the pointer pointed
|
||||
to by
|
||||
.Fa ptr
|
||||
to the begin of this length field. This pointer must then be fed into
|
||||
.Fn asn_commit_header
|
||||
directly after writing the value to the buffer. The function will compute the
|
||||
length, insert it into the right place and shift the value if the resulting
|
||||
length field is shorter than the estimated one.
|
||||
.Pp
|
||||
The function
|
||||
.Fn asn_get_integer_raw
|
||||
is used to decode a signed integer value (32-bit). It assumes, that the
|
||||
header of the integer has been decoded already.
|
||||
.Fa len
|
||||
is the length obtained from the ASN.1 header and the integer will be returned
|
||||
in the value pointed to by
|
||||
.Fa res .
|
||||
.Pp
|
||||
The function
|
||||
.Fn asn_get_integer
|
||||
decodes a complete 32-bit signed integer including the header. If the
|
||||
tag is wrong
|
||||
.Li ASN_ERR_TAG
|
||||
is returned.
|
||||
The function
|
||||
.Fn asn_put_integer
|
||||
encodes a 32-bit signed integer.
|
||||
.Pp
|
||||
The function
|
||||
.Fn asn_get_octetstring_raw
|
||||
decodes the value field of an ASN.1 octet string. The length obtained from the
|
||||
header must be fed into the
|
||||
.Fa len
|
||||
argument and
|
||||
.Fa out
|
||||
must point to a buffer to receive the octet string. On entry to the function
|
||||
.Fa outsize
|
||||
must point to the size of the buffer. On exit
|
||||
.Fa outsize
|
||||
will point to the number of octets decoded (if no error occurs this will be
|
||||
equal to
|
||||
.Fa len ).
|
||||
The function
|
||||
.Fn asn_get_octetstring
|
||||
decodes an octetstring including the header.
|
||||
.Fa out
|
||||
must point to a buffer to receive the string,
|
||||
.Fa outsize
|
||||
must point to the size of the buffer. On exit of the function
|
||||
.Fa outsize
|
||||
will point to the number of octets decoded.
|
||||
The function
|
||||
.Fn asn_put_octetstring
|
||||
encodes an octetstring (including the header).
|
||||
.Fa str
|
||||
points to the string to encode and
|
||||
.Fa strsize
|
||||
is the length of the string (the string may contain embedded
|
||||
.Li NUL Ns s).
|
||||
.Pp
|
||||
The function
|
||||
.Fn asn_get_null_raw
|
||||
decodes a null value.
|
||||
.Fa len
|
||||
is the length obtained from the header and must be 0.
|
||||
The function
|
||||
.Fn asn_get_null
|
||||
decodes a null including the header and the function
|
||||
.Fn asn_put_null
|
||||
encodes a null.
|
||||
.Pp
|
||||
The function
|
||||
.Fn asn_put_exception
|
||||
is used to encode an SNMPv2 exception. The exception type is
|
||||
.Fa type .
|
||||
.Pp
|
||||
The function
|
||||
.Fn asn_get_objid_raw
|
||||
is used to decode an OID value.
|
||||
.Fa len
|
||||
must be the value length obtained from the header and
|
||||
.Fa oid
|
||||
will receive the decoded OID.
|
||||
The function
|
||||
.Fn asn_get_objid
|
||||
decodes a complete OID (including the header) and the function
|
||||
.Fn asn_put_objid
|
||||
encodes a complete OID.
|
||||
.Pp
|
||||
The function
|
||||
.Fn asn_get_sequence
|
||||
decodes a sequence header.
|
||||
The length of the sequence value will be stored in the value pointed to by
|
||||
.Fa lenp .
|
||||
.Pp
|
||||
The function
|
||||
.Fn asn_get_ipaddress_raw
|
||||
decodes an IP address value.
|
||||
.Fa len
|
||||
is the length from the header and must be 4.
|
||||
.Fa ipa
|
||||
will receive the decoded IP address and must point to a buffer of at least
|
||||
four bytes.
|
||||
The function
|
||||
.Fn asn_get_ipaddress
|
||||
decodes a complete IP address (including the header) and
|
||||
.Fn asn_put_ipaddress
|
||||
encodes an IP address.
|
||||
.Pp
|
||||
The function
|
||||
.Fn asn_get_uint32_raw
|
||||
decodes an unsigned 32-bit integer value.
|
||||
.Fa len
|
||||
is the length from the header and
|
||||
.Fa res
|
||||
will get the decoded value.
|
||||
The function
|
||||
.Fn asn_put_uint32
|
||||
encodes an unsigned 32-bit integer value and inserts the tag given in
|
||||
.Fa type
|
||||
into the header.
|
||||
.Pp
|
||||
The function
|
||||
.Fn asn_get_counter64_raw
|
||||
decodes an unsigned 64-bit integer value.
|
||||
.Fa len
|
||||
must be the value length from the header. The resulting value is
|
||||
stored into the variable pointed to by
|
||||
.Fa res .
|
||||
The function
|
||||
.Fn asn_put_counter64
|
||||
encodes a complete unsigned 64-bit value.
|
||||
.Pp
|
||||
The function
|
||||
.Fn asn_get_timeticks
|
||||
decodes an ASN.1 object of type
|
||||
.Li TIMETICKS
|
||||
and the function
|
||||
.Fn asn_put_timeticks
|
||||
encodes such an object.
|
||||
.Pp
|
||||
The function
|
||||
.Fn asn_skip
|
||||
can be used to skip
|
||||
.Fa len
|
||||
bytes in the input buffer.
|
||||
.Pp
|
||||
The function
|
||||
.Fn asn_slice_oid
|
||||
splits a part out from an OID. It takes all the subids from the OID
|
||||
pointed to by
|
||||
.Fa src
|
||||
starting with the subid at position
|
||||
.Fa from
|
||||
(the first subid beeing subid 0) up to, but not including, subid
|
||||
.Fa to
|
||||
and generates a new OID in
|
||||
.Fa dest .
|
||||
If
|
||||
.Fa to
|
||||
is less or equal to
|
||||
.Fa from
|
||||
the resulting OID will have a length of zero.
|
||||
.Pp
|
||||
The function
|
||||
.Fn asn_append_oid
|
||||
appends the OID
|
||||
.Fa from
|
||||
to the OID
|
||||
.Fa to
|
||||
given that the resulting OID is not too long. If the maximum length is exceeded
|
||||
the result is undefined.
|
||||
.Pp
|
||||
The function
|
||||
.Fn asn_compare_oid
|
||||
compares two oids and returns the values
|
||||
.Li -1 ,
|
||||
.Li 0 or
|
||||
.Li +1
|
||||
when
|
||||
.Fa oid1
|
||||
is lesser than, equal, or larger than
|
||||
.Fa oid2
|
||||
resp.
|
||||
.Pp
|
||||
The function
|
||||
.Fn asn_is_suboid
|
||||
returns 1 if
|
||||
.Fa oid1
|
||||
is equal to the leading part of
|
||||
.Fa oid2 .
|
||||
It returns 0 otherwise.
|
||||
.Pp
|
||||
The function
|
||||
.Fn asn_oid2str_r
|
||||
makes a printable string from
|
||||
.Fa oid .
|
||||
The buffer pointed to by
|
||||
.Fa str
|
||||
must be large enough to hold the result. The constant
|
||||
.Li ASN_OIDSTRLEN
|
||||
is defined to be the length of the maximum string generated by this function
|
||||
(including the trailing NUL).
|
||||
The function
|
||||
.Fn asn_oid2str
|
||||
makes a printable string from
|
||||
.Fa oid
|
||||
into a private buffer that is overwritten by each call.
|
||||
.Sh DIAGNOSTICS
|
||||
When an error occures in any of the function the function pointed to
|
||||
by the global pointer
|
||||
.Bd -literal -offset indent
|
||||
extern void (*asn_error)(const struct asn_buf *, const char *, ...);
|
||||
.Ed
|
||||
.Pp
|
||||
is called with the current buffer (this may be
|
||||
.Li NULL )
|
||||
and a
|
||||
.Xr printf 3
|
||||
style format string.
|
||||
There is a default error handler in the library that prints a message
|
||||
starting with
|
||||
.Sq ASN.1:
|
||||
followed by the error message and an optional dump of the buffer.
|
||||
.Sh SEE ALSO
|
||||
.Xr snmpd 1 ,
|
||||
.Xr gensnmptree 1 ,
|
||||
.Xr bsnmplib 3
|
||||
.Xr bsnmpclient 3 ,
|
||||
.Xr bsnmpagent 3
|
||||
.Sh STANDARDS
|
||||
This implementation conforms to the applicable IETF RFCs and ITU-T
|
||||
recommendations.
|
||||
.Sh AUTHORS
|
||||
.An Hartmut Brandt Aq brandt@fokus.gmd.de
|
994
contrib/bsnmp/lib/asn1.c
Normal file
994
contrib/bsnmp/lib/asn1.c
Normal file
@ -0,0 +1,994 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003
|
||||
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Harti Brandt <harti@freebsd.org>
|
||||
*
|
||||
* Redistribution of this software and documentation 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 or documentation 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.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
* AND ITS 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
|
||||
* FRAUNHOFER FOKUS OR ITS 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.
|
||||
*
|
||||
* $Begemot: bsnmp/lib/asn1.c,v 1.24 2003/01/28 13:44:34 hbb Exp $
|
||||
*
|
||||
* ASN.1 for SNMP.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <assert.h>
|
||||
#include "asn1.h"
|
||||
|
||||
static void asn_error_func(const struct asn_buf *, const char *, ...);
|
||||
|
||||
void (*asn_error)(const struct asn_buf *, const char *, ...) = asn_error_func;
|
||||
|
||||
/*
|
||||
* Read the next header. This reads the tag (note, that only single
|
||||
* byte tags are supported for now) and the length field. The length field
|
||||
* is restricted to a 32-bit value.
|
||||
* All errors of this function stop the decoding.
|
||||
*/
|
||||
enum asn_err
|
||||
asn_get_header(struct asn_buf *b, u_char *type, asn_len_t *len)
|
||||
{
|
||||
u_int length;
|
||||
|
||||
if (b->asn_len == 0) {
|
||||
asn_error(b, "no identifier for header");
|
||||
return (ASN_ERR_EOBUF);
|
||||
}
|
||||
*type = *b->asn_cptr;
|
||||
if ((*type & ASN_TYPE_MASK) > 0x30) {
|
||||
asn_error(b, "types > 0x30 not supported (%u)",
|
||||
*type & ASN_TYPE_MASK);
|
||||
return (ASN_ERR_FAILED);
|
||||
}
|
||||
b->asn_cptr++;
|
||||
b->asn_len--;
|
||||
if (b->asn_len == 0) {
|
||||
asn_error(b, "no length field");
|
||||
return (ASN_ERR_EOBUF);
|
||||
}
|
||||
if (*b->asn_cptr & 0x80) {
|
||||
length = *b->asn_cptr++ & 0x7f;
|
||||
b->asn_len--;
|
||||
if (length == 0) {
|
||||
asn_error(b, "indefinite length not supported");
|
||||
return (ASN_ERR_FAILED);
|
||||
}
|
||||
if (length > ASN_MAXLENLEN) {
|
||||
asn_error(b, "long length too long (%u)", length);
|
||||
return (ASN_ERR_FAILED);
|
||||
}
|
||||
if (length > b->asn_len) {
|
||||
asn_error(b, "long length truncated");
|
||||
return (ASN_ERR_EOBUF);
|
||||
}
|
||||
*len = 0;
|
||||
while (length--) {
|
||||
*len = (*len << 8) | *b->asn_cptr++;
|
||||
b->asn_len--;
|
||||
}
|
||||
} else {
|
||||
*len = *b->asn_cptr++;
|
||||
b->asn_len--;
|
||||
}
|
||||
return (ASN_ERR_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write a length field (restricted to values < 2^32-1) and return the
|
||||
* number of bytes this field takes. If ptr is NULL, the length is computed
|
||||
* but nothing is written. If the length would be too large return 0.
|
||||
*/
|
||||
static u_int
|
||||
asn_put_len(u_char *ptr, asn_len_t len)
|
||||
{
|
||||
u_int lenlen, lenlen1;
|
||||
asn_len_t tmp;
|
||||
|
||||
if (len > ASN_MAXLEN) {
|
||||
asn_error(NULL, "encoding length too long: (%u)", len);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (len <= 127) {
|
||||
if (ptr)
|
||||
*ptr++ = (u_char)len;
|
||||
return (1);
|
||||
} else {
|
||||
lenlen = 0;
|
||||
/* compute number of bytes for value (is at least 1) */
|
||||
for (tmp = len; tmp != 0; tmp >>= 8)
|
||||
lenlen++;
|
||||
if (ptr != NULL) {
|
||||
*ptr++ = (u_char)lenlen | 0x80;
|
||||
lenlen1 = lenlen;
|
||||
while (lenlen1-- > 0) {
|
||||
ptr[lenlen1] = len & 0xff;
|
||||
len >>= 8;
|
||||
}
|
||||
}
|
||||
return (lenlen + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Write a header (tag and length fields).
|
||||
* Tags are restricted to one byte tags (value <= 0x30) and the
|
||||
* lenght field to 16-bit. All errors stop the encoding.
|
||||
*/
|
||||
enum asn_err
|
||||
asn_put_header(struct asn_buf *b, u_char type, asn_len_t len)
|
||||
{
|
||||
u_int lenlen;
|
||||
|
||||
/* tag field */
|
||||
if ((type & ASN_TYPE_MASK) > 0x30) {
|
||||
asn_error(NULL, "types > 0x30 not supported (%u)",
|
||||
type & ASN_TYPE_MASK);
|
||||
return (ASN_ERR_FAILED);
|
||||
}
|
||||
if (b->asn_len == 0)
|
||||
return (ASN_ERR_EOBUF);
|
||||
|
||||
*b->asn_ptr++ = type;
|
||||
b->asn_len--;
|
||||
|
||||
/* length field */
|
||||
if ((lenlen = asn_put_len(NULL, len)) == 0)
|
||||
return (ASN_ERR_FAILED);
|
||||
if (b->asn_len < lenlen)
|
||||
return (ASN_ERR_EOBUF);
|
||||
|
||||
(void)asn_put_len(b->asn_ptr, len);
|
||||
b->asn_ptr += lenlen;
|
||||
b->asn_len -= lenlen;
|
||||
return (ASN_ERR_OK);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This constructs a temporary sequence header with space for the maximum
|
||||
* length field (three byte). Set the pointer that ptr points to to the
|
||||
* start of the encoded header. This is used for a later call to
|
||||
* asn_commit_header which will fix-up the length field and move the
|
||||
* value if needed. All errors should stop the encoding.
|
||||
*/
|
||||
#define TEMP_LEN (1 + ASN_MAXLENLEN + 1)
|
||||
enum asn_err
|
||||
asn_put_temp_header(struct asn_buf *b, u_char type, u_char **ptr)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (b->asn_len < TEMP_LEN)
|
||||
return (ASN_ERR_EOBUF);
|
||||
*ptr = b->asn_ptr;
|
||||
if ((ret = asn_put_header(b, type, ASN_MAXLEN)) == ASN_ERR_OK)
|
||||
assert(b->asn_ptr == *ptr + TEMP_LEN);
|
||||
return (ret);
|
||||
}
|
||||
enum asn_err
|
||||
asn_commit_header(struct asn_buf *b, u_char *ptr)
|
||||
{
|
||||
asn_len_t len;
|
||||
u_int lenlen, shift;
|
||||
|
||||
/* compute length of encoded value without header */
|
||||
len = b->asn_ptr - (ptr + TEMP_LEN);
|
||||
|
||||
/* insert length. may not fail. */
|
||||
lenlen = asn_put_len(ptr + 1, len);
|
||||
if (lenlen > TEMP_LEN - 1)
|
||||
return (ASN_ERR_FAILED);
|
||||
|
||||
if (lenlen < TEMP_LEN - 1) {
|
||||
/* shift value down */
|
||||
shift = (TEMP_LEN - 1) - lenlen;
|
||||
memmove(ptr + 1 + lenlen, ptr + TEMP_LEN, len);
|
||||
b->asn_ptr -= shift;
|
||||
b->asn_len += shift;
|
||||
}
|
||||
return (ASN_ERR_OK);
|
||||
}
|
||||
#undef TEMP_LEN
|
||||
|
||||
/*
|
||||
* BER integer. This may be used to get a signed 64 bit integer at maximum.
|
||||
* The maximum length should be checked by the caller. This cannot overflow
|
||||
* if the caller ensures that len is at maximum 8.
|
||||
*
|
||||
* <bytes>
|
||||
*/
|
||||
static enum asn_err
|
||||
asn_get_real_integer(struct asn_buf *b, asn_len_t len, int64_t *vp)
|
||||
{
|
||||
u_int64_t val;
|
||||
int neg = 0;
|
||||
enum asn_err err;
|
||||
|
||||
if (b->asn_len < len) {
|
||||
asn_error(b, "truncated integer");
|
||||
return (ASN_ERR_EOBUF);
|
||||
}
|
||||
if (len == 0) {
|
||||
asn_error(b, "zero-length integer");
|
||||
*vp = 0;
|
||||
return (ASN_ERR_BADLEN);
|
||||
}
|
||||
err = ASN_ERR_OK;
|
||||
if (len > 8)
|
||||
err = ASN_ERR_RANGE;
|
||||
if (*b->asn_cptr & 0x80)
|
||||
neg = 1;
|
||||
val = 0;
|
||||
while (len--) {
|
||||
val <<= 8;
|
||||
val |= neg ? (u_char)~*b->asn_cptr : *b->asn_cptr;
|
||||
b->asn_len--;
|
||||
b->asn_cptr++;
|
||||
}
|
||||
if (neg) {
|
||||
*vp = -(int64_t)val - 1;
|
||||
} else
|
||||
*vp = (int64_t)val;
|
||||
return (err);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write a signed integer with the given type. The caller has to ensure
|
||||
* that the actual value is ok for this type.
|
||||
*/
|
||||
static enum asn_err
|
||||
asn_put_real_integer(struct asn_buf *b, u_char type, int64_t ival)
|
||||
{
|
||||
int i, neg = 0;
|
||||
# define OCTETS 8
|
||||
u_char buf[OCTETS];
|
||||
u_int64_t val;
|
||||
enum asn_err ret;
|
||||
|
||||
if (ival < 0) {
|
||||
/* this may fail if |INT64_MIN| > |INT64_MAX| and
|
||||
* the value is between * INT64_MIN <= ival < -(INT64_MAX+1) */
|
||||
val = (u_int64_t)-(ival + 1);
|
||||
neg = 1;
|
||||
} else
|
||||
val = (u_int64_t)ival;
|
||||
|
||||
/* split the value into octets */
|
||||
for (i = OCTETS - 1; i >= 0; i--) {
|
||||
buf[i] = val & 0xff;
|
||||
if (neg)
|
||||
buf[i] = ~buf[i];
|
||||
val >>= 8;
|
||||
}
|
||||
/* no leading 9 zeroes or ones */
|
||||
for (i = 0; i < OCTETS - 1; i++)
|
||||
if (!((buf[i] == 0xff && (buf[i + 1] & 0x80) != 0) ||
|
||||
(buf[i] == 0x00 && (buf[i + 1] & 0x80) == 0)))
|
||||
break;
|
||||
if ((ret = asn_put_header(b, type, OCTETS - i)))
|
||||
return (ret);
|
||||
if (OCTETS - (u_int)i > b->asn_len)
|
||||
return (ASN_ERR_EOBUF);
|
||||
|
||||
while (i < OCTETS) {
|
||||
*b->asn_ptr++ = buf[i++];
|
||||
b->asn_len--;
|
||||
}
|
||||
return (ASN_ERR_OK);
|
||||
# undef OCTETS
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The same for unsigned 64-bitters. Here we have the problem, that overflow
|
||||
* can happen, because the value maybe 9 bytes long. In this case the
|
||||
* first byte must be 0.
|
||||
*/
|
||||
static enum asn_err
|
||||
asn_get_real_unsigned(struct asn_buf *b, asn_len_t len, u_int64_t *vp)
|
||||
{
|
||||
enum asn_err err;
|
||||
|
||||
if (b->asn_len < len) {
|
||||
asn_error(b, "truncated integer");
|
||||
return (ASN_ERR_EOBUF);
|
||||
}
|
||||
if (len == 0) {
|
||||
asn_error(b, "zero-length integer");
|
||||
*vp = 0;
|
||||
return (ASN_ERR_BADLEN);
|
||||
}
|
||||
err = ASN_ERR_OK;
|
||||
*vp = 0;
|
||||
if ((*b->asn_cptr & 0x80) || (len == 9 && *b->asn_cptr != 0)) {
|
||||
/* negative integer or too larger */
|
||||
*vp = 0xffffffffffffffffULL;
|
||||
err = ASN_ERR_RANGE;
|
||||
}
|
||||
|
||||
while (len--) {
|
||||
*vp = (*vp << 8) | *b->asn_cptr++;
|
||||
b->asn_len--;
|
||||
}
|
||||
return (err);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Values with the msb on need 9 octets.
|
||||
*/
|
||||
static int
|
||||
asn_put_real_unsigned(struct asn_buf *b, u_char type, u_int64_t val)
|
||||
{
|
||||
int i;
|
||||
# define OCTETS 9
|
||||
u_char buf[OCTETS];
|
||||
enum asn_err ret;
|
||||
|
||||
/* split the value into octets */
|
||||
for (i = OCTETS - 1; i >= 0; i--) {
|
||||
buf[i] = val & 0xff;
|
||||
val >>= 8;
|
||||
}
|
||||
/* no leading 9 zeroes */
|
||||
for (i = 0; i < OCTETS - 1; i++)
|
||||
if (!(buf[i] == 0x00 && (buf[i + 1] & 0x80) == 0))
|
||||
break;
|
||||
if ((ret = asn_put_header(b, type, OCTETS - i)))
|
||||
return (ret);
|
||||
if (OCTETS - (u_int)i > b->asn_len)
|
||||
return (ASN_ERR_EOBUF);
|
||||
|
||||
while (i < OCTETS) {
|
||||
*b->asn_ptr++ = buf[i++];
|
||||
b->asn_len--;
|
||||
}
|
||||
#undef OCTETS
|
||||
return (ASN_ERR_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* The ASN.1 INTEGER type is restricted to 32-bit signed by the SMI.
|
||||
*/
|
||||
enum asn_err
|
||||
asn_get_integer_raw(struct asn_buf *b, asn_len_t len, int32_t *vp)
|
||||
{
|
||||
int64_t val;
|
||||
enum asn_err ret;
|
||||
|
||||
if ((ret = asn_get_real_integer(b, len, &val)) == ASN_ERR_OK) {
|
||||
if (len > 4)
|
||||
ret = ASN_ERR_BADLEN;
|
||||
else if (val > INT32_MAX || val < INT32_MIN)
|
||||
/* may not happen */
|
||||
ret = ASN_ERR_RANGE;
|
||||
*vp = (int32_t)val;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
enum asn_err
|
||||
asn_get_integer(struct asn_buf *b, int32_t *vp)
|
||||
{
|
||||
asn_len_t len;
|
||||
u_char type;
|
||||
enum asn_err err;
|
||||
|
||||
if ((err = asn_get_header(b, &type, &len)) != ASN_ERR_OK)
|
||||
return (err);
|
||||
if (type != ASN_TYPE_INTEGER) {
|
||||
asn_error(b, "bad type for integer (%u)", type);
|
||||
return (ASN_ERR_TAG);
|
||||
}
|
||||
|
||||
return (asn_get_integer_raw(b, len, vp));
|
||||
}
|
||||
|
||||
enum asn_err
|
||||
asn_put_integer(struct asn_buf *b, int32_t val)
|
||||
{
|
||||
return (asn_put_real_integer(b, ASN_TYPE_INTEGER, val));
|
||||
}
|
||||
|
||||
/*
|
||||
* OCTETSTRING
|
||||
*
|
||||
* <0x04> <len> <data ...>
|
||||
*
|
||||
* Get an octetstring. noctets must point to the buffer size and on
|
||||
* return will contain the size of the octetstring, regardless of the
|
||||
* buffer size.
|
||||
*/
|
||||
enum asn_err
|
||||
asn_get_octetstring_raw(struct asn_buf *b, asn_len_t len, u_char *octets,
|
||||
u_int *noctets)
|
||||
{
|
||||
enum asn_err err = ASN_ERR_OK;
|
||||
|
||||
if (*noctets < len) {
|
||||
asn_error(b, "octetstring truncated");
|
||||
err = ASN_ERR_RANGE;
|
||||
}
|
||||
if (b->asn_len < len) {
|
||||
asn_error(b, "truncatet octetstring");
|
||||
return (ASN_ERR_EOBUF);
|
||||
}
|
||||
if (*noctets < len)
|
||||
memcpy(octets, b->asn_cptr, *noctets);
|
||||
else
|
||||
memcpy(octets, b->asn_cptr, len);
|
||||
*noctets = len;
|
||||
b->asn_cptr += len;
|
||||
b->asn_len -= len;
|
||||
return (err);
|
||||
}
|
||||
|
||||
enum asn_err
|
||||
asn_get_octetstring(struct asn_buf *b, u_char *octets, u_int *noctets)
|
||||
{
|
||||
enum asn_err err;
|
||||
u_char type;
|
||||
asn_len_t len;
|
||||
|
||||
if ((err = asn_get_header(b, &type, &len)) != ASN_ERR_OK)
|
||||
return (err);
|
||||
if (type != ASN_TYPE_OCTETSTRING) {
|
||||
asn_error(b, "bad type for octetstring (%u)", type);
|
||||
return (ASN_ERR_TAG);
|
||||
}
|
||||
return (asn_get_octetstring_raw(b, len, octets, noctets));
|
||||
}
|
||||
|
||||
enum asn_err
|
||||
asn_put_octetstring(struct asn_buf *b, const u_char *octets, u_int noctets)
|
||||
{
|
||||
enum asn_err ret;
|
||||
|
||||
if ((ret = asn_put_header(b, ASN_TYPE_OCTETSTRING, noctets)) != ASN_ERR_OK)
|
||||
return (ret);
|
||||
if (b->asn_len < noctets)
|
||||
return (ASN_ERR_EOBUF);
|
||||
|
||||
memcpy(b->asn_ptr, octets, noctets);
|
||||
b->asn_ptr += noctets;
|
||||
b->asn_len -= noctets;
|
||||
return (ASN_ERR_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* NULL
|
||||
*
|
||||
* <0x05> <0x00>
|
||||
*/
|
||||
enum asn_err
|
||||
asn_get_null_raw(struct asn_buf *b, asn_len_t len)
|
||||
{
|
||||
if (len != 0) {
|
||||
if (b->asn_len < len) {
|
||||
asn_error(b, "truncated NULL");
|
||||
return (ASN_ERR_EOBUF);
|
||||
}
|
||||
asn_error(b, "bad length for NULL (%u)", len);
|
||||
b->asn_len -= len;
|
||||
b->asn_ptr += len;
|
||||
return (ASN_ERR_BADLEN);
|
||||
}
|
||||
return (ASN_ERR_OK);
|
||||
}
|
||||
|
||||
enum asn_err
|
||||
asn_get_null(struct asn_buf *b)
|
||||
{
|
||||
u_char type;
|
||||
asn_len_t len;
|
||||
enum asn_err err;
|
||||
|
||||
if ((err = asn_get_header(b, &type, &len)) != ASN_ERR_OK)
|
||||
return (err);
|
||||
if (type != ASN_TYPE_NULL) {
|
||||
asn_error(b, "bad type for NULL (%u)", type);
|
||||
return (ASN_ERR_TAG);
|
||||
}
|
||||
return (asn_get_null_raw(b, len));
|
||||
}
|
||||
|
||||
enum asn_err
|
||||
asn_put_null(struct asn_buf *b)
|
||||
{
|
||||
return (asn_put_header(b, ASN_TYPE_NULL, 0));
|
||||
}
|
||||
|
||||
enum asn_err
|
||||
asn_put_exception(struct asn_buf *b, u_int except)
|
||||
{
|
||||
return (asn_put_header(b, ASN_CLASS_CONTEXT | except, 0));
|
||||
}
|
||||
|
||||
/*
|
||||
* OBJID
|
||||
*
|
||||
* <0x06> <len> <subid...>
|
||||
*/
|
||||
enum asn_err
|
||||
asn_get_objid_raw(struct asn_buf *b, asn_len_t len, struct asn_oid *oid)
|
||||
{
|
||||
asn_subid_t subid;
|
||||
enum asn_err err;
|
||||
|
||||
if (b->asn_len < len) {
|
||||
asn_error(b, "truncated OBJID");
|
||||
return (ASN_ERR_EOBUF);
|
||||
}
|
||||
oid->len = 0;
|
||||
if (len == 0) {
|
||||
asn_error(b, "short OBJID");
|
||||
oid->subs[oid->len++] = 0;
|
||||
oid->subs[oid->len++] = 0;
|
||||
return (ASN_ERR_BADLEN);
|
||||
}
|
||||
err = ASN_ERR_OK;
|
||||
while (len != 0) {
|
||||
if (oid->len == ASN_MAXOIDLEN) {
|
||||
asn_error(b, "OID too long (%u)", oid->len);
|
||||
b->asn_cptr += len;
|
||||
b->asn_len -= len;
|
||||
return (ASN_ERR_BADLEN);
|
||||
}
|
||||
subid = 0;
|
||||
do {
|
||||
if (len == 0) {
|
||||
asn_error(b, "unterminated subid");
|
||||
return (ASN_ERR_EOBUF);
|
||||
}
|
||||
if (subid > (ASN_MAXID >> 7)) {
|
||||
asn_error(b, "OBID subid too larger");
|
||||
err = ASN_ERR_RANGE;
|
||||
}
|
||||
subid = (subid << 7) | (*b->asn_cptr & 0x7f);
|
||||
len--;
|
||||
b->asn_len--;
|
||||
} while (*b->asn_cptr++ & 0x80);
|
||||
if (oid->len == 0) {
|
||||
if (subid < 80) {
|
||||
oid->subs[oid->len++] = subid / 40;
|
||||
oid->subs[oid->len++] = subid % 40;
|
||||
} else {
|
||||
oid->subs[oid->len++] = 2;
|
||||
oid->subs[oid->len++] = subid - 80;
|
||||
}
|
||||
} else {
|
||||
oid->subs[oid->len++] = subid;
|
||||
}
|
||||
}
|
||||
return (err);
|
||||
|
||||
}
|
||||
|
||||
enum asn_err
|
||||
asn_get_objid(struct asn_buf *b, struct asn_oid *oid)
|
||||
{
|
||||
u_char type;
|
||||
asn_len_t len;
|
||||
enum asn_err err;
|
||||
|
||||
if ((err = asn_get_header(b, &type, &len)) != ASN_ERR_OK)
|
||||
return (err);
|
||||
if (type != ASN_TYPE_OBJID) {
|
||||
asn_error(b, "bad type for OBJID (%u)", type);
|
||||
return (ASN_ERR_TAG);
|
||||
}
|
||||
return (asn_get_objid_raw(b, len, oid));
|
||||
}
|
||||
|
||||
enum asn_err
|
||||
asn_put_objid(struct asn_buf *b, const struct asn_oid *oid)
|
||||
{
|
||||
asn_subid_t first, sub;
|
||||
enum asn_err err, err1;
|
||||
u_int i, oidlen;
|
||||
asn_len_t len;
|
||||
|
||||
err = ASN_ERR_OK;
|
||||
if (oid->len == 0) {
|
||||
/* illegal */
|
||||
asn_error(NULL, "short oid");
|
||||
err = ASN_ERR_RANGE;
|
||||
first = 0;
|
||||
oidlen = 2;
|
||||
} else if (oid->len == 1) {
|
||||
/* illegal */
|
||||
asn_error(b, "short oid");
|
||||
if (oid->subs[0] > 2)
|
||||
asn_error(NULL, "oid[0] too large (%u)", oid->subs[0]);
|
||||
err = ASN_ERR_RANGE;
|
||||
first = oid->subs[0] * 40;
|
||||
oidlen = 2;
|
||||
} else {
|
||||
if (oid->len > ASN_MAXOIDLEN) {
|
||||
asn_error(NULL, "oid too long %u", oid->len);
|
||||
err = ASN_ERR_RANGE;
|
||||
}
|
||||
if (oid->subs[0] > 2 ||
|
||||
(oid->subs[0] < 2 && oid->subs[0] >= 40)) {
|
||||
asn_error(NULL, "oid out of range (%u,%u)",
|
||||
oid->subs[0], oid->subs[1]);
|
||||
err = ASN_ERR_RANGE;
|
||||
}
|
||||
first = 40 * oid->subs[0] + oid->subs[1];
|
||||
oidlen = oid->len;
|
||||
}
|
||||
len = 0;
|
||||
for (i = 1; i < oidlen; i++) {
|
||||
sub = (i == 1) ? first : oid->subs[i];
|
||||
if (sub > ASN_MAXID) {
|
||||
asn_error(NULL, "oid subid too large");
|
||||
err = ASN_ERR_RANGE;
|
||||
}
|
||||
len += (sub <= 0x7f) ? 1
|
||||
: (sub <= 0x3fff) ? 2
|
||||
: (sub <= 0x1fffff) ? 3
|
||||
: (sub <= 0xfffffff) ? 4
|
||||
: 5;
|
||||
}
|
||||
if ((err1 = asn_put_header(b, ASN_TYPE_OBJID, len)) != ASN_ERR_OK)
|
||||
return (err1);
|
||||
if (b->asn_len < len)
|
||||
return (ASN_ERR_EOBUF);
|
||||
|
||||
for (i = 1; i < oidlen; i++) {
|
||||
sub = (i == 1) ? first : oid->subs[i];
|
||||
if (sub <= 0x7f) {
|
||||
*b->asn_ptr++ = sub;
|
||||
b->asn_len--;
|
||||
} else if (sub <= 0x3fff) {
|
||||
*b->asn_ptr++ = (sub >> 7) | 0x80;
|
||||
*b->asn_ptr++ = sub & 0x7f;
|
||||
b->asn_len -= 2;
|
||||
} else if (sub <= 0x1fffff) {
|
||||
*b->asn_ptr++ = (sub >> 14) | 0x80;
|
||||
*b->asn_ptr++ = ((sub >> 7) & 0x7f) | 0x80;
|
||||
*b->asn_ptr++ = sub & 0x7f;
|
||||
b->asn_len -= 3;
|
||||
} else if (sub <= 0xfffffff) {
|
||||
*b->asn_ptr++ = (sub >> 21) | 0x80;
|
||||
*b->asn_ptr++ = ((sub >> 14) & 0x7f) | 0x80;
|
||||
*b->asn_ptr++ = ((sub >> 7) & 0x7f) | 0x80;
|
||||
*b->asn_ptr++ = sub & 0x7f;
|
||||
b->asn_len -= 4;
|
||||
} else {
|
||||
*b->asn_ptr++ = (sub >> 28) | 0x80;
|
||||
*b->asn_ptr++ = ((sub >> 21) & 0x7f) | 0x80;
|
||||
*b->asn_ptr++ = ((sub >> 14) & 0x7f) | 0x80;
|
||||
*b->asn_ptr++ = ((sub >> 7) & 0x7f) | 0x80;
|
||||
*b->asn_ptr++ = sub & 0x7f;
|
||||
b->asn_len -= 5;
|
||||
}
|
||||
}
|
||||
return (err);
|
||||
}
|
||||
/*
|
||||
* SEQUENCE header
|
||||
*
|
||||
* <0x10|0x20> <len> <data...>
|
||||
*/
|
||||
enum asn_err
|
||||
asn_get_sequence(struct asn_buf *b, asn_len_t *len)
|
||||
{
|
||||
u_char type;
|
||||
enum asn_err err;
|
||||
|
||||
if ((err = asn_get_header(b, &type, len)) != ASN_ERR_OK)
|
||||
return (err);
|
||||
if (type != (ASN_TYPE_SEQUENCE|ASN_TYPE_CONSTRUCTED)) {
|
||||
asn_error(b, "bad sequence type %u", type);
|
||||
return (ASN_ERR_TAG);
|
||||
}
|
||||
if (*len > b->asn_len) {
|
||||
asn_error(b, "truncated sequence");
|
||||
return (ASN_ERR_EOBUF);
|
||||
}
|
||||
return (ASN_ERR_OK);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Application types
|
||||
*
|
||||
* 0x40 4 MSB 2MSB 2LSB LSB
|
||||
*/
|
||||
enum asn_err
|
||||
asn_get_ipaddress_raw(struct asn_buf *b, asn_len_t len, u_char *addr)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
if (b->asn_len < len) {
|
||||
asn_error(b, "truncated ip-address");
|
||||
return (ASN_ERR_EOBUF);
|
||||
}
|
||||
if (len < 4) {
|
||||
asn_error(b, "short length for ip-Address %u", len);
|
||||
for (i = 0; i < len; i++)
|
||||
*addr++ = *b->asn_cptr++;
|
||||
while (i++ < len)
|
||||
*addr++ = 0;
|
||||
b->asn_len -= len;
|
||||
return (ASN_ERR_BADLEN);
|
||||
}
|
||||
for (i = 0; i < 4; i++)
|
||||
*addr++ = *b->asn_cptr++;
|
||||
b->asn_cptr += len - 4;
|
||||
b->asn_len -= len;
|
||||
return (ASN_ERR_OK);
|
||||
}
|
||||
|
||||
enum asn_err
|
||||
asn_get_ipaddress(struct asn_buf *b, u_char *addr)
|
||||
{
|
||||
u_char type;
|
||||
asn_len_t len;
|
||||
enum asn_err err;
|
||||
|
||||
if ((err = asn_get_header(b, &type, &len)) != ASN_ERR_OK)
|
||||
return (err);
|
||||
if (type != (ASN_CLASS_APPLICATION|ASN_APP_IPADDRESS)) {
|
||||
asn_error(b, "bad type for ip-address %u", type);
|
||||
return (ASN_ERR_TAG);
|
||||
}
|
||||
return (asn_get_ipaddress_raw(b, len, addr));
|
||||
}
|
||||
|
||||
enum asn_err
|
||||
asn_put_ipaddress(struct asn_buf *b, const u_char *addr)
|
||||
{
|
||||
enum asn_err err;
|
||||
|
||||
if ((err = asn_put_header(b, ASN_CLASS_APPLICATION|ASN_APP_IPADDRESS,
|
||||
4)) != ASN_ERR_OK)
|
||||
return (err);
|
||||
if (b->asn_len < 4)
|
||||
return (ASN_ERR_EOBUF);
|
||||
|
||||
memcpy(b->asn_ptr, addr, 4);
|
||||
b->asn_ptr += 4;
|
||||
b->asn_len -= 4;
|
||||
return (ASN_ERR_OK);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* UNSIGNED32
|
||||
*
|
||||
* 0x42|0x41 <len> ...
|
||||
*/
|
||||
enum asn_err
|
||||
asn_get_uint32_raw(struct asn_buf *b, asn_len_t len, u_int32_t *vp)
|
||||
{
|
||||
u_int64_t v;
|
||||
enum asn_err err;
|
||||
|
||||
if ((err = asn_get_real_unsigned(b, len, &v)) == ASN_ERR_OK) {
|
||||
if (len > 5) {
|
||||
asn_error(b, "uint32 too long %u", len);
|
||||
err = ASN_ERR_BADLEN;
|
||||
} else if (v > UINT32_MAX) {
|
||||
asn_error(b, "uint32 too large %llu", v);
|
||||
err = ASN_ERR_RANGE;
|
||||
}
|
||||
*vp = (u_int32_t)v;
|
||||
}
|
||||
return (err);
|
||||
}
|
||||
|
||||
enum asn_err
|
||||
asn_put_uint32(struct asn_buf *b, u_char type, u_int32_t val)
|
||||
{
|
||||
u_int64_t v = val;
|
||||
|
||||
return (asn_put_real_unsigned(b, ASN_CLASS_APPLICATION|type, v));
|
||||
}
|
||||
|
||||
/*
|
||||
* COUNTER64
|
||||
* 0x46 <len> ...
|
||||
*/
|
||||
enum asn_err
|
||||
asn_get_counter64_raw(struct asn_buf *b, asn_len_t len, u_int64_t *vp)
|
||||
{
|
||||
return (asn_get_real_unsigned(b, len, vp));
|
||||
}
|
||||
|
||||
enum asn_err
|
||||
asn_put_counter64(struct asn_buf *b, u_int64_t val)
|
||||
{
|
||||
return (asn_put_real_unsigned(b,
|
||||
ASN_CLASS_APPLICATION | ASN_APP_COUNTER64, val));
|
||||
}
|
||||
|
||||
/*
|
||||
* TimeTicks
|
||||
* 0x43 <len> ...
|
||||
*/
|
||||
enum asn_err
|
||||
asn_get_timeticks(struct asn_buf *b, u_int32_t *vp)
|
||||
{
|
||||
asn_len_t len;
|
||||
u_char type;
|
||||
enum asn_err err;
|
||||
|
||||
if ((err = asn_get_header(b, &type, &len)) != ASN_ERR_OK)
|
||||
return (err);
|
||||
if (type != (ASN_CLASS_APPLICATION|ASN_APP_TIMETICKS)) {
|
||||
asn_error(b, "bad type for timeticks %u", type);
|
||||
return (ASN_ERR_TAG);
|
||||
}
|
||||
return (asn_get_uint32_raw(b, len, vp));
|
||||
}
|
||||
|
||||
enum asn_err
|
||||
asn_put_timeticks(struct asn_buf *b, u_int32_t val)
|
||||
{
|
||||
u_int64_t v = val;
|
||||
|
||||
return (asn_put_real_unsigned(b,
|
||||
ASN_CLASS_APPLICATION | ASN_APP_TIMETICKS, v));
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct a new OID by taking a range of sub ids of the original oid.
|
||||
*/
|
||||
void
|
||||
asn_slice_oid(struct asn_oid *dest, const struct asn_oid *src,
|
||||
u_int from, u_int to)
|
||||
{
|
||||
if (from >= to) {
|
||||
dest->len = 0;
|
||||
return;
|
||||
}
|
||||
dest->len = to - from;
|
||||
memcpy(dest->subs, &src->subs[from], dest->len * sizeof(dest->subs[0]));
|
||||
}
|
||||
|
||||
/*
|
||||
* Append from to to
|
||||
*/
|
||||
void
|
||||
asn_append_oid(struct asn_oid *to, const struct asn_oid *from)
|
||||
{
|
||||
memcpy(&to->subs[to->len], &from->subs[0],
|
||||
from->len * sizeof(from->subs[0]));
|
||||
to->len += from->len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip a value
|
||||
*/
|
||||
enum asn_err
|
||||
asn_skip(struct asn_buf *b, asn_len_t len)
|
||||
{
|
||||
if (b->asn_len < len)
|
||||
return (ASN_ERR_EOBUF);
|
||||
b->asn_cptr += len;
|
||||
b->asn_len -= len;
|
||||
return (ASN_ERR_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare two OIDs.
|
||||
*
|
||||
* o1 < o2 : -1
|
||||
* o1 > o2 : +1
|
||||
* o1 = o2 : 0
|
||||
*/
|
||||
int
|
||||
asn_compare_oid(const struct asn_oid *o1, const struct asn_oid *o2)
|
||||
{
|
||||
u_long i;
|
||||
|
||||
for (i = 0; i < o1->len && i < o2->len; i++) {
|
||||
if (o1->subs[i] < o2->subs[i])
|
||||
return (-1);
|
||||
if (o1->subs[i] > o2->subs[i])
|
||||
return (+1);
|
||||
}
|
||||
if (o1->len < o2->len)
|
||||
return (-1);
|
||||
if (o1->len > o2->len)
|
||||
return (+1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether an OID is a sub-string of another OID.
|
||||
*/
|
||||
int
|
||||
asn_is_suboid(const struct asn_oid *o1, const struct asn_oid *o2)
|
||||
{
|
||||
u_long i;
|
||||
|
||||
for (i = 0; i < o1->len; i++)
|
||||
if (i >= o2->len || o1->subs[i] != o2->subs[i])
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Put a string representation of an oid into a user buffer. This buffer
|
||||
* is assumed to be at least ASN_OIDSTRLEN characters long.
|
||||
*
|
||||
* sprintf is assumed not to fail here.
|
||||
*/
|
||||
char *
|
||||
asn_oid2str_r(const struct asn_oid *oid, char *buf)
|
||||
{
|
||||
u_int len, i;
|
||||
char *ptr;
|
||||
|
||||
if ((len = oid->len) > ASN_MAXOIDLEN)
|
||||
len = ASN_MAXOIDLEN;
|
||||
buf[0] = '\0';
|
||||
for (i = 0, ptr = buf; i < len; i++) {
|
||||
if (i > 0)
|
||||
*ptr++ = '.';
|
||||
ptr += sprintf(ptr, "%u", oid->subs[i]);
|
||||
}
|
||||
return (buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a string from an OID in a private buffer.
|
||||
*/
|
||||
char *
|
||||
asn_oid2str(const struct asn_oid *oid)
|
||||
{
|
||||
static char str[ASN_OIDSTRLEN];
|
||||
|
||||
return (asn_oid2str_r(oid, str));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
asn_error_func(const struct asn_buf *b, const char *err, ...)
|
||||
{
|
||||
va_list ap;
|
||||
u_long i;
|
||||
|
||||
fprintf(stderr, "ASN.1: ");
|
||||
va_start(ap, err);
|
||||
vfprintf(stderr, err, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (b != NULL) {
|
||||
fprintf(stderr, " at");
|
||||
for (i = 0; b->asn_len > i; i++)
|
||||
fprintf(stderr, " %02x", b->asn_cptr[i]);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
186
contrib/bsnmp/lib/asn1.h
Normal file
186
contrib/bsnmp/lib/asn1.h
Normal file
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003
|
||||
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Harti Brandt <harti@freebsd.org>
|
||||
*
|
||||
* Redistribution of this software and documentation 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 or documentation 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.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
* AND ITS 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
|
||||
* FRAUNHOFER FOKUS OR ITS 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.
|
||||
*
|
||||
* $Begemot: bsnmp/lib/asn1.h,v 1.16 2002/02/11 10:19:57 hbb Exp $
|
||||
*
|
||||
* ASN.1 for SNMP
|
||||
*/
|
||||
#ifndef asn1_h_
|
||||
#define asn1_h_
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
struct asn_buf {
|
||||
union {
|
||||
u_char *ptr;
|
||||
const u_char *cptr;
|
||||
} asn_u;
|
||||
size_t asn_len;
|
||||
};
|
||||
#define asn_cptr asn_u.cptr
|
||||
#define asn_ptr asn_u.ptr
|
||||
|
||||
/* these restrictions are in the SMI */
|
||||
#define ASN_MAXID 0xffffffff
|
||||
#define ASN_MAXOIDLEN 128
|
||||
|
||||
/* the string needed for this (with trailing zero) */
|
||||
#define ASN_OIDSTRLEN (ASN_MAXOIDLEN * (10 + 1) - 1 + 1)
|
||||
|
||||
/* type of subidentifiers */
|
||||
typedef u_int32_t asn_subid_t;
|
||||
|
||||
struct asn_oid {
|
||||
u_int len;
|
||||
asn_subid_t subs[ASN_MAXOIDLEN];
|
||||
};
|
||||
|
||||
enum asn_err {
|
||||
/* conversion was ok */
|
||||
ASN_ERR_OK = 0,
|
||||
/* conversion failed and stopped */
|
||||
ASN_ERR_FAILED = 1 | 0x1000,
|
||||
/* length field bad, value skipped */
|
||||
ASN_ERR_BADLEN = 2,
|
||||
/* out of buffer, stopped */
|
||||
ASN_ERR_EOBUF = 3 | 0x1000,
|
||||
/* length ok, but value is out of range */
|
||||
ASN_ERR_RANGE = 4,
|
||||
/* not the expected tag, stopped */
|
||||
ASN_ERR_TAG = 5 | 0x1000,
|
||||
};
|
||||
#define ASN_ERR_STOPPED(E) (((E) & 0x1000) != 0)
|
||||
|
||||
/* type for the length field of encoded values. The length is restricted
|
||||
* to 65535, but using u_int16_t would give conversion warnings on gcc */
|
||||
typedef u_int32_t asn_len_t; /* could be also u_int16_t */
|
||||
|
||||
/* maximal length of a long length field without the length of the length */
|
||||
#define ASN_MAXLEN 65535
|
||||
#define ASN_MAXLENLEN 2 /* number of bytes in a length */
|
||||
|
||||
/* maximum size of an octet string as per SMIv2 */
|
||||
#define ASN_MAXOCTETSTRING 65535
|
||||
|
||||
extern void (*asn_error)(const struct asn_buf *, const char *, ...);
|
||||
|
||||
enum asn_err asn_get_header(struct asn_buf *, u_char *, asn_len_t *);
|
||||
enum asn_err asn_put_header(struct asn_buf *, u_char, asn_len_t);
|
||||
|
||||
enum asn_err asn_put_temp_header(struct asn_buf *, u_char, u_char **);
|
||||
enum asn_err asn_commit_header(struct asn_buf *, u_char *);
|
||||
|
||||
enum asn_err asn_get_integer_raw(struct asn_buf *, asn_len_t, int32_t *);
|
||||
enum asn_err asn_get_integer(struct asn_buf *, int32_t *);
|
||||
enum asn_err asn_put_integer(struct asn_buf *, int32_t);
|
||||
|
||||
enum asn_err asn_get_octetstring_raw(struct asn_buf *, asn_len_t, u_char *, u_int *);
|
||||
enum asn_err asn_get_octetstring(struct asn_buf *, u_char *, u_int *);
|
||||
enum asn_err asn_put_octetstring(struct asn_buf *, const u_char *, u_int);
|
||||
|
||||
enum asn_err asn_get_null_raw(struct asn_buf *b, asn_len_t);
|
||||
enum asn_err asn_get_null(struct asn_buf *);
|
||||
enum asn_err asn_put_null(struct asn_buf *);
|
||||
|
||||
enum asn_err asn_put_exception(struct asn_buf *, u_int);
|
||||
|
||||
enum asn_err asn_get_objid_raw(struct asn_buf *, asn_len_t, struct asn_oid *);
|
||||
enum asn_err asn_get_objid(struct asn_buf *, struct asn_oid *);
|
||||
enum asn_err asn_put_objid(struct asn_buf *, const struct asn_oid *);
|
||||
|
||||
enum asn_err asn_get_sequence(struct asn_buf *, asn_len_t *);
|
||||
|
||||
enum asn_err asn_get_ipaddress_raw(struct asn_buf *, asn_len_t, u_char *);
|
||||
enum asn_err asn_get_ipaddress(struct asn_buf *, u_char *);
|
||||
enum asn_err asn_put_ipaddress(struct asn_buf *, const u_char *);
|
||||
|
||||
enum asn_err asn_get_uint32_raw(struct asn_buf *, asn_len_t, u_int32_t *);
|
||||
enum asn_err asn_put_uint32(struct asn_buf *, u_char, u_int32_t);
|
||||
|
||||
enum asn_err asn_get_counter64_raw(struct asn_buf *, asn_len_t, u_int64_t *);
|
||||
enum asn_err asn_put_counter64(struct asn_buf *, u_int64_t);
|
||||
|
||||
enum asn_err asn_get_timeticks(struct asn_buf *, u_int32_t *);
|
||||
enum asn_err asn_put_timeticks(struct asn_buf *, u_int32_t);
|
||||
|
||||
enum asn_err asn_skip(struct asn_buf *, asn_len_t);
|
||||
|
||||
/*
|
||||
* Utility functions for OIDs
|
||||
*/
|
||||
/* get a sub-OID from the middle of another OID */
|
||||
void asn_slice_oid(struct asn_oid *, const struct asn_oid *, u_int, u_int);
|
||||
|
||||
/* append an OID to another one */
|
||||
void asn_append_oid(struct asn_oid *, const struct asn_oid *);
|
||||
|
||||
/* compare two OIDs */
|
||||
int asn_compare_oid(const struct asn_oid *, const struct asn_oid *);
|
||||
|
||||
/* check whether the first is a suboid of the second one */
|
||||
int asn_is_suboid(const struct asn_oid *, const struct asn_oid *);
|
||||
|
||||
/* format an OID into a user buffer of size ASN_OIDSTRLEN */
|
||||
char *asn_oid2str_r(const struct asn_oid *, char *);
|
||||
|
||||
/* format an OID into a private static buffer */
|
||||
char *asn_oid2str(const struct asn_oid *);
|
||||
|
||||
enum {
|
||||
ASN_TYPE_BOOLEAN = 0x01,
|
||||
ASN_TYPE_INTEGER = 0x02,
|
||||
ASN_TYPE_BITSTRING = 0x03,
|
||||
ASN_TYPE_OCTETSTRING = 0x04,
|
||||
ASN_TYPE_NULL = 0x05,
|
||||
ASN_TYPE_OBJID = 0x06,
|
||||
ASN_TYPE_SEQUENCE = 0x10,
|
||||
|
||||
ASN_TYPE_CONSTRUCTED = 0x20,
|
||||
ASN_CLASS_UNIVERSAL = 0x00,
|
||||
ASN_CLASS_APPLICATION = 0x40,
|
||||
ASN_CLASS_CONTEXT = 0x80,
|
||||
ASN_CLASS_PRIVATE = 0xc0,
|
||||
ASN_TYPE_MASK = 0x1f,
|
||||
|
||||
ASN_APP_IPADDRESS = 0x00,
|
||||
ASN_APP_COUNTER = 0x01,
|
||||
ASN_APP_GAUGE = 0x02,
|
||||
ASN_APP_TIMETICKS = 0x03,
|
||||
ASN_APP_OPAQUE = 0x04, /* not implemented */
|
||||
ASN_APP_COUNTER64 = 0x06,
|
||||
|
||||
ASN_EXCEPT_NOSUCHOBJECT = 0x00,
|
||||
ASN_EXCEPT_NOSUCHINSTANCE = 0x01,
|
||||
ASN_EXCEPT_ENDOFMIBVIEW = 0x02,
|
||||
};
|
||||
|
||||
#endif
|
417
contrib/bsnmp/lib/bsnmpagent.3
Normal file
417
contrib/bsnmp/lib/bsnmpagent.3
Normal file
@ -0,0 +1,417 @@
|
||||
.\"
|
||||
.\" Copyright (c) 2001-2003
|
||||
.\" Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Author: Harti Brandt <harti@freebsd.org>
|
||||
.\"
|
||||
.\" Redistribution of this software and documentation 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 or documentation 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.
|
||||
.\" 3. Neither the name of the Institute nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
.\" AND ITS 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
|
||||
.\" FRAUNHOFER FOKUS OR ITS 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.
|
||||
.\"
|
||||
.\" $Begemot: bsnmp/lib/bsnmpagent.3,v 1.1 2002/08/16 12:22:58 hbb Exp $
|
||||
.\"
|
||||
.Dd August 16, 2002
|
||||
.Dt bsnmpagent 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm snmp_depop_t ,
|
||||
.Nm snmp_set_finish_t ,
|
||||
.Nm snmp_op_t ,
|
||||
.Nm tree ,
|
||||
.Nm tree_size ,
|
||||
.Nm snmp_trace ,
|
||||
.Nm snmp_debug ,
|
||||
.Nm snmp_get ,
|
||||
.Nm snmp_getnext ,
|
||||
.Nm snmp_getbulk ,
|
||||
.Nm snmp_set ,
|
||||
.Nm snmp_make_errresp ,
|
||||
.Nm snmp_dep_lookup ,
|
||||
.Nm snmp_set_atfinish ,
|
||||
.Nm snmp_init_context ,
|
||||
.Nm snmp_dep_commit ,
|
||||
.Nm snmp_dep_rollback
|
||||
.Nd "SNMP agent library"
|
||||
.Sh LIBRARY
|
||||
Begemot SNMP library
|
||||
.Pq libbsnmp, -lbsnmp
|
||||
.Sh SYNOPSIS
|
||||
.In asn1.h
|
||||
.In snmp.h
|
||||
.In snmpagent.h
|
||||
.Ft typedef int
|
||||
.Fn (*snmp_depop_t) "struct snmp_context *ctx" "struct snmp_dependency *dep" "enum snmp_depop op"
|
||||
.Ft typedef void
|
||||
.Fn (*snmp_set_finish_t) "struct snmp_context *ctx" "int fail" "void *uarg"
|
||||
.Ft typedef int
|
||||
.Fn (*snmp_op_t) "struct snmp_context *ctx" "struct snmp_value *val" "u_int len" "u_int idx" "enum snmp_op op"
|
||||
.Vt extern struct snmp_node *tree ;
|
||||
.Vt extern u_int tree_size ;
|
||||
.Vt extern u_int snmp_trace ;
|
||||
.Vt extern void (*snmp_debug)(const char *fmt, ...) ;
|
||||
.Ft enum snmp_ret
|
||||
.Fn snmp_get "struct snmp_pdu *pdu" "struct asn_buf *resp_b" "struct snmp_pdu *resp" "void *data"
|
||||
.Ft enum snmp_ret
|
||||
.Fn snmp_getnext "struct snmp_pdu *pdu" "struct asn_buf *resp_b" "struct snmp_pdu *resp" "void *data"
|
||||
.Ft enum snmp_ret
|
||||
.Fn snmp_getbulk "struct snmp_pdu *pdu" "struct asn_buf *resp_b" "struct snmp_pdu *resp" "void *data"
|
||||
.Ft enum snmp_ret
|
||||
.Fn snmp_set "struct snmp_pdu *pdu" "struct asn_buf *resp_b" "struct snmp_pdu *resp" "void *data"
|
||||
.Ft enum snmp_ret
|
||||
.Fn snmp_make_errresp "const struct snmp_pdu *pdu" "struct asn_buf *req_b" "struct asn_buf *resp_b"
|
||||
.Ft struct snmp_dependency *
|
||||
.Fn snmp_dep_lookup "struct snmp_context *ctx" "const struct asn_oid *base" "const struct asn_oid *idx" "size_t alloc" "snmp_depop_t func"
|
||||
.Ft int
|
||||
.Fn snmp_set_atfinish "struct snmp_context *ctx" "snmp_set_finish_t func" "void *uarg"
|
||||
.Ft struct snmp_context *
|
||||
.Fn snmp_init_context "void"
|
||||
.Ft int
|
||||
.Fn snmp_dep_commit "struct snmp_context *ctx"
|
||||
.Ft int
|
||||
.Fn snmp_dep_rollback "struct snmp_context *ctx"
|
||||
.Sh DESCRIPTION
|
||||
The SNMP library contains routines to easily build SNMP agent applications
|
||||
that use SNMP versions 1 or 2. Note, however, that it may be even easier to
|
||||
build an
|
||||
.Xr snmpd 1
|
||||
loadable module, that handles the new MIB (see
|
||||
.Xr snmpmod 3 ).
|
||||
.Pp
|
||||
Most of the agent routines operate on a global array that the describes the
|
||||
complete MIB served by the agent. This array is held in the two variables:
|
||||
.Bd -literal -offset indent
|
||||
extern struct snmp_node *tree;
|
||||
extern u_int tree_size;
|
||||
.Ed
|
||||
.Pp
|
||||
The elements of the array are of type
|
||||
.Vt struct snmp_node :
|
||||
.Bd -literal -offset indent
|
||||
typedef int (*snmp_op_t)(struct snmp_context *, struct snmp_value *,
|
||||
u_int, u_int, enum snmp_op);
|
||||
|
||||
struct snmp_node {
|
||||
struct asn_oid oid;
|
||||
const char *name; /* name of the leaf */
|
||||
enum snmp_node_type type; /* type of this node */
|
||||
enum snmp_syntax syntax;
|
||||
snmp_op_t op;
|
||||
u_int flags;
|
||||
u_int32_t index; /* index data */
|
||||
void *data; /* application data */
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
The fields of this structure are described below.
|
||||
.Bl -tag -width "syntax"
|
||||
.It Va oid
|
||||
Base OID of the scalar or table column.
|
||||
.It Va name
|
||||
Name of this variable.
|
||||
.It Va type
|
||||
Type of this variable. One of:
|
||||
.Bd -literal -offset indent
|
||||
enum snmp_node_type {
|
||||
SNMP_NODE_LEAF = 1,
|
||||
SNMP_NODE_COLUMN
|
||||
};
|
||||
.Ed
|
||||
.It Va syntax
|
||||
The SNMP syntax of this variable.
|
||||
.It Va op
|
||||
The user supplied handler for this variable. The handler is called with
|
||||
the following arguments:
|
||||
.Bl -tag -width "ctx"
|
||||
.It Fa ctx
|
||||
A pointer to the context (see below).
|
||||
.Li NULL .
|
||||
.It Fa val
|
||||
The value to be set or retrieved. For GETNEXT and GETBULK operations the oid in
|
||||
this value is the current OID. The function (called in this case only for
|
||||
table rows) must find the lexically next existing OID within the same column and
|
||||
set the oid and value subfields accordingly. If the table column is exhausted the
|
||||
function must return
|
||||
.Li SNMP_ERR_NOSUCHNAME .
|
||||
For all other operations the oid in
|
||||
.Fa val
|
||||
is the oid to fetch or set.
|
||||
.It Fa len
|
||||
The length of the base oid without index.
|
||||
.It Fa idx
|
||||
For table columns this is the index expression from the node (see below).
|
||||
.It Fa op
|
||||
This is the operation to execute, one of:
|
||||
.Bd -literal -offset indent
|
||||
enum snmp_op {
|
||||
SNMP_OP_GET = 1,
|
||||
SNMP_OP_GETNEXT,
|
||||
SNMP_OP_SET,
|
||||
SNMP_OP_COMMIT,
|
||||
SNMP_OP_ROLLBACK,
|
||||
};
|
||||
.Ed
|
||||
.El
|
||||
.Pp
|
||||
The user handler must return an appropiate SNMP v2 error code. If the original
|
||||
PDU was a version 1 PDU, the error code is mapped automatically.
|
||||
.It Va flags
|
||||
Currently only the flag
|
||||
.Li SNMP_NODE_CANSET is defined and set for nodes, that can be written or
|
||||
created.
|
||||
.It Va index
|
||||
This word describes the index for table columns. Each part of the index
|
||||
takes 4 bits starting at bit 4. Bits 0 to 3 hold the number of index parts.
|
||||
This arrangment allows for tables with up to seven indexes. Each bit group
|
||||
contains the syntax for the index part. There are a number of macros to
|
||||
help in parsing this field:
|
||||
.Bd -literal -offset indent
|
||||
#define SNMP_INDEXES_MAX 7
|
||||
#define SNMP_INDEX_SHIFT 4
|
||||
#define SNMP_INDEX_MASK 0xf
|
||||
#define SNMP_INDEX_COUNT(V) ((V) & SNMP_INDEX_MASK)
|
||||
#define SNMP_INDEX(V,I) \e
|
||||
(((V) >> (((I) + 1) * SNMP_INDEX_SHIFT)) & \e
|
||||
SNMP_INDEX_MASK)
|
||||
.Ed
|
||||
.It Va data
|
||||
This field may contain arbitrary data and is not used by the library.
|
||||
.El
|
||||
.Pp
|
||||
The easiest way to construct the node table is
|
||||
.Xr gensnmptree 1 .
|
||||
Note, that one must be careful when changing the tree while executing a SET
|
||||
operation. Consult the sources for
|
||||
.Xr snmpd 1 .
|
||||
.Pp
|
||||
The global variable
|
||||
.Va snmp_trace
|
||||
together with the function pointed to by
|
||||
.Va snmp_debug
|
||||
help in debugging the library and the agent.
|
||||
.Va snmp_trace is a bit mask with the following bits:
|
||||
.Bd -literal -offset indent
|
||||
enum {
|
||||
SNMP_TRACE_GET,
|
||||
SNMP_TRACE_GETNEXT,
|
||||
SNMP_TRACE_SET,
|
||||
SNMP_TRACE_DEPEND,
|
||||
SNMP_TRACE_FIND,
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
Setting a bit to true causes the library to call
|
||||
.Fn snmp_debug
|
||||
in strategic places with a debug string. The library contains a default
|
||||
implementation for the debug function that prints a message to standard error.
|
||||
.Pp
|
||||
Many of the functions use a so called context:
|
||||
.Bd -literal -offset indent
|
||||
struct snmp_context {
|
||||
u_int var_index;
|
||||
struct snmp_scratch *scratch;
|
||||
struct snmp_dependency *dep;
|
||||
void *data; /* user data */
|
||||
};
|
||||
|
||||
struct snmp_scratch {
|
||||
void *ptr1;
|
||||
void *ptr2;
|
||||
u_int32_t int1;
|
||||
u_int32_t int2;
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
The fields are used as follows:
|
||||
.Bl -tag -width ".It Va var_index"
|
||||
.It Va va_index
|
||||
For the node operation callback this is the
|
||||
index of the variable binding that should be returned if an error occures.
|
||||
Set by the library. In all other functions this is undefined.
|
||||
.It Va scratch
|
||||
For the node operation callback this is a pointer to a per variable binding
|
||||
scratch area that can be used to implement the commit and rollback. Set
|
||||
by the library.
|
||||
.It Va dep
|
||||
In the dependency callback function (see below) this is a pointer to the
|
||||
current dependency. Set by the library.
|
||||
.It Va data
|
||||
This is the
|
||||
.Fa data
|
||||
argument from the call to the library and is not used by the library.
|
||||
.El
|
||||
.Pp
|
||||
The next three functions execute different kinds of GET requests.
|
||||
The function
|
||||
.Fn snmp_get
|
||||
executes an SNMP GET operation, the function
|
||||
.Fn snmp_getnext
|
||||
executes an SNMP GETNEXT operation and the function
|
||||
.Fn snmp_getbulk
|
||||
executes an SNMP GETBULK operation.
|
||||
For all three functions the response PDU is constructed and encoded
|
||||
on the fly. If everything is ok, the response PDU is returned in
|
||||
.Fa resp
|
||||
and
|
||||
.Fa resp_b .
|
||||
The caller must call
|
||||
.Fn snmp_pdu_free
|
||||
to free the response PDU in this case. One of the following values may be
|
||||
returned:
|
||||
.Bl -tag -width ".It Li SNMP_RET_ERR"
|
||||
.It Li SNMP_RET_OK
|
||||
Operation successful, response PDU may be sent.
|
||||
.It Li SNMP_RET_IGN
|
||||
Operation failed, no response PDU constructed. Request is ignored.
|
||||
.It Li SNMP_RET_ERR
|
||||
Error in operation. The error code and index have been set in
|
||||
.Fa pdu .
|
||||
No response PDU has been constructed.
|
||||
The caller may construct an error response PDU via
|
||||
.Fn snmp_make_errresp .
|
||||
.El
|
||||
.Pp
|
||||
The function
|
||||
.Fn snmp_set
|
||||
executes an SNMP SET operation. The arguments are the same as for the previous
|
||||
three functions. The operation of this functions is, however, much more complex.
|
||||
.Pp
|
||||
The SET operation occures in several stages:
|
||||
.Bl -enum -offset indent
|
||||
.It
|
||||
For each binding search the corresponding nodes, check that the
|
||||
variable is writeable and the syntax is ok. The writeable check can be done
|
||||
only for scalars. For columns it must be done in the node's operation callback
|
||||
function.
|
||||
.It
|
||||
For each binding call the node's operation callback with function SNMP_OP_SET.
|
||||
The callback may create dependencies or finalizers (see below). For simple
|
||||
scalars the scratch area may be enough to handle commit and rollback, for
|
||||
interdependend table columns dependencies may be necessary.
|
||||
.It
|
||||
If the previous step fails at any point, the node's operation callback
|
||||
functions are called for all bindings for which SNMP_OP_SET was executed
|
||||
with SNMP_OP_ROLLBACK, in the opposite order. This allows all variables to
|
||||
undo the effect of the SET operation. After this all the dependencies
|
||||
are freed
|
||||
and the finalizers are executed with a fail flag of 1. Then the function
|
||||
returns to the caller with an appropriate error indication.
|
||||
.It
|
||||
If the SET step was successful for all bindings, the dependency callbacks
|
||||
are executed in the order in which the dependencies were created with an
|
||||
operation of SNMP_DEPOP_COMMIT. If any of the dependencies fails, all the
|
||||
committed dependencies are called again in the opposite order
|
||||
with SNMP_DEPOP_ROLLBACK. Than for all bindings from the last to the first
|
||||
the node's operation callback is called with SNMP_OP_ROLLBACK to undo
|
||||
the effect of SNMP_OP_SET. At the end the dependencies are freed
|
||||
and the finalizers are called with a fail flag
|
||||
of 1 and the function returns to the caller with an appropriate error indication.
|
||||
.It
|
||||
If the dependency commits were successful, for each binding the node's
|
||||
operation callback is called with SNMP_OP_COMMIT. Any error returned from
|
||||
the callbacks is ignored (an error message is generated via
|
||||
.Fn snmp_error ).
|
||||
.It
|
||||
Now the dependencies are freed and the finalizers are called
|
||||
with a fail flag of 0. Then the function returns
|
||||
.Li SNMP_ERR_OK .
|
||||
.El
|
||||
.Pp
|
||||
There are to mechanisms to help in complex SET operations: dependencies and
|
||||
finalizers. A dependency is used if several bindings depend on each other.
|
||||
A typical example is the creation of a conceptual row, which requires
|
||||
the setting of several columns to succeed. A dependency is identified by
|
||||
two OIDs. In the table case, the first oid is typically the table's base OID
|
||||
and the second one the index. Both of these can easily be generated from the
|
||||
variables OID with
|
||||
.Fn asn_slice_oid .
|
||||
The function
|
||||
.Fn snmp_dep_lookup
|
||||
tries to find a dependency based on these two OIDs and, if it cannot find one
|
||||
creates a new one. This means for the table example, that the function
|
||||
returns the same dependency for each of the columns of the same table row.
|
||||
This allows during the SNMP_OP_SET processing to collect all information
|
||||
about the row into the dependency. The arguments to
|
||||
.Fn snmp_dep_lookup
|
||||
are: the two OIDs to identify the dependency (they are copied into newly
|
||||
created dependencies), the size of the structure to allocate and
|
||||
the dependency callback.
|
||||
.Pp
|
||||
When all SNMP_OP_SET operations have succeeded the dependencies are executed.
|
||||
At this stage the dependency callback has all information about the given
|
||||
table row that was available in this SET PDU and can operate accordingly.
|
||||
.Pp
|
||||
If a SNMP_OP_SET operation fails, the dependency callbacks are never
|
||||
called. The nodes SNMP_OP_ROLLBACK operations have to ensure, that
|
||||
any dynamically allocated data is freed.
|
||||
.Pp
|
||||
Finalizers are a
|
||||
.Sq last change
|
||||
to do processing.
|
||||
They are called after everything has been done, just before returning to the
|
||||
user. They get a flag, that tells them, whether the return to the user is a good
|
||||
one or not. The typical use is to finally remove deleted table elements.
|
||||
Finalizers are created with
|
||||
.Fn snmp_set_atfinish
|
||||
which takes the callback function and a user data pointer as argument.
|
||||
.Pp
|
||||
The function
|
||||
.Fn snmp_make_errresp
|
||||
makes an error response if an operation has failed. It takes the original
|
||||
request PDU (it will look only on the error code and index fields), the
|
||||
buffer containing the original PDU and a buffer for the error PDU. It copies
|
||||
the bindings field from the original PDUs buffer directly to the response
|
||||
PDU and thus does not depend on the decodability of this field. It may return
|
||||
the same values as the operation functions.
|
||||
.Pp
|
||||
The next three functions allow some parts of the SET operation to be executed.
|
||||
This is only used in
|
||||
.Xr snmpd 1
|
||||
to implement the configuration as a single transaction.
|
||||
The function
|
||||
.Fn snmp_init_context
|
||||
creates and initializes a context.
|
||||
The function
|
||||
.Fn snmp_dep_commit
|
||||
executes SNMP_DEPOP_COMMIT for all dependencies in the context stopping at
|
||||
the first error.
|
||||
The function
|
||||
.Fn snmp_dep_rollback
|
||||
executes SNMP_DEPOP_ROLLBACK starting at the previous of the current
|
||||
dependency in the context.
|
||||
.Sh DIAGNOSTICS
|
||||
If an error occures in any of the function an error indication as described
|
||||
above is returned. Additionally the functions may call snmp_error on unexected
|
||||
errors.
|
||||
.Sh SEE ALSO
|
||||
.Xr snmpd 1 ,
|
||||
.Xr gensnmptree 1 ,
|
||||
.Xr bsnmplib 3
|
||||
.Xr bsnmpclient 3 ,
|
||||
.Xr snmpmod 3
|
||||
.Sh STANDARDS
|
||||
This implementation conforms to the applicable IETF RFCs and ITU-T
|
||||
recommendations.
|
||||
.Sh AUTHORS
|
||||
.An Hartmut Brandt Aq brandt@fokus.gmd.de
|
590
contrib/bsnmp/lib/bsnmpclient.3
Normal file
590
contrib/bsnmp/lib/bsnmpclient.3
Normal file
@ -0,0 +1,590 @@
|
||||
.\"
|
||||
.\" Copyright (c) 2001-2003
|
||||
.\" Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Author: Harti Brandt <harti@freebsd.org>
|
||||
.\"
|
||||
.\" Redistribution of this software and documentation 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 or documentation 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.
|
||||
.\" 3. Neither the name of the Institute nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
.\" AND ITS 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
|
||||
.\" FRAUNHOFER FOKUS OR ITS 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.
|
||||
.\"
|
||||
.\" $Begemot: bsnmp/lib/bsnmpclient.3,v 1.3 2002/12/11 15:54:07 hbb Exp $
|
||||
.\"
|
||||
.Dd August 15, 2002
|
||||
.Dt bsnmpclient 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm snmp_client ,
|
||||
.Nm snmp_send_cb_f ,
|
||||
.Nm snmp_timeout_cb_f ,
|
||||
.Nm snmp_timeout_start_f ,
|
||||
.Nm snmp_timeout_stop_f ,
|
||||
.Nm snmp_open ,
|
||||
.Nm snmp_close ,
|
||||
.Nm snmp_pdu_create ,
|
||||
.Nm snmp_add_binding ,
|
||||
.Nm snmp_pdu_check ,
|
||||
.Nm snmp_pdu_send ,
|
||||
.Nm snmp_oid_append ,
|
||||
.Nm snmp_receive ,
|
||||
.Nm snmp_table_cb_f ,
|
||||
.Nm snmp_table_fetch ,
|
||||
.Nm snmp_table_fetch_async ,
|
||||
.Nm snmp_dialog
|
||||
.Nd "SNMP client library"
|
||||
.Sh LIBRARY
|
||||
Begemot SNMP library
|
||||
.Pq libbsnmp, -lbsnmp
|
||||
.Sh SYNOPSIS
|
||||
.In asn1.h
|
||||
.In snmp.h
|
||||
.In snmpclient.h
|
||||
.Ft typedef void
|
||||
.Fn (*snmp_send_cb_f) "struct snmp_pdu *req" "struct snmp_pdu *resp" "void *uarg"
|
||||
.Ft typedef void
|
||||
.Fn (*snmp_timeout_cb_f) "void *uarg"
|
||||
.Ft typedef void *
|
||||
.Fn (*snmp_timeout_start_f) "struct timeval *timeout" "snmp_timeout_cb_f callback" "void *uarg"
|
||||
.Ft typedef void
|
||||
.Fn (*snmp_timeout_stop_f) "void *timeout_id"
|
||||
.Vt extern struct snmp_client snmp_client ;
|
||||
.Ft void
|
||||
.Fn snmp_client_init "struct snmp_client *client"
|
||||
.Ft int
|
||||
.Fn snmp_client_set_host "struct snmp_client *client" "const char *host"
|
||||
.Ft int
|
||||
.Fn snmp_client_set_port "struct snmp_client *client" "const char *port"
|
||||
.Ft int
|
||||
.Fn snmp_open "const char *host" "const char *port" "const char *read_community" "const char *write_community"
|
||||
.Ft void
|
||||
.Fn snmp_close "void"
|
||||
.Ft void
|
||||
.Fn snmp_pdu_create "struct snmp_pdu *pdu" "u_int op"
|
||||
.Ft int
|
||||
.Fn snmp_add_binding "struct snmp_pdu *pdu" "..."
|
||||
.Ft int
|
||||
.Fn snmp_pdu_check "const struct snmp_pdu *req" "const struct snmp_pdu *resp"
|
||||
.Ft int32_t
|
||||
.Fn snmp_pdu_send "struct snmp_pdu *pdu" "snmp_send_cb_f func" "void *uarg"
|
||||
.Ft int
|
||||
.Fn snmp_oid_append "struct asn_oid *oid" "const char *fmt" "..."
|
||||
.Ft int
|
||||
.Fn snmp_receive "int blocking"
|
||||
.Ft typedef void
|
||||
.Fn (*snmp_table_cb_f) "void *list" "void *arg" "int res"
|
||||
.Ft int
|
||||
.Fn snmp_table_fetch "const struct snmp_table *descr" "void *list"
|
||||
.Ft int
|
||||
.Fn snmp_table_fetch_async "const struct snmp_table *descr" "void *list" "snmp_table_cb_f callback" "void *uarg"
|
||||
.Ft int
|
||||
.Fn snmp_dialog "struct snmp_pdu *req" "struct snmp_pdu *resp"
|
||||
.Sh DESCRIPTION
|
||||
The SNMP library contains routines to easily build SNMP client applications
|
||||
that use SNMP versions 1 or 2. Most of the routines use a
|
||||
.Vt struct snmp_client :
|
||||
.Bd -literal -offset indent
|
||||
struct snmp_client {
|
||||
enum snmp_version version;
|
||||
int local; /* use local socket */
|
||||
|
||||
/* these two are read-only for the application */
|
||||
char *cport; /* port number as string */
|
||||
char *chost; /* host name or IP address as string */
|
||||
|
||||
char read_community[SNMP_COMMUNITY_MAXLEN + 1];
|
||||
char write_community[SNMP_COMMUNITY_MAXLEN + 1];
|
||||
|
||||
struct timeval timeout;
|
||||
u_int retries;
|
||||
|
||||
int dump_pdus;
|
||||
|
||||
size_t txbuflen;
|
||||
size_t rxbuflen;
|
||||
|
||||
int fd;
|
||||
|
||||
int32_t next_reqid;
|
||||
int32_t max_reqid;
|
||||
int32_t min_reqid;
|
||||
|
||||
char error[SNMP_STRERROR_LEN];
|
||||
|
||||
snmp_timeout_start_f timeout_start;
|
||||
snmp_timeout_stop_f timeout_stop;
|
||||
|
||||
/* private */
|
||||
char local_path[sizeof(SNMP_LOCAL_PATH)];
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
The fields of this structure are described below.
|
||||
.Bl -tag -width "timeout_start"
|
||||
.It Va version
|
||||
This is the version of SNMP to use. See
|
||||
.Xr bsnmplib 3
|
||||
for applicable values. The default version is
|
||||
.Li SNMP_V2c .
|
||||
.It Va local
|
||||
If this is set to true, the library opens a
|
||||
.Ux
|
||||
domain socket rather than
|
||||
an UDP socket. It uses the
|
||||
.Va chost
|
||||
field as the path to the server's socket.
|
||||
.It Va cport
|
||||
The SNMP agent's UDP port number. This may be a symbolic port number (from
|
||||
.Pa /etc/services
|
||||
or a numeric port number. If this field is
|
||||
.Li NULL
|
||||
(the default) the standard SNMP port is used. This field should not be changed
|
||||
directly but rather by calling
|
||||
.Fn snmp_client_set_port .
|
||||
.It Va chost
|
||||
The SNMP agent's host name, IP address or
|
||||
.Ux
|
||||
domain socket path name.
|
||||
If this is
|
||||
.Li NULL
|
||||
(the default)
|
||||
.Li localhost
|
||||
is assumed. This field should not be changed directly but rather through
|
||||
calling
|
||||
.Fn snmp_client_set_host .
|
||||
.It Va read_community
|
||||
This is the community name to be used for all requests except SET requests.
|
||||
The default is
|
||||
.Sq public .
|
||||
.It Va write_community
|
||||
The community name to be used for SET requests. The default is
|
||||
.Sq private .
|
||||
.It Va timeout
|
||||
The maximum time to wait for responses to requests. If the time elapses, the
|
||||
request is resent up to
|
||||
.Va retries
|
||||
times. The default is 3 seconds.
|
||||
.It Va retries
|
||||
Number of times a request PDU is to be resent. If set to 0, the request is
|
||||
sent only once. The default is 3 retransmissions.
|
||||
.It Va dump_pdus
|
||||
If set to a non-zero value all received and sent PDUs are dumped via
|
||||
.Xr snmp_pdu_dump 3 .
|
||||
The default is not to dump PDUs.
|
||||
.It Va txbuflen
|
||||
The encoding buffer size to be allocated for transmitted PDUs. The default is
|
||||
10000 octets.
|
||||
.It Va rxbuflen
|
||||
The decoding buffer size to be allocated for received PDUs. This is the size
|
||||
of the maximum PDU that can be received. The default is 10000 octets.
|
||||
.It Va fd
|
||||
After calling
|
||||
.Fn snmp_open
|
||||
this is the file socket file descriptor used for sending and receiving PDUs.
|
||||
.It Va next_reqid
|
||||
The request id of the next PDU to send. Used internal by the library.
|
||||
.It Va max_reqid
|
||||
The maximum request id to use for outging PDUs. The default is
|
||||
.Li INT32_MAX .
|
||||
.It Va min_reqid
|
||||
The minimum request id to use for outgoing PDUs. Request ids are allocated
|
||||
linerily starting at
|
||||
.Va min_reqid
|
||||
up to
|
||||
.Va max_reqid .
|
||||
.It Va error
|
||||
If an error happens, this field is set to a printable string describing the
|
||||
error.
|
||||
.It Va timeout_start
|
||||
This field must point to a function setting up a one shot timeout. After the
|
||||
timeout has elapsed, the given callback function must be called with the
|
||||
user argument. The
|
||||
.Fn timeout_start
|
||||
function must return a
|
||||
.Vt void *
|
||||
identifying the timeout.
|
||||
.It Va timeout_stop
|
||||
This field must be set to a function that stops a running timeout. The function
|
||||
will be called with the return value of the corresponding
|
||||
.Fn timeout_start
|
||||
function.
|
||||
.It Va local_path
|
||||
If in local socket mode, the name of the clients socket. Not needed by the
|
||||
application.
|
||||
.El
|
||||
.Pp
|
||||
In the current implementation there is a global variable
|
||||
.Bd -unfilled -offset indent
|
||||
.Vt extern struct snmp_client snmp_client ;
|
||||
.Ed
|
||||
.Pp
|
||||
that is used by all the library functions. The first call into the library must
|
||||
be a call to
|
||||
.Fn snmp_client_init
|
||||
to initialize this global variable to the default values.
|
||||
After this call and before calling
|
||||
.Fn snmp_open
|
||||
the fields of the variable may be modified by the user.
|
||||
The modification of the
|
||||
.Va chost
|
||||
and
|
||||
.Va cport
|
||||
fields should be done only via the functions
|
||||
.Fn snmp_client_set_host
|
||||
and
|
||||
.Fn snmp_client_set_port .
|
||||
.Pp
|
||||
The function
|
||||
.Fn snmp_open
|
||||
creates a UDP or
|
||||
.Ux
|
||||
domain socket and connects it to the agent's IP address and port.
|
||||
If any of the arguments of the call is not
|
||||
.Li NULL
|
||||
the corresponding field in the global
|
||||
.Va snmp_client
|
||||
is set from the argument. Otherwise the values that are already in that variable
|
||||
are used.
|
||||
The function
|
||||
.Fn snmp_close
|
||||
closes the socket, stops all timeouts and frees all dynamically allocated
|
||||
resources.
|
||||
.Pp
|
||||
The next three functions are used to create request PDUs. The function
|
||||
.Fn snmp_pdu_create
|
||||
initializes a PDU of type
|
||||
.Va op .
|
||||
It does not allocate space for the PDU itself. This is the responsibility of
|
||||
the caller.
|
||||
.Fn snmp_add_binding
|
||||
adds bindings to the PDU and returns the (zero based) index of the first new
|
||||
binding. The arguments are pairs of pointer to the OIDs and syntax constants,
|
||||
terminated by a NULL. The call
|
||||
.Bd -literal -offset indent
|
||||
snmp_add_binding(&pdu,
|
||||
&oid1, SNMP_SYNTAX_INTEGER,
|
||||
&oid2, SNMP_SYNTAX_OCTETSTRING,
|
||||
NULL);
|
||||
.Ed
|
||||
.Pp
|
||||
adds two new bindings to the PDU and returns the index of the first one.
|
||||
It is the responsibility of the caller to set the value part of the binding
|
||||
if neccesary. The functions returns -1 if the maximum number of bindings
|
||||
is exhausted.
|
||||
The function
|
||||
.Fn snmp_oid_append
|
||||
can be used to construct variable OIDs for requests. It takes a pointer
|
||||
to an
|
||||
.Vt struct asn_oid
|
||||
that is to be constructed, a format string, and a number of arguments
|
||||
the type of which depends on the format string. The format string is interpreted
|
||||
character by character in the following way:
|
||||
.Bl -tag -width ".It Li ( Va N Ns Li )"
|
||||
.It Li i
|
||||
This format expects an argument of type
|
||||
.Vt asn_subid_t
|
||||
and appends this as a single integer to the OID.
|
||||
.It Li a
|
||||
This format expects an argument of type
|
||||
.Vt struct in_addr
|
||||
and appends to four parts of the IP address to the OID.
|
||||
.It Li s
|
||||
This format expects an argument of type
|
||||
.Vt const char *
|
||||
and appends the length of the string (as computed by
|
||||
.Xr strlen 3 )
|
||||
and each of the characters in the string to the OID.
|
||||
.It Li ( Va N Ns Li )
|
||||
This format expects no argument.
|
||||
.Va N
|
||||
must be a decimal number and is stored into an internal variable
|
||||
.Va size .
|
||||
.It Li b
|
||||
This format expects an argument of type
|
||||
.Vt const char *
|
||||
and appends
|
||||
.Va size
|
||||
characters from the string to the OID. The string may contain
|
||||
.Li NUL
|
||||
characters.
|
||||
.It Li c
|
||||
This format expects two arguments: one of type
|
||||
.Vt size_t
|
||||
and one of type
|
||||
.Vt const u_char * .
|
||||
The first argument gives the number of bytes to append to the OID from the string
|
||||
pointed to by the second argument.
|
||||
.El
|
||||
.Pp
|
||||
The function
|
||||
.Fn snmp_pdu_check
|
||||
may be used to check a response PDU. A number of checks are performed
|
||||
(error code, equal number of bindings, syntaxes and values for SET PDUs).
|
||||
The function returns +1 if everything is ok, 0 if a NOSUCHNAME or similar
|
||||
error was detected, -1 if the response PDU had fatal errors
|
||||
and -2 if
|
||||
.Fa resp
|
||||
is
|
||||
.Li NULL
|
||||
(a timeout occured).
|
||||
.Pp
|
||||
The function
|
||||
.Fn snmp_pdu_send
|
||||
encodes and sends the given PDU. It records the PDU together with the callback
|
||||
and user pointers in an internal list and arranges for retransmission if no
|
||||
response is received. When a response is received or the retransmission count
|
||||
is exceeded the callback
|
||||
.Fa func
|
||||
is called with the orignal request PDU, the response PDU and the user argument
|
||||
.Fa uarg .
|
||||
If the retransmit count is exceeded,
|
||||
.Fa func
|
||||
is called with the original request PDU, the reponse pointer set to
|
||||
.Li NULL
|
||||
and the user argument
|
||||
.Fa uarg .
|
||||
The caller should not free the request PDU until the callback function is
|
||||
called. The callback function must free the request PDU and the response
|
||||
PDU (if not
|
||||
.Li NULL ).
|
||||
.Pp
|
||||
The function
|
||||
.Fn snmp_receive
|
||||
tries to receive a PDU. If the argument is zero, the function polls to see
|
||||
whether a packet is available, if the argument is non-zero, the function blocks
|
||||
until the next packet is received. The packet is delivered via the usual callback
|
||||
mechanism (non-response packets are silently dropped).
|
||||
The function returns 0, if a packet was received and successfully dispatched,
|
||||
-1 if an error occured or no packet was available (in polling mode).
|
||||
.Pp
|
||||
The next two functions are used to retrieve tables from SNMP agents. The use
|
||||
the following input structure, that describes the table:
|
||||
.Bd -literal -offset indent
|
||||
struct snmp_table {
|
||||
struct asn_oid table;
|
||||
struct asn_oid last_change;
|
||||
u_int max_iter;
|
||||
size_t entry_size;
|
||||
u_int index_size;
|
||||
u_int64_t req_mask;
|
||||
|
||||
struct snmp_table_entry {
|
||||
asn_subid_t subid;
|
||||
enum snmp_syntax syntax;
|
||||
off_t offset;
|
||||
} entries[];
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
The fields of this structure have the following meaning:
|
||||
.Bl -tag -width "last_change"
|
||||
.It Va table
|
||||
This is the base OID of the table.
|
||||
.It Va last_change
|
||||
Some tables have a scalar variable of type TIMETICKS attached to them,
|
||||
that holds the time when the table was last changed. This OID should be
|
||||
the OID of this variable (without the \&.0 index). When the table is retrieved
|
||||
with multiple GET requests, and the variable changes between two request,
|
||||
the table fetch is restarted.
|
||||
.It Va max_iter
|
||||
Maximum number of tries to fetch the table.
|
||||
.It Va entry_size
|
||||
The table fetching routines return a list of structure one for each table
|
||||
row. This variable is the size of one structure and used to
|
||||
.Xr malloc 3
|
||||
the structure.
|
||||
.It Va index_size
|
||||
This is the number of index columns in the table.
|
||||
.It Va req_mask
|
||||
This is a bit mask with a 1 for each table column that is required.
|
||||
Bit 0 corresponds to the first element (index 0) in the array
|
||||
.Va entries ,
|
||||
bit 1 to the second (index 1) and so on. SNMP tables may be sparse. For sparse
|
||||
columns the bit should not be set. If the bit for a given column is set and
|
||||
the column value cannot be retrieved for a given row, the table fetch is
|
||||
restarted assuming that the table is currently beeing modified by the agent.
|
||||
The bits for the index columns are ignored.
|
||||
.It Va entries
|
||||
This is a variable sized array of column descriptors. This array is terminated
|
||||
by an element with syntax
|
||||
.Li SNMP_SYNTAX_NULL .
|
||||
The first
|
||||
.Va index_size
|
||||
elements describe all the index columns of the table, the rest are normal
|
||||
columns. If for a the column at
|
||||
.Ql entries[N]
|
||||
the expression
|
||||
.Ql req_mask & (1 << N)
|
||||
yields true, the column is considered a required column.
|
||||
The fields of this the array elements have the following meaning:
|
||||
.Bl -tag -width "syntax"
|
||||
.It Va subid
|
||||
This is the OID subid of the column. This is ignored for index entries. Index
|
||||
entries are decoded according to the
|
||||
.Va syntax
|
||||
field.
|
||||
.It Va syntax
|
||||
This is the syntax of the column or index. A syntax of
|
||||
.Li SNMP_SYNTAX_NULL
|
||||
terminates the array.
|
||||
.It Va offset
|
||||
This is the starting offset of the value of the column in the return structures.
|
||||
This field can be set with the ISO-C
|
||||
.Fn offsetof
|
||||
macro.
|
||||
.El
|
||||
.El
|
||||
.Pp
|
||||
Both table fetching functions return TAILQ (see
|
||||
.Xr queue 3 )
|
||||
of structures--one for each table row. These structures must start with a
|
||||
.Fn TAILQ_ENTRY
|
||||
and a
|
||||
.Vt u_int64_t
|
||||
and are allocated via
|
||||
.Xr malloc 3 .
|
||||
The
|
||||
.Fa list
|
||||
argument of the table functions must point to a
|
||||
.Fn TAILQ_HEAD .
|
||||
The
|
||||
.Vt u_int64_t
|
||||
fields, usually called
|
||||
.Va found
|
||||
is used to indicate which of the columns have been found for the given
|
||||
row. It is encoded like the
|
||||
.Fa req_mask
|
||||
field.
|
||||
.Pp
|
||||
The function
|
||||
.Fn snmp_table_fetch
|
||||
synchronuosly fetches the given table. If everything is ok 0 is returned.
|
||||
Otherwise the function returns -1 and sets an appropriate error string.
|
||||
The function
|
||||
.Fn snmp_table_fetch_async
|
||||
fetches the tables asynchronuosly. If either the entire table is fetch, or
|
||||
an error occures the callback function
|
||||
.Fa callback
|
||||
is called with the callers arguments
|
||||
.Fa list
|
||||
and
|
||||
.Fa uarg
|
||||
and a parameter that is either 0 if the table was fetched, or
|
||||
-1 if there was an error. The function itself returns -1 if it could not
|
||||
initialize fetching of the table.
|
||||
.Pp
|
||||
The following table description is used to fetch the ATM interface table:
|
||||
.Bd -literal -offset indent
|
||||
/*
|
||||
* ATM interface table
|
||||
*/
|
||||
struct atmif {
|
||||
TAILQ_ENTRY(atmif) link;
|
||||
u_int64_t found;
|
||||
int32_t index;
|
||||
u_char *ifname;
|
||||
size_t ifnamelen;
|
||||
u_int32_t node_id;
|
||||
u_int32_t pcr;
|
||||
int32_t media;
|
||||
u_int32_t vpi_bits;
|
||||
u_int32_t vci_bits;
|
||||
u_int32_t max_vpcs;
|
||||
u_int32_t max_vccs;
|
||||
u_char *esi;
|
||||
size_t esilen;
|
||||
int32_t carrier;
|
||||
};
|
||||
TAILQ_HEAD(atmif_list, atmif);
|
||||
|
||||
/* list of all ATM interfaces */
|
||||
struct atmif_list atmif_list;
|
||||
|
||||
static const struct snmp_table atmif_table = {
|
||||
OIDX_begemotAtmIfTable,
|
||||
OIDX_begemotAtmIfTableLastChange, 2,
|
||||
sizeof(struct atmif),
|
||||
1, 0x7ffULL,
|
||||
{
|
||||
{ 0, SNMP_SYNTAX_INTEGER,
|
||||
offsetof(struct atmif, index) },
|
||||
{ 1, SNMP_SYNTAX_OCTETSTRING,
|
||||
offsetof(struct atmif, ifname) },
|
||||
{ 2, SNMP_SYNTAX_GAUGE,
|
||||
offsetof(struct atmif, node_id) },
|
||||
{ 3, SNMP_SYNTAX_GAUGE,
|
||||
offsetof(struct atmif, pcr) },
|
||||
{ 4, SNMP_SYNTAX_INTEGER,
|
||||
offsetof(struct atmif, media) },
|
||||
{ 5, SNMP_SYNTAX_GAUGE,
|
||||
offsetof(struct atmif, vpi_bits) },
|
||||
{ 6, SNMP_SYNTAX_GAUGE,
|
||||
offsetof(struct atmif, vci_bits) },
|
||||
{ 7, SNMP_SYNTAX_GAUGE,
|
||||
offsetof(struct atmif, max_vpcs) },
|
||||
{ 8, SNMP_SYNTAX_GAUGE,
|
||||
offsetof(struct atmif, max_vccs) },
|
||||
{ 9, SNMP_SYNTAX_OCTETSTRING,
|
||||
offsetof(struct atmif, esi) },
|
||||
{ 10, SNMP_SYNTAX_INTEGER,
|
||||
offsetof(struct atmif, carrier) },
|
||||
{ 0, SNMP_SYNTAX_NULL, 0 }
|
||||
}
|
||||
};
|
||||
|
||||
\&...
|
||||
if (snmp_table_fetch(&atmif_table, &atmif_list) != 0)
|
||||
errx(1, "AtmIf table: %s", snmp_client.error);
|
||||
\&...
|
||||
.Ed
|
||||
.Pp
|
||||
The function
|
||||
.Fn snmp_dialog
|
||||
is used to execute a synchonuous dialog with the agent. The request PDU
|
||||
.Fa req
|
||||
is sent and the function blocks until the response PDU is received. Note,
|
||||
that asynchonuous receives are handled (i.e. callback functions of other send
|
||||
calls or table fetches may be called while in the function). The response
|
||||
PDU is returned in
|
||||
.Fa resp .
|
||||
If no reponse could be received after all timeouts and retries, the function
|
||||
returns -1. If a response was received 0 is returned.
|
||||
.Sh DIAGNOSTICS
|
||||
If an error occures in any of the function an error indication as described
|
||||
above is returned. Additionally the function sets a printable error string
|
||||
in the
|
||||
.Va error
|
||||
filed of
|
||||
.Va snmp_client .
|
||||
.Sh SEE ALSO
|
||||
.Xr snmpd 1 ,
|
||||
.Xr gensnmptree 1 ,
|
||||
.Xr bsnmplib 3
|
||||
.Xr bsnmpagent 3
|
||||
.Sh STANDARDS
|
||||
This implementation conforms to the applicable IETF RFCs and ITU-T
|
||||
recommendations.
|
||||
.Sh AUTHORS
|
||||
.An Hartmut Brandt Aq brandt@fokus.gmd.de
|
||||
.An Kendy Kutzner Aq kutzner@fokus.gmd.de
|
306
contrib/bsnmp/lib/bsnmplib.3
Normal file
306
contrib/bsnmp/lib/bsnmplib.3
Normal file
@ -0,0 +1,306 @@
|
||||
.\"
|
||||
.\" Copyright (c) 2001-2003
|
||||
.\" Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Author: Harti Brandt <harti@freebsd.org>
|
||||
.\"
|
||||
.\" Redistribution of this software and documentation 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 or documentation 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.
|
||||
.\" 3. Neither the name of the Institute nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
.\" AND ITS 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
|
||||
.\" FRAUNHOFER FOKUS OR ITS 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.
|
||||
.\"
|
||||
.\" $Begemot: bsnmp/lib/bsnmplib.3,v 1.2 2002/08/16 10:02:53 hbb Exp $
|
||||
.\"
|
||||
.Dd August 15, 2002
|
||||
.Dt bsnmplib 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm snmp_value_free ,
|
||||
.Nm snmp_value_parse ,
|
||||
.Nm snmp_value_copy ,
|
||||
.Nm snmp_pdu_free ,
|
||||
.Nm snmp_code snmp_pdu_decode ,
|
||||
.Nm snmp_code snmp_pdu_encode ,
|
||||
.Nm snmp_pdu_dump ,
|
||||
.Nm TRUTH_MK ,
|
||||
.Nm TRUTH_GET ,
|
||||
.Nm TRUTH_OK
|
||||
.Nd "SNMP decoding and encoding library"
|
||||
.Sh LIBRARY
|
||||
Begemot SNMP library
|
||||
.Pq libbsnmp, -lbsnmp
|
||||
.Sh SYNOPSIS
|
||||
.In bsnmp/asn1.h
|
||||
.In bsnmp/snmp.h
|
||||
.Ft void
|
||||
.Fn snmp_value_free "struct snmp_value *value"
|
||||
.Ft int
|
||||
.Fn snmp_value_parse "const char *buf" "enum snmp_syntax" "union snmp_values *value"
|
||||
.Ft int
|
||||
.Fn snmp_value_copy "struct snmp_value *to" "const struct snmp_value *from"
|
||||
.Ft void
|
||||
.Fn snmp_pdu_free "struct snmp_pdu *value"
|
||||
.Ft enum snmp_code
|
||||
.Fn snmp_pdu_decode "struct asn_buf *buf" "struct snmp_pdu *pdu" "int32_t *ip"
|
||||
.Ft enum snmp_code
|
||||
.Fn snmp_pdu_encode "struct snmp_pdu *pdu" "struct asn_buf *buf"
|
||||
.Ft void
|
||||
.Fn snmp_pdu_dump "const struct snmp_pdu *pdu"
|
||||
.Ft int
|
||||
.Fn TRUTH_MK "F"
|
||||
.Ft int
|
||||
.Fn TRUTH_GET "T"
|
||||
.Ft int
|
||||
.Fn TRUTH_OK "T"
|
||||
.Sh DESCRIPTION
|
||||
The SNMP library contains routines to handle SNMP version 1 and 2 PDUs.
|
||||
There are two basic structures used throughout the library:
|
||||
.Bd -literal -offset indent
|
||||
struct snmp_value {
|
||||
struct asn_oid var;
|
||||
enum snmp_syntax syntax;
|
||||
union snmp_values {
|
||||
int32_t integer;/* also integer32 */
|
||||
struct {
|
||||
u_int len;
|
||||
u_char *octets;
|
||||
} octetstring;
|
||||
struct asn_oid oid;
|
||||
u_char ipaddress[4];
|
||||
u_int32_t uint32; /* also gauge32, counter32,
|
||||
unsigned32, timeticks */
|
||||
u_int64_t counter64;
|
||||
} v;
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
This structure represents one variable binding from an SNMP PDU. The
|
||||
field
|
||||
.Fa var
|
||||
is the ASN.1 of the variable that is bound.
|
||||
.Fa syntax
|
||||
contains either the syntax code of the value or an exception code for SNMPv2
|
||||
and may be one of:
|
||||
.Bd -literal -offset indent
|
||||
enum snmp_syntax {
|
||||
SNMP_SYNTAX_NULL = 0,
|
||||
SNMP_SYNTAX_INTEGER, /* == INTEGER32 */
|
||||
SNMP_SYNTAX_OCTETSTRING,
|
||||
SNMP_SYNTAX_OID,
|
||||
SNMP_SYNTAX_IPADDRESS,
|
||||
SNMP_SYNTAX_COUNTER,
|
||||
SNMP_SYNTAX_GAUGE, /* == UNSIGNED32 */
|
||||
SNMP_SYNTAX_TIMETICKS,
|
||||
|
||||
/* v2 additions */
|
||||
SNMP_SYNTAX_COUNTER64,
|
||||
/* exceptions */
|
||||
SNMP_SYNTAX_NOSUCHOBJECT,
|
||||
SNMP_SYNTAX_NOSUCHINSTANCE,
|
||||
SNMP_SYNTAX_ENDOFMIBVIEW,
|
||||
};
|
||||
.Ed
|
||||
The field
|
||||
.Fa v
|
||||
holds the actual value depending on
|
||||
.Fa syntax .
|
||||
Note, that if
|
||||
.Fa syntax
|
||||
is
|
||||
.Li SNMP_SYNTAX_OCTETSTRING
|
||||
and
|
||||
.Fa v.octetstring.len
|
||||
is not zero,
|
||||
.Fa v.octetstring.octets
|
||||
points to a string allocated by
|
||||
.Xr malloc 3 .
|
||||
.Pp
|
||||
.Bd -literal -offset indent
|
||||
#define SNMP_COMMUNITY_MAXLEN 128
|
||||
#define SNMP_MAX_BINDINGS 100
|
||||
|
||||
struct snmp_pdu {
|
||||
char community[SNMP_COMMUNITY_MAXLEN + 1];
|
||||
enum snmp_version version;
|
||||
u_int type;
|
||||
|
||||
/* trap only */
|
||||
struct asn_oid enterprise;
|
||||
u_char agent_addr[4];
|
||||
int32_t generic_trap;
|
||||
int32_t specific_trap;
|
||||
u_int32_t time_stamp;
|
||||
|
||||
/* others */
|
||||
int32_t request_id;
|
||||
int32_t error_status;
|
||||
int32_t error_index;
|
||||
|
||||
/* fixes for encoding */
|
||||
u_char *outer_ptr;
|
||||
u_char *pdu_ptr;
|
||||
u_char *vars_ptr;
|
||||
|
||||
struct snmp_value bindings[SNMP_MAX_BINDINGS];
|
||||
u_int nbindings;
|
||||
};
|
||||
.Ed
|
||||
This structure contains a decoded SNMP PDU.
|
||||
.Fa version
|
||||
is one of
|
||||
.Bd -literal -offset indent
|
||||
enum snmp_version {
|
||||
SNMP_Verr = 0,
|
||||
SNMP_V1 = 1,
|
||||
SNMP_V2c,
|
||||
};
|
||||
.Ed
|
||||
and
|
||||
.Fa type
|
||||
is the type of the PDU.
|
||||
.Pp
|
||||
The function
|
||||
.Fn snmp_value_free
|
||||
is used to free all the dynamic allocated contents of an SNMP value. It does
|
||||
not free the structure pointed to by
|
||||
.Fa value
|
||||
itself.
|
||||
.Pp
|
||||
The function
|
||||
.Fn snmp_value_parse
|
||||
parses the ASCII representation of an SNMP value into its binary form.
|
||||
This function is mainly used by the configuration file reader of
|
||||
.Xr snmpd 1 .
|
||||
.Pp
|
||||
The function
|
||||
.Fn snmp_value_copy
|
||||
makes a deep copy of the value pointed to by
|
||||
.Fa from
|
||||
to the structure pointed to by
|
||||
.Fa to .
|
||||
It assumes that
|
||||
.Fa to
|
||||
is uninitialized and will overwrite its previous contents. It does not itself
|
||||
allocate the structure pointed to by
|
||||
.Fa to .
|
||||
.Pp
|
||||
The function
|
||||
.Fn snmp_pdu_free
|
||||
frees all the dynamically allocated components of the PDU. It does not itself
|
||||
free the structure pointed to by
|
||||
.Fa pdu .
|
||||
.Pp
|
||||
The function
|
||||
.Fn snmp_pdu_decode
|
||||
decodes the PDU pointed to by
|
||||
.Fa buf
|
||||
and stores the result into
|
||||
.Fa pdu .
|
||||
If an error occurs in a variable binding the (1 based) index of this binding
|
||||
is stored in the variable pointed to by
|
||||
.Fa ip .
|
||||
.Pp
|
||||
The function
|
||||
.Fn snmp_pdu_encode
|
||||
encodes the PDU
|
||||
.Fa pdu
|
||||
into the an octetstring in buffer
|
||||
.Fa buf .
|
||||
.Pp
|
||||
The function
|
||||
.Fn snmp_pdu_dump
|
||||
dumps the PDU in a human readable form by calling
|
||||
.Fn snmp_printf .
|
||||
.Pp
|
||||
The function
|
||||
.Fn TRUTH_MK
|
||||
takes a C truth value (zero or non-zero) and makes an SNMP truth value (2 or 1).
|
||||
The function
|
||||
.Fn TRUTH_GET
|
||||
takes an SNMP truth value and makes a C truth value (0 or 1).
|
||||
The function
|
||||
.Fn TRUTH_OK
|
||||
checks, whether its argument is a legal SNMP truth value.
|
||||
.Sh DIAGNOSTICS
|
||||
When an error occures in any of the function the function pointed to
|
||||
by the global pointer
|
||||
.Bd -literal -offset indent
|
||||
extern void (*snmp_error)(const char *, ...);
|
||||
.Ed
|
||||
.Pp
|
||||
with a
|
||||
.Xr printf 3
|
||||
style format string.
|
||||
There is a default error handler in the library that prints a message
|
||||
starting with
|
||||
.Sq SNMP:
|
||||
followed by the error message to standard error.
|
||||
.Pp
|
||||
The function pointed to by
|
||||
.Bd -literal -offset indent
|
||||
extern void (*snmp_printf)(const char *, ...);
|
||||
.Ed
|
||||
.Pp
|
||||
is called by the
|
||||
.Fn snmp_pdu_dump
|
||||
function.
|
||||
The default handler is
|
||||
.Xr printf 3 .
|
||||
.Sh ERRORS
|
||||
.Fn snmp_pdu_decode
|
||||
will return one of the following return codes:
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er SNMP_CODE_OK
|
||||
Success.
|
||||
.It Bq Er SNMP_CODE_FAILED
|
||||
The ASN.1 coding was wrong.
|
||||
.It Bq Er SNMP_CODE_BADLEN
|
||||
A variable binding value had a wrong length field.
|
||||
.It Bq Er SNMP_CODE_OORANGE
|
||||
A variable binding value was out of the allowed range.
|
||||
.It Bq Er SNMP_CODE_BADVERS
|
||||
The PDU is of an unsupported version.
|
||||
.It Bq Er SNMP_CODE_BADENQ
|
||||
There was an ASN.1 value with an unsupported tag.
|
||||
.El
|
||||
.Pp
|
||||
.Fn snmp_pdu_encode
|
||||
will return one of the following return codes:
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er SNMP_CODE_OK
|
||||
Success.
|
||||
.It Bq Er SNMP_CODE_FAILED
|
||||
Encoding failed.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr snmpd 1 ,
|
||||
.Xr gensnmptree 1 ,
|
||||
.Xr bsnmplib 3
|
||||
.Xr bsnmpclient 3 ,
|
||||
.Xr bsnmpagent 3
|
||||
.Sh STANDARDS
|
||||
This implementation conforms to the applicable IETF RFCs and ITU-T
|
||||
recommendations.
|
||||
.Sh AUTHORS
|
||||
.An Hartmut Brandt Aq brandt@fokus.gmd.de
|
1027
contrib/bsnmp/lib/snmp.c
Normal file
1027
contrib/bsnmp/lib/snmp.c
Normal file
File diff suppressed because it is too large
Load Diff
176
contrib/bsnmp/lib/snmp.h
Normal file
176
contrib/bsnmp/lib/snmp.h
Normal file
@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003
|
||||
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Harti Brandt <harti@freebsd.org>
|
||||
*
|
||||
* Redistribution of this software and documentation 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 or documentation 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.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
* AND ITS 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
|
||||
* FRAUNHOFER FOKUS OR ITS 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.
|
||||
*
|
||||
* $Begemot: bsnmp/lib/snmp.h,v 1.27 2002/03/08 14:24:58 hbb Exp $
|
||||
*
|
||||
* Header file for SNMP functions.
|
||||
*/
|
||||
#ifndef snmp_h_
|
||||
#define snmp_h_
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#define SNMP_COMMUNITY_MAXLEN 128
|
||||
#define SNMP_MAX_BINDINGS 100
|
||||
|
||||
enum snmp_syntax {
|
||||
SNMP_SYNTAX_NULL = 0,
|
||||
SNMP_SYNTAX_INTEGER, /* == INTEGER32 */
|
||||
SNMP_SYNTAX_OCTETSTRING,
|
||||
SNMP_SYNTAX_OID,
|
||||
SNMP_SYNTAX_IPADDRESS,
|
||||
SNMP_SYNTAX_COUNTER,
|
||||
SNMP_SYNTAX_GAUGE, /* == UNSIGNED32 */
|
||||
SNMP_SYNTAX_TIMETICKS,
|
||||
|
||||
/* v2 additions */
|
||||
SNMP_SYNTAX_COUNTER64,
|
||||
SNMP_SYNTAX_NOSUCHOBJECT, /* exception */
|
||||
SNMP_SYNTAX_NOSUCHINSTANCE, /* exception */
|
||||
SNMP_SYNTAX_ENDOFMIBVIEW, /* exception */
|
||||
};
|
||||
|
||||
struct snmp_value {
|
||||
struct asn_oid var;
|
||||
enum snmp_syntax syntax;
|
||||
union snmp_values {
|
||||
int32_t integer; /* also integer32 */
|
||||
struct {
|
||||
u_int len;
|
||||
u_char *octets;
|
||||
} octetstring;
|
||||
struct asn_oid oid;
|
||||
u_char ipaddress[4];
|
||||
u_int32_t uint32; /* also gauge32, counter32,
|
||||
unsigned32, timeticks */
|
||||
u_int64_t counter64;
|
||||
} v;
|
||||
};
|
||||
|
||||
enum snmp_version {
|
||||
SNMP_Verr = 0,
|
||||
SNMP_V1 = 1,
|
||||
SNMP_V2c,
|
||||
};
|
||||
|
||||
struct snmp_pdu {
|
||||
char community[SNMP_COMMUNITY_MAXLEN + 1];
|
||||
enum snmp_version version;
|
||||
u_int type;
|
||||
|
||||
/* trap only */
|
||||
struct asn_oid enterprise;
|
||||
u_char agent_addr[4];
|
||||
int32_t generic_trap;
|
||||
int32_t specific_trap;
|
||||
u_int32_t time_stamp;
|
||||
|
||||
/* others */
|
||||
int32_t request_id;
|
||||
int32_t error_status;
|
||||
int32_t error_index;
|
||||
|
||||
/* fixes for encoding */
|
||||
u_char *outer_ptr;
|
||||
u_char *pdu_ptr;
|
||||
u_char *vars_ptr;
|
||||
|
||||
struct snmp_value bindings[SNMP_MAX_BINDINGS];
|
||||
u_int nbindings;
|
||||
};
|
||||
#define snmp_v1_pdu snmp_pdu
|
||||
|
||||
#define SNMP_PDU_GET 0
|
||||
#define SNMP_PDU_GETNEXT 1
|
||||
#define SNMP_PDU_RESPONSE 2
|
||||
#define SNMP_PDU_SET 3
|
||||
#define SNMP_PDU_TRAP 4 /* v1 */
|
||||
#define SNMP_PDU_GETBULK 5 /* v2 */
|
||||
#define SNMP_PDU_INFORM 6 /* v2 */
|
||||
#define SNMP_PDU_TRAP2 7 /* v2 */
|
||||
#define SNMP_PDU_REPORT 8 /* v2 */
|
||||
|
||||
#define SNMP_ERR_NOERROR 0
|
||||
#define SNMP_ERR_TOOBIG 1
|
||||
#define SNMP_ERR_NOSUCHNAME 2 /* v1 */
|
||||
#define SNMP_ERR_BADVALUE 3 /* v1 */
|
||||
#define SNMP_ERR_READONLY 4 /* v1 */
|
||||
#define SNMP_ERR_GENERR 5
|
||||
#define SNMP_ERR_NO_ACCESS 6 /* v2 */
|
||||
#define SNMP_ERR_WRONG_TYPE 7 /* v2 */
|
||||
#define SNMP_ERR_WRONG_LENGTH 8 /* v2 */
|
||||
#define SNMP_ERR_WRONG_ENCODING 9 /* v2 */
|
||||
#define SNMP_ERR_WRONG_VALUE 10 /* v2 */
|
||||
#define SNMP_ERR_NO_CREATION 11 /* v2 */
|
||||
#define SNMP_ERR_INCONS_VALUE 12 /* v2 */
|
||||
#define SNMP_ERR_RES_UNAVAIL 13 /* v2 */
|
||||
#define SNMP_ERR_COMMIT_FAILED 14 /* v2 */
|
||||
#define SNMP_ERR_UNDO_FAILED 15 /* v2 */
|
||||
#define SNMP_ERR_AUTH_ERR 16 /* v2 */
|
||||
#define SNMP_ERR_NOT_WRITEABLE 17 /* v2 */
|
||||
#define SNMP_ERR_INCONS_NAME 18 /* v2 */
|
||||
|
||||
#define SNMP_TRAP_COLDSTART 0
|
||||
#define SNMP_TRAP_WARMSTART 1
|
||||
#define SNMP_TRAP_LINKDOWN 2
|
||||
#define SNMP_TRAP_LINKUP 3
|
||||
#define SNMP_TRAP_AUTHENTICATION_FAILURE 4
|
||||
#define SNMP_TRAP_EGP_NEIGHBOR_LOSS 5
|
||||
#define SNMP_TRAP_ENTERPRISE 6
|
||||
|
||||
enum snmp_code {
|
||||
SNMP_CODE_OK = 0,
|
||||
SNMP_CODE_FAILED,
|
||||
SNMP_CODE_BADVERS,
|
||||
SNMP_CODE_BADLEN,
|
||||
SNMP_CODE_BADENC,
|
||||
SNMP_CODE_OORANGE,
|
||||
};
|
||||
|
||||
void snmp_value_free(struct snmp_value *);
|
||||
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 *);
|
||||
enum snmp_code snmp_pdu_decode(struct asn_buf *b, struct snmp_pdu *pdu, int32_t *);
|
||||
enum snmp_code snmp_pdu_encode(struct snmp_pdu *pdu, struct asn_buf *resp_b);
|
||||
|
||||
void snmp_pdu_dump(const struct snmp_pdu *pdu);
|
||||
|
||||
extern void (*snmp_error)(const char *, ...);
|
||||
extern void (*snmp_printf)(const char *, ...);
|
||||
|
||||
#define TRUTH_MK(F) ((F) ? 1 : 2)
|
||||
#define TRUTH_GET(T) (((T) == 1) ? 1 : 0)
|
||||
#define TRUTH_OK(T) ((T) == 1 || (T) == 2)
|
||||
|
||||
#endif
|
1031
contrib/bsnmp/lib/snmpagent.c
Normal file
1031
contrib/bsnmp/lib/snmpagent.c
Normal file
File diff suppressed because it is too large
Load Diff
159
contrib/bsnmp/lib/snmpagent.h
Normal file
159
contrib/bsnmp/lib/snmpagent.h
Normal file
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003
|
||||
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Harti Brandt <harti@freebsd.org>
|
||||
*
|
||||
* Redistribution of this software and documentation 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 or documentation 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.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
* AND ITS 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
|
||||
* FRAUNHOFER FOKUS OR ITS 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.
|
||||
*
|
||||
* $Begemot: bsnmp/lib/snmpagent.h,v 1.9 2002/03/08 14:24:58 hbb Exp $
|
||||
*
|
||||
* Header file for SNMP functions. This requires snmp.h to be included.
|
||||
*/
|
||||
#ifndef snmp_agent_h_
|
||||
#define snmp_agent_h_
|
||||
|
||||
struct snmp_dependency;
|
||||
|
||||
/* Semi-Opaque object for SET operations */
|
||||
struct snmp_context {
|
||||
u_int var_index;
|
||||
struct snmp_scratch *scratch;
|
||||
struct snmp_dependency *dep;
|
||||
void *data; /* user data */
|
||||
};
|
||||
|
||||
struct snmp_scratch {
|
||||
void *ptr1;
|
||||
void *ptr2;
|
||||
u_int32_t int1;
|
||||
u_int32_t int2;
|
||||
};
|
||||
|
||||
enum snmp_depop {
|
||||
SNMP_DEPOP_COMMIT,
|
||||
SNMP_DEPOP_ROLLBACK
|
||||
};
|
||||
|
||||
typedef int (*snmp_depop_t)(struct snmp_context *, struct snmp_dependency *,
|
||||
enum snmp_depop);
|
||||
|
||||
struct snmp_dependency {
|
||||
struct asn_oid obj;
|
||||
struct asn_oid idx;
|
||||
};
|
||||
|
||||
/*
|
||||
* Functions to be called at the end of a SET operation.
|
||||
*/
|
||||
typedef void (*snmp_set_finish_t)(struct snmp_context *, int fail, void *);
|
||||
|
||||
/*
|
||||
* The TREE
|
||||
*/
|
||||
enum snmp_node_type {
|
||||
SNMP_NODE_LEAF = 1,
|
||||
SNMP_NODE_COLUMN
|
||||
};
|
||||
|
||||
enum snmp_op {
|
||||
SNMP_OP_GET = 1,
|
||||
SNMP_OP_GETNEXT,
|
||||
SNMP_OP_SET,
|
||||
SNMP_OP_COMMIT,
|
||||
SNMP_OP_ROLLBACK,
|
||||
};
|
||||
|
||||
enum snmp_ret {
|
||||
/* OK, generate a response */
|
||||
SNMP_RET_OK = 0,
|
||||
/* Error, ignore packet (no response) */
|
||||
SNMP_RET_IGN = 1,
|
||||
/* Error, generate response from original packet */
|
||||
SNMP_RET_ERR = 2
|
||||
};
|
||||
|
||||
typedef int (*snmp_op_t)(struct snmp_context *, struct snmp_value *,
|
||||
u_int, u_int, enum snmp_op);
|
||||
|
||||
struct snmp_node {
|
||||
struct asn_oid oid;
|
||||
const char *name; /* name of the leaf */
|
||||
enum snmp_node_type type; /* type of this node */
|
||||
enum snmp_syntax syntax;
|
||||
snmp_op_t op;
|
||||
u_int flags;
|
||||
u_int32_t index; /* index data */
|
||||
void *data; /* application data */
|
||||
};
|
||||
extern struct snmp_node *tree;
|
||||
extern u_int tree_size;
|
||||
|
||||
#define SNMP_NODE_CANSET 0x0001 /* SET allowed */
|
||||
|
||||
#define SNMP_INDEXES_MAX 7
|
||||
#define SNMP_INDEX_SHIFT 4
|
||||
#define SNMP_INDEX_MASK 0xf
|
||||
#define SNMP_INDEX_COUNT(V) ((V) & SNMP_INDEX_MASK)
|
||||
#define SNMP_INDEX(V,I) \
|
||||
(((V) >> (((I) + 1) * SNMP_INDEX_SHIFT)) & SNMP_INDEX_MASK)
|
||||
|
||||
enum {
|
||||
SNMP_TRACE_GET = 0x00000001,
|
||||
SNMP_TRACE_GETNEXT = 0x00000002,
|
||||
SNMP_TRACE_SET = 0x00000004,
|
||||
SNMP_TRACE_DEPEND = 0x00000008,
|
||||
SNMP_TRACE_FIND = 0x00000010,
|
||||
};
|
||||
/* trace flag for the following functions */
|
||||
extern u_int snmp_trace;
|
||||
|
||||
/* called to write the trace */
|
||||
extern void (*snmp_debug)(const char *fmt, ...);
|
||||
|
||||
enum snmp_ret snmp_get(struct snmp_pdu *pdu, struct asn_buf *resp_b,
|
||||
struct snmp_pdu *resp, void *);
|
||||
enum snmp_ret snmp_getnext(struct snmp_pdu *pdu, struct asn_buf *resp_b,
|
||||
struct snmp_pdu *resp, void *);
|
||||
enum snmp_ret snmp_getbulk(struct snmp_pdu *pdu, struct asn_buf *resp_b,
|
||||
struct snmp_pdu *resp, void *);
|
||||
enum snmp_ret snmp_set(struct snmp_pdu *pdu, struct asn_buf *resp_b,
|
||||
struct snmp_pdu *resp, void *);
|
||||
|
||||
enum snmp_ret snmp_make_errresp(const struct snmp_pdu *, struct asn_buf *,
|
||||
struct asn_buf *);
|
||||
|
||||
struct snmp_dependency *snmp_dep_lookup(struct snmp_context *,
|
||||
const struct asn_oid *, const struct asn_oid *, size_t, snmp_depop_t);
|
||||
|
||||
int snmp_set_atfinish(struct snmp_context *, snmp_set_finish_t func, void *arg);
|
||||
|
||||
struct snmp_context *snmp_init_context(void);
|
||||
int snmp_dep_commit(struct snmp_context *);
|
||||
int snmp_dep_rollback(struct snmp_context *);
|
||||
|
||||
#endif
|
1658
contrib/bsnmp/lib/snmpclient.c
Normal file
1658
contrib/bsnmp/lib/snmpclient.c
Normal file
File diff suppressed because it is too large
Load Diff
182
contrib/bsnmp/lib/snmpclient.h
Normal file
182
contrib/bsnmp/lib/snmpclient.h
Normal file
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003
|
||||
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Harti Brandt <harti@freebsd.org>
|
||||
* Kendy Kutzner
|
||||
*
|
||||
* Redistribution of this software and documentation 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 or documentation 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.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
* AND ITS 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
|
||||
* FRAUNHOFER FOKUS OR ITS 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.
|
||||
*
|
||||
* $Begemot: bsnmp/lib/snmpclient.h,v 1.15 2002/12/11 15:54:07 hbb Exp $
|
||||
*/
|
||||
#ifndef _BSNMP_SNMPCLIENT_H
|
||||
#define _BSNMP_SNMPCLIENT_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
#define SNMP_STRERROR_LEN 200
|
||||
|
||||
#define SNMP_LOCAL_PATH "/tmp/snmpXXXXXXXXXXXXXX"
|
||||
|
||||
|
||||
/* type of callback function for responses
|
||||
* this callback function is responsible for free() any memory associated with
|
||||
* any of the PDUs. Therefor it may call snmp_pdu_free() */
|
||||
typedef void (*snmp_send_cb_f)(struct snmp_pdu *, struct snmp_pdu *, void *);
|
||||
|
||||
/* type of callback function for timeouts */
|
||||
typedef void (*snmp_timeout_cb_f)(void * );
|
||||
|
||||
/* timeout start function */
|
||||
typedef void *(*snmp_timeout_start_f)(struct timeval *timeout,
|
||||
snmp_timeout_cb_f callback, void *);
|
||||
|
||||
/* timeout stop function */
|
||||
typedef void (*snmp_timeout_stop_f)(void *timeout_id);
|
||||
|
||||
/*
|
||||
* Client context.
|
||||
*/
|
||||
struct snmp_client {
|
||||
enum snmp_version version;
|
||||
int local; /* use local socket */
|
||||
|
||||
/* these two are read-only for the application */
|
||||
char *cport; /* port number as string */
|
||||
char *chost; /* host name or IP address as string */
|
||||
|
||||
char read_community[SNMP_COMMUNITY_MAXLEN + 1];
|
||||
char write_community[SNMP_COMMUNITY_MAXLEN + 1];
|
||||
|
||||
struct timeval timeout;
|
||||
u_int retries;
|
||||
|
||||
int dump_pdus;
|
||||
|
||||
size_t txbuflen;
|
||||
size_t rxbuflen;
|
||||
|
||||
int fd;
|
||||
|
||||
int32_t next_reqid;
|
||||
int32_t max_reqid;
|
||||
int32_t min_reqid;
|
||||
|
||||
char error[SNMP_STRERROR_LEN];
|
||||
|
||||
snmp_timeout_start_f timeout_start;
|
||||
snmp_timeout_stop_f timeout_stop;
|
||||
|
||||
char local_path[sizeof(SNMP_LOCAL_PATH)];
|
||||
};
|
||||
|
||||
/* the global context */
|
||||
extern struct snmp_client snmp_client;
|
||||
|
||||
/* initizialies a snmp_client structure */
|
||||
void snmp_client_init(struct snmp_client *);
|
||||
|
||||
/* initialize fields */
|
||||
int snmp_client_set_host(struct snmp_client *, const char *);
|
||||
int snmp_client_set_port(struct snmp_client *, const char *);
|
||||
|
||||
/* open connection to snmp server (hostname or portname can be NULL) */
|
||||
int snmp_open(const char *_hostname, const char *_portname,
|
||||
const char *_read_community, const char *_write_community);
|
||||
|
||||
/* close connection */
|
||||
void snmp_close(void);
|
||||
|
||||
/* initialize a snmp_pdu structure */
|
||||
void snmp_pdu_create(struct snmp_pdu *, u_int _op);
|
||||
|
||||
/* add pairs of (struct asn_oid *, enum snmp_syntax) to an existing pdu */
|
||||
int snmp_add_binding(struct snmp_pdu *, ...);
|
||||
|
||||
/* check wheater the answer is valid or not */
|
||||
int snmp_pdu_check(const struct snmp_pdu *_req, const struct snmp_pdu *_resp);
|
||||
|
||||
int32_t snmp_pdu_send(struct snmp_pdu *_pdu, snmp_send_cb_f _func, void *_arg);
|
||||
|
||||
/* append an index to an oid */
|
||||
int snmp_oid_append(struct asn_oid *_oid, const char *_fmt, ...);
|
||||
|
||||
/* receive a packet */
|
||||
int snmp_receive(int _blocking);
|
||||
|
||||
/*
|
||||
* This structure is used to describe an SNMP table that is to be fetched.
|
||||
* The C-structure that is produced by the fetch function must start with
|
||||
* a TAILQ_ENTRY and an u_int64_t.
|
||||
*/
|
||||
struct snmp_table {
|
||||
/* base OID of the table */
|
||||
struct asn_oid table;
|
||||
/* type OID of the LastChange variable for the table if any */
|
||||
struct asn_oid last_change;
|
||||
/* maximum number of iterations if table has changed */
|
||||
u_int max_iter;
|
||||
/* size of the C-structure */
|
||||
size_t entry_size;
|
||||
/* number of index fields */
|
||||
u_int index_size;
|
||||
/* bit mask of required fields */
|
||||
u_int64_t req_mask;
|
||||
|
||||
/* indexes and columns to fetch. Ended by a NULL syntax entry */
|
||||
struct snmp_table_entry {
|
||||
/* the column sub-oid, ignored for index fields */
|
||||
asn_subid_t subid;
|
||||
/* the syntax of the column or index */
|
||||
enum snmp_syntax syntax;
|
||||
/* offset of the field into the C-structure. For octet strings
|
||||
* this points to an u_char * followed by a size_t */
|
||||
off_t offset;
|
||||
#if defined(__GNUC__) && __GNUC__ < 3
|
||||
} entries[0];
|
||||
#else
|
||||
} entries[];
|
||||
#endif
|
||||
};
|
||||
|
||||
/* callback type for table fetch */
|
||||
typedef void (*snmp_table_cb_f)(void *_list, void *_arg, int _res);
|
||||
|
||||
/* fetch a table. The argument points to a TAILQ_HEAD */
|
||||
int snmp_table_fetch(const struct snmp_table *descr, void *);
|
||||
int snmp_table_fetch_async(const struct snmp_table *, void *,
|
||||
snmp_table_cb_f, void *);
|
||||
|
||||
/* send a request and wait for the response */
|
||||
int snmp_dialog(struct snmp_pdu *_req, struct snmp_pdu *_resp);
|
||||
|
||||
#endif /* _BSNMP_SNMPCLIENT_H */
|
47
contrib/bsnmp/lib/snmppriv.h
Normal file
47
contrib/bsnmp/lib/snmppriv.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003
|
||||
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Harti Brandt <harti@freebsd.org>
|
||||
*
|
||||
* Redistribution of this software and documentation 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 or documentation 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.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
* AND ITS 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
|
||||
* FRAUNHOFER FOKUS OR ITS 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.
|
||||
*
|
||||
* $Begemot: bsnmp/lib/snmppriv.h,v 1.7 2002/12/11 15:54:07 hbb Exp $
|
||||
*
|
||||
* Private functions.
|
||||
*/
|
||||
enum asn_err snmp_binding_encode(struct asn_buf *, const struct snmp_value *);
|
||||
enum snmp_code snmp_pdu_encode_header(struct asn_buf *, struct snmp_pdu *);
|
||||
enum snmp_code snmp_fix_encoding(struct asn_buf *, const struct snmp_pdu *);
|
||||
enum asn_err snmp_parse_message_hdr(struct asn_buf *b, struct snmp_pdu *pdu,
|
||||
asn_len_t *lenp);
|
||||
enum asn_err snmp_parse_pdus_hdr(struct asn_buf *b, struct snmp_pdu *pdu,
|
||||
asn_len_t *lenp);
|
||||
|
||||
#define DEFAULT_HOST "localhost"
|
||||
#define DEFAULT_PORT "snmp"
|
||||
#define DEFAULT_LOCAL "/var/run/snmp.sock"
|
1564
contrib/bsnmp/snmp_mibII/mibII.c
Normal file
1564
contrib/bsnmp/snmp_mibII/mibII.c
Normal file
File diff suppressed because it is too large
Load Diff
238
contrib/bsnmp/snmp_mibII/mibII.h
Normal file
238
contrib/bsnmp/snmp_mibII/mibII.h
Normal file
@ -0,0 +1,238 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003
|
||||
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Harti Brandt <harti@freebsd.org>
|
||||
*
|
||||
* Redistribution of this software and documentation 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 or documentation 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.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
* AND ITS 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
|
||||
* FRAUNHOFER FOKUS OR ITS 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.
|
||||
*
|
||||
* $Begemot: bsnmp/snmp_mibII/mibII.h,v 1.11 2002/03/21 10:43:06 hbb Exp $
|
||||
*
|
||||
* Implementation of the interfaces and IP groups of MIB-II.
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <err.h>
|
||||
#include <ctype.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_mib.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "asn1.h"
|
||||
#include "snmp.h"
|
||||
#include "snmpmod.h"
|
||||
#include "snmp_mibII.h"
|
||||
#include "mibII_tree.h"
|
||||
|
||||
|
||||
/*
|
||||
* Interface list and flags.
|
||||
*/
|
||||
TAILQ_HEAD(mibif_list, mibif);
|
||||
enum {
|
||||
MIBIF_FOUND = 0x0001,
|
||||
MIBIF_HIGHSPEED = 0x0002,
|
||||
MIBIF_VERYHIGHSPEED = 0x0004,
|
||||
};
|
||||
#define hc_inoctets mib.ifmd_data.ifi_ibytes
|
||||
#define hc_outoctets mib.ifmd_data.ifi_obytes
|
||||
#define hc_omcasts mib.ifmd_data.ifi_omcasts
|
||||
#define hc_opackets mib.ifmd_data.ifi_opackets
|
||||
#define hc_imcasts mib.ifmd_data.ifi_imcasts
|
||||
#define hc_ipackets mib.ifmd_data.ifi_ipackets
|
||||
|
||||
/*
|
||||
* Interface addresses.
|
||||
*/
|
||||
TAILQ_HEAD(mibifa_list, mibifa);
|
||||
enum {
|
||||
MIBIFA_FOUND = 0x0001,
|
||||
MIBIFA_DESTROYED = 0x0002,
|
||||
};
|
||||
|
||||
/*
|
||||
* Receive addresses
|
||||
*/
|
||||
TAILQ_HEAD(mibrcvaddr_list, mibrcvaddr);
|
||||
enum {
|
||||
MIBRCVADDR_FOUND = 0x00010000,
|
||||
};
|
||||
|
||||
/*
|
||||
* Interface index mapping. The problem here is, that if the same interface
|
||||
* is reinstantiated (for examble by unloading and loading the hardware driver)
|
||||
* we must use the same index for this interface. For dynamic interfaces
|
||||
* (clip, lane) we must use a fresh index, each time a new interface is created.
|
||||
* To differentiate between these types of interfaces we use the following table
|
||||
* which contains an entry for each dynamic interface type. All other interface
|
||||
* types are supposed to be static. The mibindexmap contains an entry for
|
||||
* all interfaces. The mibif pointer is NULL, if the interface doesn't exist
|
||||
* anymore.
|
||||
*/
|
||||
struct mibdynif {
|
||||
SLIST_ENTRY(mibdynif) link;
|
||||
char name[IFNAMSIZ];
|
||||
};
|
||||
SLIST_HEAD(mibdynif_list, mibdynif);
|
||||
|
||||
struct mibindexmap {
|
||||
STAILQ_ENTRY(mibindexmap) link;
|
||||
u_short sysindex;
|
||||
u_int ifindex;
|
||||
struct mibif *mibif; /* may be NULL */
|
||||
char name[IFNAMSIZ];
|
||||
};
|
||||
STAILQ_HEAD(mibindexmap_list, mibindexmap);
|
||||
|
||||
/*
|
||||
* Interface stacking. The generic code cannot know how the interfaces stack.
|
||||
* For this reason it instantiates only the x.0 and 0.x table elements. All
|
||||
* others have to be instantiated by the interface specific modules.
|
||||
* The table is read-only.
|
||||
*/
|
||||
struct mibifstack {
|
||||
TAILQ_ENTRY(mibifstack) link;
|
||||
struct asn_oid index;
|
||||
};
|
||||
TAILQ_HEAD(mibifstack_list, mibifstack);
|
||||
|
||||
/*
|
||||
* NetToMediaTable (ArpTable)
|
||||
*/
|
||||
struct mibarp {
|
||||
TAILQ_ENTRY(mibarp) link;
|
||||
struct asn_oid index; /* contains both the ifindex and addr */
|
||||
u_char phys[128]; /* the physical address */
|
||||
u_int physlen; /* and its length */
|
||||
u_int flags;
|
||||
};
|
||||
TAILQ_HEAD(mibarp_list, mibarp);
|
||||
enum {
|
||||
MIBARP_FOUND = 0x00010000,
|
||||
MIBARP_PERM = 0x00000001,
|
||||
};
|
||||
|
||||
/*
|
||||
* New if registrations
|
||||
*/
|
||||
struct newifreg {
|
||||
TAILQ_ENTRY(newifreg) link;
|
||||
const struct lmodule *mod;
|
||||
int (*func)(struct mibif *);
|
||||
};
|
||||
TAILQ_HEAD(newifreg_list, newifreg);
|
||||
|
||||
/* list of all IP addresses */
|
||||
extern struct mibifa_list mibifa_list;
|
||||
|
||||
/* list of all interfaces */
|
||||
extern struct mibif_list mibif_list;
|
||||
|
||||
/* list of dynamic interface names */
|
||||
extern struct mibdynif_list mibdynif_list;
|
||||
|
||||
/* list of all interface index mappings */
|
||||
extern struct mibindexmap_list mibindexmap_list;
|
||||
|
||||
/* list of all stacking entries */
|
||||
extern struct mibifstack_list mibifstack_list;
|
||||
|
||||
/* list of all receive addresses */
|
||||
extern struct mibrcvaddr_list mibrcvaddr_list;
|
||||
|
||||
/* list of all NetToMedia entries */
|
||||
extern struct mibarp_list mibarp_list;
|
||||
|
||||
/* number of interfaces */
|
||||
extern int32_t mib_if_number;
|
||||
|
||||
/* last change of interface table */
|
||||
extern u_int32_t mib_iftable_last_change;
|
||||
|
||||
/* last change of stack table */
|
||||
extern u_int32_t mib_ifstack_last_change;
|
||||
|
||||
/* if this is set, one of our lists may be bad. refresh them when idle */
|
||||
extern int mib_iflist_bad;
|
||||
|
||||
/* last time refreshed */
|
||||
extern u_int32_t mibarpticks;
|
||||
|
||||
/* info on system clocks */
|
||||
extern struct clockinfo clockinfo;
|
||||
|
||||
/* get interfaces and interface addresses. */
|
||||
void mib_fetch_interfaces(void);
|
||||
|
||||
/* check whether this interface(type) is dynamic */
|
||||
int mib_if_is_dyn(const char *name);
|
||||
|
||||
/* destroy an interface address */
|
||||
int mib_destroy_ifa(struct mibifa *);
|
||||
|
||||
/* restituate a deleted interface address */
|
||||
void mib_undestroy_ifa(struct mibifa *);
|
||||
|
||||
/* change interface address */
|
||||
int mib_modify_ifa(struct mibifa *);
|
||||
|
||||
/* undo if address modification */
|
||||
void mib_unmodify_ifa(struct mibifa *);
|
||||
|
||||
/* create an interface address */
|
||||
struct mibifa * mib_create_ifa(u_int ifindex, struct in_addr addr, struct in_addr mask, struct in_addr bcast);
|
||||
|
||||
/* delete a freshly created address */
|
||||
void mib_uncreate_ifa(struct mibifa *);
|
||||
|
||||
/* create/delete arp entries */
|
||||
struct mibarp *mib_arp_create(const struct mibif *, struct in_addr, const u_char *, size_t);
|
||||
void mib_arp_delete(struct mibarp *);
|
||||
|
||||
/* find arp entry */
|
||||
struct mibarp *mib_find_arp(const struct mibif *, struct in_addr);
|
||||
|
||||
/* update arp table */
|
||||
void mib_arp_update(void);
|
||||
|
||||
/* fetch routing table */
|
||||
u_char *mib_fetch_rtab(int af, int info, int arg, size_t *lenp);
|
||||
|
||||
/* extract addresses from routing message */
|
||||
void mib_extract_addrs(int, u_char *, struct sockaddr **);
|
80
contrib/bsnmp/snmp_mibII/mibII_ifmib.c
Normal file
80
contrib/bsnmp/snmp_mibII/mibII_ifmib.c
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003
|
||||
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Harti Brandt <harti@freebsd.org>
|
||||
*
|
||||
* Redistribution of this software and documentation 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 or documentation 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.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
* AND ITS 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
|
||||
* FRAUNHOFER FOKUS OR ITS 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.
|
||||
*
|
||||
* $Begemot: bsnmp/snmp_mibII/mibII_ifmib.c,v 1.7 2003/01/28 13:44:35 hbb Exp $
|
||||
*
|
||||
* Interfaces group.
|
||||
*/
|
||||
#include "mibII.h"
|
||||
#include "mibII_oid.h"
|
||||
|
||||
/*
|
||||
* Scalars
|
||||
*/
|
||||
int
|
||||
op_ifmib(struct snmp_context *ctx __unused, struct snmp_value *value,
|
||||
u_int sub, u_int idx __unused, enum snmp_op op)
|
||||
{
|
||||
switch (op) {
|
||||
|
||||
case SNMP_OP_GETNEXT:
|
||||
abort();
|
||||
|
||||
case SNMP_OP_GET:
|
||||
break;
|
||||
|
||||
case SNMP_OP_SET:
|
||||
return (SNMP_ERR_NOT_WRITEABLE);
|
||||
|
||||
case SNMP_OP_ROLLBACK:
|
||||
case SNMP_OP_COMMIT:
|
||||
abort();
|
||||
}
|
||||
|
||||
switch (value->var.subs[sub - 1]) {
|
||||
|
||||
case LEAF_ifTableLastChange:
|
||||
if (mib_iftable_last_change > start_tick)
|
||||
value->v.uint32 = mib_iftable_last_change - start_tick;
|
||||
else
|
||||
value->v.uint32 = 0;
|
||||
break;
|
||||
|
||||
case LEAF_ifStackLastChange:
|
||||
if (mib_ifstack_last_change > start_tick)
|
||||
value->v.uint32 = mib_ifstack_last_change - start_tick;
|
||||
else
|
||||
value->v.uint32 = 0;
|
||||
break;
|
||||
}
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
109
contrib/bsnmp/snmp_mibII/mibII_ifstack.c
Normal file
109
contrib/bsnmp/snmp_mibII/mibII_ifstack.c
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003
|
||||
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Harti Brandt <harti@freebsd.org>
|
||||
*
|
||||
* Redistribution of this software and documentation 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 or documentation 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.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
* AND ITS 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
|
||||
* FRAUNHOFER FOKUS OR ITS 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.
|
||||
*
|
||||
* $Begemot: bsnmp/snmp_mibII/mibII_ifstack.c,v 1.5 2003/01/28 13:44:35 hbb Exp $
|
||||
*
|
||||
* ifStackTable. Read-only.
|
||||
*/
|
||||
#include "mibII.h"
|
||||
|
||||
int
|
||||
mib_ifstack_create(const struct mibif *lower, const struct mibif *upper)
|
||||
{
|
||||
struct mibifstack *stack;
|
||||
|
||||
if ((stack = malloc(sizeof(*stack))) == NULL)
|
||||
return (-1);
|
||||
|
||||
stack->index.len = 2;
|
||||
stack->index.subs[0] = upper ? upper->index : 0;
|
||||
stack->index.subs[1] = lower ? lower->index : 0;
|
||||
|
||||
INSERT_OBJECT_OID(stack, &mibifstack_list);
|
||||
|
||||
mib_ifstack_last_change = get_ticks();
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
mib_ifstack_delete(const struct mibif *lower, const struct mibif *upper)
|
||||
{
|
||||
struct mibifstack *stack;
|
||||
|
||||
TAILQ_FOREACH(stack, &mibifstack_list, link)
|
||||
if (stack->index.subs[0] == (upper ? upper->index : 0) &&
|
||||
stack->index.subs[1] == (lower ? lower->index : 0)) {
|
||||
TAILQ_REMOVE(&mibifstack_list, stack, link);
|
||||
free(stack);
|
||||
mib_ifstack_last_change = get_ticks();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
op_ifstack(struct snmp_context *ctx __unused, struct snmp_value *value,
|
||||
u_int sub, u_int iidx __unused, enum snmp_op op)
|
||||
{
|
||||
struct mibifstack *stack;
|
||||
|
||||
switch (op) {
|
||||
|
||||
case SNMP_OP_GETNEXT:
|
||||
if ((stack = NEXT_OBJECT_OID(&mibifstack_list, &value->var, sub)) == NULL)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
index_append(&value->var, sub, &stack->index);
|
||||
break;
|
||||
|
||||
case SNMP_OP_GET:
|
||||
if ((stack = FIND_OBJECT_OID(&mibifstack_list, &value->var, sub)) == NULL)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
break;
|
||||
|
||||
case SNMP_OP_SET:
|
||||
if ((stack = FIND_OBJECT_OID(&mibifstack_list, &value->var, sub)) == NULL)
|
||||
return (SNMP_ERR_NO_CREATION);
|
||||
return (SNMP_ERR_NOT_WRITEABLE);
|
||||
|
||||
case SNMP_OP_ROLLBACK:
|
||||
case SNMP_OP_COMMIT:
|
||||
abort();
|
||||
}
|
||||
|
||||
switch (value->var.subs[sub - 1]) {
|
||||
|
||||
case LEAF_ifStackStatus:
|
||||
value->v.integer = 1;
|
||||
break;
|
||||
}
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
524
contrib/bsnmp/snmp_mibII/mibII_interfaces.c
Normal file
524
contrib/bsnmp/snmp_mibII/mibII_interfaces.c
Normal file
@ -0,0 +1,524 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003
|
||||
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Harti Brandt <harti@freebsd.org>
|
||||
*
|
||||
* Redistribution of this software and documentation 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 or documentation 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.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
* AND ITS 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
|
||||
* FRAUNHOFER FOKUS OR ITS 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.
|
||||
*
|
||||
* $Begemot: bsnmp/snmp_mibII/mibII_interfaces.c,v 1.9 2003/01/28 13:44:35 hbb Exp $
|
||||
*
|
||||
* Interfaces group.
|
||||
*/
|
||||
#include "mibII.h"
|
||||
#include "mibII_oid.h"
|
||||
|
||||
/*
|
||||
* This structure catches all changes to a interface entry
|
||||
*/
|
||||
struct ifchange {
|
||||
struct snmp_dependency dep;
|
||||
|
||||
u_int ifindex;
|
||||
|
||||
u_int32_t set;
|
||||
int promisc;
|
||||
int admin;
|
||||
int traps;
|
||||
|
||||
u_int32_t rb;
|
||||
int rb_flags;
|
||||
int rb_traps;
|
||||
};
|
||||
#define IFC_PROMISC 0x0001
|
||||
#define IFC_ADMIN 0x0002
|
||||
#define IFC_TRAPS 0x0004
|
||||
#define IFRB_FLAGS 0x0001
|
||||
#define IFRB_TRAPS 0x0002
|
||||
|
||||
static const struct asn_oid
|
||||
oid_ifTable = OIDX_ifTable;
|
||||
|
||||
/*
|
||||
* This function handles all changes to the interface table and interface
|
||||
* extension table.
|
||||
*/
|
||||
static int
|
||||
ifchange_func(struct snmp_context *ctx __unused, struct snmp_dependency *dep,
|
||||
enum snmp_depop op)
|
||||
{
|
||||
struct ifchange *ifc = (struct ifchange *)dep;
|
||||
struct mibif *ifp;
|
||||
struct ifreq ifr, ifr1;
|
||||
|
||||
if ((ifp = mib_find_if(ifc->ifindex)) == NULL)
|
||||
return (SNMP_ERR_NO_CREATION);
|
||||
|
||||
switch (op) {
|
||||
|
||||
case SNMP_DEPOP_COMMIT:
|
||||
strncpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
|
||||
if (ioctl(mib_netsock, SIOCGIFFLAGS, &ifr) == -1) {
|
||||
syslog(LOG_ERR, "GIFFLAGS(%s): %m", ifp->name);
|
||||
return (SNMP_ERR_GENERR);
|
||||
}
|
||||
if (ifc->set & IFC_PROMISC) {
|
||||
ifr.ifr_flags &= ~IFF_PROMISC;
|
||||
if (ifc->promisc)
|
||||
ifr.ifr_flags |= IFF_PROMISC;
|
||||
ifc->rb |= IFRB_FLAGS;
|
||||
}
|
||||
if (ifc->set & IFC_ADMIN) {
|
||||
ifr.ifr_flags &= ~IFF_UP;
|
||||
if (ifc->admin)
|
||||
ifr.ifr_flags |= IFF_UP;
|
||||
ifc->rb |= IFRB_FLAGS;
|
||||
}
|
||||
if (ifc->rb & IFRB_FLAGS) {
|
||||
strncpy(ifr1.ifr_name, ifp->name, sizeof(ifr1.ifr_name));
|
||||
if (ioctl(mib_netsock, SIOCGIFFLAGS, &ifr1) == -1) {
|
||||
syslog(LOG_ERR, "GIFFLAGS(%s): %m", ifp->name);
|
||||
return (SNMP_ERR_GENERR);
|
||||
}
|
||||
ifc->rb_flags = ifr1.ifr_flags;
|
||||
if (ioctl(mib_netsock, SIOCSIFFLAGS, &ifr) == -1) {
|
||||
syslog(LOG_ERR, "SIFFLAGS(%s): %m", ifp->name);
|
||||
return (SNMP_ERR_GENERR);
|
||||
}
|
||||
(void)mib_fetch_ifmib(ifp);
|
||||
}
|
||||
if (ifc->set & IFC_TRAPS) {
|
||||
ifc->rb |= IFRB_TRAPS;
|
||||
ifc->rb_traps = ifp->trap_enable;
|
||||
ifp->trap_enable = ifc->traps;
|
||||
}
|
||||
return (SNMP_ERR_NOERROR);
|
||||
|
||||
case SNMP_DEPOP_ROLLBACK:
|
||||
if (ifc->rb & IFRB_FLAGS) {
|
||||
strncpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
|
||||
ifr.ifr_flags = ifc->rb_flags;
|
||||
if (ioctl(mib_netsock, SIOCSIFFLAGS, &ifr) == -1) {
|
||||
syslog(LOG_ERR, "SIFFLAGS(%s): %m", ifp->name);
|
||||
return (SNMP_ERR_UNDO_FAILED);
|
||||
}
|
||||
(void)mib_fetch_ifmib(ifp);
|
||||
}
|
||||
if (ifc->rb & IFRB_TRAPS)
|
||||
ifp->trap_enable = ifc->rb_traps;
|
||||
return (SNMP_ERR_NOERROR);
|
||||
|
||||
}
|
||||
abort();
|
||||
}
|
||||
|
||||
static u_int32_t
|
||||
ticks_get_timeval(struct timeval *tv)
|
||||
{
|
||||
u_int32_t v;
|
||||
|
||||
if (tv->tv_sec != 0 || tv->tv_usec != 0) {
|
||||
v = 100 * tv->tv_sec + tv->tv_usec / 10000;
|
||||
if (v > start_tick)
|
||||
return (v - start_tick);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Scalars
|
||||
*/
|
||||
int
|
||||
op_interfaces(struct snmp_context *ctx __unused, struct snmp_value *value,
|
||||
u_int sub, u_int idx __unused, enum snmp_op op)
|
||||
{
|
||||
switch (op) {
|
||||
|
||||
case SNMP_OP_GETNEXT:
|
||||
abort();
|
||||
|
||||
case SNMP_OP_GET:
|
||||
break;
|
||||
|
||||
case SNMP_OP_SET:
|
||||
return (SNMP_ERR_NOT_WRITEABLE);
|
||||
|
||||
case SNMP_OP_ROLLBACK:
|
||||
case SNMP_OP_COMMIT:
|
||||
abort();
|
||||
}
|
||||
|
||||
switch (value->var.subs[sub - 1]) {
|
||||
|
||||
case LEAF_ifNumber:
|
||||
value->v.integer = mib_if_number;
|
||||
break;
|
||||
}
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Iftable entry
|
||||
*/
|
||||
int
|
||||
op_ifentry(struct snmp_context *ctx, struct snmp_value *value,
|
||||
u_int sub, u_int iidx __unused, enum snmp_op op)
|
||||
{
|
||||
struct mibif *ifp = NULL;
|
||||
int ret;
|
||||
struct ifchange *ifc;
|
||||
struct asn_oid idx;
|
||||
|
||||
switch (op) {
|
||||
|
||||
case SNMP_OP_GETNEXT:
|
||||
if ((ifp = NEXT_OBJECT_INT(&mibif_list, &value->var, sub)) == NULL)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
value->var.len = sub + 1;
|
||||
value->var.subs[sub] = ifp->index;
|
||||
break;
|
||||
|
||||
case SNMP_OP_GET:
|
||||
if (value->var.len - sub != 1)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
if ((ifp = mib_find_if(value->var.subs[sub])) == NULL)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
break;
|
||||
|
||||
case SNMP_OP_SET:
|
||||
if (value->var.len - sub != 1)
|
||||
return (SNMP_ERR_NO_CREATION);
|
||||
if ((ifp = mib_find_if(value->var.subs[sub])) == NULL)
|
||||
return (SNMP_ERR_NO_CREATION);
|
||||
if (value->var.subs[sub - 1] != LEAF_ifAdminStatus)
|
||||
return (SNMP_ERR_NOT_WRITEABLE);
|
||||
|
||||
idx.len = 1;
|
||||
idx.subs[0] = ifp->index;
|
||||
|
||||
if (value->v.integer != 1 && value->v.integer != 2)
|
||||
return (SNMP_ERR_WRONG_VALUE);
|
||||
|
||||
if ((ifc = (struct ifchange *)snmp_dep_lookup(ctx,
|
||||
&oid_ifTable, &idx, sizeof(*ifc), ifchange_func)) == NULL)
|
||||
return (SNMP_ERR_RES_UNAVAIL);
|
||||
ifc->ifindex = ifp->index;
|
||||
|
||||
if (ifc->set & IFC_ADMIN)
|
||||
return (SNMP_ERR_INCONS_VALUE);
|
||||
ifc->set |= IFC_ADMIN;
|
||||
ifc->admin = (value->v.integer == 1) ? 1 : 0;
|
||||
|
||||
return (SNMP_ERR_NOERROR);
|
||||
|
||||
case SNMP_OP_ROLLBACK:
|
||||
case SNMP_OP_COMMIT:
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
if (ifp->mibtick < this_tick)
|
||||
(void)mib_fetch_ifmib(ifp);
|
||||
|
||||
ret = SNMP_ERR_NOERROR;
|
||||
switch (value->var.subs[sub - 1]) {
|
||||
|
||||
case LEAF_ifIndex:
|
||||
value->v.integer = ifp->index;
|
||||
break;
|
||||
|
||||
case LEAF_ifDescr:
|
||||
ret = string_get(value, ifp->descr, -1);
|
||||
break;
|
||||
|
||||
case LEAF_ifType:
|
||||
value->v.integer = ifp->mib.ifmd_data.ifi_type;
|
||||
break;
|
||||
|
||||
case LEAF_ifMtu:
|
||||
value->v.integer = ifp->mib.ifmd_data.ifi_mtu;
|
||||
break;
|
||||
|
||||
case LEAF_ifSpeed:
|
||||
value->v.integer = ifp->mib.ifmd_data.ifi_baudrate;
|
||||
break;
|
||||
|
||||
case LEAF_ifPhysAddress:
|
||||
ret = string_get(value, ifp->physaddr,
|
||||
ifp->physaddrlen);
|
||||
break;
|
||||
|
||||
case LEAF_ifAdminStatus:
|
||||
value->v.integer =
|
||||
(ifp->mib.ifmd_flags & IFF_UP) ? 1 : 2;
|
||||
break;
|
||||
|
||||
case LEAF_ifOperStatus:
|
||||
value->v.integer =
|
||||
(ifp->mib.ifmd_flags & IFF_RUNNING) ? 1 : 2;
|
||||
break;
|
||||
|
||||
case LEAF_ifLastChange:
|
||||
value->v.uint32 =
|
||||
ticks_get_timeval(&ifp->mib.ifmd_data.ifi_lastchange);
|
||||
break;
|
||||
|
||||
case LEAF_ifInOctets:
|
||||
value->v.uint32 = ifp->mib.ifmd_data.ifi_ibytes;
|
||||
break;
|
||||
|
||||
case LEAF_ifInUcastPkts:
|
||||
value->v.uint32 = ifp->mib.ifmd_data.ifi_ipackets -
|
||||
ifp->mib.ifmd_data.ifi_imcasts;
|
||||
break;
|
||||
|
||||
case LEAF_ifInNUcastPkts:
|
||||
value->v.uint32 = ifp->mib.ifmd_data.ifi_imcasts;
|
||||
break;
|
||||
|
||||
case LEAF_ifInDiscards:
|
||||
value->v.uint32 = ifp->mib.ifmd_data.ifi_iqdrops;
|
||||
break;
|
||||
|
||||
case LEAF_ifInErrors:
|
||||
value->v.uint32 = ifp->mib.ifmd_data.ifi_ierrors;
|
||||
break;
|
||||
|
||||
case LEAF_ifInUnknownProtos:
|
||||
value->v.uint32 = ifp->mib.ifmd_data.ifi_noproto;
|
||||
break;
|
||||
|
||||
case LEAF_ifOutOctets:
|
||||
value->v.uint32 = ifp->mib.ifmd_data.ifi_obytes;
|
||||
break;
|
||||
|
||||
case LEAF_ifOutUcastPkts:
|
||||
value->v.uint32 = ifp->mib.ifmd_data.ifi_opackets -
|
||||
ifp->mib.ifmd_data.ifi_omcasts;
|
||||
break;
|
||||
|
||||
case LEAF_ifOutNUcastPkts:
|
||||
value->v.uint32 = ifp->mib.ifmd_data.ifi_omcasts;
|
||||
break;
|
||||
|
||||
case LEAF_ifOutDiscards:
|
||||
value->v.uint32 = ifp->mib.ifmd_snd_drops;
|
||||
break;
|
||||
|
||||
case LEAF_ifOutErrors:
|
||||
value->v.uint32 = ifp->mib.ifmd_data.ifi_oerrors;
|
||||
break;
|
||||
|
||||
case LEAF_ifOutQLen:
|
||||
value->v.uint32 = ifp->mib.ifmd_snd_len;
|
||||
break;
|
||||
|
||||
case LEAF_ifSpecific:
|
||||
value->v.oid = oid_zeroDotZero;
|
||||
break;
|
||||
}
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* IfXtable entry
|
||||
*/
|
||||
int
|
||||
op_ifxtable(struct snmp_context *ctx, struct snmp_value *value,
|
||||
u_int sub, u_int iidx __unused, enum snmp_op op)
|
||||
{
|
||||
struct mibif *ifp = NULL;
|
||||
int ret;
|
||||
struct ifchange *ifc;
|
||||
struct asn_oid idx;
|
||||
|
||||
switch (op) {
|
||||
|
||||
again:
|
||||
if (op != SNMP_OP_GETNEXT)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case SNMP_OP_GETNEXT:
|
||||
if ((ifp = NEXT_OBJECT_INT(&mibif_list, &value->var, sub)) == NULL)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
value->var.len = sub + 1;
|
||||
value->var.subs[sub] = ifp->index;
|
||||
break;
|
||||
|
||||
case SNMP_OP_GET:
|
||||
if (value->var.len - sub != 1)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
if ((ifp = mib_find_if(value->var.subs[sub])) == NULL)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
break;
|
||||
|
||||
case SNMP_OP_SET:
|
||||
if (value->var.len - sub != 1)
|
||||
return (SNMP_ERR_NO_CREATION);
|
||||
if ((ifp = mib_find_if(value->var.subs[sub])) == NULL)
|
||||
return (SNMP_ERR_NO_CREATION);
|
||||
|
||||
idx.len = 1;
|
||||
idx.subs[0] = ifp->index;
|
||||
|
||||
if ((ifc = (struct ifchange *)snmp_dep_lookup(ctx,
|
||||
&oid_ifTable, &idx, sizeof(*ifc), ifchange_func)) == NULL)
|
||||
return (SNMP_ERR_RES_UNAVAIL);
|
||||
ifc->ifindex = ifp->index;
|
||||
|
||||
switch (value->var.subs[sub - 1]) {
|
||||
|
||||
case LEAF_ifLinkUpDownTrapEnable:
|
||||
if (value->v.integer != 1 && value->v.integer != 2)
|
||||
return (SNMP_ERR_WRONG_VALUE);
|
||||
if (ifc->set & IFC_TRAPS)
|
||||
return (SNMP_ERR_INCONS_VALUE);
|
||||
ifc->set |= IFC_TRAPS;
|
||||
ifc->traps = (value->v.integer == 1) ? 1 : 0;
|
||||
return (SNMP_ERR_NOERROR);
|
||||
|
||||
case LEAF_ifPromiscuousMode:
|
||||
if (value->v.integer != 1 && value->v.integer != 2)
|
||||
return (SNMP_ERR_WRONG_VALUE);
|
||||
if (ifc->set & IFC_PROMISC)
|
||||
return (SNMP_ERR_INCONS_VALUE);
|
||||
ifc->set |= IFC_PROMISC;
|
||||
ifc->promisc = (value->v.integer == 1) ? 1 : 0;
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
return (SNMP_ERR_NOT_WRITEABLE);
|
||||
|
||||
case SNMP_OP_ROLLBACK:
|
||||
case SNMP_OP_COMMIT:
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
if (ifp->mibtick < this_tick)
|
||||
(void)mib_fetch_ifmib(ifp);
|
||||
|
||||
ret = SNMP_ERR_NOERROR;
|
||||
switch (value->var.subs[sub - 1]) {
|
||||
|
||||
case LEAF_ifName:
|
||||
ret = string_get(value, ifp->name, -1);
|
||||
break;
|
||||
|
||||
case LEAF_ifInMulticastPkts:
|
||||
value->v.uint32 = ifp->mib.ifmd_data.ifi_imcasts;
|
||||
break;
|
||||
|
||||
case LEAF_ifInBroadcastPkts:
|
||||
value->v.uint32 = 0;
|
||||
break;
|
||||
|
||||
case LEAF_ifOutMulticastPkts:
|
||||
value->v.uint32 = ifp->mib.ifmd_data.ifi_omcasts;
|
||||
break;
|
||||
|
||||
case LEAF_ifOutBroadcastPkts:
|
||||
value->v.uint32 = 0;
|
||||
break;
|
||||
|
||||
case LEAF_ifHCInOctets:
|
||||
if (!(ifp->flags & MIBIF_HIGHSPEED))
|
||||
goto again;
|
||||
value->v.counter64 = ifp->hc_inoctets;
|
||||
break;
|
||||
|
||||
case LEAF_ifHCInUcastPkts:
|
||||
if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
|
||||
goto again;
|
||||
value->v.counter64 = ifp->hc_ipackets - ifp->hc_imcasts;
|
||||
break;
|
||||
|
||||
case LEAF_ifHCInMulticastPkts:
|
||||
if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
|
||||
goto again;
|
||||
value->v.counter64 = ifp->hc_imcasts;
|
||||
break;
|
||||
|
||||
case LEAF_ifHCInBroadcastPkts:
|
||||
if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
|
||||
goto again;
|
||||
value->v.counter64 = 0;
|
||||
break;
|
||||
|
||||
case LEAF_ifHCOutOctets:
|
||||
if (!(ifp->flags & MIBIF_HIGHSPEED))
|
||||
goto again;
|
||||
value->v.counter64 = ifp->hc_inoctets;
|
||||
break;
|
||||
|
||||
case LEAF_ifHCOutUcastPkts:
|
||||
if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
|
||||
goto again;
|
||||
value->v.counter64 = ifp->hc_opackets - ifp->hc_omcasts;
|
||||
break;
|
||||
|
||||
case LEAF_ifHCOutMulticastPkts:
|
||||
if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
|
||||
goto again;
|
||||
value->v.counter64 = ifp->hc_omcasts;
|
||||
break;
|
||||
|
||||
case LEAF_ifHCOutBroadcastPkts:
|
||||
if (!(ifp->flags & (MIBIF_VERYHIGHSPEED|MIBIF_HIGHSPEED)))
|
||||
goto again;
|
||||
value->v.counter64 = 0;
|
||||
break;
|
||||
|
||||
case LEAF_ifLinkUpDownTrapEnable:
|
||||
value->v.integer = ifp->trap_enable ? 1 : 2;
|
||||
break;
|
||||
|
||||
case LEAF_ifHighSpeed:
|
||||
value->v.integer =
|
||||
(ifp->mib.ifmd_data.ifi_baudrate + 499999) / 1000000;
|
||||
break;
|
||||
|
||||
case LEAF_ifPromiscuousMode:
|
||||
value->v.integer =
|
||||
(ifp->mib.ifmd_flags & IFF_PROMISC) ? 1 : 2;
|
||||
break;
|
||||
|
||||
case LEAF_ifConnectorPresent:
|
||||
value->v.integer = ifp->has_connector ? 1 : 2;
|
||||
break;
|
||||
|
||||
case LEAF_ifAlias:
|
||||
ret = string_get(value, "", -1);
|
||||
break;
|
||||
|
||||
case LEAF_ifCounterDiscontinuityTime:
|
||||
if (ifp->counter_disc > start_tick)
|
||||
value->v.uint32 = ifp->counter_disc - start_tick;
|
||||
else
|
||||
value->v.uint32 = 0;
|
||||
break;
|
||||
}
|
||||
return (ret);
|
||||
}
|
497
contrib/bsnmp/snmp_mibII/mibII_ip.c
Normal file
497
contrib/bsnmp/snmp_mibII/mibII_ip.c
Normal file
@ -0,0 +1,497 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003
|
||||
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Harti Brandt <harti@freebsd.org>
|
||||
*
|
||||
* Redistribution of this software and documentation 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 or documentation 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.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
* AND ITS 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
|
||||
* FRAUNHOFER FOKUS OR ITS 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.
|
||||
*
|
||||
* $Begemot: bsnmp/snmp_mibII/mibII_ip.c,v 1.8 2003/01/28 13:44:35 hbb Exp $
|
||||
*
|
||||
* ip group scalars.
|
||||
*/
|
||||
#include "mibII.h"
|
||||
#include "mibII_oid.h"
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip_var.h>
|
||||
#include <netinet/ip_icmp.h>
|
||||
#include <netinet/icmp_var.h>
|
||||
|
||||
static struct ipstat ipstat;
|
||||
static u_int ip_idrop;
|
||||
static struct icmpstat icmpstat;
|
||||
|
||||
static int ip_forwarding;
|
||||
static int ip_defttl;
|
||||
static u_int32_t ip_tick;
|
||||
|
||||
static u_int32_t ipstat_tick;
|
||||
|
||||
static int
|
||||
fetch_ipstat(void)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
len = sizeof(ipstat);
|
||||
if (sysctlbyname("net.inet.ip.stats", &ipstat, &len, NULL, 0) == -1) {
|
||||
syslog(LOG_ERR, "net.inet.ip.stats: %m");
|
||||
return (-1);
|
||||
}
|
||||
if (len != sizeof(ipstat)) {
|
||||
syslog(LOG_ERR, "net.inet.ip.stats: wrong size");
|
||||
return (-1);
|
||||
}
|
||||
len = sizeof(ip_idrop);
|
||||
if (sysctlbyname("net.inet.ip.intr_queue_drops", &ip_idrop, &len, NULL, 0) == -1)
|
||||
syslog(LOG_WARNING, "net.inet.ip.intr_queue_drops: %m");
|
||||
if (len != sizeof(ip_idrop)) {
|
||||
syslog(LOG_WARNING, "net.inet.ip.intr_queue_drops: wrong size");
|
||||
ip_idrop = 0;
|
||||
}
|
||||
len = sizeof(icmpstat);
|
||||
if (sysctlbyname("net.inet.icmp.stats", &icmpstat, &len, NULL, 0) == -1) {
|
||||
syslog(LOG_ERR, "net.inet.icmp.stats: %m");
|
||||
return (-1);
|
||||
}
|
||||
if (len != sizeof(icmpstat)) {
|
||||
syslog(LOG_ERR, "net.inet.icmp.stats: wrong size");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
ipstat_tick = get_ticks();
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
fetch_ip(void)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
len = sizeof(ip_forwarding);
|
||||
if (sysctlbyname("net.inet.ip.forwarding", &ip_forwarding, &len,
|
||||
NULL, 0) == -1) {
|
||||
syslog(LOG_ERR, "net.inet.ip.forwarding: %m");
|
||||
return (-1);
|
||||
}
|
||||
if (len != sizeof(ip_forwarding)) {
|
||||
syslog(LOG_ERR, "net.inet.ip.forwarding: wrong size");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
len = sizeof(ip_defttl);
|
||||
if (sysctlbyname("net.inet.ip.ttl", &ip_defttl, &len,
|
||||
NULL, 0) == -1) {
|
||||
syslog(LOG_ERR, "net.inet.ip.ttl: %m");
|
||||
return (-1);
|
||||
}
|
||||
if (len != sizeof(ip_defttl)) {
|
||||
syslog(LOG_ERR, "net.inet.ip.ttl: wrong size");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
ip_tick = get_ticks();
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ip_forward(int forw, int *old)
|
||||
{
|
||||
size_t olen;
|
||||
|
||||
olen = sizeof(*old);
|
||||
if (sysctlbyname("net.inet.ip.forwarding", old, old ? &olen : NULL,
|
||||
&forw, sizeof(forw)) == -1) {
|
||||
syslog(LOG_ERR, "set net.inet.ip.forwarding: %m");
|
||||
return (-1);
|
||||
}
|
||||
ip_forwarding = forw;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ip_setttl(int ttl, int *old)
|
||||
{
|
||||
size_t olen;
|
||||
|
||||
olen = sizeof(*old);
|
||||
if (sysctlbyname("net.inet.ip.ttl", old, old ? &olen : NULL,
|
||||
&ttl, sizeof(ttl)) == -1) {
|
||||
syslog(LOG_ERR, "set net.inet.ip.ttl: %m");
|
||||
return (-1);
|
||||
}
|
||||
ip_defttl = ttl;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* READ/WRITE ip group.
|
||||
*/
|
||||
int
|
||||
op_ip(struct snmp_context *ctx, struct snmp_value *value,
|
||||
u_int sub, u_int idx __unused, enum snmp_op op)
|
||||
{
|
||||
int old;
|
||||
|
||||
switch (op) {
|
||||
|
||||
case SNMP_OP_GETNEXT:
|
||||
abort();
|
||||
|
||||
case SNMP_OP_GET:
|
||||
break;
|
||||
|
||||
case SNMP_OP_SET:
|
||||
if (ip_tick < this_tick)
|
||||
if (fetch_ip() == -1)
|
||||
return (SNMP_ERR_GENERR);
|
||||
|
||||
switch (value->var.subs[sub - 1]) {
|
||||
|
||||
case LEAF_ipForwarding:
|
||||
ctx->scratch->int1 = ip_forwarding ? 1 : 2;
|
||||
ctx->scratch->int2 = value->v.integer;
|
||||
if (value->v.integer == 1) {
|
||||
if (!ip_forwarding && ip_forward(1, &old))
|
||||
return (SNMP_ERR_GENERR);
|
||||
ctx->scratch->int1 = old ? 1 : 2;
|
||||
} else if (value->v.integer == 2) {
|
||||
if (ip_forwarding && ip_forward(0, &old))
|
||||
return (SNMP_ERR_GENERR);
|
||||
ctx->scratch->int1 = old;
|
||||
} else
|
||||
return (SNMP_ERR_WRONG_VALUE);
|
||||
break;
|
||||
|
||||
case LEAF_ipDefaultTTL:
|
||||
ctx->scratch->int1 = ip_defttl;
|
||||
ctx->scratch->int2 = value->v.integer;
|
||||
if (value->v.integer < 1 || value->v.integer > 255)
|
||||
return (SNMP_ERR_WRONG_VALUE);
|
||||
if (ip_defttl != value->v.integer &&
|
||||
ip_setttl(value->v.integer, &old))
|
||||
return (SNMP_ERR_GENERR);
|
||||
ctx->scratch->int1 = old;
|
||||
break;
|
||||
}
|
||||
return (SNMP_ERR_NOERROR);
|
||||
|
||||
case SNMP_OP_ROLLBACK:
|
||||
switch (value->var.subs[sub - 1]) {
|
||||
|
||||
case LEAF_ipForwarding:
|
||||
if (ctx->scratch->int1 == 1) {
|
||||
if (ctx->scratch->int2 == 2)
|
||||
(void)ip_forward(1, NULL);
|
||||
} else {
|
||||
if (ctx->scratch->int2 == 1)
|
||||
(void)ip_forward(0, NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
case LEAF_ipDefaultTTL:
|
||||
if (ctx->scratch->int1 != ctx->scratch->int2)
|
||||
(void)ip_setttl(ctx->scratch->int1, NULL);
|
||||
break;
|
||||
}
|
||||
return (SNMP_ERR_NOERROR);
|
||||
|
||||
case SNMP_OP_COMMIT:
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
if (ip_tick < this_tick)
|
||||
if (fetch_ip() == -1)
|
||||
return (SNMP_ERR_GENERR);
|
||||
|
||||
switch (value->var.subs[sub - 1]) {
|
||||
|
||||
case LEAF_ipForwarding:
|
||||
value->v.integer = ip_forwarding ? 1 : 2;
|
||||
break;
|
||||
|
||||
case LEAF_ipDefaultTTL:
|
||||
value->v.integer = ip_defttl;
|
||||
break;
|
||||
}
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* READ-ONLY statistics ip group.
|
||||
*/
|
||||
int
|
||||
op_ipstat(struct snmp_context *ctx __unused, struct snmp_value *value,
|
||||
u_int sub, u_int idx __unused, enum snmp_op op)
|
||||
{
|
||||
switch (op) {
|
||||
|
||||
case SNMP_OP_GETNEXT:
|
||||
abort();
|
||||
|
||||
case SNMP_OP_GET:
|
||||
break;
|
||||
|
||||
case SNMP_OP_SET:
|
||||
return (SNMP_ERR_NOT_WRITEABLE);
|
||||
|
||||
case SNMP_OP_ROLLBACK:
|
||||
case SNMP_OP_COMMIT:
|
||||
abort();
|
||||
}
|
||||
|
||||
if (ipstat_tick < this_tick)
|
||||
fetch_ipstat();
|
||||
|
||||
switch (value->var.subs[sub - 1]) {
|
||||
|
||||
case LEAF_ipInReceives:
|
||||
value->v.uint32 = ipstat.ips_total;
|
||||
break;
|
||||
|
||||
case LEAF_ipInHdrErrors:
|
||||
value->v.uint32 = ipstat.ips_badsum + ipstat.ips_tooshort
|
||||
+ ipstat.ips_toosmall + ipstat.ips_badhlen
|
||||
+ ipstat.ips_badlen + ipstat.ips_badvers +
|
||||
+ ipstat.ips_toolong;
|
||||
break;
|
||||
|
||||
case LEAF_ipInAddrErrors:
|
||||
value->v.uint32 = ipstat.ips_cantforward;
|
||||
break;
|
||||
|
||||
case LEAF_ipForwDatagrams:
|
||||
value->v.uint32 = ipstat.ips_forward;
|
||||
break;
|
||||
|
||||
case LEAF_ipInUnknownProtos:
|
||||
value->v.uint32 = ipstat.ips_noproto;
|
||||
break;
|
||||
|
||||
case LEAF_ipInDiscards:
|
||||
value->v.uint32 = ip_idrop;
|
||||
break;
|
||||
|
||||
case LEAF_ipInDelivers:
|
||||
value->v.uint32 = ipstat.ips_delivered;
|
||||
break;
|
||||
|
||||
case LEAF_ipOutRequests:
|
||||
value->v.uint32 = ipstat.ips_localout;
|
||||
break;
|
||||
|
||||
case LEAF_ipOutDiscards:
|
||||
value->v.uint32 = ipstat.ips_odropped;
|
||||
break;
|
||||
|
||||
case LEAF_ipOutNoRoutes:
|
||||
value->v.uint32 = ipstat.ips_noroute;
|
||||
break;
|
||||
|
||||
case LEAF_ipReasmTimeout:
|
||||
value->v.integer = IPFRAGTTL;
|
||||
break;
|
||||
|
||||
case LEAF_ipReasmReqds:
|
||||
value->v.uint32 = ipstat.ips_fragments;
|
||||
break;
|
||||
|
||||
case LEAF_ipReasmOKs:
|
||||
value->v.uint32 = ipstat.ips_reassembled;
|
||||
break;
|
||||
|
||||
case LEAF_ipReasmFails:
|
||||
value->v.uint32 = ipstat.ips_fragdropped
|
||||
+ ipstat.ips_fragtimeout;
|
||||
break;
|
||||
|
||||
case LEAF_ipFragOKs:
|
||||
value->v.uint32 = ipstat.ips_fragmented;
|
||||
break;
|
||||
|
||||
case LEAF_ipFragFails:
|
||||
value->v.uint32 = ipstat.ips_cantfrag;
|
||||
break;
|
||||
|
||||
case LEAF_ipFragCreates:
|
||||
value->v.uint32 = ipstat.ips_ofragments;
|
||||
break;
|
||||
}
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* READ-ONLY statistics icmp group.
|
||||
*/
|
||||
int
|
||||
op_icmpstat(struct snmp_context *ctx __unused, struct snmp_value *value,
|
||||
u_int sub, u_int idx __unused, enum snmp_op op)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
switch (op) {
|
||||
|
||||
case SNMP_OP_GETNEXT:
|
||||
abort();
|
||||
|
||||
case SNMP_OP_GET:
|
||||
break;
|
||||
|
||||
case SNMP_OP_SET:
|
||||
return (SNMP_ERR_NOT_WRITEABLE);
|
||||
|
||||
case SNMP_OP_ROLLBACK:
|
||||
case SNMP_OP_COMMIT:
|
||||
abort();
|
||||
}
|
||||
|
||||
if (ipstat_tick < this_tick)
|
||||
fetch_ipstat();
|
||||
|
||||
switch (value->var.subs[sub - 1]) {
|
||||
|
||||
case LEAF_icmpInMsgs:
|
||||
value->v.integer = 0;
|
||||
for (i = 0; i <= ICMP_MAXTYPE; i++)
|
||||
value->v.integer += icmpstat.icps_inhist[i];
|
||||
value->v.integer += icmpstat.icps_tooshort +
|
||||
icmpstat.icps_checksum;
|
||||
/* missing: bad type and packets on faith */
|
||||
break;
|
||||
|
||||
case LEAF_icmpInErrors:
|
||||
value->v.integer = icmpstat.icps_tooshort +
|
||||
icmpstat.icps_checksum +
|
||||
icmpstat.icps_badlen +
|
||||
icmpstat.icps_badcode +
|
||||
icmpstat.icps_bmcastecho +
|
||||
icmpstat.icps_bmcasttstamp;
|
||||
break;
|
||||
|
||||
case LEAF_icmpInDestUnreachs:
|
||||
value->v.integer = icmpstat.icps_inhist[ICMP_UNREACH];
|
||||
break;
|
||||
|
||||
case LEAF_icmpInTimeExcds:
|
||||
value->v.integer = icmpstat.icps_inhist[ICMP_TIMXCEED];
|
||||
break;
|
||||
|
||||
case LEAF_icmpInParmProbs:
|
||||
value->v.integer = icmpstat.icps_inhist[ICMP_PARAMPROB];
|
||||
break;
|
||||
|
||||
case LEAF_icmpInSrcQuenchs:
|
||||
value->v.integer = icmpstat.icps_inhist[ICMP_SOURCEQUENCH];
|
||||
break;
|
||||
|
||||
case LEAF_icmpInRedirects:
|
||||
value->v.integer = icmpstat.icps_inhist[ICMP_REDIRECT];
|
||||
break;
|
||||
|
||||
case LEAF_icmpInEchos:
|
||||
value->v.integer = icmpstat.icps_inhist[ICMP_ECHO];
|
||||
break;
|
||||
|
||||
case LEAF_icmpInEchoReps:
|
||||
value->v.integer = icmpstat.icps_inhist[ICMP_ECHOREPLY];
|
||||
break;
|
||||
|
||||
case LEAF_icmpInTimestamps:
|
||||
value->v.integer = icmpstat.icps_inhist[ICMP_TSTAMP];
|
||||
break;
|
||||
|
||||
case LEAF_icmpInTimestampReps:
|
||||
value->v.integer = icmpstat.icps_inhist[ICMP_TSTAMPREPLY];
|
||||
break;
|
||||
|
||||
case LEAF_icmpInAddrMasks:
|
||||
value->v.integer = icmpstat.icps_inhist[ICMP_MASKREQ];
|
||||
break;
|
||||
|
||||
case LEAF_icmpInAddrMaskReps:
|
||||
value->v.integer = icmpstat.icps_inhist[ICMP_MASKREPLY];
|
||||
break;
|
||||
|
||||
case LEAF_icmpOutMsgs:
|
||||
value->v.integer = 0;
|
||||
for (i = 0; i <= ICMP_MAXTYPE; i++)
|
||||
value->v.integer += icmpstat.icps_outhist[i];
|
||||
value->v.integer += icmpstat.icps_badaddr +
|
||||
icmpstat.icps_noroute;
|
||||
break;
|
||||
|
||||
case LEAF_icmpOutErrors:
|
||||
value->v.integer = icmpstat.icps_badaddr +
|
||||
icmpstat.icps_noroute;
|
||||
break;
|
||||
|
||||
case LEAF_icmpOutDestUnreachs:
|
||||
value->v.integer = icmpstat.icps_outhist[ICMP_UNREACH];
|
||||
break;
|
||||
|
||||
case LEAF_icmpOutTimeExcds:
|
||||
value->v.integer = icmpstat.icps_outhist[ICMP_TIMXCEED];
|
||||
break;
|
||||
|
||||
case LEAF_icmpOutParmProbs:
|
||||
value->v.integer = icmpstat.icps_outhist[ICMP_PARAMPROB];
|
||||
break;
|
||||
|
||||
case LEAF_icmpOutSrcQuenchs:
|
||||
value->v.integer = icmpstat.icps_outhist[ICMP_SOURCEQUENCH];
|
||||
break;
|
||||
|
||||
case LEAF_icmpOutRedirects:
|
||||
value->v.integer = icmpstat.icps_outhist[ICMP_REDIRECT];
|
||||
break;
|
||||
|
||||
case LEAF_icmpOutEchos:
|
||||
value->v.integer = icmpstat.icps_outhist[ICMP_ECHO];
|
||||
break;
|
||||
|
||||
case LEAF_icmpOutEchoReps:
|
||||
value->v.integer = icmpstat.icps_outhist[ICMP_ECHOREPLY];
|
||||
break;
|
||||
|
||||
case LEAF_icmpOutTimestamps:
|
||||
value->v.integer = icmpstat.icps_outhist[ICMP_TSTAMP];
|
||||
break;
|
||||
|
||||
case LEAF_icmpOutTimestampReps:
|
||||
value->v.integer = icmpstat.icps_outhist[ICMP_TSTAMPREPLY];
|
||||
break;
|
||||
|
||||
case LEAF_icmpOutAddrMasks:
|
||||
value->v.integer = icmpstat.icps_outhist[ICMP_MASKREQ];
|
||||
break;
|
||||
|
||||
case LEAF_icmpOutAddrMaskReps:
|
||||
value->v.integer = icmpstat.icps_outhist[ICMP_MASKREPLY];
|
||||
break;
|
||||
}
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
351
contrib/bsnmp/snmp_mibII/mibII_ipaddr.c
Normal file
351
contrib/bsnmp/snmp_mibII/mibII_ipaddr.c
Normal file
@ -0,0 +1,351 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2002
|
||||
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Harti Brandt <harti@freebsd.org>
|
||||
*
|
||||
* Redistribution of this software and documentation 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 or documentation 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.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
* AND ITS 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
|
||||
* FRAUNHOFER FOKUS OR ITS 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.
|
||||
*
|
||||
* $Begemot: bsnmp/snmp_mibII/mibII_ipaddr.c,v 1.6 2003/01/28 13:44:35 hbb Exp $
|
||||
*
|
||||
* IP address table. This table is writeable!
|
||||
*
|
||||
* Writing to this table will add a new IP address to the interface.
|
||||
* An address can be deleted with writing the interface index 0.
|
||||
*/
|
||||
#include "mibII.h"
|
||||
#include "mibII_oid.h"
|
||||
|
||||
static const struct asn_oid
|
||||
oid_ipAddrTable = OIDX_ipAddrTable;
|
||||
|
||||
/*
|
||||
* Be careful not to hold any pointers during the SET processing - the
|
||||
* interface and address lists can be relocated at any time.
|
||||
*/
|
||||
struct update {
|
||||
struct snmp_dependency dep;
|
||||
|
||||
u_int32_t set;
|
||||
struct in_addr addr;
|
||||
struct in_addr mask;
|
||||
int bcast;
|
||||
u_int ifindex;
|
||||
|
||||
u_int32_t rb;
|
||||
struct in_addr rb_mask;
|
||||
struct in_addr rb_bcast;
|
||||
};
|
||||
#define UPD_IFINDEX 0x0001
|
||||
#define UPD_MASK 0x0002
|
||||
#define UPD_BCAST 0x0004
|
||||
#define RB_CREATE 0x0001
|
||||
#define RB_DESTROY 0x0002
|
||||
#define RB_MODIFY 0x0004
|
||||
|
||||
/*
|
||||
* Create a new interface address
|
||||
*/
|
||||
static int
|
||||
create(struct update *upd)
|
||||
{
|
||||
struct in_addr bcast;
|
||||
struct mibifa *ifa;
|
||||
|
||||
if (!(upd->set & UPD_MASK)) {
|
||||
if (IN_CLASSA(ntohl(upd->addr.s_addr)))
|
||||
upd->mask.s_addr = htonl(IN_CLASSA_NET);
|
||||
else if (IN_CLASSB(ntohl(upd->addr.s_addr)))
|
||||
upd->mask.s_addr = htonl(IN_CLASSB_NET);
|
||||
else if (IN_CLASSC(ntohl(upd->addr.s_addr)))
|
||||
upd->mask.s_addr = htonl(IN_CLASSC_NET);
|
||||
else
|
||||
upd->mask.s_addr = 0xffffffff;
|
||||
}
|
||||
|
||||
bcast.s_addr = upd->addr.s_addr & upd->mask.s_addr;
|
||||
if (!(upd->set & UPD_BCAST) || upd->bcast)
|
||||
bcast.s_addr |= htonl(0xffffffff & ~ntohl(upd->mask.s_addr));
|
||||
|
||||
if ((ifa = mib_create_ifa(upd->ifindex, upd->addr, upd->mask, bcast)) == NULL)
|
||||
return (SNMP_ERR_GENERR);
|
||||
|
||||
upd->rb |= RB_CREATE;
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Modify the netmask or broadcast address. The ifindex cannot be
|
||||
* changed (obviously).
|
||||
*/
|
||||
static int
|
||||
modify(struct update *upd, struct mibifa *ifa)
|
||||
{
|
||||
struct mibif *ifp;
|
||||
|
||||
if ((ifp = mib_find_if(ifa->ifindex)) == NULL)
|
||||
return (SNMP_ERR_WRONG_VALUE);
|
||||
if ((upd->set & UPD_IFINDEX) && upd->ifindex != ifa->ifindex)
|
||||
return (SNMP_ERR_INCONS_VALUE);
|
||||
|
||||
upd->rb_mask = ifa->inmask;
|
||||
upd->rb_bcast = ifa->inbcast;
|
||||
if (((upd->set & UPD_MASK) && upd->mask.s_addr != ifa->inmask.s_addr) ||
|
||||
(upd->set & UPD_BCAST)) {
|
||||
if (upd->set & UPD_MASK)
|
||||
ifa->inmask = upd->mask;
|
||||
if (upd->set & UPD_BCAST) {
|
||||
ifa->inbcast.s_addr = ifa->inaddr.s_addr
|
||||
& ifa->inmask.s_addr;
|
||||
if (upd->bcast)
|
||||
ifa->inbcast.s_addr |= 0xffffffff
|
||||
& ~ifa->inmask.s_addr;
|
||||
}
|
||||
if (mib_modify_ifa(ifa)) {
|
||||
syslog(LOG_ERR, "set netmask/bcast: %m");
|
||||
ifa->inmask = upd->rb_mask;
|
||||
ifa->inbcast = upd->rb_bcast;
|
||||
mib_unmodify_ifa(ifa);
|
||||
return (SNMP_ERR_GENERR);
|
||||
}
|
||||
upd->rb |= RB_MODIFY;
|
||||
}
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove an IP address from an interface. This is called when
|
||||
* the SET finishes.
|
||||
*/
|
||||
static void
|
||||
destroy_func(struct snmp_context *ctx __unused, int fail __unused, void *arg)
|
||||
{
|
||||
struct mibifa *ifa = arg;
|
||||
|
||||
if (ifa->flags & MIBIFA_DESTROYED) {
|
||||
TAILQ_REMOVE(&mibifa_list, ifa, link);
|
||||
free(ifa);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy the given row in the table. We remove the address from the
|
||||
* system, but keep the structure around for the COMMIT. It's deleted
|
||||
* only in the finish function.
|
||||
*/
|
||||
static int
|
||||
destroy(struct snmp_context *ctx, struct update *upd, struct mibifa *ifa)
|
||||
{
|
||||
if (mib_destroy_ifa(ifa))
|
||||
return (SNMP_ERR_GENERR);
|
||||
if (snmp_set_atfinish(ctx, destroy_func, ifa)) {
|
||||
syslog(LOG_ERR, "atfinish: %m");
|
||||
mib_undestroy_ifa(ifa);
|
||||
return (SNMP_ERR_GENERR);
|
||||
}
|
||||
upd->rb |= RB_DESTROY;
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called to commit/rollback a SET on an IpAddrEntry
|
||||
*/
|
||||
static int
|
||||
update_func(struct snmp_context *ctx, struct snmp_dependency *dep,
|
||||
enum snmp_depop op)
|
||||
{
|
||||
struct update *upd = (struct update *)dep;
|
||||
struct mibifa *ifa;
|
||||
|
||||
switch (op) {
|
||||
|
||||
case SNMP_DEPOP_COMMIT:
|
||||
if ((ifa = mib_find_ifa(upd->addr)) == NULL) {
|
||||
/* non existing entry - must have ifindex */
|
||||
if (!(upd->set & UPD_IFINDEX))
|
||||
return (SNMP_ERR_INCONS_NAME);
|
||||
return (create(upd));
|
||||
}
|
||||
/* existing entry */
|
||||
if ((upd->set & UPD_IFINDEX) && upd->ifindex == 0) {
|
||||
/* delete */
|
||||
return (destroy(ctx, upd, ifa));
|
||||
}
|
||||
/* modify entry */
|
||||
return (modify(upd, ifa));
|
||||
|
||||
case SNMP_DEPOP_ROLLBACK:
|
||||
if ((ifa = mib_find_ifa(upd->addr)) == NULL) {
|
||||
/* ups */
|
||||
mib_iflist_bad = 1;
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
if (upd->rb & RB_CREATE) {
|
||||
mib_uncreate_ifa(ifa);
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
if (upd->rb & RB_DESTROY) {
|
||||
mib_undestroy_ifa(ifa);
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
if (upd->rb & RB_MODIFY) {
|
||||
ifa->inmask = upd->rb_mask;
|
||||
ifa->inbcast = upd->rb_bcast;
|
||||
mib_unmodify_ifa(ifa);
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
abort();
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
/*
|
||||
* ACTION
|
||||
*/
|
||||
int
|
||||
op_ipaddr(struct snmp_context *ctx, struct snmp_value *value,
|
||||
u_int sub, u_int iidx, enum snmp_op op)
|
||||
{
|
||||
asn_subid_t which;
|
||||
struct mibifa *ifa;
|
||||
struct update *upd;
|
||||
struct asn_oid idx;
|
||||
u_char ipaddr[4];
|
||||
|
||||
which = value->var.subs[sub - 1];
|
||||
|
||||
ifa = NULL;
|
||||
|
||||
switch (op) {
|
||||
|
||||
case SNMP_OP_GETNEXT:
|
||||
if ((ifa = NEXT_OBJECT_OID(&mibifa_list, &value->var, sub)) == NULL)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
index_append(&value->var, sub, &ifa->index);
|
||||
break;
|
||||
|
||||
case SNMP_OP_GET:
|
||||
if ((ifa = FIND_OBJECT_OID(&mibifa_list, &value->var, sub)) == NULL)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
break;
|
||||
|
||||
case SNMP_OP_SET:
|
||||
if (index_decode(&value->var, sub, iidx, ipaddr))
|
||||
return (SNMP_ERR_NO_CREATION);
|
||||
ifa = FIND_OBJECT_OID(&mibifa_list, &value->var, sub);
|
||||
idx.len = 4;
|
||||
idx.subs[0] = ipaddr[0];
|
||||
idx.subs[1] = ipaddr[1];
|
||||
idx.subs[2] = ipaddr[2];
|
||||
idx.subs[3] = ipaddr[3];
|
||||
|
||||
if ((upd = (struct update *)snmp_dep_lookup(ctx,
|
||||
&oid_ipAddrTable, &idx, sizeof(*upd), update_func)) == NULL)
|
||||
return (SNMP_ERR_RES_UNAVAIL);
|
||||
|
||||
upd->addr.s_addr = htonl((ipaddr[0] << 24) | (ipaddr[1] << 16) |
|
||||
(ipaddr[2] << 8) | (ipaddr[3] << 0));
|
||||
|
||||
switch (which) {
|
||||
|
||||
case LEAF_ipAdEntIfIndex:
|
||||
if (upd->set & UPD_IFINDEX)
|
||||
return (SNMP_ERR_INCONS_VALUE);
|
||||
if (value->v.integer < 0 ||
|
||||
value->v.integer > 0x07fffffff)
|
||||
return (SNMP_ERR_WRONG_VALUE);
|
||||
if (ifa != NULL) {
|
||||
if (ifa->ifindex != (u_int)value->v.integer &&
|
||||
value->v.integer != 0)
|
||||
return (SNMP_ERR_INCONS_VALUE);
|
||||
}
|
||||
upd->set |= UPD_IFINDEX;
|
||||
upd->ifindex = (u_int)value->v.integer;
|
||||
break;
|
||||
|
||||
case LEAF_ipAdEntNetMask:
|
||||
if (upd->set & UPD_MASK)
|
||||
return (SNMP_ERR_INCONS_VALUE);
|
||||
upd->mask.s_addr = htonl((value->v.ipaddress[0] << 24)
|
||||
| (value->v.ipaddress[1] << 16)
|
||||
| (value->v.ipaddress[2] << 8)
|
||||
| (value->v.ipaddress[3] << 0));
|
||||
upd->set |= UPD_MASK;
|
||||
break;
|
||||
|
||||
case LEAF_ipAdEntBcastAddr:
|
||||
if (upd->set & UPD_BCAST)
|
||||
return (SNMP_ERR_INCONS_VALUE);
|
||||
if (value->v.integer != 0 && value->v.integer != 1)
|
||||
return (SNMP_ERR_WRONG_VALUE);
|
||||
upd->bcast = value->v.integer;
|
||||
upd->set |= UPD_BCAST;
|
||||
break;
|
||||
|
||||
}
|
||||
return (SNMP_ERR_NOERROR);
|
||||
|
||||
case SNMP_OP_ROLLBACK:
|
||||
case SNMP_OP_COMMIT:
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
switch (which) {
|
||||
|
||||
case LEAF_ipAdEntAddr:
|
||||
value->v.ipaddress[0] = ifa->index.subs[0];
|
||||
value->v.ipaddress[1] = ifa->index.subs[1];
|
||||
value->v.ipaddress[2] = ifa->index.subs[2];
|
||||
value->v.ipaddress[3] = ifa->index.subs[3];
|
||||
break;
|
||||
|
||||
case LEAF_ipAdEntIfIndex:
|
||||
if (ifa->flags & MIBIFA_DESTROYED)
|
||||
value->v.integer = 0;
|
||||
else
|
||||
value->v.integer = ifa->ifindex;
|
||||
break;
|
||||
|
||||
case LEAF_ipAdEntNetMask:
|
||||
value->v.ipaddress[0] = (ntohl(ifa->inmask.s_addr) >> 24) & 0xff;
|
||||
value->v.ipaddress[1] = (ntohl(ifa->inmask.s_addr) >> 16) & 0xff;
|
||||
value->v.ipaddress[2] = (ntohl(ifa->inmask.s_addr) >> 8) & 0xff;
|
||||
value->v.ipaddress[3] = (ntohl(ifa->inmask.s_addr) >> 0) & 0xff;
|
||||
break;
|
||||
|
||||
case LEAF_ipAdEntBcastAddr:
|
||||
value->v.integer = ntohl(ifa->inbcast.s_addr) & 1;
|
||||
break;
|
||||
|
||||
|
||||
case LEAF_ipAdEntReasmMaxSize:
|
||||
value->v.integer = 65535;
|
||||
break;
|
||||
}
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
154
contrib/bsnmp/snmp_mibII/mibII_nettomedia.c
Normal file
154
contrib/bsnmp/snmp_mibII/mibII_nettomedia.c
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003
|
||||
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Harti Brandt <harti@freebsd.org>
|
||||
*
|
||||
* Redistribution of this software and documentation 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 or documentation 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.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
* AND ITS 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
|
||||
* FRAUNHOFER FOKUS OR ITS 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.
|
||||
*
|
||||
* $Begemot: bsnmp/snmp_mibII/mibII_nettomedia.c,v 1.6 2003/01/28 13:44:35 hbb Exp $
|
||||
*
|
||||
* Read-only implementation of the Arp table (ipNetToMediaTable)
|
||||
*
|
||||
* The problem with the table is, that we don't receive routing message
|
||||
* when a) an arp table entry is resolved and b) when an arp table entry is
|
||||
* deleted automatically. Therefor we need to poll the table from time to
|
||||
* time.
|
||||
*/
|
||||
#include "mibII.h"
|
||||
#include "mibII_oid.h"
|
||||
|
||||
#define ARPREFRESH 30
|
||||
|
||||
struct mibarp *
|
||||
mib_find_arp(const struct mibif *ifp, struct in_addr in)
|
||||
{
|
||||
struct mibarp *at;
|
||||
u_int32_t a = ntohl(in.s_addr);
|
||||
|
||||
if (get_ticks() >= mibarpticks + ARPREFRESH)
|
||||
mib_arp_update();
|
||||
|
||||
TAILQ_FOREACH(at, &mibarp_list, link)
|
||||
if (at->index.subs[0] == ifp->index &&
|
||||
(at->index.subs[1] == ((a >> 24) & 0xff)) &&
|
||||
(at->index.subs[2] == ((a >> 16) & 0xff)) &&
|
||||
(at->index.subs[3] == ((a >> 8) & 0xff)) &&
|
||||
(at->index.subs[4] == ((a >> 0) & 0xff)))
|
||||
return (at);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
struct mibarp *
|
||||
mib_arp_create(const struct mibif *ifp, struct in_addr in, const u_char *phys,
|
||||
size_t physlen)
|
||||
{
|
||||
struct mibarp *at;
|
||||
u_int32_t a = ntohl(in.s_addr);
|
||||
|
||||
if ((at = malloc(sizeof(*at))) == NULL)
|
||||
return (NULL);
|
||||
at->flags = 0;
|
||||
|
||||
at->index.len = 5;
|
||||
at->index.subs[0] = ifp->index;
|
||||
at->index.subs[1] = (a >> 24) & 0xff;
|
||||
at->index.subs[2] = (a >> 16) & 0xff;
|
||||
at->index.subs[3] = (a >> 8) & 0xff;
|
||||
at->index.subs[4] = (a >> 0) & 0xff;
|
||||
if ((at->physlen = physlen) > sizeof(at->phys))
|
||||
at->physlen = sizeof(at->phys);
|
||||
memcpy(at->phys, phys, at->physlen);
|
||||
|
||||
INSERT_OBJECT_OID(at, &mibarp_list);
|
||||
|
||||
return (at);
|
||||
}
|
||||
|
||||
void
|
||||
mib_arp_delete(struct mibarp *at)
|
||||
{
|
||||
TAILQ_REMOVE(&mibarp_list, at, link);
|
||||
free(at);
|
||||
}
|
||||
|
||||
int
|
||||
op_nettomedia(struct snmp_context *ctx __unused, struct snmp_value *value,
|
||||
u_int sub, u_int iidx __unused, enum snmp_op op)
|
||||
{
|
||||
struct mibarp *at;
|
||||
|
||||
at = NULL; /* gcc */
|
||||
|
||||
if (get_ticks() >= mibarpticks + ARPREFRESH)
|
||||
mib_arp_update();
|
||||
|
||||
switch (op) {
|
||||
|
||||
case SNMP_OP_GETNEXT:
|
||||
if ((at = NEXT_OBJECT_OID(&mibarp_list, &value->var, sub)) == NULL)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
index_append(&value->var, sub, &at->index);
|
||||
break;
|
||||
|
||||
case SNMP_OP_GET:
|
||||
if ((at = FIND_OBJECT_OID(&mibarp_list, &value->var, sub)) == NULL)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
break;
|
||||
|
||||
case SNMP_OP_SET:
|
||||
if ((at = FIND_OBJECT_OID(&mibarp_list, &value->var, sub)) == NULL)
|
||||
return (SNMP_ERR_NO_CREATION);
|
||||
return (SNMP_ERR_NOT_WRITEABLE);
|
||||
|
||||
case SNMP_OP_ROLLBACK:
|
||||
case SNMP_OP_COMMIT:
|
||||
abort();
|
||||
}
|
||||
|
||||
switch (value->var.subs[sub - 1]) {
|
||||
|
||||
case LEAF_ipNetToMediaIfIndex:
|
||||
value->v.integer = at->index.subs[0];
|
||||
break;
|
||||
|
||||
case LEAF_ipNetToMediaPhysAddress:
|
||||
return (string_get(value, at->phys, at->physlen));
|
||||
|
||||
case LEAF_ipNetToMediaNetAddress:
|
||||
value->v.ipaddress[0] = at->index.subs[1];
|
||||
value->v.ipaddress[1] = at->index.subs[2];
|
||||
value->v.ipaddress[2] = at->index.subs[3];
|
||||
value->v.ipaddress[3] = at->index.subs[4];
|
||||
break;
|
||||
|
||||
case LEAF_ipNetToMediaType:
|
||||
value->v.integer = (at->flags & MIBARP_PERM) ? 4 : 3;
|
||||
break;
|
||||
}
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
138
contrib/bsnmp/snmp_mibII/mibII_rcvaddr.c
Normal file
138
contrib/bsnmp/snmp_mibII/mibII_rcvaddr.c
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003
|
||||
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Harti Brandt <harti@freebsd.org>
|
||||
*
|
||||
* Redistribution of this software and documentation 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 or documentation 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.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
* AND ITS 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
|
||||
* FRAUNHOFER FOKUS OR ITS 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.
|
||||
*
|
||||
* $Begemot: bsnmp/snmp_mibII/mibII_rcvaddr.c,v 1.7 2003/01/28 13:44:35 hbb Exp $
|
||||
*
|
||||
* Interface receive address table.
|
||||
*/
|
||||
#include "mibII.h"
|
||||
#include "mibII_oid.h"
|
||||
|
||||
/*
|
||||
* find receive address
|
||||
*/
|
||||
struct mibrcvaddr *
|
||||
mib_find_rcvaddr(u_int ifindex, const u_char *addr, size_t addrlen)
|
||||
{
|
||||
struct mibrcvaddr *rcv;
|
||||
|
||||
TAILQ_FOREACH(rcv, &mibrcvaddr_list, link)
|
||||
if (rcv->ifindex == ifindex &&
|
||||
rcv->addrlen == addrlen &&
|
||||
memcmp(rcv->addr, addr, addrlen) == 0)
|
||||
return (rcv);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create receive address
|
||||
*/
|
||||
struct mibrcvaddr *
|
||||
mib_rcvaddr_create(struct mibif *ifp, const u_char *addr, size_t addrlen)
|
||||
{
|
||||
struct mibrcvaddr *rcv;
|
||||
u_int i;
|
||||
|
||||
if (addrlen + OIDLEN_ifRcvAddressEntry + 1 > ASN_MAXOIDLEN)
|
||||
return (NULL);
|
||||
|
||||
if ((rcv = malloc(sizeof(*rcv))) == NULL)
|
||||
return (NULL);
|
||||
rcv->ifindex = ifp->index;
|
||||
rcv->addrlen = addrlen;
|
||||
memcpy(rcv->addr, addr, addrlen);
|
||||
rcv->flags = 0;
|
||||
|
||||
rcv->index.len = addrlen + 2;
|
||||
rcv->index.subs[0] = ifp->index;
|
||||
rcv->index.subs[1] = addrlen;
|
||||
for (i = 0; i < addrlen; i++)
|
||||
rcv->index.subs[i + 2] = addr[i];
|
||||
|
||||
INSERT_OBJECT_OID(rcv, &mibrcvaddr_list);
|
||||
|
||||
return (rcv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete a receive address
|
||||
*/
|
||||
void
|
||||
mib_rcvaddr_delete(struct mibrcvaddr *rcv)
|
||||
{
|
||||
TAILQ_REMOVE(&mibrcvaddr_list, rcv, link);
|
||||
free(rcv);
|
||||
}
|
||||
|
||||
int
|
||||
op_rcvaddr(struct snmp_context *ctx __unused, struct snmp_value *value,
|
||||
u_int sub, u_int iidx __unused, enum snmp_op op)
|
||||
{
|
||||
struct mibrcvaddr *rcv;
|
||||
|
||||
rcv = NULL; /* make compiler happy */
|
||||
|
||||
switch (op) {
|
||||
|
||||
case SNMP_OP_GETNEXT:
|
||||
if ((rcv = NEXT_OBJECT_OID(&mibrcvaddr_list, &value->var, sub)) == NULL)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
index_append(&value->var, sub, &rcv->index);
|
||||
break;
|
||||
|
||||
case SNMP_OP_GET:
|
||||
if ((rcv = FIND_OBJECT_OID(&mibrcvaddr_list, &value->var, sub)) == NULL)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
break;
|
||||
|
||||
case SNMP_OP_SET:
|
||||
if ((rcv = FIND_OBJECT_OID(&mibrcvaddr_list, &value->var, sub)) == NULL)
|
||||
return (SNMP_ERR_NO_CREATION);
|
||||
return (SNMP_ERR_NOT_WRITEABLE);
|
||||
|
||||
case SNMP_OP_ROLLBACK:
|
||||
case SNMP_OP_COMMIT:
|
||||
abort();
|
||||
}
|
||||
|
||||
switch (value->var.subs[sub - 1]) {
|
||||
|
||||
case LEAF_ifRcvAddressStatus:
|
||||
value->v.integer = 1;
|
||||
break;
|
||||
|
||||
case LEAF_ifRcvAddressType:
|
||||
value->v.integer = (rcv->flags & MIBRCVADDR_VOLATILE) ? 2 : 3;
|
||||
break;
|
||||
}
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
299
contrib/bsnmp/snmp_mibII/mibII_route.c
Normal file
299
contrib/bsnmp/snmp_mibII/mibII_route.c
Normal file
@ -0,0 +1,299 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003
|
||||
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Harti Brandt <harti@freebsd.org>
|
||||
*
|
||||
* Redistribution of this software and documentation 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 or documentation 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.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
* AND ITS 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
|
||||
* FRAUNHOFER FOKUS OR ITS 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.
|
||||
*
|
||||
* $Begemot: bsnmp/snmp_mibII/mibII_route.c,v 1.3 2003/01/28 13:44:35 hbb Exp $
|
||||
*
|
||||
* Routing table
|
||||
*/
|
||||
#include "mibII.h"
|
||||
#include "mibII_oid.h"
|
||||
|
||||
struct sroute {
|
||||
TAILQ_ENTRY(sroute) link;
|
||||
struct asn_oid index;
|
||||
u_int ifindex;
|
||||
u_int type;
|
||||
u_int proto;
|
||||
};
|
||||
static TAILQ_HEAD(, sroute) sroute_list = TAILQ_HEAD_INITIALIZER(sroute_list);
|
||||
|
||||
static u_int32_t route_tick;
|
||||
static u_int route_total;
|
||||
|
||||
static int
|
||||
fetch_route(void)
|
||||
{
|
||||
u_char *rtab, *next;
|
||||
size_t len;
|
||||
struct sroute *r;
|
||||
struct rt_msghdr *rtm;
|
||||
struct sockaddr *addrs[RTAX_MAX];
|
||||
struct sockaddr_in *sa, *gw;
|
||||
struct in_addr mask, nhop;
|
||||
in_addr_t ha;
|
||||
struct mibif *ifp;
|
||||
|
||||
while ((r = TAILQ_FIRST(&sroute_list)) != NULL) {
|
||||
TAILQ_REMOVE(&sroute_list, r, link);
|
||||
free(r);
|
||||
}
|
||||
route_total = 0;
|
||||
|
||||
if ((rtab = mib_fetch_rtab(AF_INET, NET_RT_DUMP, 0, &len)) == NULL)
|
||||
return (-1);
|
||||
|
||||
next = rtab;
|
||||
for (next = rtab; next < rtab + len; next += rtm->rtm_msglen) {
|
||||
rtm = (struct rt_msghdr *)(void *)next;
|
||||
if (rtm->rtm_type != RTM_GET ||
|
||||
!(rtm->rtm_flags & RTF_UP))
|
||||
continue;
|
||||
mib_extract_addrs(rtm->rtm_addrs, (u_char *)(rtm + 1), addrs);
|
||||
|
||||
if (addrs[RTAX_DST] == NULL || addrs[RTAX_GATEWAY] == NULL ||
|
||||
addrs[RTAX_DST]->sa_family != AF_INET)
|
||||
continue;
|
||||
|
||||
sa = (struct sockaddr_in *)(void *)addrs[RTAX_DST];
|
||||
|
||||
if (rtm->rtm_flags & RTF_HOST) {
|
||||
mask.s_addr = 0xffffffff;
|
||||
} else {
|
||||
if (addrs[RTAX_NETMASK] == NULL ||
|
||||
addrs[RTAX_NETMASK]->sa_len == 0)
|
||||
mask.s_addr = 0;
|
||||
else
|
||||
mask = ((struct sockaddr_in *)(void *)
|
||||
addrs[RTAX_NETMASK])->sin_addr;
|
||||
}
|
||||
if (addrs[RTAX_GATEWAY] == NULL) {
|
||||
nhop.s_addr = 0;
|
||||
} else if (rtm->rtm_flags & RTF_LLINFO) {
|
||||
nhop = sa->sin_addr;
|
||||
} else {
|
||||
gw = (struct sockaddr_in *)(void *)addrs[RTAX_GATEWAY];
|
||||
if (gw->sin_family != AF_INET)
|
||||
continue;
|
||||
nhop = gw->sin_addr;
|
||||
}
|
||||
if ((ifp = mib_find_if_sys(rtm->rtm_index)) == NULL) {
|
||||
mib_iflist_bad = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((r = malloc(sizeof(*r))) == NULL) {
|
||||
syslog(LOG_ERR, "%m");
|
||||
continue;
|
||||
}
|
||||
|
||||
route_total++;
|
||||
|
||||
r->index.len = 13;
|
||||
ha = ntohl(sa->sin_addr.s_addr);
|
||||
r->index.subs[0] = (ha >> 24) & 0xff;
|
||||
r->index.subs[1] = (ha >> 16) & 0xff;
|
||||
r->index.subs[2] = (ha >> 8) & 0xff;
|
||||
r->index.subs[3] = (ha >> 0) & 0xff;
|
||||
ha = ntohl(mask.s_addr);
|
||||
r->index.subs[4] = (ha >> 24) & 0xff;
|
||||
r->index.subs[5] = (ha >> 16) & 0xff;
|
||||
r->index.subs[6] = (ha >> 8) & 0xff;
|
||||
r->index.subs[7] = (ha >> 0) & 0xff;
|
||||
|
||||
r->index.subs[8] = 0;
|
||||
|
||||
ha = ntohl(nhop.s_addr);
|
||||
r->index.subs[9] = (ha >> 24) & 0xff;
|
||||
r->index.subs[10] = (ha >> 16) & 0xff;
|
||||
r->index.subs[11] = (ha >> 8) & 0xff;
|
||||
r->index.subs[12] = (ha >> 0) & 0xff;
|
||||
|
||||
r->ifindex = ifp->index;
|
||||
|
||||
r->type = (rtm->rtm_flags & RTF_LLINFO) ? 3 :
|
||||
(rtm->rtm_flags & RTF_REJECT) ? 2 : 4;
|
||||
|
||||
/* cannot really know, what protocol it runs */
|
||||
r->proto = (rtm->rtm_flags & RTF_LOCAL) ? 2 :
|
||||
(rtm->rtm_flags & RTF_STATIC) ? 3 :
|
||||
(rtm->rtm_flags & RTF_DYNAMIC) ? 4 : 10;
|
||||
|
||||
INSERT_OBJECT_OID(r, &sroute_list);
|
||||
}
|
||||
|
||||
free(rtab);
|
||||
route_tick = get_ticks();
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Table
|
||||
*/
|
||||
int
|
||||
op_route_table(struct snmp_context *ctx __unused, struct snmp_value *value,
|
||||
u_int sub, u_int iidx __unused, enum snmp_op op)
|
||||
{
|
||||
static struct sroute *r;
|
||||
|
||||
if (route_tick < this_tick)
|
||||
if (fetch_route() == -1)
|
||||
return (SNMP_ERR_GENERR);
|
||||
|
||||
switch (op) {
|
||||
|
||||
case SNMP_OP_GETNEXT:
|
||||
if ((r = NEXT_OBJECT_OID(&sroute_list, &value->var, sub)) == NULL)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
index_append(&value->var, sub, &r->index);
|
||||
break;
|
||||
|
||||
case SNMP_OP_GET:
|
||||
if ((r = FIND_OBJECT_OID(&sroute_list, &value->var, sub)) == NULL)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
break;
|
||||
|
||||
case SNMP_OP_SET:
|
||||
if ((r = FIND_OBJECT_OID(&sroute_list, &value->var, sub)) == NULL)
|
||||
return (SNMP_ERR_NO_CREATION);
|
||||
return (SNMP_ERR_NOT_WRITEABLE);
|
||||
|
||||
case SNMP_OP_ROLLBACK:
|
||||
case SNMP_OP_COMMIT:
|
||||
abort();
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
switch (value->var.subs[sub - 1]) {
|
||||
|
||||
case LEAF_ipCidrRouteDest:
|
||||
value->v.ipaddress[0] = r->index.subs[0];
|
||||
value->v.ipaddress[1] = r->index.subs[1];
|
||||
value->v.ipaddress[2] = r->index.subs[2];
|
||||
value->v.ipaddress[3] = r->index.subs[3];
|
||||
break;
|
||||
|
||||
case LEAF_ipCidrRouteMask:
|
||||
value->v.ipaddress[0] = r->index.subs[4];
|
||||
value->v.ipaddress[1] = r->index.subs[5];
|
||||
value->v.ipaddress[2] = r->index.subs[6];
|
||||
value->v.ipaddress[3] = r->index.subs[7];
|
||||
break;
|
||||
|
||||
case LEAF_ipCidrRouteTos:
|
||||
value->v.integer = r->index.subs[8];
|
||||
break;
|
||||
|
||||
case LEAF_ipCidrRouteNextHop:
|
||||
value->v.ipaddress[0] = r->index.subs[9];
|
||||
value->v.ipaddress[1] = r->index.subs[10];
|
||||
value->v.ipaddress[2] = r->index.subs[11];
|
||||
value->v.ipaddress[3] = r->index.subs[12];
|
||||
break;
|
||||
|
||||
case LEAF_ipCidrRouteIfIndex:
|
||||
value->v.integer = r->ifindex;
|
||||
break;
|
||||
|
||||
case LEAF_ipCidrRouteType:
|
||||
value->v.integer = r->type;
|
||||
break;
|
||||
|
||||
case LEAF_ipCidrRouteProto:
|
||||
value->v.integer = r->proto;
|
||||
break;
|
||||
|
||||
case LEAF_ipCidrRouteAge:
|
||||
value->v.integer = 0;
|
||||
break;
|
||||
|
||||
case LEAF_ipCidrRouteInfo:
|
||||
value->v.oid = oid_zeroDotZero;
|
||||
break;
|
||||
|
||||
case LEAF_ipCidrRouteNextHopAS:
|
||||
value->v.integer = 0;
|
||||
break;
|
||||
|
||||
case LEAF_ipCidrRouteMetric1:
|
||||
case LEAF_ipCidrRouteMetric2:
|
||||
case LEAF_ipCidrRouteMetric3:
|
||||
case LEAF_ipCidrRouteMetric4:
|
||||
case LEAF_ipCidrRouteMetric5:
|
||||
value->v.integer = -1;
|
||||
break;
|
||||
|
||||
case LEAF_ipCidrRouteStatus:
|
||||
value->v.integer = 1;
|
||||
break;
|
||||
}
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* scalars
|
||||
*/
|
||||
int
|
||||
op_route(struct snmp_context *ctx __unused, struct snmp_value *value,
|
||||
u_int sub, u_int iidx __unused, enum snmp_op op)
|
||||
{
|
||||
switch (op) {
|
||||
|
||||
case SNMP_OP_GETNEXT:
|
||||
abort();
|
||||
|
||||
case SNMP_OP_GET:
|
||||
break;
|
||||
|
||||
case SNMP_OP_SET:
|
||||
return (SNMP_ERR_NOT_WRITEABLE);
|
||||
|
||||
case SNMP_OP_ROLLBACK:
|
||||
case SNMP_OP_COMMIT:
|
||||
abort();
|
||||
}
|
||||
|
||||
if (route_tick < this_tick)
|
||||
if (fetch_route() == -1)
|
||||
return (SNMP_ERR_GENERR);
|
||||
|
||||
switch (value->var.subs[sub - 1]) {
|
||||
|
||||
case LEAF_ipCidrRouteNumber:
|
||||
value->v.uint32 = route_total;
|
||||
break;
|
||||
|
||||
}
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
361
contrib/bsnmp/snmp_mibII/mibII_tcp.c
Normal file
361
contrib/bsnmp/snmp_mibII/mibII_tcp.c
Normal file
@ -0,0 +1,361 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003
|
||||
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Harti Brandt <harti@freebsd.org>
|
||||
*
|
||||
* Redistribution of this software and documentation 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 or documentation 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.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
* AND ITS 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
|
||||
* FRAUNHOFER FOKUS OR ITS 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.
|
||||
*
|
||||
* $Begemot: bsnmp/snmp_mibII/mibII_tcp.c,v 1.4 2003/01/28 13:44:35 hbb Exp $
|
||||
*
|
||||
* tcp
|
||||
*/
|
||||
#include "mibII.h"
|
||||
#include "mibII_oid.h"
|
||||
#include <sys/socketvar.h>
|
||||
#include <netinet/in_pcb.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/tcp_var.h>
|
||||
#include <netinet/tcp_timer.h>
|
||||
#include <netinet/tcp_fsm.h>
|
||||
|
||||
struct tcp_index {
|
||||
struct asn_oid index;
|
||||
struct xtcpcb *tp;
|
||||
};
|
||||
|
||||
static u_int32_t tcp_tick;
|
||||
static struct tcpstat tcpstat;
|
||||
static struct xinpgen *xinpgen;
|
||||
static size_t xinpgen_len;
|
||||
static u_int tcp_count;
|
||||
static u_int tcp_total;
|
||||
|
||||
static u_int oidnum;
|
||||
static struct tcp_index *tcpoids;
|
||||
|
||||
static int
|
||||
tcp_compare(const void *p1, const void *p2)
|
||||
{
|
||||
const struct tcp_index *t1 = p1;
|
||||
const struct tcp_index *t2 = p2;
|
||||
|
||||
return (asn_compare_oid(&t1->index, &t2->index));
|
||||
}
|
||||
|
||||
static int
|
||||
fetch_tcp(void)
|
||||
{
|
||||
size_t len;
|
||||
struct xinpgen *ptr;
|
||||
struct xtcpcb *tp;
|
||||
struct tcp_index *oid;
|
||||
in_addr_t inaddr;
|
||||
|
||||
len = sizeof(tcpstat);
|
||||
if (sysctlbyname("net.inet.tcp.stats", &tcpstat, &len, NULL, 0) == -1) {
|
||||
syslog(LOG_ERR, "net.inet.tcp.stats: %m");
|
||||
return (-1);
|
||||
}
|
||||
if (len != sizeof(tcpstat)) {
|
||||
syslog(LOG_ERR, "net.inet.tcp.stats: wrong size");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
len = 0;
|
||||
if (sysctlbyname("net.inet.tcp.pcblist", NULL, &len, NULL, 0) == -1) {
|
||||
syslog(LOG_ERR, "net.inet.tcp.pcblist: %m");
|
||||
return (-1);
|
||||
}
|
||||
if (len > xinpgen_len) {
|
||||
if ((ptr = realloc(xinpgen, len)) == NULL) {
|
||||
syslog(LOG_ERR, "%zu: %m", len);
|
||||
return (-1);
|
||||
}
|
||||
xinpgen = ptr;
|
||||
xinpgen_len = len;
|
||||
}
|
||||
if (sysctlbyname("net.inet.tcp.pcblist", xinpgen, &len, NULL, 0) == -1) {
|
||||
syslog(LOG_ERR, "net.inet.tcp.pcblist: %m");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
tcp_tick = get_ticks();
|
||||
|
||||
tcp_count = 0;
|
||||
tcp_total = 0;
|
||||
for (ptr = (struct xinpgen *)(void *)((char *)xinpgen + xinpgen->xig_len);
|
||||
ptr->xig_len > sizeof(struct xinpgen);
|
||||
ptr = (struct xinpgen *)(void *)((char *)ptr + ptr->xig_len)) {
|
||||
tp = (struct xtcpcb *)ptr;
|
||||
if (tp->xt_inp.inp_gencnt > xinpgen->xig_gen ||
|
||||
(tp->xt_inp.inp_vflag & INP_IPV4) == 0)
|
||||
continue;
|
||||
|
||||
tcp_total++;
|
||||
if (tp->xt_tp.t_state == TCPS_ESTABLISHED ||
|
||||
tp->xt_tp.t_state == TCPS_CLOSE_WAIT)
|
||||
tcp_count++;
|
||||
}
|
||||
|
||||
if (oidnum < tcp_total) {
|
||||
oid = realloc(tcpoids, tcp_total * sizeof(tcpoids[0]));
|
||||
if (oid == NULL) {
|
||||
free(tcpoids);
|
||||
oidnum = 0;
|
||||
return (0);
|
||||
}
|
||||
tcpoids = oid;
|
||||
oidnum = tcp_total;
|
||||
}
|
||||
|
||||
oid = tcpoids;
|
||||
for (ptr = (struct xinpgen *)(void *)((char *)xinpgen + xinpgen->xig_len);
|
||||
ptr->xig_len > sizeof(struct xinpgen);
|
||||
ptr = (struct xinpgen *)(void *)((char *)ptr + ptr->xig_len)) {
|
||||
tp = (struct xtcpcb *)ptr;
|
||||
if (tp->xt_inp.inp_gencnt > xinpgen->xig_gen ||
|
||||
(tp->xt_inp.inp_vflag & INP_IPV4) == 0)
|
||||
continue;
|
||||
oid->tp = tp;
|
||||
oid->index.len = 10;
|
||||
inaddr = ntohl(tp->xt_inp.inp_laddr.s_addr);
|
||||
oid->index.subs[0] = (inaddr >> 24) & 0xff;
|
||||
oid->index.subs[1] = (inaddr >> 16) & 0xff;
|
||||
oid->index.subs[2] = (inaddr >> 8) & 0xff;
|
||||
oid->index.subs[3] = (inaddr >> 0) & 0xff;
|
||||
oid->index.subs[4] = ntohs(tp->xt_inp.inp_lport);
|
||||
inaddr = ntohl(tp->xt_inp.inp_faddr.s_addr);
|
||||
oid->index.subs[5] = (inaddr >> 24) & 0xff;
|
||||
oid->index.subs[6] = (inaddr >> 16) & 0xff;
|
||||
oid->index.subs[7] = (inaddr >> 8) & 0xff;
|
||||
oid->index.subs[8] = (inaddr >> 0) & 0xff;
|
||||
oid->index.subs[9] = ntohs(tp->xt_inp.inp_fport);
|
||||
oid++;
|
||||
}
|
||||
|
||||
qsort(tcpoids, tcp_total, sizeof(tcpoids[0]), tcp_compare);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Scalars
|
||||
*/
|
||||
int
|
||||
op_tcp(struct snmp_context *ctx __unused, struct snmp_value *value,
|
||||
u_int sub, u_int iidx __unused, enum snmp_op op)
|
||||
{
|
||||
switch (op) {
|
||||
|
||||
case SNMP_OP_GETNEXT:
|
||||
abort();
|
||||
|
||||
case SNMP_OP_GET:
|
||||
break;
|
||||
|
||||
case SNMP_OP_SET:
|
||||
return (SNMP_ERR_NOT_WRITEABLE);
|
||||
|
||||
case SNMP_OP_ROLLBACK:
|
||||
case SNMP_OP_COMMIT:
|
||||
abort();
|
||||
}
|
||||
|
||||
if (tcp_tick < this_tick)
|
||||
if (fetch_tcp() == -1)
|
||||
return (SNMP_ERR_GENERR);
|
||||
|
||||
switch (value->var.subs[sub - 1]) {
|
||||
|
||||
case LEAF_tcpRtoAlgorithm:
|
||||
value->v.integer = 4; /* Van Jacobson */
|
||||
break;
|
||||
|
||||
#define hz clockinfo.hz
|
||||
|
||||
case LEAF_tcpRtoMin:
|
||||
value->v.integer = 1000 * TCPTV_MIN / hz;
|
||||
break;
|
||||
|
||||
case LEAF_tcpRtoMax:
|
||||
value->v.integer = 1000 * TCPTV_REXMTMAX / hz;
|
||||
break;
|
||||
#undef hz
|
||||
|
||||
case LEAF_tcpMaxConn:
|
||||
value->v.integer = -1;
|
||||
break;
|
||||
|
||||
case LEAF_tcpActiveOpens:
|
||||
value->v.uint32 = tcpstat.tcps_connattempt;
|
||||
break;
|
||||
|
||||
case LEAF_tcpPassiveOpens:
|
||||
value->v.uint32 = tcpstat.tcps_accepts;
|
||||
break;
|
||||
|
||||
case LEAF_tcpAttemptFails:
|
||||
value->v.uint32 = tcpstat.tcps_conndrops;
|
||||
break;
|
||||
|
||||
case LEAF_tcpEstabResets:
|
||||
value->v.uint32 = tcpstat.tcps_drops;
|
||||
break;
|
||||
|
||||
case LEAF_tcpCurrEstab:
|
||||
value->v.uint32 = tcp_count;
|
||||
break;
|
||||
|
||||
case LEAF_tcpInSegs:
|
||||
value->v.uint32 = tcpstat.tcps_rcvtotal;
|
||||
break;
|
||||
|
||||
case LEAF_tcpOutSegs:
|
||||
value->v.uint32 = tcpstat.tcps_sndtotal -
|
||||
tcpstat.tcps_sndrexmitpack;
|
||||
break;
|
||||
|
||||
case LEAF_tcpRetransSegs:
|
||||
value->v.uint32 = tcpstat.tcps_sndrexmitpack;
|
||||
break;
|
||||
|
||||
case LEAF_tcpInErrs:
|
||||
value->v.uint32 = tcpstat.tcps_rcvbadsum +
|
||||
tcpstat.tcps_rcvbadoff +
|
||||
tcpstat.tcps_rcvshort;
|
||||
break;
|
||||
}
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
int
|
||||
op_tcpconn(struct snmp_context *ctx __unused, struct snmp_value *value,
|
||||
u_int sub, u_int iidx __unused, enum snmp_op op)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
if (tcp_tick < this_tick)
|
||||
if (fetch_tcp() == -1)
|
||||
return (SNMP_ERR_GENERR);
|
||||
|
||||
switch (op) {
|
||||
|
||||
case SNMP_OP_GETNEXT:
|
||||
for (i = 0; i < tcp_total; i++)
|
||||
if (index_compare(&value->var, sub, &tcpoids[i].index) < 0)
|
||||
break;
|
||||
if (i == tcp_total)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
index_append(&value->var, sub, &tcpoids[i].index);
|
||||
break;
|
||||
|
||||
case SNMP_OP_GET:
|
||||
for (i = 0; i < tcp_total; i++)
|
||||
if (index_compare(&value->var, sub, &tcpoids[i].index) == 0)
|
||||
break;
|
||||
if (i == tcp_total)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
break;
|
||||
|
||||
case SNMP_OP_SET:
|
||||
return (SNMP_ERR_NOT_WRITEABLE);
|
||||
|
||||
case SNMP_OP_ROLLBACK:
|
||||
case SNMP_OP_COMMIT:
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
switch (value->var.subs[sub - 1]) {
|
||||
|
||||
case LEAF_tcpConnState:
|
||||
switch (tcpoids[i].tp->xt_tp.t_state) {
|
||||
|
||||
case TCPS_CLOSED:
|
||||
value->v.integer = 1;
|
||||
break;
|
||||
case TCPS_LISTEN:
|
||||
value->v.integer = 2;
|
||||
break;
|
||||
case TCPS_SYN_SENT:
|
||||
value->v.integer = 3;
|
||||
break;
|
||||
case TCPS_SYN_RECEIVED:
|
||||
value->v.integer = 4;
|
||||
break;
|
||||
case TCPS_ESTABLISHED:
|
||||
value->v.integer = 5;
|
||||
break;
|
||||
case TCPS_CLOSE_WAIT:
|
||||
value->v.integer = 8;
|
||||
break;
|
||||
case TCPS_FIN_WAIT_1:
|
||||
value->v.integer = 6;
|
||||
break;
|
||||
case TCPS_CLOSING:
|
||||
value->v.integer = 10;
|
||||
break;
|
||||
case TCPS_LAST_ACK:
|
||||
value->v.integer = 9;
|
||||
break;
|
||||
case TCPS_FIN_WAIT_2:
|
||||
value->v.integer = 7;
|
||||
break;
|
||||
case TCPS_TIME_WAIT:
|
||||
value->v.integer = 11;
|
||||
break;
|
||||
default:
|
||||
value->v.integer = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case LEAF_tcpConnLocalAddress:
|
||||
value->v.ipaddress[0] = tcpoids[i].index.subs[0];
|
||||
value->v.ipaddress[1] = tcpoids[i].index.subs[1];
|
||||
value->v.ipaddress[2] = tcpoids[i].index.subs[2];
|
||||
value->v.ipaddress[3] = tcpoids[i].index.subs[3];
|
||||
break;
|
||||
|
||||
case LEAF_tcpConnLocalPort:
|
||||
value->v.integer = tcpoids[i].index.subs[4];
|
||||
break;
|
||||
|
||||
case LEAF_tcpConnRemAddress:
|
||||
value->v.ipaddress[0] = tcpoids[i].index.subs[5];
|
||||
value->v.ipaddress[1] = tcpoids[i].index.subs[6];
|
||||
value->v.ipaddress[2] = tcpoids[i].index.subs[7];
|
||||
value->v.ipaddress[3] = tcpoids[i].index.subs[8];
|
||||
break;
|
||||
|
||||
case LEAF_tcpConnRemPort:
|
||||
value->v.integer = tcpoids[i].index.subs[9];
|
||||
break;
|
||||
}
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
248
contrib/bsnmp/snmp_mibII/mibII_tree.def
Normal file
248
contrib/bsnmp/snmp_mibII/mibII_tree.def
Normal file
@ -0,0 +1,248 @@
|
||||
#
|
||||
# Copyright (c) 2001-2003
|
||||
# Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
# All rights reserved.
|
||||
#
|
||||
# Author: Harti Brandt <harti@freebsd.org>
|
||||
#
|
||||
# Redistribution of this software and documentation 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 or documentation 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.
|
||||
# 3. Neither the name of the Institute nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
# AND ITS 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
|
||||
# FRAUNHOFER FOKUS OR ITS 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.
|
||||
#
|
||||
# $Begemot: bsnmp/snmp_mibII/mibII_tree.def,v 1.10 2002/02/06 12:43:51 hbb Exp $
|
||||
#
|
||||
# Definition of the standard interfaces and ip trees.
|
||||
#
|
||||
(1 internet
|
||||
(2 mgmt
|
||||
(1 mib2
|
||||
(2 interfaces
|
||||
(1 ifNumber INTEGER op_interfaces GET)
|
||||
(2 ifTable
|
||||
(1 ifEntry : INTEGER op_ifentry
|
||||
(1 ifIndex INTEGER GET)
|
||||
(2 ifDescr OCTETSTRING GET)
|
||||
(3 ifType INTEGER GET)
|
||||
(4 ifMtu INTEGER32 GET)
|
||||
(5 ifSpeed GAUGE GET)
|
||||
(6 ifPhysAddress OCTETSTRING GET)
|
||||
(7 ifAdminStatus INTEGER GET SET)
|
||||
(8 ifOperStatus INTEGER GET)
|
||||
(9 ifLastChange TIMETICKS GET)
|
||||
(10 ifInOctets COUNTER GET)
|
||||
(11 ifInUcastPkts COUNTER GET)
|
||||
(12 ifInNUcastPkts COUNTER GET)
|
||||
(13 ifInDiscards COUNTER GET)
|
||||
(14 ifInErrors COUNTER GET)
|
||||
(15 ifInUnknownProtos COUNTER GET)
|
||||
(16 ifOutOctets COUNTER GET)
|
||||
(17 ifOutUcastPkts COUNTER GET)
|
||||
(18 ifOutNUcastPkts COUNTER GET)
|
||||
(19 ifOutDiscards COUNTER GET)
|
||||
(20 ifOutErrors COUNTER GET)
|
||||
(21 ifOutQLen GAUGE GET)
|
||||
(22 ifSpecific OID GET)
|
||||
))
|
||||
)
|
||||
(4 ip
|
||||
(1 ipForwarding INTEGER op_ip GET SET)
|
||||
(2 ipDefaultTTL INTEGER op_ip GET SET)
|
||||
(3 ipInReceives COUNTER op_ipstat GET)
|
||||
(4 ipInHdrErrors COUNTER op_ipstat GET)
|
||||
(5 ipInAddrErrors COUNTER op_ipstat GET)
|
||||
(6 ipForwDatagrams COUNTER op_ipstat GET)
|
||||
(7 ipInUnknownProtos COUNTER op_ipstat GET)
|
||||
(8 ipInDiscards COUNTER op_ipstat GET)
|
||||
(9 ipInDelivers COUNTER op_ipstat GET)
|
||||
(10 ipOutRequests COUNTER op_ipstat GET)
|
||||
(11 ipOutDiscards COUNTER op_ipstat GET)
|
||||
(12 ipOutNoRoutes COUNTER op_ipstat GET)
|
||||
(13 ipReasmTimeout INTEGER32 op_ipstat GET)
|
||||
(14 ipReasmReqds COUNTER op_ipstat GET)
|
||||
(15 ipReasmOKs COUNTER op_ipstat GET)
|
||||
(16 ipReasmFails COUNTER op_ipstat GET)
|
||||
(17 ipFragOKs COUNTER op_ipstat GET)
|
||||
(18 ipFragFails COUNTER op_ipstat GET)
|
||||
(19 ipFragCreates COUNTER op_ipstat GET)
|
||||
(20 ipAddrTable
|
||||
(1 ipAddrEntry : IPADDRESS op_ipaddr
|
||||
(1 ipAdEntAddr IPADDRESS GET)
|
||||
(2 ipAdEntIfIndex INTEGER GET SET)
|
||||
(3 ipAdEntNetMask IPADDRESS GET SET)
|
||||
(4 ipAdEntBcastAddr INTEGER GET SET)
|
||||
(5 ipAdEntReasmMaxSize INTEGER GET)
|
||||
))
|
||||
(22 ipNetToMediaTable
|
||||
(1 ipNetToMediaEntry : INTEGER IPADDRESS op_nettomedia
|
||||
(1 ipNetToMediaIfIndex INTEGER GET)
|
||||
(2 ipNetToMediaPhysAddress OCTETSTRING GET)
|
||||
(3 ipNetToMediaNetAddress IPADDRESS GET)
|
||||
(4 ipNetToMediaType INTEGER GET)
|
||||
))
|
||||
(23 ipRoutingDiscards INTEGER op_ipstat) # not available
|
||||
(24 ipForward
|
||||
(3 ipCidrRouteNumber GAUGE op_route GET)
|
||||
(4 ipCidrRouteTable
|
||||
(1 ipCidrRouteEntry : IPADDRESS IPADDRESS INTEGER IPADDRESS op_route_table
|
||||
(1 ipCidrRouteDest IPADDRESS GET)
|
||||
(2 ipCidrRouteMask IPADDRESS GET)
|
||||
(3 ipCidrRouteTos INTEGER GET)
|
||||
(4 ipCidrRouteNextHop IPADDRESS GET)
|
||||
(5 ipCidrRouteIfIndex INTEGER GET) # SET
|
||||
(6 ipCidrRouteType INTEGER GET) # SET
|
||||
(7 ipCidrRouteProto INTEGER GET)
|
||||
(8 ipCidrRouteAge INTEGER GET)
|
||||
(9 ipCidrRouteInfo OID GET) # SET
|
||||
(10 ipCidrRouteNextHopAS INTEGER GET) # SET
|
||||
(11 ipCidrRouteMetric1 INTEGER GET) # SET
|
||||
(12 ipCidrRouteMetric2 INTEGER GET) # SET
|
||||
(13 ipCidrRouteMetric3 INTEGER GET) # SET
|
||||
(14 ipCidrRouteMetric4 INTEGER GET) # SET
|
||||
(15 ipCidrRouteMetric5 INTEGER GET) # SET
|
||||
(16 ipCidrRouteStatus INTEGER GET) # SET
|
||||
))
|
||||
)
|
||||
)
|
||||
(5 icmp
|
||||
(1 icmpInMsgs COUNTER op_icmpstat GET)
|
||||
(2 icmpInErrors COUNTER op_icmpstat GET)
|
||||
(3 icmpInDestUnreachs COUNTER op_icmpstat GET)
|
||||
(4 icmpInTimeExcds COUNTER op_icmpstat GET)
|
||||
(5 icmpInParmProbs COUNTER op_icmpstat GET)
|
||||
(6 icmpInSrcQuenchs COUNTER op_icmpstat GET)
|
||||
(7 icmpInRedirects COUNTER op_icmpstat GET)
|
||||
(8 icmpInEchos COUNTER op_icmpstat GET)
|
||||
(9 icmpInEchoReps COUNTER op_icmpstat GET)
|
||||
(10 icmpInTimestamps COUNTER op_icmpstat GET)
|
||||
(11 icmpInTimestampReps COUNTER op_icmpstat GET)
|
||||
(12 icmpInAddrMasks COUNTER op_icmpstat GET)
|
||||
(13 icmpInAddrMaskReps COUNTER op_icmpstat GET)
|
||||
(14 icmpOutMsgs COUNTER op_icmpstat GET)
|
||||
(15 icmpOutErrors COUNTER op_icmpstat GET)
|
||||
(16 icmpOutDestUnreachs COUNTER op_icmpstat GET)
|
||||
(17 icmpOutTimeExcds COUNTER op_icmpstat GET)
|
||||
(18 icmpOutParmProbs COUNTER op_icmpstat GET)
|
||||
(19 icmpOutSrcQuenchs COUNTER op_icmpstat GET)
|
||||
(20 icmpOutRedirects COUNTER op_icmpstat GET)
|
||||
(21 icmpOutEchos COUNTER op_icmpstat GET)
|
||||
(22 icmpOutEchoReps COUNTER op_icmpstat GET)
|
||||
(23 icmpOutTimestamps COUNTER op_icmpstat GET)
|
||||
(24 icmpOutTimestampReps COUNTER op_icmpstat GET)
|
||||
(25 icmpOutAddrMasks COUNTER op_icmpstat GET)
|
||||
(26 icmpOutAddrMaskReps COUNTER op_icmpstat GET)
|
||||
)
|
||||
(6 tcp
|
||||
(1 tcpRtoAlgorithm INTEGER op_tcp GET)
|
||||
(2 tcpRtoMin INTEGER32 op_tcp GET)
|
||||
(3 tcpRtoMax INTEGER32 op_tcp GET)
|
||||
(4 tcpMaxConn INTEGER32 op_tcp GET)
|
||||
(5 tcpActiveOpens COUNTER op_tcp GET)
|
||||
(6 tcpPassiveOpens COUNTER op_tcp GET)
|
||||
(7 tcpAttemptFails COUNTER op_tcp GET)
|
||||
(8 tcpEstabResets COUNTER op_tcp GET)
|
||||
(9 tcpCurrEstab GAUGE op_tcp GET)
|
||||
(10 tcpInSegs COUNTER op_tcp GET)
|
||||
(11 tcpOutSegs COUNTER op_tcp GET)
|
||||
(12 tcpRetransSegs COUNTER op_tcp GET)
|
||||
(13 tcpConnTable
|
||||
(1 tcpConnEntry : IPADDRESS INTEGER IPADDRESS INTEGER op_tcpconn
|
||||
(1 tcpConnState INTEGER GET)
|
||||
(2 tcpConnLocalAddress IPADDRESS GET)
|
||||
(3 tcpConnLocalPort INTEGER GET)
|
||||
(4 tcpConnRemAddress IPADDRESS GET)
|
||||
(5 tcpConnRemPort INTEGER GET)
|
||||
))
|
||||
(14 tcpInErrs COUNTER op_tcp GET)
|
||||
(15 tcpOutRsts COUNTER op_tcp) # don't know
|
||||
)
|
||||
(7 udp
|
||||
(1 udpInDatagrams COUNTER op_udp GET)
|
||||
(2 udpNoPorts COUNTER op_udp GET)
|
||||
(3 udpInErrors COUNTER op_udp GET)
|
||||
(4 udpOutDatagrams COUNTER op_udp GET)
|
||||
(5 udpTable
|
||||
(1 udpEntry : IPADDRESS INTEGER op_udptable
|
||||
(1 udpLocalAddress IPADDRESS GET)
|
||||
(2 udpLocalPort INTEGER GET)
|
||||
))
|
||||
)
|
||||
(31 ifMIB
|
||||
(1 ifMIBObjects
|
||||
(1 ifXTable
|
||||
(1 ifXEntry : INTEGER op_ifxtable
|
||||
(1 ifName OCTETSTRING GET)
|
||||
(2 ifInMulticastPkts COUNTER GET)
|
||||
(3 ifInBroadcastPkts COUNTER GET)
|
||||
(4 ifOutMulticastPkts COUNTER GET)
|
||||
(5 ifOutBroadcastPkts COUNTER GET)
|
||||
(6 ifHCInOctets COUNTER64 GET)
|
||||
(7 ifHCInUcastPkts COUNTER64 GET)
|
||||
(8 ifHCInMulticastPkts COUNTER64 GET)
|
||||
(9 ifHCInBroadcastPkts COUNTER64 GET)
|
||||
(10 ifHCOutOctets COUNTER64 GET)
|
||||
(11 ifHCOutUcastPkts COUNTER64 GET)
|
||||
(12 ifHCOutMulticastPkts COUNTER64 GET)
|
||||
(13 ifHCOutBroadcastPkts COUNTER64 GET)
|
||||
(14 ifLinkUpDownTrapEnable INTEGER GET SET)
|
||||
(15 ifHighSpeed GAUGE GET)
|
||||
(16 ifPromiscuousMode INTEGER GET SET)
|
||||
(17 ifConnectorPresent INTEGER GET)
|
||||
(18 ifAlias OCTETSTRING GET)
|
||||
(19 ifCounterDiscontinuityTime TIMETICKS GET)
|
||||
))
|
||||
(2 ifStackTable
|
||||
(1 ifStackEntry : INTEGER INTEGER op_ifstack
|
||||
(1 ifStackHigherLayer INTEGER)
|
||||
(2 ifStackLowerLayer INTEGER)
|
||||
(3 ifStackStatus INTEGER GET)
|
||||
))
|
||||
(4 ifRcvAddressTable
|
||||
(1 ifRcvAddressEntry : INTEGER OCTETSTRING op_rcvaddr
|
||||
(1 ifRcvAddressAddress OCTETSTRING)
|
||||
(2 ifRcvAddressStatus INTEGER GET)
|
||||
(3 ifRcvAddressType INTEGER GET)
|
||||
))
|
||||
(5 ifTableLastChange TIMETICKS op_ifmib GET)
|
||||
(6 ifStackLastChange TIMETICKS op_ifmib GET)
|
||||
)
|
||||
)
|
||||
(48 ipMIB
|
||||
)
|
||||
(49 tcpMIB
|
||||
)
|
||||
(50 udpMIB
|
||||
)
|
||||
))
|
||||
(6 snmpV2
|
||||
(3 snmpModules
|
||||
(1 snmpMIB
|
||||
(1 snmpMIBObjects
|
||||
(5 snmpTraps
|
||||
(3 linkDown OID op_snmp_trap)
|
||||
(4 linkUp OID op_snmp_trap)
|
||||
)
|
||||
)
|
||||
)
|
||||
))
|
||||
)
|
257
contrib/bsnmp/snmp_mibII/mibII_udp.c
Normal file
257
contrib/bsnmp/snmp_mibII/mibII_udp.c
Normal file
@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003
|
||||
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Harti Brandt <harti@freebsd.org>
|
||||
*
|
||||
* Redistribution of this software and documentation 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 or documentation 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.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
* AND ITS 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
|
||||
* FRAUNHOFER FOKUS OR ITS 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.
|
||||
*
|
||||
* $Begemot: bsnmp/snmp_mibII/mibII_udp.c,v 1.4 2003/01/28 13:44:35 hbb Exp $
|
||||
*
|
||||
* udp
|
||||
*/
|
||||
#include "mibII.h"
|
||||
#include "mibII_oid.h"
|
||||
#include <sys/socketvar.h>
|
||||
#include <netinet/in_pcb.h>
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/ip_var.h>
|
||||
#include <netinet/udp_var.h>
|
||||
|
||||
struct udp_index {
|
||||
struct asn_oid index;
|
||||
struct xinpcb *inp;
|
||||
};
|
||||
|
||||
static u_int32_t udp_tick;
|
||||
static struct udpstat udpstat;
|
||||
static struct xinpgen *xinpgen;
|
||||
static size_t xinpgen_len;
|
||||
static u_int udp_total;
|
||||
|
||||
static u_int oidnum;
|
||||
static struct udp_index *udpoids;
|
||||
|
||||
static int
|
||||
udp_compare(const void *p1, const void *p2)
|
||||
{
|
||||
const struct udp_index *t1 = p1;
|
||||
const struct udp_index *t2 = p2;
|
||||
|
||||
return (asn_compare_oid(&t1->index, &t2->index));
|
||||
}
|
||||
|
||||
static int
|
||||
fetch_udp(void)
|
||||
{
|
||||
size_t len;
|
||||
struct xinpgen *ptr;
|
||||
struct xinpcb *inp;
|
||||
struct udp_index *oid;
|
||||
in_addr_t inaddr;
|
||||
|
||||
len = sizeof(udpstat);
|
||||
if (sysctlbyname("net.inet.udp.stats", &udpstat, &len, NULL, 0) == -1) {
|
||||
syslog(LOG_ERR, "net.inet.udp.stats: %m");
|
||||
return (-1);
|
||||
}
|
||||
if (len != sizeof(udpstat)) {
|
||||
syslog(LOG_ERR, "net.inet.udp.stats: wrong size");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
udp_tick = get_ticks();
|
||||
|
||||
len = 0;
|
||||
if (sysctlbyname("net.inet.udp.pcblist", NULL, &len, NULL, 0) == -1) {
|
||||
syslog(LOG_ERR, "net.inet.udp.pcblist: %m");
|
||||
return (-1);
|
||||
}
|
||||
if (len > xinpgen_len) {
|
||||
if ((ptr = realloc(xinpgen, len)) == NULL) {
|
||||
syslog(LOG_ERR, "%zu: %m", len);
|
||||
return (-1);
|
||||
}
|
||||
xinpgen = ptr;
|
||||
xinpgen_len = len;
|
||||
}
|
||||
if (sysctlbyname("net.inet.udp.pcblist", xinpgen, &len, NULL, 0) == -1) {
|
||||
syslog(LOG_ERR, "net.inet.udp.pcblist: %m");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
udp_total = 0;
|
||||
for (ptr = (struct xinpgen *)(void *)((char *)xinpgen + xinpgen->xig_len);
|
||||
ptr->xig_len > sizeof(struct xinpgen);
|
||||
ptr = (struct xinpgen *)(void *)((char *)ptr + ptr->xig_len)) {
|
||||
inp = (struct xinpcb *)ptr;
|
||||
if (inp->xi_inp.inp_gencnt > xinpgen->xig_gen ||
|
||||
(inp->xi_inp.inp_vflag & INP_IPV4) == 0)
|
||||
continue;
|
||||
|
||||
udp_total++;
|
||||
}
|
||||
|
||||
if (oidnum < udp_total) {
|
||||
oid = realloc(udpoids, udp_total * sizeof(udpoids[0]));
|
||||
if (oid == NULL) {
|
||||
free(udpoids);
|
||||
oidnum = 0;
|
||||
return (0);
|
||||
}
|
||||
udpoids = oid;
|
||||
oidnum = udp_total;
|
||||
}
|
||||
|
||||
oid = udpoids;
|
||||
for (ptr = (struct xinpgen *)(void *)((char *)xinpgen + xinpgen->xig_len);
|
||||
ptr->xig_len > sizeof(struct xinpgen);
|
||||
ptr = (struct xinpgen *)(void *)((char *)ptr + ptr->xig_len)) {
|
||||
inp = (struct xinpcb *)ptr;
|
||||
if (inp->xi_inp.inp_gencnt > xinpgen->xig_gen ||
|
||||
(inp->xi_inp.inp_vflag & INP_IPV4) == 0)
|
||||
continue;
|
||||
oid->inp = inp;
|
||||
oid->index.len = 5;
|
||||
inaddr = ntohl(inp->xi_inp.inp_laddr.s_addr);
|
||||
oid->index.subs[0] = (inaddr >> 24) & 0xff;
|
||||
oid->index.subs[1] = (inaddr >> 16) & 0xff;
|
||||
oid->index.subs[2] = (inaddr >> 8) & 0xff;
|
||||
oid->index.subs[3] = (inaddr >> 0) & 0xff;
|
||||
oid->index.subs[4] = ntohs(inp->xi_inp.inp_lport);
|
||||
oid++;
|
||||
}
|
||||
|
||||
qsort(udpoids, udp_total, sizeof(udpoids[0]), udp_compare);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
op_udp(struct snmp_context *ctx __unused, struct snmp_value *value,
|
||||
u_int sub, u_int iidx __unused, enum snmp_op op)
|
||||
{
|
||||
switch (op) {
|
||||
|
||||
case SNMP_OP_GETNEXT:
|
||||
abort();
|
||||
|
||||
case SNMP_OP_GET:
|
||||
break;
|
||||
|
||||
case SNMP_OP_SET:
|
||||
return (SNMP_ERR_NOT_WRITEABLE);
|
||||
|
||||
case SNMP_OP_ROLLBACK:
|
||||
case SNMP_OP_COMMIT:
|
||||
abort();
|
||||
}
|
||||
|
||||
if (udp_tick < this_tick)
|
||||
if (fetch_udp() == -1)
|
||||
return (SNMP_ERR_GENERR);
|
||||
|
||||
switch (value->var.subs[sub - 1]) {
|
||||
|
||||
case LEAF_udpInDatagrams:
|
||||
value->v.uint32 = udpstat.udps_ipackets;
|
||||
break;
|
||||
|
||||
case LEAF_udpNoPorts:
|
||||
value->v.uint32 = udpstat.udps_noport +
|
||||
udpstat.udps_noportbcast +
|
||||
udpstat.udps_noportmcast;
|
||||
break;
|
||||
|
||||
case LEAF_udpInErrors:
|
||||
value->v.uint32 = udpstat.udps_hdrops +
|
||||
udpstat.udps_badsum +
|
||||
udpstat.udps_badlen +
|
||||
udpstat.udps_fullsock;
|
||||
break;
|
||||
|
||||
case LEAF_udpOutDatagrams:
|
||||
value->v.uint32 = udpstat.udps_opackets;
|
||||
break;
|
||||
}
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
int
|
||||
op_udptable(struct snmp_context *ctx __unused, struct snmp_value *value,
|
||||
u_int sub, u_int iidx __unused, enum snmp_op op)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
if (udp_tick < this_tick)
|
||||
if (fetch_udp() == -1)
|
||||
return (SNMP_ERR_GENERR);
|
||||
|
||||
switch (op) {
|
||||
|
||||
case SNMP_OP_GETNEXT:
|
||||
for (i = 0; i < udp_total; i++)
|
||||
if (index_compare(&value->var, sub, &udpoids[i].index) < 0)
|
||||
break;
|
||||
if (i == udp_total)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
index_append(&value->var, sub, &udpoids[i].index);
|
||||
break;
|
||||
|
||||
case SNMP_OP_GET:
|
||||
for (i = 0; i < udp_total; i++)
|
||||
if (index_compare(&value->var, sub, &udpoids[i].index) == 0)
|
||||
break;
|
||||
if (i == udp_total)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
break;
|
||||
|
||||
case SNMP_OP_SET:
|
||||
return (SNMP_ERR_NOT_WRITEABLE);
|
||||
|
||||
case SNMP_OP_ROLLBACK:
|
||||
case SNMP_OP_COMMIT:
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
switch (value->var.subs[sub - 1]) {
|
||||
|
||||
case LEAF_udpLocalAddress:
|
||||
value->v.ipaddress[0] = udpoids[i].index.subs[0];
|
||||
value->v.ipaddress[1] = udpoids[i].index.subs[1];
|
||||
value->v.ipaddress[2] = udpoids[i].index.subs[2];
|
||||
value->v.ipaddress[3] = udpoids[i].index.subs[3];
|
||||
break;
|
||||
|
||||
case LEAF_udpLocalPort:
|
||||
value->v.integer = udpoids[i].index.subs[4];
|
||||
break;
|
||||
|
||||
}
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
348
contrib/bsnmp/snmp_mibII/snmp_mibII.3
Normal file
348
contrib/bsnmp/snmp_mibII/snmp_mibII.3
Normal file
@ -0,0 +1,348 @@
|
||||
.\"
|
||||
.\" Copyright (c) 2001-2003
|
||||
.\" Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Author: Harti Brandt <harti@freebsd.org>
|
||||
.\"
|
||||
.\" Redistribution of this software and documentation 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 or documentation 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.
|
||||
.\" 3. Neither the name of the Institute nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
.\" AND ITS 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
|
||||
.\" FRAUNHOFER FOKUS OR ITS 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.
|
||||
.\"
|
||||
.\" $Begemot: bsnmp/snmp_mibII/snmp_mibII.3,v 1.1 2002/08/19 09:30:14 hbb Exp $
|
||||
.\"
|
||||
.Dd August 19, 2002
|
||||
.Dt snmp_mibII 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mibif_notify_f ,
|
||||
.Nm mib_netsock ,
|
||||
.Nm mib_if_set_dyn ,
|
||||
.Nm mib_refresh_iflist ,
|
||||
.Nm mib_find_if ,
|
||||
.Nm mib_find_if_sys ,
|
||||
.Nm mib_find_if_name ,
|
||||
.Nm mib_first_if ,
|
||||
.Nm mib_next_if ,
|
||||
.Nm mib_register_newif ,
|
||||
.Nm mib_unregister_newif ,
|
||||
.Nm mib_fetch_ifmib ,
|
||||
.Nm mib_if_admin ,
|
||||
.Nm mib_find_ifa ,
|
||||
.Nm mib_first_ififa ,
|
||||
.Nm mib_next_ififa ,
|
||||
.Nm mib_ifstack_create ,
|
||||
.Nm mib_ifstack_delete ,
|
||||
.Nm mib_find_rcvaddr ,
|
||||
.Nm mib_rcvaddr_create ,
|
||||
.Nm mib_rcvaddr_delete ,
|
||||
.Nm mibif_notify ,
|
||||
.Nm mibif_unnotify
|
||||
.Nd "mib-2 module for snmpd.
|
||||
.Sh LIBRARY
|
||||
.Pq begemotSnmpdModulePath."mibII" = "/usr/local/lib/snmp_mibII.so"
|
||||
.Sh SYNOPSIS
|
||||
.In bsnmp/snmpmod.h
|
||||
.In bsnmp/snmp_mibII.h
|
||||
.Ft typedef void
|
||||
.Fn (*mibif_notify_f) "struct mibif *ifp" "enum mibif_notify event" "void *uarg"
|
||||
.Vt extern int mib_netsock ;
|
||||
.Ft void
|
||||
.Fn mib_if_set_dyn "const char *ifname"
|
||||
.Ft void
|
||||
.Fn mib_refresh_iflist "void"
|
||||
.Ft struct mibif *
|
||||
.Fn mib_find_if "u_int ifindex"
|
||||
.Ft struct mibif *
|
||||
.Fn mib_find_if_sys "u_int sysindex"
|
||||
.Ft struct mibif *
|
||||
.Fn mib_find_if_name "const char *ifname"
|
||||
.Ft struct mibif *
|
||||
.Fn mib_first_if "void"
|
||||
.Ft struct mibif *
|
||||
.Fn mib_next_if "const struct mibif *ifp"
|
||||
.Ft int
|
||||
.Fn mib_register_newif "int (*func)(struct mibif *)" "const struct lmodule *mod"
|
||||
.Ft void
|
||||
.Fn mib_unregister_newif "const struct lmodule *mod"
|
||||
.Ft int
|
||||
.Fn mib_fetch_ifmib "struct mibif *ifp"
|
||||
.Ft int
|
||||
.Fn mib_if_admin "struct mibif *ifp" "int up"
|
||||
.Ft struct mibifa *
|
||||
.Fn mib_find_ifa "struct in_addr ipa"
|
||||
.Ft struct mibifa *
|
||||
.Fn mib_first_ififa "const struct mibif *ifp"
|
||||
.Ft struct mibifa *
|
||||
.Fn mib_next_ififa "struct mibifa *ifa"
|
||||
.Ft int
|
||||
.Fn mib_ifstack_create "const struct mibif *lower" "const struct mibif *upper"
|
||||
.Ft void
|
||||
.Fn mib_ifstack_delete "const struct mibif *lower" "const struct mibif *upper"
|
||||
.Ft struct mibrcvaddr *
|
||||
.Fn mib_find_rcvaddr "u_int ifindex" "const u_char *addr" "size_t addrlen"
|
||||
.Ft struct mibrcvaddr *
|
||||
.Fn mib_rcvaddr_create "struct mibif *ifp" "const u_char *addr" "size_t addrlen"
|
||||
.Ft void
|
||||
.Fn mib_rcvaddr_delete "struct mibrcvaddr *addr"
|
||||
.Ft void *
|
||||
.Fn mibif_notify "struct mibif *ifp" "const struct lmodule *mod" "mibif_notify_f func" "void *uarg"
|
||||
.Ft void
|
||||
.Fn mibif_unnotify "void *reg"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm snmp_mibII
|
||||
module implements parts of the internet standard MIB-2. Most of the relevant
|
||||
MIBs are implemented. Some of the tables are restricted to be read-only
|
||||
instead of read-write. The exact current implementation can be found in
|
||||
.Pa /usr/local/include/bsnmp/mibII_tree.def .
|
||||
The module also exports a number of functions and global variables for use
|
||||
by other modules, that need to handle network interfaces. This man page describes
|
||||
these functions.
|
||||
.Ss DIRECT NETWORK ACCESS
|
||||
The
|
||||
.Nm
|
||||
module opens a socket that is used to execute all network related
|
||||
.Xr ioctl 2
|
||||
functions. This socket is globally available under the name
|
||||
.Va mib_netsock .
|
||||
.Ss NETWORK INTERFACES
|
||||
The
|
||||
.Nm
|
||||
module handles a list of all currently existing network interfaces. It allows
|
||||
other modules to handle their own interface lists with special information
|
||||
by providing a mechanism to register to events that change the interface list
|
||||
(see below). The basic data structure is the interface structure:
|
||||
.Bd -literal -offset indent
|
||||
struct mibif {
|
||||
TAILQ_ENTRY(mibif) link;
|
||||
u_int flags;
|
||||
u_int index; /* logical ifindex */
|
||||
u_int sysindex;
|
||||
char name[IFNAMSIZ];
|
||||
char descr[256];
|
||||
struct ifmibdata mib;
|
||||
u_int32_t mibtick;
|
||||
void *specmib;
|
||||
size_t specmiblen;
|
||||
u_char *physaddr;
|
||||
u_int physaddrlen;
|
||||
int has_connector;
|
||||
int trap_enable;
|
||||
u_int32_t counter_disc;
|
||||
mibif_notify_f xnotify;
|
||||
void *xnotify_data;
|
||||
const struct lmodule *xnotify_mod;
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Nm
|
||||
module tries to implement the semantic if
|
||||
.Va ifIndex
|
||||
as described in RFC-2863. This RFC states, that an interface indexes may not
|
||||
be reused. That means, for example, if
|
||||
.Pa tun
|
||||
is a synthetic interface type and the system creates the interface
|
||||
.Pa tun0 ,
|
||||
destroys this interfaces and again creates a
|
||||
.Pa tun 0 ,
|
||||
then these interfaces must have different interface indexes, because in fact
|
||||
they are different interfaces. If, on the other hand, there is a hardware
|
||||
interface
|
||||
.Pa xl0
|
||||
and this interface disappears, because its driver is unloaded and appears
|
||||
again, because the driver is loaded again, the interface index must stay
|
||||
the same.
|
||||
.Nm
|
||||
implements this by differentiating between real and synthetic (dynamic)
|
||||
interfaces. An interface type can be declared dynamic by calling the function
|
||||
.Fn mib_if_set_dyn
|
||||
with the name if the interface type (for example
|
||||
.Qq tun ).
|
||||
For real interfaces, the module keeps the mapping between the interface name
|
||||
and its
|
||||
.Va ifIndex
|
||||
in a special list, if the interface is unloaded. For dynamic interfaces
|
||||
a new
|
||||
.Va ifIndex
|
||||
is generated each time the interface comes into existance. This
|
||||
means, that the interface index as seen by SNMP is not the same index
|
||||
as used by the system. The SNMP
|
||||
.Va ifIndex
|
||||
is held in field
|
||||
.Va index ,
|
||||
the system's interface index is
|
||||
.Va sysindex .
|
||||
.Pp
|
||||
A call to
|
||||
.Nm mib_refresh_iflist
|
||||
causes the entire interface list to be re-created.
|
||||
.Pp
|
||||
The interface list can be traversed with the functions
|
||||
.Fn mib_first_if
|
||||
and
|
||||
.Fn mib_next_if .
|
||||
Be sure not to change the interface list while traversing the list with
|
||||
these two calls.
|
||||
.Pp
|
||||
There are three functions to find an interface by name or index.
|
||||
.Fn mib_find_if
|
||||
finds an interface by searching for an SNMP
|
||||
.Va ifIndex ,
|
||||
.Fn mib_find_if_sys
|
||||
finds an interface by searching for a system interface index and
|
||||
.Fn mib_find_if_name
|
||||
finds an interface by looking for an interface name. Each of the
|
||||
function returns
|
||||
.Li NULL
|
||||
if the interface cannot be found.
|
||||
.Pp
|
||||
The function
|
||||
.Fn mib_fetch_ifmib
|
||||
causes the interface MIB to be refreshed from the kernel.
|
||||
.Pp
|
||||
The function
|
||||
.Fn mib_if_admin
|
||||
can be used to change the interface administrative state to up
|
||||
(argument is 1) or down (argument is 0).
|
||||
.Ss INTERFACE EVENTS
|
||||
A module can register itself to receive a notification when a new entry is
|
||||
created in the interface list. This is done by calling
|
||||
.Fn mib_register_newif .
|
||||
A module can register only one function, a second call to
|
||||
.Fn mib_register_newif
|
||||
causes the registration to be overwritten. The registration can be removed
|
||||
with a call to
|
||||
.Fn mib_unregister_newif .
|
||||
If is unregistered automatically, when the registering module is unloaded.
|
||||
.Pp
|
||||
A module can also register to events on a specific interface. This is done
|
||||
by calling
|
||||
.Fn mibif_notify .
|
||||
This causes the given callback
|
||||
.Fa func
|
||||
to be called with the interface pointer, a notification code and
|
||||
the user argument
|
||||
.Fa uarg
|
||||
when any of the following events occur:
|
||||
.Bl -tag -width "XXXXX"
|
||||
.It Li MIBIF_NOTIFY_DESTROY
|
||||
The interface is destroyed.
|
||||
.El
|
||||
.Pp
|
||||
This mechanism can be used to implement interface type specific MIB parts
|
||||
in other modules. The registration can be removed with
|
||||
.Fn mib_unnotify
|
||||
which the return value from
|
||||
.Fa mib_notify .
|
||||
Any notification registration is removed automatically when the interface
|
||||
is destroyed or the registering module is unloaded.
|
||||
.Em Note that only one module can register to any given interface .
|
||||
.Ss INTERFACE ADDRESSES
|
||||
The
|
||||
.Nm
|
||||
module handles a table of interface IP-addresses. These addresses are held
|
||||
in a
|
||||
.Bd -literal -offset indent
|
||||
struct mibifa {
|
||||
TAILQ_ENTRY(mibifa) link;
|
||||
struct in_addr inaddr;
|
||||
struct in_addr inmask;
|
||||
struct in_addr inbcast;
|
||||
struct asn_oid index;
|
||||
u_int ifindex;
|
||||
u_int flags;
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
The (ordered) list of IP-addresses on a given interface can be traversed by
|
||||
calling
|
||||
.Fn mib_first_ififa
|
||||
and
|
||||
.Fn mib_next_ififa .
|
||||
The list should not be considered read-only.
|
||||
.Ss INTERFACE RECEIVE ADDRESSES
|
||||
The internet MIB-2 contains a table of interface receive addresses. These
|
||||
addresses are handled in:
|
||||
.Bd -literal -offset indent
|
||||
struct mibrcvaddr {
|
||||
TAILQ_ENTRY(mibrcvaddr) link;
|
||||
struct asn_oid index;
|
||||
u_int ifindex;
|
||||
u_char addr[ASN_MAXOIDLEN];
|
||||
size_t addrlen;
|
||||
u_int flags;
|
||||
};
|
||||
enum {
|
||||
MIBRCVADDR_VOLATILE = 0x00000001,
|
||||
MIBRCVADDR_BCAST = 0x00000002,
|
||||
MIBRCVADDR_HW = 0x00000004,
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
Note, that the assignment of
|
||||
.Li MIBRCVADDR_BCAST
|
||||
is based on a list of known interface types. The flags should be handled
|
||||
by modules inplementing interface type specific MIBs.
|
||||
.Pp
|
||||
A receive address can be created with
|
||||
.Fn mib_rcvaddr_create
|
||||
and deleted with
|
||||
.Fn mib_rcvaddr_delete .
|
||||
This needs to be done only for addresses that are not automatically handled
|
||||
by the system.
|
||||
.Pp
|
||||
A receive address can be found with
|
||||
.Fn mib_find_rcvaddr .
|
||||
.Ss INTERFACE STACK TABLE
|
||||
The
|
||||
.Nm
|
||||
module maintains also the interface stack table. Because for complex stacks,
|
||||
there is no system supported generic way of getting this information, interface
|
||||
type specific modules need to help setting up stack entries. The
|
||||
.Nm
|
||||
module handles only the top and bottom entries.
|
||||
.Pp
|
||||
A table entry is created with
|
||||
.Fn mib_ifstack_create
|
||||
and deleted with
|
||||
.Fn mib_ifstack_delete .
|
||||
Both functions need the pointers to the interfaces. Entries are automatically
|
||||
deleted if any of the interfaces of the entry is destroyed. The functions handle
|
||||
both the stack table and the reverse stack table.
|
||||
.Sh FILES
|
||||
.Bl -tag -width ".It Pa /usr/local/include/bsnmp/mibII_tree.def" -compact
|
||||
.It Pa /usr/local/include/bsnmp/mibII_tree.def
|
||||
The description of the MIB tree implemented by
|
||||
.Nm .
|
||||
.It Pa /usr/local/share/snmp/mibs
|
||||
The various internet MIBs.
|
||||
.Sh SEE ALSO
|
||||
.Xr snmpmod 3 ,
|
||||
.Xr gensnmptree 1
|
||||
.Sh STANDARDS
|
||||
This implementation conforms to the applicable IETF RFCs.
|
||||
.Sh AUTHORS
|
||||
.An Hartmut Brandt Aq brandt@fokus.gmd.de
|
167
contrib/bsnmp/snmp_mibII/snmp_mibII.h
Normal file
167
contrib/bsnmp/snmp_mibII/snmp_mibII.h
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003
|
||||
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Harti Brandt <harti@freebsd.org>
|
||||
*
|
||||
* Redistribution of this software and documentation 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 or documentation 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.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
* AND ITS 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
|
||||
* FRAUNHOFER FOKUS OR ITS 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.
|
||||
*
|
||||
* $Begemot: bsnmp/snmp_mibII/snmp_mibII.h,v 1.13 2002/03/21 11:18:51 hbb Exp $
|
||||
*
|
||||
* Implementation of the interfaces and IP groups of MIB-II.
|
||||
*/
|
||||
#ifndef snmp_mibII_h_
|
||||
#define snmp_mibII_h_
|
||||
|
||||
/* forward declaration */
|
||||
struct mibif;
|
||||
|
||||
enum mibif_notify {
|
||||
MIBIF_NOTIFY_DESTROY
|
||||
};
|
||||
|
||||
typedef void (*mibif_notify_f)(struct mibif *, enum mibif_notify, void *);
|
||||
|
||||
/*
|
||||
* Interfaces. This structure describes one interface as seen in the MIB.
|
||||
* Interfaces are indexed by ifindex. This is not the same as the index
|
||||
* used by the system because of the rules in RFC-2863 section 3.1.5. This
|
||||
* RFC requires, that an ifindex is not to be re-used for ANOTHER dynamically
|
||||
* interfaces once the interface was deleted. The system's ifindex is in
|
||||
* sysindex. Mapping is via the mapping table below.
|
||||
*/
|
||||
struct mibif {
|
||||
TAILQ_ENTRY(mibif) link;
|
||||
u_int flags;
|
||||
u_int index; /* the logical ifindex */
|
||||
u_int sysindex;
|
||||
char name[IFNAMSIZ];
|
||||
char descr[256];
|
||||
struct ifmibdata mib;
|
||||
u_int32_t mibtick;
|
||||
void *specmib;
|
||||
size_t specmiblen;
|
||||
u_char *physaddr;
|
||||
u_int physaddrlen;
|
||||
int has_connector;
|
||||
int trap_enable;
|
||||
u_int32_t counter_disc;
|
||||
|
||||
/*
|
||||
* This is needed to handle interface type specific information
|
||||
* in sub-modules. It contains a function pointer which handles
|
||||
* notifications and a data pointer to arbitrary data.
|
||||
* Should be set via the mibif_notify function.
|
||||
*/
|
||||
mibif_notify_f xnotify;
|
||||
void *xnotify_data;
|
||||
const struct lmodule *xnotify_mod;
|
||||
};
|
||||
|
||||
/*
|
||||
* Interface IP-address table.
|
||||
*/
|
||||
struct mibifa {
|
||||
TAILQ_ENTRY(mibifa) link;
|
||||
struct in_addr inaddr;
|
||||
struct in_addr inmask;
|
||||
struct in_addr inbcast;
|
||||
struct asn_oid index; /* index for table search */
|
||||
u_int ifindex;
|
||||
u_int flags;
|
||||
};
|
||||
|
||||
/*
|
||||
* Interface receive addresses. Interface link-level multicast, broadcast
|
||||
* and hardware addresses are handled automatically.
|
||||
*/
|
||||
struct mibrcvaddr {
|
||||
TAILQ_ENTRY(mibrcvaddr) link;
|
||||
struct asn_oid index;
|
||||
u_int ifindex;
|
||||
u_char addr[ASN_MAXOIDLEN];
|
||||
size_t addrlen;
|
||||
u_int flags;
|
||||
};
|
||||
enum {
|
||||
MIBRCVADDR_VOLATILE = 0x00000001,
|
||||
MIBRCVADDR_BCAST = 0x00000002,
|
||||
MIBRCVADDR_HW = 0x00000004,
|
||||
};
|
||||
|
||||
/* network socket */
|
||||
extern int mib_netsock;
|
||||
|
||||
/* set an interface name to dynamic mode */
|
||||
void mib_if_set_dyn(const char *);
|
||||
|
||||
/* re-read the systems interface list */
|
||||
void mib_refresh_iflist(void);
|
||||
|
||||
/* find interface by index */
|
||||
struct mibif *mib_find_if(u_int);
|
||||
struct mibif *mib_find_if_sys(u_int);
|
||||
struct mibif *mib_find_if_name(const char *);
|
||||
|
||||
/* iterate through all interfaces */
|
||||
struct mibif *mib_first_if(void);
|
||||
struct mibif *mib_next_if(const struct mibif *);
|
||||
|
||||
/* register for interface creations */
|
||||
int mib_register_newif(int (*)(struct mibif *), const struct lmodule *);
|
||||
void mib_unregister_newif(const struct lmodule *);
|
||||
|
||||
/* get fresh MIB data */
|
||||
int mib_fetch_ifmib(struct mibif *);
|
||||
|
||||
/* change the ADMIN status of an interface and refresh the MIB */
|
||||
int mib_if_admin(struct mibif *, int up);
|
||||
|
||||
/* find interface address by address */
|
||||
struct mibifa *mib_find_ifa(struct in_addr);
|
||||
|
||||
/* find first/next address for a given interface */
|
||||
struct mibifa *mib_first_ififa(const struct mibif *);
|
||||
struct mibifa *mib_next_ififa(struct mibifa *);
|
||||
|
||||
/* create/delete stacking entries */
|
||||
int mib_ifstack_create(const struct mibif *lower, const struct mibif *upper);
|
||||
void mib_ifstack_delete(const struct mibif *lower, const struct mibif *upper);
|
||||
|
||||
/* find receive address */
|
||||
struct mibrcvaddr *mib_find_rcvaddr(u_int, const u_char *, size_t);
|
||||
|
||||
/* create/delete receive addresses */
|
||||
struct mibrcvaddr *mib_rcvaddr_create(struct mibif *, const u_char *, size_t);
|
||||
void mib_rcvaddr_delete(struct mibrcvaddr *);
|
||||
|
||||
/* register for interface notification */
|
||||
void *mibif_notify(struct mibif *, const struct lmodule *, mibif_notify_f,
|
||||
void *);
|
||||
void mibif_unnotify(void *);
|
||||
|
||||
#endif
|
2
contrib/bsnmp/snmpd/.gdbinit
Normal file
2
contrib/bsnmp/snmpd/.gdbinit
Normal file
@ -0,0 +1,2 @@
|
||||
dir ../snmp_netgraph
|
||||
dir ../snmp_mibII
|
63
contrib/bsnmp/snmpd/BEGEMOT-MIB.txt
Normal file
63
contrib/bsnmp/snmpd/BEGEMOT-MIB.txt
Normal file
@ -0,0 +1,63 @@
|
||||
--
|
||||
-- Copyright (c) 2001-2003
|
||||
-- Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
-- All rights reserved.
|
||||
--
|
||||
-- Author: Harti Brandt <harti@freebsd.org>
|
||||
--
|
||||
-- Redistribution of this software and documentation 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 or documentation 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.
|
||||
-- 3. Neither the name of the Institute nor the names of its contributors
|
||||
-- may be used to endorse or promote products derived from this software
|
||||
-- without specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
-- AND ITS 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
|
||||
-- FRAUNHOFER FOKUS OR ITS 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.
|
||||
--
|
||||
-- $Begemot: bsnmp/snmpd/BEGEMOT-MIB.txt,v 1.3 2002/02/06 12:43:51 hbb Exp $
|
||||
--
|
||||
-- Begemot private definitions and root.
|
||||
--
|
||||
BEGEMOT-MIB DEFINITIONS ::= BEGIN
|
||||
|
||||
IMPORTS
|
||||
MODULE-IDENTITY
|
||||
FROM SNMPv2-SMI
|
||||
fokus
|
||||
FROM FOKUS-MIB;
|
||||
|
||||
begemot MODULE-IDENTITY
|
||||
LAST-UPDATED "200201300000Z"
|
||||
ORGANIZATION "Fraunhofer FOKUS, CATS"
|
||||
CONTACT-INFO
|
||||
" Hartmut Brandt
|
||||
|
||||
Postal: Fraunhofer Institute for Open Communication Systems
|
||||
Kaiserin-Augusta-Allee 31
|
||||
10589 Berlin
|
||||
Germany
|
||||
|
||||
Fax: +49 30 3463 7352
|
||||
|
||||
E-mail: harti@freebsd.org"
|
||||
DESCRIPTION
|
||||
"The root of the Begemot subtree of the fokus tree."
|
||||
::= { fokus 1 }
|
||||
|
||||
END
|
482
contrib/bsnmp/snmpd/BEGEMOT-SNMPD.txt
Normal file
482
contrib/bsnmp/snmpd/BEGEMOT-SNMPD.txt
Normal file
@ -0,0 +1,482 @@
|
||||
--
|
||||
-- Copyright (c) 2001-2003
|
||||
-- Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
-- All rights reserved.
|
||||
--
|
||||
-- Author: Harti Brandt <harti@freebsd.org>
|
||||
--
|
||||
-- Redistribution of this software and documentation 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 or documentation 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.
|
||||
-- 3. Neither the name of the Institute nor the names of its contributors
|
||||
-- may be used to endorse or promote products derived from this software
|
||||
-- without specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
-- AND ITS 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
|
||||
-- FRAUNHOFER FOKUS OR ITS 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.
|
||||
--
|
||||
-- $Begemot: bsnmp/snmpd/BEGEMOT-SNMPD.txt,v 1.18 2002/12/11 15:54:07 hbb Exp $
|
||||
--
|
||||
-- Begemot Private SNMPd MIB.
|
||||
--
|
||||
BEGEMOT-SNMPD-MIB DEFINITIONS ::= BEGIN
|
||||
|
||||
IMPORTS
|
||||
MODULE-IDENTITY, OBJECT-TYPE, OBJECT-IDENTITY, Counter32,
|
||||
Unsigned32
|
||||
FROM SNMPv2-SMI
|
||||
TEXTUAL-CONVENTION, TruthValue, RowStatus
|
||||
FROM SNMPv2-TC
|
||||
MODULE-COMPLIANCE, OBJECT-GROUP
|
||||
FROM SNMPv2-CONF
|
||||
begemot
|
||||
FROM BEGEMOT-MIB;
|
||||
|
||||
begemotSnmpd MODULE-IDENTITY
|
||||
LAST-UPDATED "200212040000Z"
|
||||
ORGANIZATION "Fraunhofer FOKUS, CATS"
|
||||
CONTACT-INFO
|
||||
" Hartmut Brandt
|
||||
|
||||
Postal: Fraunhofer Institute for Open Communication Systems
|
||||
Kaiserin-Augusta-Allee 31
|
||||
10589 Berlin
|
||||
Germany
|
||||
|
||||
Fax: +49 30 3463 7352
|
||||
|
||||
E-mail: harti@freebsd.org"
|
||||
DESCRIPTION
|
||||
"The MIB module for the Begemot SNMP daemon."
|
||||
::= { begemot 1 }
|
||||
|
||||
begemotSnmpdObjects OBJECT IDENTIFIER ::= { begemotSnmpd 1 }
|
||||
begemotSnmpdDefs OBJECT IDENTIFIER ::= { begemotSnmpd 2 }
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
|
||||
SectionName ::= TEXTUAL-CONVENTION
|
||||
DISPLAY-HINT "14a"
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Name of a loadable module. Should consist of alphanumeric characers
|
||||
only, the first character must be a letter."
|
||||
SYNTAX OCTET STRING (SIZE(1..14))
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
--
|
||||
-- Agent types
|
||||
--
|
||||
begemotSnmpdAgent OBJECT IDENTIFIER ::= { begemotSnmpdDefs 1 }
|
||||
|
||||
begemotSnmpdAgentFreeBSD OBJECT-IDENTITY
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Identifies the agent as running on FreeBSD."
|
||||
::= { begemotSnmpdAgent 1 }
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
--
|
||||
-- The Config Group
|
||||
--
|
||||
begemotSnmpdConfig OBJECT IDENTIFIER ::= { begemotSnmpdObjects 1 }
|
||||
|
||||
begemotSnmpdTransmitBuffer OBJECT-TYPE
|
||||
SYNTAX INTEGER (484..65535)
|
||||
MAX-ACCESS read-write
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"The size of the receive buffer in bytes. Larger messages
|
||||
are dropped by SNMPd."
|
||||
DEFVAL { 2048 }
|
||||
::= { begemotSnmpdConfig 1 }
|
||||
|
||||
begemotSnmpdReceiveBuffer OBJECT-TYPE
|
||||
SYNTAX INTEGER (484..65535)
|
||||
MAX-ACCESS read-write
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"The size of the transmit buffer in bytes. Larger messages
|
||||
cannot be sent by the SNMPd."
|
||||
DEFVAL { 2048 }
|
||||
::= { begemotSnmpdConfig 2 }
|
||||
|
||||
begemotSnmpdCommunityDisable OBJECT-TYPE
|
||||
SYNTAX TruthValue
|
||||
MAX-ACCESS read-write
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Disables all access to the CommunityTable from SNMP. Once
|
||||
set it cannot be cleared."
|
||||
DEFVAL { false }
|
||||
::= { begemotSnmpdConfig 3 }
|
||||
|
||||
begemotSnmpdTrap1Addr OBJECT-TYPE
|
||||
SYNTAX IpAddress
|
||||
MAX-ACCESS read-write
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"The trap sink for v1 traps."
|
||||
::= { begemotSnmpdConfig 4 }
|
||||
|
||||
--
|
||||
-- Trap destinations
|
||||
--
|
||||
begemotTrapSinkTable OBJECT-TYPE
|
||||
SYNTAX SEQUENCE OF BegemotTrapSinkEntry
|
||||
MAX-ACCESS not-accessible
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"A table with destinations for standard traps."
|
||||
INDEX { begemotTrapSinkAddr, begemotTrapSinkPort }
|
||||
::= { begemotSnmpdObjects 2 }
|
||||
|
||||
begemotTrapSinkEntry OBJECT-TYPE
|
||||
SYNTAX BegemotTrapSinkEntry
|
||||
MAX-ACCESS not-accessible
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Entry describes one trap destination."
|
||||
INDEX { begemotTrapSinkAddr, begemotTrapSinkPort }
|
||||
::= { begemotTrapSinkTable 1 }
|
||||
|
||||
BegemotTrapSinkEntry ::= SEQUENCE {
|
||||
begemotTrapSinkAddr IpAddress,
|
||||
begemotTrapSinkPort INTEGER,
|
||||
begemotTrapSinkStatus RowStatus
|
||||
}
|
||||
|
||||
begemotTrapSinkAddr OBJECT-TYPE
|
||||
SYNTAX IpAddress
|
||||
MAX-ACCESS not-accessible
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Destination IP address of the manager station where to send
|
||||
traps."
|
||||
::= { begemotTrapSinkEntry 1 }
|
||||
|
||||
begemotTrapSinkPort OBJECT-TYPE
|
||||
SYNTAX INTEGER (1..65535)
|
||||
MAX-ACCESS not-accessible
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Destination UDP port of the manager station where to send
|
||||
traps."
|
||||
::= { begemotTrapSinkEntry 2 }
|
||||
|
||||
begemotTrapSinkStatus OBJECT-TYPE
|
||||
SYNTAX RowStatus
|
||||
MAX-ACCESS read-create
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Used to create/activate/destroy the entry."
|
||||
::= { begemotTrapSinkEntry 3 }
|
||||
|
||||
--
|
||||
-- SNMP port table
|
||||
--
|
||||
begemotSnmpdPortTable OBJECT-TYPE
|
||||
SYNTAX SEQUENCE OF BegemotSnmpdPortEntry
|
||||
MAX-ACCESS not-accessible
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"A table with descriptions of UDP ports to listen on
|
||||
for SNMP messages."
|
||||
::= { begemotSnmpdObjects 4 }
|
||||
|
||||
begemotSnmpdPortEntry OBJECT-TYPE
|
||||
SYNTAX BegemotSnmpdPortEntry
|
||||
MAX-ACCESS not-accessible
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"An entry in the table with descriptions of UDP ports to
|
||||
listen on for SNMP messages."
|
||||
INDEX { begemotSnmpdPortAddress, begemotSnmpdPortPort }
|
||||
::= { begemotSnmpdPortTable 1 }
|
||||
|
||||
BegemotSnmpdPortEntry ::= SEQUENCE {
|
||||
begemotSnmpdPortAddress IpAddress,
|
||||
begemotSnmpdPortPort INTEGER,
|
||||
begemotSnmpdPortStatus INTEGER
|
||||
}
|
||||
|
||||
begemotSnmpdPortAddress OBJECT-TYPE
|
||||
SYNTAX IpAddress
|
||||
MAX-ACCESS not-accessible
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"The IP address to bind to."
|
||||
::= { begemotSnmpdPortEntry 1 }
|
||||
|
||||
begemotSnmpdPortPort OBJECT-TYPE
|
||||
SYNTAX INTEGER (1..65535)
|
||||
MAX-ACCESS not-accessible
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"The UDP port to listen on for SNMP messages."
|
||||
::= { begemotSnmpdPortEntry 2 }
|
||||
|
||||
begemotSnmpdPortStatus OBJECT-TYPE
|
||||
SYNTAX INTEGER { valid(1), invalid(2) }
|
||||
MAX-ACCESS read-create
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Set status to 1 to create entry, set it to 2 to delete it."
|
||||
::= { begemotSnmpdPortEntry 3 }
|
||||
|
||||
---
|
||||
--- Community table
|
||||
---
|
||||
begemotSnmpdCommunityTable OBJECT-TYPE
|
||||
SYNTAX SEQUENCE OF BegemotSnmpdCommunityEntry
|
||||
MAX-ACCESS not-accessible
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"A table with the community strings for access control."
|
||||
::= { begemotSnmpdObjects 5 }
|
||||
|
||||
begemotSnmpdCommunityEntry OBJECT-TYPE
|
||||
SYNTAX BegemotSnmpdCommunityEntry
|
||||
MAX-ACCESS not-accessible
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"A table with the community strings for access control.
|
||||
When begemotSnmpdCommDisable is true, this table disappears."
|
||||
INDEX { begemotSnmpdCommunityModule, begemotSnmpdCommunityIndex }
|
||||
::= { begemotSnmpdCommunityTable 1 }
|
||||
|
||||
BegemotSnmpdCommunityEntry ::= SEQUENCE {
|
||||
begemotSnmpdCommunityModule SectionName,
|
||||
begemotSnmpdCommunityIndex Unsigned32,
|
||||
begemotSnmpdCommunityString OCTET STRING,
|
||||
begemotSnmpdCommunityDescr OCTET STRING
|
||||
}
|
||||
|
||||
begemotSnmpdCommunityModule OBJECT-TYPE
|
||||
SYNTAX SectionName
|
||||
MAX-ACCESS not-accessible
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Index of the module that has registered this community.
|
||||
For global communities this is the empty string."
|
||||
::= { begemotSnmpdCommunityEntry 1 }
|
||||
|
||||
begemotSnmpdCommunityIndex OBJECT-TYPE
|
||||
SYNTAX Unsigned32 (1..4294967295)
|
||||
MAX-ACCESS not-accessible
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"The numerical index of the community (private to the module)."
|
||||
::= { begemotSnmpdCommunityEntry 2 }
|
||||
|
||||
begemotSnmpdCommunityString OBJECT-TYPE
|
||||
SYNTAX OCTET STRING
|
||||
MAX-ACCESS read-write
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"The string for access to SNMPd."
|
||||
::= { begemotSnmpdCommunityEntry 3 }
|
||||
|
||||
begemotSnmpdCommunityDescr OBJECT-TYPE
|
||||
SYNTAX OCTET STRING
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"A description what this community is good for."
|
||||
::= { begemotSnmpdCommunityEntry 4 }
|
||||
|
||||
--
|
||||
-- Module table
|
||||
--
|
||||
begemotSnmpdModuleTable OBJECT-TYPE
|
||||
SYNTAX SEQUENCE OF BegemotSnmpdModuleEntry
|
||||
MAX-ACCESS not-accessible
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"A table describing all the currently loaded dynamic modules.
|
||||
Writing to this table loads and unloads modules."
|
||||
::= { begemotSnmpdObjects 6 }
|
||||
|
||||
begemotSnmpdModuleEntry OBJECT-TYPE
|
||||
SYNTAX BegemotSnmpdModuleEntry
|
||||
MAX-ACCESS not-accessible
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"A table entry describing a loadable module."
|
||||
INDEX { begemotSnmpdModuleSection }
|
||||
::= { begemotSnmpdModuleTable 1 }
|
||||
|
||||
BegemotSnmpdModuleEntry ::= SEQUENCE {
|
||||
begemotSnmpdModuleSection SectionName,
|
||||
begemotSnmpdModulePath OCTET STRING,
|
||||
begemotSnmpdModuleComment OCTET STRING
|
||||
}
|
||||
|
||||
begemotSnmpdModuleSection OBJECT-TYPE
|
||||
SYNTAX SectionName
|
||||
MAX-ACCESS not-accessible
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"The string used for matching configuration file sections
|
||||
and indexes the module table."
|
||||
::= { begemotSnmpdModuleEntry 1 }
|
||||
|
||||
|
||||
begemotSnmpdModulePath OBJECT-TYPE
|
||||
SYNTAX OCTET STRING
|
||||
MAX-ACCESS read-create
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"The path name of the module. Set to empty string
|
||||
to unload a module. The path of an existing module
|
||||
may not be changed."
|
||||
::= { begemotSnmpdModuleEntry 2 }
|
||||
|
||||
begemotSnmpdModuleComment OBJECT-TYPE
|
||||
SYNTAX OCTET STRING
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"A comment describing this module."
|
||||
::= { begemotSnmpdModuleEntry 3 }
|
||||
|
||||
|
||||
-- --------------------------------------------------------------------------
|
||||
--
|
||||
-- The STATISTICS Group
|
||||
--
|
||||
begemotSnmpdStats OBJECT IDENTIFIER ::= { begemotSnmpdObjects 7 }
|
||||
|
||||
begemotSnmpdStatsNoRxBufs OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Number of times a receive buffer could not be allocated
|
||||
for a packet."
|
||||
::= { begemotSnmpdStats 1 }
|
||||
|
||||
begemotSnmpdStatsNoTxBufs OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Number of times a transmit buffer could not be allocated
|
||||
for a packet."
|
||||
::= { begemotSnmpdStats 2 }
|
||||
|
||||
begemotSnmpdStatsInTooLongPkts OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Number of packets received that were longer than the
|
||||
receive buffer. These packets are dropped."
|
||||
::= { begemotSnmpdStats 3 }
|
||||
|
||||
begemotSnmpdStatsInBadPduTypes OBJECT-TYPE
|
||||
SYNTAX Counter32
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Number of packets received with a bad type field."
|
||||
::= { begemotSnmpdStats 4 }
|
||||
|
||||
--
|
||||
-- The Debug Group
|
||||
--
|
||||
begemotSnmpdDebug OBJECT IDENTIFIER ::= { begemotSnmpdObjects 8 }
|
||||
|
||||
begemotSnmpdDebugDumpPdus OBJECT-TYPE
|
||||
SYNTAX TruthValue
|
||||
MAX-ACCESS read-write
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Dump PDUs to log file if true."
|
||||
DEFVAL { false }
|
||||
::= { begemotSnmpdDebug 1 }
|
||||
|
||||
begemotSnmpdDebugSnmpTrace OBJECT-TYPE
|
||||
SYNTAX Unsigned32
|
||||
MAX-ACCESS read-write
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Tracing flags for the SNMP library. These flags have the
|
||||
following meaning:
|
||||
0x00000001 trace GET operator
|
||||
0x00000002 trace GETNEXT operator
|
||||
0x00000004 trace SET operator
|
||||
0x00000008 trace dependency processing
|
||||
0x00000010 trace node finding
|
||||
Individual values can be or-ed together."
|
||||
DEFVAL { 0 }
|
||||
::= { begemotSnmpdDebug 2 }
|
||||
|
||||
begemotSnmpdDebugSyslogPri OBJECT-TYPE
|
||||
SYNTAX INTEGER (0..8)
|
||||
MAX-ACCESS read-write
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Events with this or higher priority should not be logged."
|
||||
DEFVAL { 7 } -- don't log debug messages
|
||||
::= { begemotSnmpdDebug 3 }
|
||||
|
||||
--
|
||||
-- Local port table
|
||||
--
|
||||
begemotSnmpdLocalPortTable OBJECT-TYPE
|
||||
SYNTAX SEQUENCE OF BegemotSnmpdLocalPortEntry
|
||||
MAX-ACCESS not-accessible
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"A table with descriptions of local (unix domain) ports to listen
|
||||
on for SNMP messages."
|
||||
::= { begemotSnmpdObjects 9 }
|
||||
|
||||
begemotSnmpdLocalPortEntry OBJECT-TYPE
|
||||
SYNTAX BegemotSnmpdLocalPortEntry
|
||||
MAX-ACCESS not-accessible
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"An entry in the table with descriptions of local ports to
|
||||
listen on for SNMP messages."
|
||||
INDEX { begemotSnmpdLocalPortPath }
|
||||
::= { begemotSnmpdLocalPortTable 1 }
|
||||
|
||||
BegemotSnmpdLocalPortEntry ::= SEQUENCE {
|
||||
begemotSnmpdLocalPortPath OCTET STRING,
|
||||
begemotSnmpdLocalPortStatus INTEGER
|
||||
}
|
||||
|
||||
begemotSnmpdLocalPortPath OBJECT-TYPE
|
||||
SYNTAX OCTET STRING (SIZE(1..104))
|
||||
MAX-ACCESS not-accessible
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"The path name to create and listen on."
|
||||
::= { begemotSnmpdLocalPortEntry 1 }
|
||||
|
||||
begemotSnmpdLocalPortStatus OBJECT-TYPE
|
||||
SYNTAX INTEGER { valid(1), invalid(2) }
|
||||
MAX-ACCESS read-create
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"Set status to 1 to create entry, set it to 2 to delete it."
|
||||
::= { begemotSnmpdLocalPortEntry 2 }
|
||||
|
||||
END
|
61
contrib/bsnmp/snmpd/FOKUS-MIB.txt
Normal file
61
contrib/bsnmp/snmpd/FOKUS-MIB.txt
Normal file
@ -0,0 +1,61 @@
|
||||
--
|
||||
-- Copyright (c) 2001-2003
|
||||
-- Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
-- All rights reserved.
|
||||
--
|
||||
-- Author: Harti Brandt <harti@freebsd.org>
|
||||
--
|
||||
-- Redistribution of this software and documentation 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 or documentation 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.
|
||||
-- 3. Neither the name of the Institute nor the names of its contributors
|
||||
-- may be used to endorse or promote products derived from this software
|
||||
-- without specific prior written permission.
|
||||
--
|
||||
-- THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
-- AND ITS 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
|
||||
-- FRAUNHOFER FOKUS OR ITS 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.
|
||||
--
|
||||
-- $Begemot: bsnmp/snmpd/FOKUS-MIB.txt,v 1.3 2002/02/06 12:43:51 hbb Exp $
|
||||
--
|
||||
-- Begemot private definitions and fokus root.
|
||||
--
|
||||
FOKUS-MIB DEFINITIONS ::= BEGIN
|
||||
|
||||
IMPORTS
|
||||
MODULE-IDENTITY, enterprises
|
||||
FROM SNMPv2-SMI;
|
||||
|
||||
fokus MODULE-IDENTITY
|
||||
LAST-UPDATED "200202050000Z"
|
||||
ORGANIZATION "Fraunhofer FOKUS, CATS"
|
||||
CONTACT-INFO
|
||||
" Hartmut Brandt
|
||||
|
||||
Postal: Fraunhofer Institute for Open Communication Systems
|
||||
Kaiserin-Augusta-Allee 31
|
||||
10589 Berlin
|
||||
Germany
|
||||
|
||||
Fax: +49 30 3463 7352
|
||||
|
||||
E-mail: harti@freebsd.org"
|
||||
DESCRIPTION
|
||||
"The root of the Fokus enterprises tree."
|
||||
::= { enterprises 12325 }
|
||||
|
||||
END
|
1145
contrib/bsnmp/snmpd/action.c
Normal file
1145
contrib/bsnmp/snmpd/action.c
Normal file
File diff suppressed because it is too large
Load Diff
256
contrib/bsnmp/snmpd/bsnmpd.1
Normal file
256
contrib/bsnmp/snmpd/bsnmpd.1
Normal file
@ -0,0 +1,256 @@
|
||||
.\"
|
||||
.\" Copyright (c) 2001-2003
|
||||
.\" Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Author: Harti Brandt <harti@freebsd.org>
|
||||
.\"
|
||||
.\" Redistribution of this software and documentation 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 or documentation 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.
|
||||
.\" 3. Neither the name of the Institute nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
.\" AND ITS 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
|
||||
.\" FRAUNHOFER FOKUS OR ITS 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.
|
||||
.\"
|
||||
.\" $Begemot: bsnmp/snmpd/snmpd.1,v 1.2 2002/08/15 13:27:47 hbb Exp $
|
||||
.\"
|
||||
.Dd August 15, 2002
|
||||
.Dt SNMPD 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm snmpd
|
||||
.Nd "simple and extendable SNMP daemon"
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl dh
|
||||
.Op Fl c Ar file
|
||||
.Op Fl D Ar options
|
||||
.Op Fl I Ar paths
|
||||
.Op Fl l Ar prefix
|
||||
.Op Fl m Ar variable Ns Op = Ns Ar value
|
||||
.Op Fl p Ar file
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
daemon servers the internet SNMP (Simple Network Managment Protocol).
|
||||
It is intended to server only the absolute basic MIBs and implement all other
|
||||
MIBs through loadable modules. In this way the
|
||||
.Nm
|
||||
can be used in unexpected ways.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width ".It Fl D Ar options"
|
||||
.It Fl d
|
||||
This option is used for debugging
|
||||
.Nm
|
||||
and causes it not to daemonize itself.
|
||||
.It Fl h
|
||||
This option prints a short usage message.
|
||||
.It Fl c Ar file
|
||||
Use
|
||||
.Ar file
|
||||
as configuration file instead of the standard one.
|
||||
.It Fl D Ar options
|
||||
Debugging options are specified with a
|
||||
.Fl o
|
||||
flag followed by a comma separated string of options.
|
||||
The following options are available.
|
||||
.Bl -tag -width ".It Cm trace Ns Cm = Ns Cm level"
|
||||
.It Cm dump
|
||||
This option causes all sent and received PDUs to be dumped to the terminal.
|
||||
.It Cm events
|
||||
This causes the debugging level of the event library (see
|
||||
.Xr eventlib 3 )
|
||||
to be set to 10.
|
||||
.It Cm trace Ns Cm = Ns Cm level
|
||||
This option causes the snmp library trace flag to be set to the specified
|
||||
value. The value can be specified in the usual C-syntax for numbers.
|
||||
.El
|
||||
.It Fl I Ar paths
|
||||
This option specifies a colon separated list of directories to search for
|
||||
configuration include files. The default is
|
||||
.Pa /etc:/usr/etc/:/usr/local/etc .
|
||||
These paths are only searched for include specified within <> parantheses.
|
||||
.It Fl l Ar prefix
|
||||
The
|
||||
.Ar prefix
|
||||
is used as the default basename for the pid and the configuration files.
|
||||
.It Fl m Ar variable Ns Op = Ns Ar value
|
||||
Define a configuration variable.
|
||||
.It Fl p Ar file
|
||||
Specify an alternate pid file instead of the default one.
|
||||
.El
|
||||
.Sh CONFIGURATION
|
||||
The
|
||||
.Nm
|
||||
reads its configuration from either the default or the user specified
|
||||
configuration file. The configuration file consists of the following types of
|
||||
lines:
|
||||
.Bl -bullet -offset indent
|
||||
.It
|
||||
variable assignments
|
||||
.It
|
||||
section separators
|
||||
.It
|
||||
include directives
|
||||
.It
|
||||
MIB variable assignments
|
||||
.El
|
||||
.Pp
|
||||
If a line is too long it can be continued on the next line by ending it with
|
||||
a backslash. Empty lines and lines who's first non-blank character is a
|
||||
.Dq #
|
||||
sign are ignored.
|
||||
.Pp
|
||||
All MIB variable assignments of the entire configuration (including nested
|
||||
configuration files) are handled as one transaction, i.e. as if they arrived
|
||||
in a single SET PDU. Any failure during the initial configuration read causes
|
||||
.Nm
|
||||
to exit. A failure during the configuration read caused by a module load
|
||||
causes the loading of the module to fail.
|
||||
.Pp
|
||||
The configuration is red during initialisation of
|
||||
.Nm ,
|
||||
when a module is loaded and when
|
||||
.Nm
|
||||
receives a SIGHUP.
|
||||
.Ss VARIABLE ASSIGNMENTS
|
||||
Variable assignments can take one of two forms:
|
||||
.Bd -unfilled -offset indent
|
||||
variable := string
|
||||
variable ?= string
|
||||
.Ed
|
||||
.Pp
|
||||
The string reaches from the first non-blank character after the
|
||||
equal sign until the first new line or
|
||||
.Dq #
|
||||
character. In the first case
|
||||
the string is assigned to the variable unconditionally, in the second case the
|
||||
variable is only assigned if it does not exist yet.
|
||||
.Pp
|
||||
Variable names must begin with a letter or underscore and contain only letters,
|
||||
digits or underscores.
|
||||
.Ss SECTION SEPARATORS
|
||||
The configuration consists of named sections. The MIB variable assignments in
|
||||
the section named
|
||||
.Dq snmpd
|
||||
are executed only during initial setup or when
|
||||
.Nm
|
||||
receives a SIGHUP. All other sections are executed when either a module
|
||||
with the same name as the section is loaded or
|
||||
.Nm
|
||||
receives a SIGHUP and that module is already loaded. The default section
|
||||
at the start of the configuration is
|
||||
.Dq snmpd .
|
||||
One can switch to another section with the syntax
|
||||
.Bd -unfilled -offset indent
|
||||
%secname
|
||||
.Ed
|
||||
.Pp
|
||||
Where
|
||||
.Ar secname
|
||||
is the name of the section. The same
|
||||
.Ar secname
|
||||
can be used in more than one place in the configuration. All of these parts are
|
||||
collected into one section.
|
||||
.Ss INCLUDE DIRECTIVES
|
||||
Another configuration file can be included into the current one with the
|
||||
include directive that takes one of two forms:
|
||||
.Bd -unfilled -offset indent
|
||||
\&.include "file"
|
||||
\&.include <"file">
|
||||
.Ed
|
||||
.Pp
|
||||
The first form causes the file to be searched in the current directory, the
|
||||
second form causes the file to be searched in the directories specified in
|
||||
the system include path. Nesting depths is only restricted by available
|
||||
memory.
|
||||
.Ss MIB VARIABLE ASSIGNMENTS
|
||||
A MIB variable is assigned with the syntax
|
||||
.Bd -unfilled -offset indent
|
||||
oid [ suboids ] = value
|
||||
.Ed
|
||||
.Pp
|
||||
.Va oid
|
||||
is the name of the variable to be set. Only the last component of the entire
|
||||
name is used here. If the variable is a scalar, the index (.0) is automatically
|
||||
appended and need not to be specified. If the variable is a table column,
|
||||
the index (
|
||||
.Va suboids )
|
||||
must be specified. The index consist of elements each seperated from the
|
||||
previous one by a dot. Elements may be either numbers, strings or hostnames
|
||||
enclosed in [] brackets. If the element is a number it is appended
|
||||
to the current oid. If the element is a string, its length and the
|
||||
.Tn ASCII
|
||||
code of each of its characters are appended to the current oid. If the
|
||||
element is a hostname, the IP address of the host is looked up and the four
|
||||
elements of the IP address are appended to the oid.
|
||||
.Pp
|
||||
For example a oid of
|
||||
.Bd -unfilled -offset indent
|
||||
myvariable.27.foooll.[localhost]."&^!"
|
||||
.Ed
|
||||
.Pp
|
||||
results in the oid
|
||||
.Bd -unfilled -offset indent
|
||||
myvariable.27.6.102.111.111.111.108.108.127.0.0.1.38.94.33
|
||||
.Ed
|
||||
.Pp
|
||||
The value of the assignment may be either empty, a string or a number.
|
||||
If a string starts with a letter or an underscore and consists only of
|
||||
letters, digits, underscores and minus signs, it can be written without
|
||||
quotes. In all other cases the string must be enclosed in double quotes.
|
||||
.Sh SUBSTITUTIONS
|
||||
A variable substitution is written as
|
||||
.Bd -unfilled -offset indent
|
||||
$(variable)
|
||||
.Ed
|
||||
.Pp
|
||||
where
|
||||
.Ar variable
|
||||
is the name of the variable to substitute. Using an undefined variable is
|
||||
considered an error.
|
||||
.Sh FILES
|
||||
.Bl -tag -width ".It Pa /var/run/ Ns Ao Ar prefix Ac Ns \&.pid" -compact
|
||||
.It Pa /etc/ Ns Ao Ar prefix Ac Ns \&.config
|
||||
Default configuration file, where the default
|
||||
.Aq prefix
|
||||
is
|
||||
.Dq snmpd .
|
||||
.It Pa /var/run/ Ns Ao Ar prefix Ac Ns \&.pid
|
||||
Default pid file.
|
||||
.It Pa /etc:/usr/etc/:/usr/local/etc
|
||||
This is the default search path for system include files.
|
||||
.It Pa /usr/local/share/snmp/mibs/FOKUS-MIB.txt
|
||||
.It Pa /usr/local/share/snmp/mibs/BEGEMOT-MIB.txt
|
||||
.It Pa /usr/local/share/snmp/mibs/BEGEMOT-SNMPD.txt
|
||||
The definitions for the MIBs implemented in the daemon.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr gensnmptree 1
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Nm
|
||||
conforms to the applicable IETF RFCs.
|
||||
.Sh AUTHORS
|
||||
.An Hartmut Brandt Aq brandt@fokus.gmd.de
|
||||
.Sh BUGS
|
||||
Sure.
|
1361
contrib/bsnmp/snmpd/config.c
Normal file
1361
contrib/bsnmp/snmpd/config.c
Normal file
File diff suppressed because it is too large
Load Diff
378
contrib/bsnmp/snmpd/export.c
Normal file
378
contrib/bsnmp/snmpd/export.c
Normal file
@ -0,0 +1,378 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003
|
||||
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Harti Brandt <harti@freebsd.org>
|
||||
*
|
||||
* Redistribution of this software and documentation 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 or documentation 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.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
* AND ITS 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
|
||||
* FRAUNHOFER FOKUS OR ITS 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.
|
||||
*
|
||||
* $Begemot: bsnmp/snmpd/export.c,v 1.5 2003/01/28 13:44:35 hbb Exp $
|
||||
*
|
||||
* Support functions for modules.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "snmpmod.h"
|
||||
#include "snmpd.h"
|
||||
#include "tree.h"
|
||||
|
||||
/*
|
||||
* Support functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is user for SET of string variables. If 'req' is not -1 then
|
||||
* the arguments is checked to be of that length. The old value is saved
|
||||
* in scratch->ptr1 and the new value is allocated and copied.
|
||||
* If there is an old values it must have been allocated by malloc.
|
||||
*/
|
||||
int
|
||||
string_save(struct snmp_value *value, struct snmp_context *ctx,
|
||||
ssize_t req_size, u_char **valp)
|
||||
{
|
||||
if (req_size != -1 && value->v.octetstring.len != (u_long)req_size)
|
||||
return (SNMP_ERR_BADVALUE);
|
||||
|
||||
ctx->scratch->ptr1 = *valp;
|
||||
|
||||
if ((*valp = malloc(value->v.octetstring.len + 1)) == NULL) {
|
||||
*valp = ctx->scratch->ptr1;
|
||||
return (SNMP_ERR_RES_UNAVAIL);
|
||||
}
|
||||
|
||||
memcpy(*valp, value->v.octetstring.octets, value->v.octetstring.len);
|
||||
(*valp)[value->v.octetstring.len] = '\0';
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Commit a string. This is easy - free the old value.
|
||||
*/
|
||||
void
|
||||
string_commit(struct snmp_context *ctx)
|
||||
{
|
||||
free(ctx->scratch->ptr1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Rollback a string - free new value and copy back old one.
|
||||
*/
|
||||
void
|
||||
string_rollback(struct snmp_context *ctx, u_char **valp)
|
||||
{
|
||||
free(*valp);
|
||||
*valp = ctx->scratch->ptr1;
|
||||
}
|
||||
|
||||
/*
|
||||
* ROLLBACK or COMMIT fails because instance has disappeared. Free string.
|
||||
*/
|
||||
void
|
||||
string_free(struct snmp_context *ctx)
|
||||
{
|
||||
free(ctx->scratch->ptr1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a string value for a response packet
|
||||
*/
|
||||
int
|
||||
string_get(struct snmp_value *value, const u_char *ptr, ssize_t len)
|
||||
{
|
||||
if (ptr == NULL) {
|
||||
value->v.octetstring.len = 0;
|
||||
value->v.octetstring.octets = NULL;
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
if (len == -1)
|
||||
len = strlen(ptr);
|
||||
value->v.octetstring.len = (u_long)len;
|
||||
if ((value->v.octetstring.octets = malloc((size_t)len)) == NULL)
|
||||
return (SNMP_ERR_RES_UNAVAIL);
|
||||
memcpy(value->v.octetstring.octets, ptr, (size_t)len);
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Support for IPADDRESS
|
||||
*
|
||||
* Save the old IP address in scratch->int1 and set the new one.
|
||||
*/
|
||||
int
|
||||
ip_save(struct snmp_value *value, struct snmp_context *ctx, u_char *valp)
|
||||
{
|
||||
ctx->scratch->int1 = (valp[0] << 24) | (valp[1] << 16) | (valp[2] << 8)
|
||||
| valp[3];
|
||||
|
||||
valp[0] = value->v.ipaddress[0];
|
||||
valp[1] = value->v.ipaddress[1];
|
||||
valp[2] = value->v.ipaddress[2];
|
||||
valp[3] = value->v.ipaddress[3];
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Rollback the address by copying back the old one
|
||||
*/
|
||||
void
|
||||
ip_rollback(struct snmp_context *ctx, u_char *valp)
|
||||
{
|
||||
valp[0] = ctx->scratch->int1 >> 24;
|
||||
valp[1] = ctx->scratch->int1 >> 16;
|
||||
valp[2] = ctx->scratch->int1 >> 8;
|
||||
valp[3] = ctx->scratch->int1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Nothing to do for commit
|
||||
*/
|
||||
void
|
||||
ip_commit(struct snmp_context *ctx __unused)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieve an IP address
|
||||
*/
|
||||
int
|
||||
ip_get(struct snmp_value *value, u_char *valp)
|
||||
{
|
||||
value->v.ipaddress[0] = valp[0];
|
||||
value->v.ipaddress[1] = valp[1];
|
||||
value->v.ipaddress[2] = valp[2];
|
||||
value->v.ipaddress[3] = valp[3];
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Object ID support
|
||||
*
|
||||
* Save the old value in a fresh allocated oid pointed to by scratch->ptr1.
|
||||
*/
|
||||
int
|
||||
oid_save(struct snmp_value *value, struct snmp_context *ctx,
|
||||
struct asn_oid *oid)
|
||||
{
|
||||
if ((ctx->scratch->ptr1 = malloc(sizeof(struct asn_oid))) == NULL)
|
||||
return (SNMP_ERR_RES_UNAVAIL);
|
||||
*(struct asn_oid *)ctx->scratch->ptr1 = *oid;
|
||||
*oid = value->v.oid;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
oid_rollback(struct snmp_context *ctx, struct asn_oid *oid)
|
||||
{
|
||||
*oid = *(struct asn_oid *)ctx->scratch->ptr1;
|
||||
free(ctx->scratch->ptr1);
|
||||
}
|
||||
|
||||
void
|
||||
oid_commit(struct snmp_context *ctx)
|
||||
{
|
||||
free(ctx->scratch->ptr1);
|
||||
}
|
||||
|
||||
int
|
||||
oid_get(struct snmp_value *value, const struct asn_oid *oid)
|
||||
{
|
||||
value->v.oid = *oid;
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode an index
|
||||
*/
|
||||
int
|
||||
index_decode(const struct asn_oid *oid, u_int sub, u_int code, ...)
|
||||
{
|
||||
va_list ap;
|
||||
u_int index_count;
|
||||
void *octs[10];
|
||||
u_int nocts;
|
||||
u_int idx;
|
||||
|
||||
va_start(ap, code);
|
||||
index_count = SNMP_INDEX_COUNT(code);
|
||||
nocts = 0;
|
||||
|
||||
for (idx = 0; idx < index_count; idx++) {
|
||||
switch (SNMP_INDEX(code, idx)) {
|
||||
|
||||
case SNMP_SYNTAX_NULL:
|
||||
break;
|
||||
|
||||
case SNMP_SYNTAX_INTEGER:
|
||||
if (sub == oid->len)
|
||||
goto err;
|
||||
*va_arg(ap, int32_t *) = oid->subs[sub++];
|
||||
break;
|
||||
|
||||
case SNMP_SYNTAX_COUNTER64:
|
||||
if (sub == oid->len)
|
||||
goto err;
|
||||
*va_arg(ap, u_int64_t *) = oid->subs[sub++];
|
||||
break;
|
||||
|
||||
case SNMP_SYNTAX_OCTETSTRING:
|
||||
{
|
||||
u_char **cval;
|
||||
size_t *sval;
|
||||
u_int i;
|
||||
|
||||
/* only variable size supported */
|
||||
if (sub == oid->len)
|
||||
goto err;
|
||||
cval = va_arg(ap, u_char **);
|
||||
sval = va_arg(ap, size_t *);
|
||||
*sval = oid->subs[sub++];
|
||||
if (sub + *sval > oid->len)
|
||||
goto err;
|
||||
if ((*cval = malloc(*sval)) == NULL) {
|
||||
syslog(LOG_ERR, "%s: %m", __func__);
|
||||
goto err;
|
||||
}
|
||||
octs[nocts++] = *cval;
|
||||
for (i = 0; i < *sval; i++) {
|
||||
if (oid->subs[sub] > 0xff)
|
||||
goto err;
|
||||
(*cval)[i] = oid->subs[sub++];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SNMP_SYNTAX_OID:
|
||||
{
|
||||
struct asn_oid *aval;
|
||||
u_int i;
|
||||
|
||||
if (sub == oid->len)
|
||||
goto err;
|
||||
aval = va_arg(ap, struct asn_oid *);
|
||||
aval->len = oid->subs[sub++];
|
||||
if (aval->len > ASN_MAXOIDLEN)
|
||||
goto err;
|
||||
for (i = 0; i < aval->len; i++)
|
||||
aval->subs[i] = oid->subs[sub++];
|
||||
break;
|
||||
}
|
||||
|
||||
case SNMP_SYNTAX_IPADDRESS:
|
||||
{
|
||||
u_int8_t *pval;
|
||||
u_int i;
|
||||
|
||||
if (sub + 4 > oid->len)
|
||||
goto err;
|
||||
pval = va_arg(ap, u_int8_t *);
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (oid->subs[sub] > 0xff)
|
||||
goto err;
|
||||
pval[i] = oid->subs[sub++];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SNMP_SYNTAX_COUNTER:
|
||||
case SNMP_SYNTAX_GAUGE:
|
||||
case SNMP_SYNTAX_TIMETICKS:
|
||||
if (sub == oid->len)
|
||||
goto err;
|
||||
if (oid->subs[sub] > 0xffffffff)
|
||||
goto err;
|
||||
*va_arg(ap, u_int32_t *) = oid->subs[sub++];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
return (0);
|
||||
|
||||
err:
|
||||
va_end(ap);
|
||||
while(nocts > 0)
|
||||
free(octs[--nocts]);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare the index part of an OID and an index.
|
||||
*/
|
||||
int
|
||||
index_compare_off(const struct asn_oid *oid, u_int sub,
|
||||
const struct asn_oid *idx, u_int off)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
for (i = off; i < idx->len && i < oid->len - sub; i++) {
|
||||
if (oid->subs[sub + i] < idx->subs[i])
|
||||
return (-1);
|
||||
if (oid->subs[sub + i] > idx->subs[i])
|
||||
return (+1);
|
||||
}
|
||||
if (oid->len - sub < idx->len)
|
||||
return (-1);
|
||||
if (oid->len - sub > idx->len)
|
||||
return (+1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
index_compare(const struct asn_oid *oid, u_int sub, const struct asn_oid *idx)
|
||||
{
|
||||
return (index_compare_off(oid, sub, idx, 0));
|
||||
}
|
||||
|
||||
/*
|
||||
* Append an index to an oid
|
||||
*/
|
||||
void
|
||||
index_append_off(struct asn_oid *var, u_int sub, const struct asn_oid *idx,
|
||||
u_int off)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
var->len = sub + idx->len;
|
||||
for (i = off; i < idx->len; i++)
|
||||
var->subs[sub + i] = idx->subs[i];
|
||||
}
|
||||
void
|
||||
index_append(struct asn_oid *var, u_int sub, const struct asn_oid *idx)
|
||||
{
|
||||
index_append_off(var, sub, idx, 0);
|
||||
}
|
||||
|
2038
contrib/bsnmp/snmpd/main.c
Normal file
2038
contrib/bsnmp/snmpd/main.c
Normal file
File diff suppressed because it is too large
Load Diff
92
contrib/bsnmp/snmpd/snmpd.config
Normal file
92
contrib/bsnmp/snmpd/snmpd.config
Normal file
@ -0,0 +1,92 @@
|
||||
#
|
||||
# Copyright (c) 2001-2003
|
||||
# Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
# All rights reserved.
|
||||
#
|
||||
# Author: Harti Brandt <harti@freebsd.org>
|
||||
#
|
||||
# Redistribution of this software and documentation 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 or documentation 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.
|
||||
# 3. Neither the name of the Institute nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
# AND ITS 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
|
||||
# FRAUNHOFER FOKUS OR ITS 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.
|
||||
#
|
||||
# $Begemot: bsnmp/snmpd/snmpd.config,v 1.11 2002/12/11 15:54:08 hbb Exp $
|
||||
#
|
||||
# Example configuration file.
|
||||
#
|
||||
|
||||
#
|
||||
# Set some common variables
|
||||
#
|
||||
host := foo.bar.com
|
||||
location := "Room 200"
|
||||
contact := "sysmeister@bar.com"
|
||||
system := 1 # FreeBSD
|
||||
traphost := noc.bar.com
|
||||
trapport := 162
|
||||
|
||||
read := "public"
|
||||
write := "geheim"
|
||||
trap := "mytrap"
|
||||
|
||||
#
|
||||
# Configuration
|
||||
#
|
||||
%snmpd
|
||||
begemotSnmpdDebugDumpPdus = 2
|
||||
begemotSnmpdDebugSyslogPri = 7
|
||||
|
||||
begemotSnmpdCommunityString.0.1 = $(read)
|
||||
begemotSnmpdCommunityString.0.2 = $(write)
|
||||
begemotSnmpdCommunityDisable = 1
|
||||
|
||||
# open standard SNMP ports
|
||||
begemotSnmpdPortStatus.[$(host)].161 = 1
|
||||
begemotSnmpdPortStatus.127.0.0.1.161 = 1
|
||||
|
||||
# open a unix domain socket
|
||||
begemotSnmpdLocalPortStatus."/var/run/snmpd.sock" = 1
|
||||
|
||||
# send traps to the traphost
|
||||
begemotTrapSinkStatus[$(traphost)].$(trapport) = 4
|
||||
begemotTrapSinkVersion[$(traphost)].$(trapport) = 2
|
||||
begemotTrapSinkComm[$(traphost)].$(trapport) = $(trap)
|
||||
|
||||
sysContact = $(contact)
|
||||
sysLocation = $(location)
|
||||
sysObjectId = 1.3.6.1.4.1.12325.1.1.2.1.$(system)
|
||||
|
||||
snmpEnableAuthenTraps = 2
|
||||
|
||||
#
|
||||
# Load MIB-2 module
|
||||
#
|
||||
begemotSnmpdModulePath."mibII" = "/usr/local/lib/snmp_mibII.so"
|
||||
|
||||
#
|
||||
# Netgraph module
|
||||
#
|
||||
begemotSnmpdModulePath."netgraph" = "/usr/local/lib/snmp_netgraph.so"
|
||||
|
||||
%netgraph
|
||||
begemotNgControlNodeName = "snmpd"
|
277
contrib/bsnmp/snmpd/snmpd.h
Normal file
277
contrib/bsnmp/snmpd/snmpd.h
Normal file
@ -0,0 +1,277 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003
|
||||
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Harti Brandt <harti@freebsd.org>
|
||||
*
|
||||
* Redistribution of this software and documentation 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 or documentation 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.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
* AND ITS 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
|
||||
* FRAUNHOFER FOKUS OR ITS 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.
|
||||
*
|
||||
* $Begemot: bsnmp/snmpd/snmpd.h,v 1.17 2003/01/28 13:44:35 hbb Exp $
|
||||
*
|
||||
* Private SNMPd data and functions.
|
||||
*/
|
||||
#include <sys/queue.h>
|
||||
#include <isc/eventlib.h>
|
||||
|
||||
#define PATH_SYSCONFIG "/etc:/usr/etc:/usr/local/etc"
|
||||
|
||||
/*************************************************************
|
||||
*
|
||||
* Communities
|
||||
*/
|
||||
struct community {
|
||||
struct lmodule *owner; /* who created the community */
|
||||
u_int private;/* private name for the module */
|
||||
u_int value; /* value of this community */
|
||||
u_char * string; /* the community string */
|
||||
const u_char * descr; /* description */
|
||||
TAILQ_ENTRY(community) link;
|
||||
|
||||
struct asn_oid index;
|
||||
};
|
||||
/* list of all known communities */
|
||||
extern TAILQ_HEAD(community_list, community) community_list;
|
||||
|
||||
/*************************************************************
|
||||
*
|
||||
* Request IDs.
|
||||
*/
|
||||
struct idrange {
|
||||
u_int type; /* type id */
|
||||
int32_t base; /* base of this range */
|
||||
int32_t size; /* size of this range */
|
||||
int32_t next; /* generator */
|
||||
struct lmodule *owner; /* owner module */
|
||||
TAILQ_ENTRY(idrange) link;
|
||||
};
|
||||
|
||||
/* list of all known ranges */
|
||||
extern TAILQ_HEAD(idrange_list, idrange) idrange_list;
|
||||
|
||||
/* identifier generator */
|
||||
extern u_int next_idrange;
|
||||
|
||||
/* request id generator for traps */
|
||||
extern u_int trap_reqid;
|
||||
|
||||
/*************************************************************
|
||||
*
|
||||
* Timers
|
||||
*/
|
||||
struct timer {
|
||||
void (*func)(void *);/* user function */
|
||||
void *udata; /* user data */
|
||||
evTimerID id; /* timer id */
|
||||
struct lmodule *owner; /* owner of the timer */
|
||||
LIST_ENTRY(timer) link;
|
||||
};
|
||||
|
||||
/* list of all current timers */
|
||||
extern LIST_HEAD(timer_list, timer) timer_list;
|
||||
|
||||
|
||||
/*************************************************************
|
||||
*
|
||||
* File descriptors
|
||||
*/
|
||||
struct fdesc {
|
||||
int fd; /* the file descriptor */
|
||||
void (*func)(int, void *);/* user function */
|
||||
void *udata; /* user data */
|
||||
evFileID id; /* file id */
|
||||
struct lmodule *owner; /* owner module of the file */
|
||||
LIST_ENTRY(fdesc) link;
|
||||
};
|
||||
|
||||
/* list of all current selected files */
|
||||
extern LIST_HEAD(fdesc_list, fdesc) fdesc_list;
|
||||
|
||||
/*************************************************************
|
||||
*
|
||||
* Loadable modules
|
||||
*/
|
||||
# define LM_SECTION_MAX 14
|
||||
struct lmodule {
|
||||
char section[LM_SECTION_MAX + 1]; /* and index */
|
||||
char *path;
|
||||
u_int flags;
|
||||
void *handle;
|
||||
const struct snmp_module *config;
|
||||
|
||||
TAILQ_ENTRY(lmodule) link;
|
||||
TAILQ_ENTRY(lmodule) start;
|
||||
|
||||
struct asn_oid index;
|
||||
};
|
||||
#define LM_STARTED 0x0001
|
||||
#define LM_ONSTARTLIST 0x0002
|
||||
|
||||
extern TAILQ_HEAD(lmodules, lmodule) lmodules;
|
||||
|
||||
struct lmodule *lm_load(const char *, const char *);
|
||||
void lm_unload(struct lmodule *);
|
||||
void lm_start(struct lmodule *);
|
||||
|
||||
/*************************************************************
|
||||
*
|
||||
* SNMP ports
|
||||
*/
|
||||
struct snmp_port {
|
||||
u_int8_t addr[4];/* host byteorder */
|
||||
u_int16_t port; /* host byteorder */
|
||||
|
||||
int sock; /* the socket */
|
||||
void * id; /* evSelect handle */
|
||||
|
||||
struct sockaddr_in ret; /* the return address */
|
||||
socklen_t retlen; /* length of that address */
|
||||
|
||||
TAILQ_ENTRY(snmp_port) link;
|
||||
|
||||
struct asn_oid index;
|
||||
};
|
||||
TAILQ_HEAD(snmp_port_list, snmp_port);
|
||||
extern struct snmp_port_list snmp_port_list;
|
||||
|
||||
void close_snmp_port(struct snmp_port *);
|
||||
int open_snmp_port(u_int8_t *, u_int32_t, struct snmp_port **);
|
||||
|
||||
struct local_port {
|
||||
char *name; /* unix path name */
|
||||
int sock; /* the socket */
|
||||
void *id; /* evSelect handle */
|
||||
|
||||
struct sockaddr_un ret; /* the return address */
|
||||
socklen_t retlen; /* length of that address */
|
||||
|
||||
TAILQ_ENTRY(local_port) link;
|
||||
|
||||
struct asn_oid index;
|
||||
};
|
||||
TAILQ_HEAD(local_port_list, local_port);
|
||||
extern struct local_port_list local_port_list;
|
||||
|
||||
void close_local_port(struct local_port *);
|
||||
int open_local_port(u_char *, size_t, struct local_port **);
|
||||
|
||||
/*************************************************************
|
||||
*
|
||||
* SNMPd scalar configuration.
|
||||
*/
|
||||
struct snmpd {
|
||||
/* transmit buffer size */
|
||||
u_int32_t txbuf;
|
||||
|
||||
/* receive buffer size */
|
||||
u_int32_t rxbuf;
|
||||
|
||||
/* disable community table */
|
||||
int comm_dis;
|
||||
|
||||
/* authentication traps */
|
||||
int auth_traps;
|
||||
|
||||
/* source address for V1 traps */
|
||||
u_char trap1addr[4];
|
||||
};
|
||||
extern struct snmpd snmpd;
|
||||
|
||||
/*
|
||||
* The debug group
|
||||
*/
|
||||
struct debug {
|
||||
u_int dump_pdus;
|
||||
u_int logpri;
|
||||
u_int evdebug;
|
||||
};
|
||||
extern struct debug debug;
|
||||
|
||||
|
||||
/*
|
||||
* SNMPd statistics table
|
||||
*/
|
||||
struct snmpd_stats {
|
||||
u_int32_t inPkts; /* total packets received */
|
||||
u_int32_t inBadVersions; /* unknown version number */
|
||||
u_int32_t inASNParseErrs; /* fatal parse errors */
|
||||
u_int32_t inBadCommunityNames;
|
||||
u_int32_t inBadCommunityUses;
|
||||
u_int32_t proxyDrops; /* dropped by proxy function */
|
||||
u_int32_t silentDrops;
|
||||
|
||||
u_int32_t inBadPduTypes;
|
||||
u_int32_t inTooLong;
|
||||
u_int32_t noTxbuf;
|
||||
u_int32_t noRxbuf;
|
||||
};
|
||||
extern struct snmpd_stats snmpd_stats;
|
||||
|
||||
/*
|
||||
* OR Table
|
||||
*/
|
||||
struct objres {
|
||||
TAILQ_ENTRY(objres) link;
|
||||
u_int index;
|
||||
struct asn_oid oid; /* the resource OID */
|
||||
char descr[256];
|
||||
u_int32_t uptime;
|
||||
struct lmodule *module;
|
||||
};
|
||||
TAILQ_HEAD(objres_list, objres);
|
||||
extern struct objres_list objres_list;
|
||||
|
||||
/*
|
||||
* Trap Sink Table
|
||||
*/
|
||||
struct trapsink {
|
||||
TAILQ_ENTRY(trapsink) link;
|
||||
struct asn_oid index;
|
||||
u_int status;
|
||||
int socket;
|
||||
u_char comm[SNMP_COMMUNITY_MAXLEN];
|
||||
int version;
|
||||
};
|
||||
enum {
|
||||
TRAPSINK_ACTIVE = 1,
|
||||
TRAPSINK_NOT_IN_SERVICE = 2,
|
||||
TRAPSINK_NOT_READY = 3,
|
||||
TRAPSINK_DESTROY = 6,
|
||||
|
||||
TRAPSINK_V1 = 1,
|
||||
TRAPSINK_V2 = 2,
|
||||
};
|
||||
TAILQ_HEAD(trapsink_list, trapsink);
|
||||
extern struct trapsink_list trapsink_list;
|
||||
|
||||
extern const char *syspath;
|
||||
|
||||
/* snmpSerialNo */
|
||||
extern int32_t snmp_serial_no;
|
||||
|
||||
int init_actvals(void);
|
||||
int read_config(const char *, struct lmodule *);
|
||||
int define_macro(const char *name, const char *value);
|
89
contrib/bsnmp/snmpd/snmpd.sh
Executable file
89
contrib/bsnmp/snmpd/snmpd.sh
Executable file
@ -0,0 +1,89 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2001-2003
|
||||
# Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
# All rights reserved.
|
||||
#
|
||||
# Author: Harti Brandt <harti@freebsd.org>
|
||||
#
|
||||
# Redistribution of this software and documentation 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 or documentation 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.
|
||||
# 3. Neither the name of the Institute nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
# AND ITS 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
|
||||
# FRAUNHOFER FOKUS OR ITS 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.
|
||||
#
|
||||
# $Begemot: bsnmp/snmpd/snmpd.sh,v 1.1 2002/12/04 11:15:23 hbb Exp $
|
||||
#
|
||||
# SNMPd startup script
|
||||
#
|
||||
SNMPD=/usr/local/bin/bsnmpd
|
||||
PID=/var/run/snmpd.pid
|
||||
CONF=/etc/snmpd.conf
|
||||
|
||||
case "$1" in
|
||||
|
||||
start)
|
||||
if [ -r ${PID} ] ; then
|
||||
if kill -0 `cat ${PID}` ; then
|
||||
echo "snmpd already running -- pid `cat ${PID}`" >/dev/stderr
|
||||
exit 1
|
||||
fi
|
||||
rm -f ${PID}
|
||||
fi
|
||||
if ${SNMPD} -c ${CONF} -p ${PID} ; then
|
||||
echo "snmpd started"
|
||||
fi
|
||||
;;
|
||||
|
||||
stop)
|
||||
if [ -r ${PID} ] ; then
|
||||
if kill -0 `cat ${PID}` ; then
|
||||
if kill -15 `cat ${PID}` ; then
|
||||
echo "snmpd stopped"
|
||||
exit 0
|
||||
fi
|
||||
echo "cannot kill snmpd" >/dev/stderr
|
||||
exit 1
|
||||
fi
|
||||
echo "stale pid file -- removing" >/dev/stderr
|
||||
rm -f ${PID}
|
||||
exit 1
|
||||
fi
|
||||
echo "snmpd not running" >/dev/stderr
|
||||
;;
|
||||
|
||||
status)
|
||||
if [ ! -r ${PID} ] ; then
|
||||
echo "snmpd not running"
|
||||
elif kill -0 `cat ${PID}` ; then
|
||||
echo "snmpd pid `cat ${PID}`"
|
||||
else
|
||||
echo "stale pid file -- pid `cat ${PID}`"
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "usage: `basename $0` {start|stop|status}"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
exit 0
|
861
contrib/bsnmp/snmpd/snmpmod.3
Normal file
861
contrib/bsnmp/snmpd/snmpmod.3
Normal file
@ -0,0 +1,861 @@
|
||||
.\"
|
||||
.\" Copyright (c) 2001-2003
|
||||
.\" Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Author: Harti Brandt <harti@freebsd.org>
|
||||
.\"
|
||||
.\" Redistribution of this software and documentation 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 or documentation 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.
|
||||
.\" 3. Neither the name of the Institute nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
.\" AND ITS 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
|
||||
.\" FRAUNHOFER FOKUS OR ITS 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.
|
||||
.\"
|
||||
.\" $Begemot: bsnmp/snmpd/snmpmod.3,v 1.3 2003/01/28 13:44:35 hbb Exp $
|
||||
.\"
|
||||
.Dd August 16, 2002
|
||||
.Dt snmpmod 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm INSERT_OBJECT_OID_LINK_INDEX ,
|
||||
.Nm INSERT_OBJECT_INT_LINK_INDEX ,
|
||||
.Nm FIND_OBJECT_OID_LINK_INDEX ,
|
||||
.Nm NEXT_OBJECT_OID_LINK_INDEX ,
|
||||
.Nm FIND_OBJECT_INT_LINK_INDEX ,
|
||||
.Nm NEXT_OBJECT_INT_LINK_INDEX ,
|
||||
.Nm INSERT_OBJECT_OID_LINK ,
|
||||
.Nm INSERT_OBJECT_INT_LINK ,
|
||||
.Nm FIND_OBJECT_OID_LINK ,
|
||||
.Nm NEXT_OBJECT_OID_LINK ,
|
||||
.Nm FIND_OBJECT_INT_LINK ,
|
||||
.Nm NEXT_OBJECT_INT_LINK ,
|
||||
.Nm INSERT_OBJECT_OID ,
|
||||
.Nm INSERT_OBJECT_INT ,
|
||||
.Nm FIND_OBJECT_OID ,
|
||||
.Nm FIND_OBJECT_INT ,
|
||||
.Nm NEXT_OBJECT_OID ,
|
||||
.Nm NEXT_OBJECT_INT ,
|
||||
.Nm this_tick ,
|
||||
.Nm start_tick ,
|
||||
.Nm get_ticks ,
|
||||
.Nm systemg ,
|
||||
.Nm comm_define ,
|
||||
.Nm community ,
|
||||
.Nm oid_zeroDotZero ,
|
||||
.Nm reqid_allocate ,
|
||||
.Nm reqid_next ,
|
||||
.Nm reqid_base ,
|
||||
.Nm reqid_istype ,
|
||||
.Nm reqid_type ,
|
||||
.Nm timer_start ,
|
||||
.Nm timer_stop ,
|
||||
.Nm fd_select ,
|
||||
.Nm fd_deselect ,
|
||||
.Nm fd_suspend ,
|
||||
.Nm fd_resume ,
|
||||
.Nm or_register ,
|
||||
.Nm or_unregister ,
|
||||
.Nm buf_alloc ,
|
||||
.Nm buf_size ,
|
||||
.Nm snmp_input_start ,
|
||||
.Nm snmp_input_finish ,
|
||||
.Nm snmp_output ,
|
||||
.Nm snmp_send_port ,
|
||||
.Nm snmp_send_trap ,
|
||||
.Nm string_save ,
|
||||
.Nm string_commit ,
|
||||
.Nm string_rollback ,
|
||||
.Nm string_get ,
|
||||
.Nm string_free ,
|
||||
.Nm ip_save ,
|
||||
.Nm ip_rollback ,
|
||||
.Nm ip_commit ,
|
||||
.Nm ip_get ,
|
||||
.Nm oid_save ,
|
||||
.Nm oid_rollback ,
|
||||
.Nm oid_commit ,
|
||||
.Nm oid_get ,
|
||||
.Nm index_decode ,
|
||||
.Nm index_compare ,
|
||||
.Nm index_compare_off ,
|
||||
.Nm index_append ,
|
||||
.Nm index_append_off
|
||||
.Nd "SNMP daemon loadable module interface"
|
||||
.Sh LIBRARY
|
||||
Begemot SNMP library
|
||||
.Pq libbsnmp, -lbsnmp
|
||||
.Sh SYNOPSIS
|
||||
.In bsnmp/snmpmod.h
|
||||
.Fn INSERT_OBJECT_OID_LINK_INDEX "PTR" "LIST" "LINK" "INDEX"
|
||||
.Fn INSERT_OBJECT_INT_LINK_INDEX "PTR" "LIST" "LINK" "INDEX"
|
||||
.Fn FIND_OBJECT_OID_LINK_INDEX "LIST" "OID" "SUB" "LINK" "INDEX"
|
||||
.Fn FIND_OBJECT_INT_LINK_INDEX "LIST" "OID" "SUB" "LINK" "INDEX"
|
||||
.Fn NEXT_OBJECT_OID_LINK_INDEX "LIST" "OID" "SUB" "LINK" "INDEX"
|
||||
.Fn NEXT_OBJECT_INT_LINK_INDEX "LIST" "OID" "SUB" "LINK" "INDEX"
|
||||
.Fn INSERT_OBJECT_OID_LINK "PTR" "LIST" "LINK"
|
||||
.Fn INSERT_OBJECT_INT_LINK "PTR" "LIST" "LINK"
|
||||
.Fn FIND_OBJECT_OID_LINK "LIST" "OID" "SUB" "LINK"
|
||||
.Fn FIND_OBJECT_INT_LINK "LIST" "OID" "SUB" "LINK"
|
||||
.Fn NEXT_OBJECT_OID_LINK "LIST" "OID" "SUB" "LINK"
|
||||
.Fn NEXT_OBJECT_INT_LINK "LIST" "OID" "SUB" "LINK"
|
||||
.Fn INSERT_OBJECT_OID "PTR" "LIST"
|
||||
.Fn INSERT_OBJECT_INT "PTR" "LIST"
|
||||
.Fn FIND_OBJECT_OID "LIST" "OID" "SUB"
|
||||
.Fn FIND_OBJECT_INT "LIST" "OID" "SUB"
|
||||
.Fn NEXT_OBJECT_OID "LIST" "OID" "SUB"
|
||||
.Fn NEXT_OBJECT_INT "LIST" "OID" "SUB"
|
||||
.Vt extern u_int32_t this_tick ;
|
||||
.Vt extern u_int32_t start_tick ;
|
||||
.Ft u_int32_t
|
||||
.Fn get_ticks "void"
|
||||
.Vt extern struct systemg systemg ;
|
||||
.Ft u_int
|
||||
.Fn comm_define "u_int priv" "const char *descr" "struct lmodule *mod" "const char *str"
|
||||
.Ft const char *
|
||||
.Fn comm_string "u_int comm"
|
||||
.Vt extern u_int community ;
|
||||
.Vt extern const struct asn_oid oid_zeroDotZero ;
|
||||
.Ft u_int
|
||||
.Fn reqid_allocate "int size" "struct lmodule *mod"
|
||||
.Ft int32_t
|
||||
.Fn reqid_next "u_int type"
|
||||
.Ft int32_t
|
||||
.Fn reqid_base "u_int type"
|
||||
.Ft int
|
||||
.Fn reqid_istype "int32_t reqid" "u_int type"
|
||||
.Ft u_int
|
||||
.Fn reqid_type "int32_t reqid"
|
||||
.Ft void *
|
||||
.Fn timer_start "u_int ticks" "void (*func)(void *)" "void *uarg" "struct lmodule *mod"
|
||||
.Ft void
|
||||
.Fn timer_stop "void *timer_id"
|
||||
.Ft void *
|
||||
.Fn fd_select "int fd" "void (*func)(int, void *)" "void *uarg" "struct lmodule *mod"
|
||||
.Ft void
|
||||
.Fn fd_deselect "void *fd_id"
|
||||
.Ft void
|
||||
.Fn fd_suspend "void *fd_id"
|
||||
.Ft int
|
||||
.Fn fd_resume "void *fd_id"
|
||||
.Ft u_int
|
||||
.Fn or_register "const struct asn_oid *oid" "const char *descr" "struct lmodule *mod"
|
||||
.Ft void
|
||||
.Fn or_unregister "u_int or_id"
|
||||
.Ft void *
|
||||
.Fn buf_alloc "int tx"
|
||||
.Ft size_t
|
||||
.Fn buf_size "int tx"
|
||||
.Ft enum snmpd_input_err
|
||||
.Fn snmp_input_start "const u_char *buf" "size_t len" "const char *source" \
|
||||
"struct snmp_pdu *pdu" "int32_t *ip"
|
||||
.Ft enum snmpd_input_err
|
||||
.Fn snmp_input_finish "struct snmp_pdu *pdu" "const u_char *rcvbuf" \
|
||||
"size_t rcvlen" "u_char *sndbuf" "size_t *sndlen" "const char *source" \
|
||||
"enum snmpd_input_err ierr" "int32_t ip" "void *data"
|
||||
.Ft void
|
||||
.Fn snmp_output "struct snmp_pdu *pdu" "u_char *sndbuf" "size_t *sndlen" \
|
||||
"const char *dest"
|
||||
.Ft void
|
||||
.Fn snmp_send_port "const struct asn_oid *port" "struct snmp_pdu *pdu" \
|
||||
"const struct sockaddr *addr" "socklen_t addrlen"
|
||||
.Ft void
|
||||
.Fn snmp_send_trap "const struct asn_oid *oid" "..."
|
||||
.Ft int
|
||||
.Fn string_save "struct snmp_value *val" "struct snmp_context *ctx" "ssize_t req_size" "u_char **strp"
|
||||
.Ft void
|
||||
.Fn string_commit "struct snmp_context *ctx"
|
||||
.Ft void
|
||||
.Fn string_rollback "struct snmp_context *ctx" "u_char **strp"
|
||||
.Ft int
|
||||
.Fn string_get "struct snmp_value *val" "const u_char *str" "ssize_t len"
|
||||
.Ft void
|
||||
.Fn string_free "struct snmp_context *ctx"
|
||||
.Ft int
|
||||
.Fn ip_save "struct snmp_value *val" "struct snmp_context *ctx" "u_char *ipa"
|
||||
.Ft void
|
||||
.Fn ip_rollback "struct snmp_context *ctx" "u_char *ipa"
|
||||
.Ft void
|
||||
.Fn ip_commit "struct snmp_context *ctx"
|
||||
.Ft int
|
||||
.Fn ip_get "struct snmp_value *val" "u_char *ipa"
|
||||
.Ft int
|
||||
.Fn oid_save "struct snmp_value *val" "struct snmp_context *ctx" "struct asn_oid *oid"
|
||||
.Ft void
|
||||
.Fn oid_rollback "struct snmp_context *ctx" "struct asn_oid *oid"
|
||||
.Ft void
|
||||
.Fn oid_commit "struct snmp_context *ctx"
|
||||
.Ft int
|
||||
.Fn oid_get "struct snmp_value *val" "const struct asn_oid *oid"
|
||||
.Ft int
|
||||
.Fn index_decode "const struct asn_oid *oid" "u_int sub" "u_int code" "..."
|
||||
.Ft int
|
||||
.Fn index_compare "const struct asn_oid *oid1" "u_int sub" "const struct asn_oid *oid2"
|
||||
.Ft int
|
||||
.Fn index_compare_off "const struct asn_oid *oid1" "u_int sub" "const struct asn_oid *oid2" "u_int off"
|
||||
.Ft void
|
||||
.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"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Xr snmpd 1
|
||||
SNMP daemon implements a minimal MIB which consists of the system group, part
|
||||
of the SNMP MIB, a private configuration MIB, a trap destination table, a
|
||||
UDP port table, a community table, a module table, a statistics group and
|
||||
a debugging group. All other MIBs are support through loadable modules.
|
||||
This allows
|
||||
.Xr snmpd 1
|
||||
to use for task, that are not the classical SNMP task.
|
||||
.Ss MODULE LOADING AND UNLOADING
|
||||
Modules are loaded by writing to the module table. This table is indexed by
|
||||
a string, that identfies the module to the daemon. This identifier is used
|
||||
to select the correct configuration section from the configuration files and
|
||||
to identify resources allocated to this module. A row in the module table is
|
||||
created by writing a string of non-zero length to the
|
||||
.Va begemotSnmpdModulePath
|
||||
column. This string must be the complete path to the file containing the module.
|
||||
A module can be unloaded by writing a zero length string to the path column
|
||||
of an existing row.
|
||||
.Pp
|
||||
Modules may depend on each other an hence must be loaded in the correct order.
|
||||
The dependencies are listed in the corresponding manual pages.
|
||||
.Pp
|
||||
Upon loading a module the SNMP daemon expects the module file to a export
|
||||
a global symbol
|
||||
.Va config .
|
||||
This symbol should be a variable of type
|
||||
.Vt struct snmp_module :
|
||||
.Bd -literal -offset indent
|
||||
typedef enum snmpd_proxy_err (*proxy_err_f)(struct snmp_pdu *,
|
||||
const struct asn_oid *, const struct sockaddr *, socklen_t,
|
||||
enum snmpd_input_err, int32_t);
|
||||
|
||||
|
||||
struct snmp_module {
|
||||
const char *comment;
|
||||
int (*init)(struct lmodule *, int argc, char *argv[]);
|
||||
int (*fini)(void);
|
||||
void (*idle)(void);
|
||||
void (*dump)(void);
|
||||
void (*config)(void);
|
||||
void (*start)(void);
|
||||
proxy_err_f proxy;
|
||||
const struct snmp_node *tree;
|
||||
u_int tree_size;
|
||||
void (*loading)(const struct lmodule *, int);
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
This structure must be statically initialized and its fields have the
|
||||
following functions:
|
||||
.Bl -tag -width ".It Va tree_size"
|
||||
.It Va comment
|
||||
This is a string that will be visible in the module table. It should give
|
||||
some hint about the function of this module.
|
||||
.It Va init
|
||||
This function is called upon loading the module. The module pointer should
|
||||
be stored by the module because it is needed in other calls and the
|
||||
argument vector will contain the arguments to this module from the daemons
|
||||
command line. This function should return 0 if everything is ok or an
|
||||
UNIX error code (see
|
||||
.Xr errno 3 ).
|
||||
Once the function returns 0, the
|
||||
.Va fini
|
||||
function is called when the module is unloaded.
|
||||
.It Va fini
|
||||
The module is unloaded. This gives the module a chance to free resources that
|
||||
are not automatically freed. Be sure to free all memory, because daemons tend
|
||||
to run very long. This function pointer may be
|
||||
.Li NULL
|
||||
if it is not needed.
|
||||
.It Va idle
|
||||
If this function pointer is not
|
||||
.Li NULL ,
|
||||
the function pointed to by it is called whenever the daemon is going
|
||||
to wait for an event. Try to avoid using this feature.
|
||||
.It Va dump
|
||||
Whenever the daemon receives a
|
||||
.Li SIGUSR1
|
||||
it dumps it internal state via
|
||||
.Xr syslog 3 .
|
||||
If the
|
||||
.Va dump
|
||||
field is not
|
||||
.Li NULL
|
||||
it is called by the daemon to dump the state of the module.
|
||||
.It Va config
|
||||
Whenever the daemon receives a
|
||||
.Li SIGHUP
|
||||
signal it re-reads its configuration file.
|
||||
If the
|
||||
.Va config
|
||||
field is not
|
||||
.Li NULL
|
||||
it is called after reading the configuration file to give the module a chance
|
||||
to adapt to the new configuration.
|
||||
.It Va start
|
||||
If not
|
||||
.Li NULL
|
||||
this function is called after successful loading and initializing the module
|
||||
to start its actual operation.
|
||||
.It Va proxy
|
||||
If the daemon receives a PDU and that PDU has a community string who's
|
||||
community was registered by this module and
|
||||
.Va proxy
|
||||
is not
|
||||
.Li NULL
|
||||
than this function is called to handle the PDU.
|
||||
.It Va tree
|
||||
This is a pointer to the node array for the MIB tree implemented by this module.
|
||||
.It Va tree_size
|
||||
This is the number of nodes in
|
||||
.Va tree .
|
||||
.It Va loading
|
||||
If this pointer is not
|
||||
.Li NULL
|
||||
it is called whenever another module was loaded or unloaded. It gets a
|
||||
pointer to that module and a flag that is 0 for unloading and 1 for loading.
|
||||
.El
|
||||
.Pp
|
||||
When everything is ok, the daemon merges the module's MIB tree into its current
|
||||
global tree, calls the modules
|
||||
.Fn init
|
||||
function. If this function returns an error, the modules MIB tree is removed from
|
||||
the global one and the module is unloaded. If initialisation is successful,
|
||||
the modules
|
||||
.Fn start
|
||||
function is called.
|
||||
After it returns the
|
||||
.Fn loaded
|
||||
functions of all modules (including the loaded one) are called.
|
||||
.Pp
|
||||
When the module is unloaded, its MIB tree is removed from the global one,
|
||||
the communities, request id ranges, running timers and selected file
|
||||
descriptors are released, the
|
||||
.Fn fini
|
||||
function is called, the module file is unloaded and the
|
||||
.Fn loaded
|
||||
functions of all other modules are called.
|
||||
.Ss IMPLEMENTING TABLES
|
||||
There are a number of macros designed to help implementing SNMP tables.
|
||||
A problem while implementing a table is the support for the GETNEXT operator.
|
||||
The GETNEXT operation has to find out whether, given an arbitrary OID, the
|
||||
lessest table row, that has an OID higher than the given OID. The easiest way
|
||||
to do this is to keep the table as an ordered list of structures each one
|
||||
of which contains an OID that is the index of the table row. This allows easy
|
||||
removal, insertion and search.
|
||||
.Pp
|
||||
The helper macros assume, that the table is organized as a TAILQ (see
|
||||
.Xr queue 3
|
||||
and each structure contains a
|
||||
.Vt struct asn_oid
|
||||
that is used as index.
|
||||
For simple tables with only a integer or unsigned index, an alternate form
|
||||
of the macros is available, that presume the existence of an integer or
|
||||
unsigned field as index field.
|
||||
.Pp
|
||||
The macros have name of the form
|
||||
.Bd -literal -offset indent
|
||||
{INSERT,FIND,NEXT}_OBJECT_{OID,INT}[_LINK[_INDEX]]
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Fn INSERT_*
|
||||
macros are used in the SET operation to insert a new table row into the table.
|
||||
The
|
||||
.Fn FIND_*
|
||||
macros are used in the GET operation to find a specific row in the table.
|
||||
The
|
||||
.Fn NEXT_*
|
||||
macros are used in the GETNEXT operation to find the next row in the table.
|
||||
The last two macros return a pointer to the row structure if a row is found,
|
||||
.Li NULL
|
||||
otherwise.
|
||||
The macros
|
||||
.Fn *_OBJECT_OID_*
|
||||
assume the existence of a
|
||||
.Vt struct asn_oid
|
||||
that is used as index, the macros
|
||||
.Fn *_OBJECT_INT_*
|
||||
assume the existance of an unsigned integer field that is used as index.
|
||||
.Pp
|
||||
The macros
|
||||
.Fn *_INDEX
|
||||
allow the explicit naming of the index field in the parameter
|
||||
.Fa INDEX ,
|
||||
whereas the other macros assume that this field is named
|
||||
.Va index .
|
||||
The macros
|
||||
.Fn *_LINK_*
|
||||
allow the explicit naming of the link field of the tail queues, the others
|
||||
assume that the link field is named
|
||||
.Va link .
|
||||
Explicitely naming the link field may be necessary if the same structures
|
||||
are held in two or more different tables.
|
||||
.Pp
|
||||
The arguments to the macros are as follows:
|
||||
.Bl -tag -width "INDEX"
|
||||
.It Fa PTR
|
||||
A pointer to the new structure to be inserted into the table.
|
||||
.It Fa LIST
|
||||
A pointer to the tail queue head.
|
||||
.It Fa LINK
|
||||
The name of the link field in the row structure.
|
||||
.It Fa INDEX
|
||||
The name of the index field in the row structure.
|
||||
.It Fa OID
|
||||
Must point to the
|
||||
.Va var
|
||||
field of the
|
||||
.Fa value
|
||||
argument to the node operation callback. This is the OID to search for.
|
||||
.It Fa SUB
|
||||
This is the index of the start of the table index in the OID pointed to
|
||||
by
|
||||
.Fa OID .
|
||||
This is usually the same as the
|
||||
.Fa sub
|
||||
argument to the node operation callback.
|
||||
.El
|
||||
.Ss DAEMON TIMESTAMPS
|
||||
The variable
|
||||
.Va this_tick
|
||||
contains the tick (there are 100 SNMP ticks in a second) when
|
||||
the current PDU processing was started.
|
||||
The variable
|
||||
.Va start_tick
|
||||
contains the tick when the daemon was started.
|
||||
The function
|
||||
.Fn get_ticks
|
||||
returns the current tick. The number of ticks since the daemon was started
|
||||
is
|
||||
.Bd -literal -offset indent
|
||||
get_ticks() - start_tick
|
||||
.Ed
|
||||
.Ss THE SYSTEM GROUP
|
||||
The scalar fields of the system group are held in the global variable
|
||||
.Va systemg :
|
||||
.Bd -literal -offset indent
|
||||
struct systemg {
|
||||
u_char *descr;
|
||||
struct asn_oid object_id;
|
||||
u_char *contact;
|
||||
u_char *name;
|
||||
u_char *location;
|
||||
u_int32_t services;
|
||||
u_int32_t or_last_change;
|
||||
};
|
||||
.Ed
|
||||
.Ss COMMUNITIES
|
||||
The SNMP daemon implements a community table. On recipte of a request message
|
||||
the community string in that message is compared to each of the community
|
||||
strings in that table, if a match is found, the global variable
|
||||
.Va community
|
||||
is set to the community identifier for that community. Community identifiers
|
||||
are unsigned integers. For the three standard communities there are three
|
||||
constants defined:
|
||||
.Bd -literal -offset indent
|
||||
#define COMM_INITIALIZE 0
|
||||
#define COMM_READ 1
|
||||
#define COMM_WRITE 2
|
||||
.Ed
|
||||
.Pp
|
||||
.Va community
|
||||
is set to
|
||||
.Li COMM_INITIALIZE
|
||||
while the assignments in the configuration file are processed. To
|
||||
.Li COMM_READ
|
||||
or
|
||||
.Li COMM_WRITE
|
||||
when the community strings for the read-write or read-only community are found
|
||||
in the incoming PDU.
|
||||
.Pp
|
||||
Modules can define additional communities. This may be necessary to provide
|
||||
transport proxying (a PDU received on one communication link is proxied to
|
||||
another link) or to implement non-UDP access points to SNMP. A new
|
||||
community is defined with the function
|
||||
.Fn comm_define .
|
||||
It takes the following parameters:
|
||||
.Bl -tag -width ".It Fa descr"
|
||||
.It Fa priv
|
||||
This is an integer identifying the community to the module. Each module has
|
||||
its own namespace with regard to this parameter. The community table is
|
||||
indexed with the module name and this identifier.
|
||||
.It Fa descr
|
||||
This is a string providing a human readable description of the community.
|
||||
It is visible in the community table.
|
||||
.It Fa mod
|
||||
This is the module defining the community.
|
||||
.It Fa str
|
||||
This is the initial community string.
|
||||
.El
|
||||
.Pp
|
||||
The function returns a globally unique community identifier. If a PDU is
|
||||
received who's community string matches, this identifier is set into the global
|
||||
.Va community .
|
||||
.Pp
|
||||
The function
|
||||
.Fn comm_string
|
||||
returns the current community string for the given community.
|
||||
.Pp
|
||||
All communities defined by a module are automatically released when the module
|
||||
is unloaded.
|
||||
.Ss WELL KNOWN OIDS
|
||||
The global variable
|
||||
.Va oid_zeroDotZero
|
||||
contains the OID 0.0.
|
||||
.Ss REQUEST ID RANGES
|
||||
For modules that implement SNMP client functions besides SNMP agent functions
|
||||
it may be necessary to identify SNMP requests by their identifier to allow
|
||||
easier routing of responses to the correct sub-system. Request id ranges
|
||||
provide a way to aquire globally non-overlapping sub-ranges of the entire
|
||||
31-bit id range.
|
||||
.Pp
|
||||
A request id range is allocated with
|
||||
.Fn reqid_allocate .
|
||||
The arguments are: the size of the range and the module allocating the range.
|
||||
For example, the call
|
||||
.Bd -literal -offset indent
|
||||
id = reqid_allocate(1000, module);
|
||||
.Ed
|
||||
.Pp
|
||||
allocates a range of 1000 request ids. The function returns the request
|
||||
id range identifier or 0 if there is not enough identifier space.
|
||||
The function
|
||||
.Fn reqid_base
|
||||
returns the lowest request id in the given range.
|
||||
.Pp
|
||||
Request id are allocated starting at the lowest one linear throughout the range.
|
||||
If the client application may have a lot of outstanding request the range
|
||||
must be large enough so that an id is not reused until it is really expired.
|
||||
.Fn reqid_next
|
||||
returns the sequentially next id in the range.
|
||||
.Pp
|
||||
The function
|
||||
.Fn reqid_istype
|
||||
checks whether the request id
|
||||
.Fa reqid
|
||||
is withing the range identified by
|
||||
.Fa type .
|
||||
The function
|
||||
.Fn reqid_type
|
||||
returns the range identifier for the given
|
||||
.Fa reqid
|
||||
or 0 if the request id is in none of the ranges.
|
||||
.Ss TIMERS
|
||||
The SNMP daemon supports an arbitrary number of timers with SNMP tick granularity.
|
||||
The function
|
||||
.Fn timer_start
|
||||
arranges for the callback
|
||||
.Fa func
|
||||
to be called with the argument
|
||||
.Fa uarg
|
||||
after
|
||||
.Fa ticks
|
||||
SNMP ticks have expired.
|
||||
.Fa mod
|
||||
is the module that starts the timer. Timers are one-shot, they are not
|
||||
restarted. The function returns a timer identifier that can be used to
|
||||
stop the timer via
|
||||
.Fn timer_stop .
|
||||
If a module is unloaded all timers started by the module that have not expired
|
||||
yet are stopped.
|
||||
.Ss FILE DESCRIPTOR SUPPORT
|
||||
A module may need to get input from socket file descriptors without blocking
|
||||
the daemon (for example to implement alternative SNMP transports).
|
||||
.Pp
|
||||
The function
|
||||
.Fn fd_select
|
||||
causes the callback function
|
||||
.Fa func
|
||||
to be called with the file descriptor
|
||||
.Fa fd
|
||||
and the user argument
|
||||
.Fa uarg
|
||||
whenever the file descriptor
|
||||
.Fa fd
|
||||
can be red or has a close condition. If the file descriptor is not in
|
||||
non-blocking mode, it is set to non-blocking mode. If the callback is not
|
||||
needed anymore,
|
||||
.Fn fd_deselect
|
||||
may be called with the value returned from
|
||||
.Fn fd_select .
|
||||
All file descriptors selected by a module are automatically deselected when
|
||||
the module is unloaded.
|
||||
.Pp
|
||||
To temporarily suspend the file descriptor registration
|
||||
.Fn fd_suspend
|
||||
can be called. This also causes the file descriptor to be switched back to
|
||||
blocking mode if it was blocking prior the call to
|
||||
.Fn fd_select .
|
||||
This is necessary to do synchronuous input on a selected socket.
|
||||
The effect of
|
||||
.Fn fd_suspend
|
||||
can be undone with
|
||||
.Fn fd_resume .
|
||||
.Ss OBJECT RESOURCES
|
||||
The system group contains an object resource table. A module may create
|
||||
an entry in this table by calling
|
||||
.Fn or_register
|
||||
with the
|
||||
.Fa oid
|
||||
to be registered, a textual description in
|
||||
.Fa str
|
||||
and a pointer to the module
|
||||
.Fa mod .
|
||||
The registration can be removed with
|
||||
.Fn or_unregister .
|
||||
All registrations of a module are automatically removed if the module is
|
||||
unloaded.
|
||||
.Ss TRANSMIT AND RECEIVE BUFFERS
|
||||
A buffer is allocated via
|
||||
.Fn buf_alloc .
|
||||
The argument must be 1 for transmit and 0 for receive buffers. The function
|
||||
may return
|
||||
.Li NULL
|
||||
if there is no memory available. The current buffersize can be obtained with
|
||||
.Fn buf_size .
|
||||
.Sh PROCESSING PDUS
|
||||
For modules that need to do their own PDU processing (for example for proxying)
|
||||
the following functions are available:
|
||||
.Pp
|
||||
Function
|
||||
.Fn snmp_input_start
|
||||
decodes the PDU, searches the community, and sets the global
|
||||
.Va this_tick .
|
||||
It returns one of the following error codes:
|
||||
.Bl -tag -width ".It Er SNMPD_INPUT_VALBADLEN"
|
||||
.It Er SNMPD_INPUT_OK
|
||||
Everything ok, continue with processing.
|
||||
.It Er SNMPD_INPUT_FAILED
|
||||
The PDU could not be decoded, has a wrong version or an unknown
|
||||
community string.
|
||||
.It Er SNMPD_INPUT_VALBADLEN
|
||||
A SET PDU had a value field in a binding with a wrong length field in an
|
||||
ASN.1 header.
|
||||
.It Er SNMPD_INPUT_VALRANGE
|
||||
A SET PDU had a value field in a binding with a value that is out of range
|
||||
for the given ASN.1 type.
|
||||
.It Er SNMPD_INPUT_VALBADENC
|
||||
A SET PDU had a value field in a binding with wrong ASN.1 encoding.
|
||||
.El
|
||||
.Pp
|
||||
The function
|
||||
.Fn snmp_input_finish
|
||||
does the other half of processing: if
|
||||
.Fn snmp_input_start
|
||||
did not return OK, tries to construct an error response. If the start was OK,
|
||||
it calls the correct function from
|
||||
.Xr bsnmpagent
|
||||
to execute the request and depending on the outcome constructs a response or
|
||||
error response PDU or ignores the request PDU. It returns either
|
||||
.Er SNMPD_INPUT_OK
|
||||
or
|
||||
.Er SNMPD_INPUT_FAILED .
|
||||
In the first case a response PDU was constructed and should be sent.
|
||||
.Pp
|
||||
The function
|
||||
.Fn snmp_output
|
||||
takes a PDU and encodes it.
|
||||
.Pp
|
||||
The function
|
||||
.Fn snmp_send_port
|
||||
takes a PDU, encodes it and sends it through the given port (identified by
|
||||
the index in the port table) to the given address.
|
||||
.Pp
|
||||
The function
|
||||
.Fn snmp_send_trap
|
||||
sends a trap to all trap destinations. The arguments are the
|
||||
.Fa oid
|
||||
identifying the trap and a NULL-terminated list of
|
||||
.Vt struct snmp_value
|
||||
pointers that are to be inserted into the trap binding list.
|
||||
.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.
|
||||
.Pp
|
||||
The following functions are used for OCTET STRING scalars, either NUL terminated
|
||||
or not:
|
||||
.Bl -tag -width "XXXXXXXXX"
|
||||
.It Fn string_save
|
||||
should be called for SNMP_OP_SET.
|
||||
.Fa value
|
||||
and
|
||||
.Fa ctx
|
||||
are the resp\&. arguments to the node callback.
|
||||
.Fa valp
|
||||
is a pointer to the pointer that holds the current value and
|
||||
.Fa req_size
|
||||
should be -1 if any size of the string is acceptable or a number larger or
|
||||
equal zero if the string must have a specific size. The function saves
|
||||
the old value in the scratch area (note, that any initial value must have
|
||||
been allocated by
|
||||
.Xr malloc 3 ),
|
||||
allocates a new string, copies over the new value, NUL-terminates it and
|
||||
sets the new current value.
|
||||
.It Fn string_commit
|
||||
simply frees the saved old value in the scratch area.
|
||||
.It Fn string_rollback
|
||||
frees the new value, and puts back the old one.
|
||||
.It Fn string_get
|
||||
is used for GET or GETNEXT. If
|
||||
.Fa len
|
||||
is -1, the length is computed via
|
||||
.Xr strlen 3
|
||||
from the current string value. If the current value is NULL,
|
||||
a OCTET STRING of zero length is returned.
|
||||
.It Fn string_free
|
||||
must be called if either rollback or commit fails to free the saved old value.
|
||||
.El
|
||||
.Pp
|
||||
The following functions are used to process scalars of type IP-address:
|
||||
.Bl -tag -width "XXXXXXXXX"
|
||||
.It Fn ip_save
|
||||
Saves the current value in the scratch area and sets the new value from
|
||||
.Fa valp .
|
||||
.It Fn ip_commit
|
||||
Does nothing.
|
||||
.It Fn ip_rollback
|
||||
Restores the old IP address from the scratch area.
|
||||
.It Fn ip_get
|
||||
Retrieves the IP current address.
|
||||
.El
|
||||
.Pp
|
||||
The following functions handle OID-typed variables:
|
||||
.Bl -tag -width "XXXXXXXXX"
|
||||
.It Fn oid_save
|
||||
Saves the current value in the scratch area by allocating a
|
||||
.Vt struct asn_oid
|
||||
with
|
||||
.Xr malloc 3
|
||||
and sets the new value from
|
||||
.Fa oid .
|
||||
.It Fn oid_commit
|
||||
Frees the old value in the scratch area.
|
||||
.It Fn oid_rollback
|
||||
Restores the old OID from the scratch area and frees the old OID.
|
||||
.It Fn oid_get
|
||||
Retrieves the OID
|
||||
.El
|
||||
.Ss TABLE INDEX HANDLING
|
||||
The following functions help in handling table indexes:
|
||||
.Bl -tag -width "XXXXXXXXX"
|
||||
.It Fn index_decode
|
||||
Decodes the index part of the OID. The parameter
|
||||
.Fa oid
|
||||
must be a pointer to the
|
||||
.Va var
|
||||
field of the
|
||||
.Fa value
|
||||
argument of the node callback. The
|
||||
.Fa sub
|
||||
argument must be the index of the start of the index in the OID (this is
|
||||
the
|
||||
.Fa sub
|
||||
argument to the node callback).
|
||||
.Fa code
|
||||
is the index expression (parameter
|
||||
.Fa idx
|
||||
to the node callback).
|
||||
These parameters are followed by parameters depending on the syntax of the index
|
||||
elements as follows:
|
||||
.Bl -tag -width ".It Li OCTET STRING"
|
||||
.It Li INTEGER
|
||||
.Vt int32_t *
|
||||
expected as argument.
|
||||
.It Li COUNTER64
|
||||
.Vt u_int64_t *
|
||||
expected as argument. Note, that this syntax is illegal for indexes.
|
||||
.It Li OCTET STRING
|
||||
A
|
||||
.Vt u_char **
|
||||
and a
|
||||
.Vt size_t *
|
||||
expected as arguments. A buffer is allocated to hold the decoded string.
|
||||
.It Li OID
|
||||
A
|
||||
.Vt struct asn_oid *
|
||||
is expected as argument.
|
||||
.It Li IP ADDRESS
|
||||
A
|
||||
.Vt u_int8_t *
|
||||
expected as argument that points to a buffer of at least four byte.
|
||||
.It Li COUNTER, GAUGE, TIMETICKS
|
||||
A
|
||||
.Vt u_int32_t
|
||||
expected.
|
||||
.It Li NULL
|
||||
No argument expected.
|
||||
.El
|
||||
.It Fn index_compare
|
||||
compares the current variable with an OID.
|
||||
.Fa oid1
|
||||
and
|
||||
.Fa sub
|
||||
come from the node callback arguments
|
||||
.Fa value->var
|
||||
and
|
||||
.Fa sub
|
||||
resp.
|
||||
.Fa oid2
|
||||
is the OID to compare to. The function returns -1, 0, +1 when the
|
||||
variable is lesser, equal, higher to the given OID.
|
||||
.Fa oid2
|
||||
must contain only the index part of the table column.
|
||||
.It Fn index_compare_off
|
||||
is equivalent to
|
||||
.Fn index_compare
|
||||
except that it takes an additional parameter
|
||||
.Fa off
|
||||
that causes it to ignore the first
|
||||
.Fa off
|
||||
components of both indexes.
|
||||
.It Fn index_append
|
||||
appends OID
|
||||
.Fa src
|
||||
beginning at position
|
||||
.Fa sub
|
||||
to
|
||||
.Fa dst .
|
||||
.It Fn index_append_off
|
||||
appends OID
|
||||
.Fa src
|
||||
beginning at position
|
||||
.Fa off
|
||||
to
|
||||
.Fa dst
|
||||
beginning at position
|
||||
.Fa sub
|
||||
+
|
||||
.Fa off .
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr snmpd 1 ,
|
||||
.Xr gensnmptree 1 ,
|
||||
.Xr bsnmplib 3
|
||||
.Xr bsnmpclient 3 ,
|
||||
.Xr bsnmpagent 3
|
||||
.Sh STANDARDS
|
||||
This implementation conforms to the applicable IETF RFCs and ITU-T
|
||||
recommendations.
|
||||
.Sh AUTHORS
|
||||
.An Hartmut Brandt Aq brandt@fokus.gmd.de
|
363
contrib/bsnmp/snmpd/snmpmod.h
Normal file
363
contrib/bsnmp/snmpd/snmpmod.h
Normal file
@ -0,0 +1,363 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003
|
||||
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Harti Brandt <harti@freebsd.org>
|
||||
*
|
||||
* Redistribution of this software and documentation 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 or documentation 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.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
* AND ITS 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
|
||||
* FRAUNHOFER FOKUS OR ITS 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.
|
||||
*
|
||||
* $Begemot: bsnmp/snmpd/snmpmod.h,v 1.23 2003/01/28 13:44:35 hbb Exp $
|
||||
*
|
||||
* SNMP daemon data and functions exported to modules.
|
||||
*/
|
||||
#ifndef snmpmod_h_
|
||||
#define snmpmod_h_
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include "asn1.h"
|
||||
#include "snmp.h"
|
||||
#include "snmpagent.h"
|
||||
|
||||
#define MAX_MOD_ARGS 16
|
||||
|
||||
/*
|
||||
* These macros help to handle object lists for SNMP tables. They use
|
||||
* tail queues to hold the objects in ascending order in the list.
|
||||
* ordering can be done either on an integer/unsigned field or and asn_oid.
|
||||
*/
|
||||
#define INSERT_OBJECT_OID_LINK_INDEX(PTR, LIST, LINK, INDEX) do { \
|
||||
__typeof (PTR) _lelem; \
|
||||
\
|
||||
TAILQ_FOREACH(_lelem, (LIST), LINK) \
|
||||
if (asn_compare_oid(&_lelem->INDEX, &(PTR)->INDEX) > 0) \
|
||||
break; \
|
||||
if (_lelem == NULL) \
|
||||
TAILQ_INSERT_TAIL((LIST), (PTR), LINK); \
|
||||
else \
|
||||
TAILQ_INSERT_BEFORE(_lelem, (PTR), LINK); \
|
||||
} while(0)
|
||||
|
||||
#define INSERT_OBJECT_INT_LINK_INDEX(PTR, LIST, LINK, INDEX) do { \
|
||||
__typeof (PTR) _lelem; \
|
||||
\
|
||||
TAILQ_FOREACH(_lelem, (LIST), LINK) \
|
||||
if ((asn_subid_t)_lelem->INDEX > (asn_subid_t)(PTR)->INDEX)\
|
||||
break; \
|
||||
if (_lelem == NULL) \
|
||||
TAILQ_INSERT_TAIL((LIST), (PTR), LINK); \
|
||||
else \
|
||||
TAILQ_INSERT_BEFORE(_lelem, (PTR), LINK); \
|
||||
} while(0)
|
||||
|
||||
#define FIND_OBJECT_OID_LINK_INDEX(LIST, OID, SUB, LINK, INDEX) ({ \
|
||||
__typeof (TAILQ_FIRST(LIST)) _lelem; \
|
||||
\
|
||||
TAILQ_FOREACH(_lelem, (LIST), LINK) \
|
||||
if (index_compare(OID, SUB, &_lelem->INDEX) == 0) \
|
||||
break; \
|
||||
(_lelem); \
|
||||
})
|
||||
|
||||
#define NEXT_OBJECT_OID_LINK_INDEX(LIST, OID, SUB, LINK, INDEX) ({ \
|
||||
__typeof (TAILQ_FIRST(LIST)) _lelem; \
|
||||
\
|
||||
TAILQ_FOREACH(_lelem, (LIST), LINK) \
|
||||
if (index_compare(OID, SUB, &_lelem->INDEX) < 0) \
|
||||
break; \
|
||||
(_lelem); \
|
||||
})
|
||||
|
||||
#define FIND_OBJECT_INT_LINK_INDEX(LIST, OID, SUB, LINK, INDEX) ({ \
|
||||
__typeof (TAILQ_FIRST(LIST)) _lelem; \
|
||||
\
|
||||
if ((OID)->len - SUB != 1) \
|
||||
_lelem = NULL; \
|
||||
else \
|
||||
TAILQ_FOREACH(_lelem, (LIST), LINK) \
|
||||
if ((OID)->subs[SUB] == (asn_subid_t)_lelem->INDEX)\
|
||||
break; \
|
||||
(_lelem); \
|
||||
})
|
||||
|
||||
#define NEXT_OBJECT_INT_LINK_INDEX(LIST, OID, SUB, LINK, INDEX) ({ \
|
||||
__typeof (TAILQ_FIRST(LIST)) _lelem; \
|
||||
\
|
||||
if ((OID)->len - SUB == 0) \
|
||||
_lelem = TAILQ_FIRST(LIST); \
|
||||
else \
|
||||
TAILQ_FOREACH(_lelem, (LIST), LINK) \
|
||||
if ((OID)->subs[SUB] < (asn_subid_t)_lelem->INDEX)\
|
||||
break; \
|
||||
(_lelem); \
|
||||
})
|
||||
|
||||
/*
|
||||
* Macros for the case where the index field is called 'index'
|
||||
*/
|
||||
#define INSERT_OBJECT_OID_LINK(PTR, LIST, LINK) \
|
||||
INSERT_OBJECT_OID_LINK_INDEX(PTR, LIST, LINK, index)
|
||||
|
||||
#define INSERT_OBJECT_INT_LINK(PTR, LIST, LINK) do { \
|
||||
INSERT_OBJECT_INT_LINK_INDEX(PTR, LIST, LINK, index)
|
||||
|
||||
#define FIND_OBJECT_OID_LINK(LIST, OID, SUB, LINK) \
|
||||
FIND_OBJECT_OID_LINK_INDEX(LIST, OID, SUB, LINK, index)
|
||||
|
||||
#define NEXT_OBJECT_OID_LINK(LIST, OID, SUB, LINK) \
|
||||
NEXT_OBJECT_OID_LINK_INDEX(LIST, OID, SUB, LINK, index)
|
||||
|
||||
#define FIND_OBJECT_INT_LINK(LIST, OID, SUB, LINK) \
|
||||
FIND_OBJECT_INT_LINK_INDEX(LIST, OID, SUB, LINK, index)
|
||||
|
||||
#define NEXT_OBJECT_INT_LINK(LIST, OID, SUB, LINK) \
|
||||
NEXT_OBJECT_INT_LINK_INDEX(LIST, OID, SUB, LINK, index)
|
||||
|
||||
/*
|
||||
* Macros for the case where the index field is called 'index' and the
|
||||
* link field 'link'.
|
||||
*/
|
||||
#define INSERT_OBJECT_OID(PTR, LIST) \
|
||||
INSERT_OBJECT_OID_LINK_INDEX(PTR, LIST, link, index)
|
||||
|
||||
#define INSERT_OBJECT_INT(PTR, LIST) \
|
||||
INSERT_OBJECT_INT_LINK_INDEX(PTR, LIST, link, index)
|
||||
|
||||
#define FIND_OBJECT_OID(LIST, OID, SUB) \
|
||||
FIND_OBJECT_OID_LINK_INDEX(LIST, OID, SUB, link, index)
|
||||
|
||||
#define FIND_OBJECT_INT(LIST, OID, SUB) \
|
||||
FIND_OBJECT_INT_LINK_INDEX(LIST, OID, SUB, link, index)
|
||||
|
||||
#define NEXT_OBJECT_OID(LIST, OID, SUB) \
|
||||
NEXT_OBJECT_OID_LINK_INDEX(LIST, OID, SUB, link, index)
|
||||
|
||||
#define NEXT_OBJECT_INT(LIST, OID, SUB) \
|
||||
NEXT_OBJECT_INT_LINK_INDEX(LIST, OID, SUB, link, index)
|
||||
|
||||
struct lmodule;
|
||||
|
||||
/* ticks when program and current packet was started */
|
||||
extern u_int32_t this_tick;
|
||||
extern u_int32_t start_tick;
|
||||
|
||||
u_int32_t get_ticks(void);
|
||||
|
||||
/*
|
||||
* Return code for proxy function
|
||||
*/
|
||||
enum snmpd_proxy_err {
|
||||
/* proxy code will process the PDU */
|
||||
SNMPD_PROXY_OK,
|
||||
/* proxy code does not process PDU */
|
||||
SNMPD_PROXY_REJ,
|
||||
/* drop this PDU */
|
||||
SNMPD_PROXY_DROP,
|
||||
/* drop because of bad community */
|
||||
SNMPD_PROXY_BADCOMM,
|
||||
/* drop because of bad community use */
|
||||
SNMPD_PROXY_BADCOMMUSE
|
||||
};
|
||||
|
||||
/*
|
||||
* Input handling
|
||||
*/
|
||||
enum snmpd_input_err {
|
||||
/* proceed with packet */
|
||||
SNMPD_INPUT_OK,
|
||||
/* fatal error in packet, ignore it */
|
||||
SNMPD_INPUT_FAILED,
|
||||
/* value encoding has wrong length in a SET operation */
|
||||
SNMPD_INPUT_VALBADLEN,
|
||||
/* value encoding is out of range */
|
||||
SNMPD_INPUT_VALRANGE,
|
||||
/* value has bad encoding */
|
||||
SNMPD_INPUT_VALBADENC,
|
||||
};
|
||||
|
||||
/*
|
||||
* Every loadable module must have one of this structures with
|
||||
* the external name 'config'.
|
||||
*/
|
||||
struct snmp_module {
|
||||
/* a comment describing what this module implements */
|
||||
const char *comment;
|
||||
|
||||
/* the initialisation function */
|
||||
int (*init)(struct lmodule *, int argc, char *argv[]);
|
||||
|
||||
/* the finalisation function */
|
||||
int (*fini)(void);
|
||||
|
||||
/* the idle function */
|
||||
void (*idle)(void);
|
||||
|
||||
/* the dump function */
|
||||
void (*dump)(void);
|
||||
|
||||
/* re-configuration function */
|
||||
void (*config)(void);
|
||||
|
||||
/* start operation */
|
||||
void (*start)(void);
|
||||
|
||||
/* proxy a PDU */
|
||||
enum snmpd_proxy_err (*proxy)(struct snmp_v1_pdu *,
|
||||
const struct asn_oid *, const struct sockaddr *, socklen_t,
|
||||
enum snmpd_input_err, int32_t);
|
||||
|
||||
/* the tree this module is going to server */
|
||||
const struct snmp_node *tree;
|
||||
u_int tree_size;
|
||||
|
||||
/* function called, when another module was unloaded/loaded */
|
||||
void (*loading)(const struct lmodule *, int);
|
||||
};
|
||||
|
||||
/*
|
||||
* Stuff exported to modules
|
||||
*/
|
||||
|
||||
/*
|
||||
* The system group.
|
||||
*/
|
||||
struct systemg {
|
||||
u_char *descr;
|
||||
struct asn_oid object_id;
|
||||
u_char *contact;
|
||||
u_char *name;
|
||||
u_char *location;
|
||||
u_int32_t services;
|
||||
u_int32_t or_last_change;
|
||||
};
|
||||
extern struct systemg systemg;
|
||||
|
||||
/*
|
||||
* Community support.
|
||||
*
|
||||
* We have 2 fixed communities for SNMP read and write access. Modules
|
||||
* can create their communities dynamically. They are deleted automatically
|
||||
* if the module is unloaded.
|
||||
*/
|
||||
#define COMM_INITIALIZE 0
|
||||
#define COMM_READ 1
|
||||
#define COMM_WRITE 2
|
||||
|
||||
u_int comm_define(u_int, const char *descr, struct lmodule *, const char *str);
|
||||
const char * comm_string(u_int);
|
||||
|
||||
/* community for current packet */
|
||||
extern u_int community;
|
||||
|
||||
/*
|
||||
* Well known OIDs
|
||||
*/
|
||||
extern const struct asn_oid oid_zeroDotZero;
|
||||
|
||||
/*
|
||||
* Request ID ranges.
|
||||
*
|
||||
* A module can request a range of request ids and associate them with a
|
||||
* type field. All ranges are deleted if a module is unloaded.
|
||||
*/
|
||||
u_int reqid_allocate(int size, struct lmodule *);
|
||||
int32_t reqid_next(u_int type);
|
||||
int32_t reqid_base(u_int type);
|
||||
int reqid_istype(int32_t reqid, u_int type);
|
||||
u_int reqid_type(int32_t reqid);
|
||||
|
||||
/*
|
||||
* Timers.
|
||||
*/
|
||||
void *timer_start(u_int, void (*)(void *), void *, struct lmodule *);
|
||||
void timer_stop(void *);
|
||||
|
||||
/*
|
||||
* File descriptors
|
||||
*/
|
||||
void *fd_select(int, void (*)(int, void *), void *, struct lmodule *);
|
||||
void fd_deselect(void *);
|
||||
void fd_suspend(void *);
|
||||
int fd_resume(void *);
|
||||
|
||||
/*
|
||||
* Object resources
|
||||
*/
|
||||
u_int or_register(const struct asn_oid *, const char *, struct lmodule *);
|
||||
void or_unregister(u_int);
|
||||
|
||||
/*
|
||||
* Buffers
|
||||
*/
|
||||
void *buf_alloc(int tx);
|
||||
size_t buf_size(int tx);
|
||||
|
||||
/* decode PDU and find community */
|
||||
enum snmpd_input_err snmp_input_start(const u_char *, size_t, const char *,
|
||||
struct snmp_v1_pdu *, int32_t *);
|
||||
|
||||
/* process the pdu. returns either _OK or _FAILED */
|
||||
enum snmpd_input_err snmp_input_finish(struct snmp_pdu *, const u_char *,
|
||||
size_t, u_char *, size_t *, const char *, enum snmpd_input_err, int32_t,
|
||||
void *);
|
||||
|
||||
void snmp_output(struct snmp_v1_pdu *, u_char *, size_t *, const char *);
|
||||
void snmp_send_port(const struct asn_oid *, struct snmp_v1_pdu *,
|
||||
const struct sockaddr *, socklen_t);
|
||||
|
||||
/* sending traps */
|
||||
void snmp_send_trap(const struct asn_oid *, ...);
|
||||
|
||||
/*
|
||||
* Action support
|
||||
*/
|
||||
int string_save(struct snmp_value *, struct snmp_context *, ssize_t, u_char **);
|
||||
void string_commit(struct snmp_context *);
|
||||
void string_rollback(struct snmp_context *, u_char **);
|
||||
int string_get(struct snmp_value *, const u_char *, ssize_t);
|
||||
void string_free(struct snmp_context *);
|
||||
|
||||
int ip_save(struct snmp_value *, struct snmp_context *, u_char *);
|
||||
void ip_rollback(struct snmp_context *, u_char *);
|
||||
void ip_commit(struct snmp_context *);
|
||||
int ip_get(struct snmp_value *, u_char *);
|
||||
|
||||
int oid_save(struct snmp_value *, struct snmp_context *, struct asn_oid *);
|
||||
void oid_rollback(struct snmp_context *, struct asn_oid *);
|
||||
void oid_commit(struct snmp_context *);
|
||||
int oid_get(struct snmp_value *, const struct asn_oid *);
|
||||
|
||||
int index_decode(const struct asn_oid *oid, u_int sub, u_int code, ...);
|
||||
int index_compare(const struct asn_oid *, u_int, const struct asn_oid *);
|
||||
int index_compare_off(const struct asn_oid *, u_int, const struct asn_oid *,
|
||||
u_int);
|
||||
void index_append(struct asn_oid *, u_int, const struct asn_oid *);
|
||||
void index_append_off(struct asn_oid *, u_int, const struct asn_oid *, u_int);
|
||||
|
||||
#endif
|
475
contrib/bsnmp/snmpd/trap.c
Normal file
475
contrib/bsnmp/snmpd/trap.c
Normal file
@ -0,0 +1,475 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003
|
||||
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Harti Brandt <harti@freebsd.org>
|
||||
*
|
||||
* Redistribution of this software and documentation 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 or documentation 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.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
* AND ITS 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
|
||||
* FRAUNHOFER FOKUS OR ITS 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.
|
||||
*
|
||||
* $Begemot: bsnmp/snmpd/trap.c,v 1.5 2003/01/28 13:44:35 hbb Exp $
|
||||
*
|
||||
* TrapSinkTable
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/un.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "snmpmod.h"
|
||||
#include "snmpd.h"
|
||||
#include "tree.h"
|
||||
#include "oid.h"
|
||||
|
||||
struct trapsink_list trapsink_list = TAILQ_HEAD_INITIALIZER(trapsink_list);
|
||||
|
||||
static const struct asn_oid oid_begemotTrapSinkTable =
|
||||
OIDX_begemotTrapSinkTable;
|
||||
static const struct asn_oid oid_sysUpTime = OIDX_sysUpTime;
|
||||
static const struct asn_oid oid_snmpTrapOID = OIDX_snmpTrapOID;
|
||||
|
||||
struct trapsink_dep {
|
||||
struct snmp_dependency dep;
|
||||
u_int set;
|
||||
u_int status;
|
||||
u_char comm[SNMP_COMMUNITY_MAXLEN + 1];
|
||||
u_int version;
|
||||
u_int rb;
|
||||
u_int rb_status;
|
||||
u_int rb_version;
|
||||
u_char rb_comm[SNMP_COMMUNITY_MAXLEN + 1];
|
||||
};
|
||||
enum {
|
||||
TDEP_STATUS = 0x0001,
|
||||
TDEP_COMM = 0x0002,
|
||||
TDEP_VERSION = 0x0004,
|
||||
|
||||
TDEP_CREATE = 0x0001,
|
||||
TDEP_MODIFY = 0x0002,
|
||||
TDEP_DESTROY = 0x0004,
|
||||
};
|
||||
|
||||
static int
|
||||
trapsink_create(struct trapsink_dep *tdep)
|
||||
{
|
||||
struct trapsink *t;
|
||||
struct sockaddr_in sa;
|
||||
|
||||
if ((t = malloc(sizeof(*t))) == NULL)
|
||||
return (SNMP_ERR_RES_UNAVAIL);
|
||||
|
||||
t->index = tdep->dep.idx;
|
||||
t->status = TRAPSINK_NOT_READY;
|
||||
t->comm[0] = '\0';
|
||||
t->version = TRAPSINK_V2;
|
||||
|
||||
if ((t->socket = socket(PF_INET, SOCK_DGRAM, 0)) == -1) {
|
||||
syslog(LOG_ERR, "socket(UDP): %m");
|
||||
free(t);
|
||||
return (SNMP_ERR_RES_UNAVAIL);
|
||||
}
|
||||
(void)shutdown(t->socket, SHUT_RD);
|
||||
|
||||
sa.sin_len = sizeof(sa);
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_addr.s_addr = htonl((t->index.subs[0] << 24) |
|
||||
(t->index.subs[1] << 16) | (t->index.subs[2] << 8) |
|
||||
(t->index.subs[3] << 0));
|
||||
sa.sin_port = htons(t->index.subs[4]);
|
||||
|
||||
if (connect(t->socket, (struct sockaddr *)&sa, sa.sin_len) == -1) {
|
||||
syslog(LOG_ERR, "connect(%s,%u): %m",
|
||||
inet_ntoa(sa.sin_addr), ntohl(sa.sin_port));
|
||||
(void)close(t->socket);
|
||||
free(t);
|
||||
return (SNMP_ERR_GENERR);
|
||||
}
|
||||
|
||||
if (tdep->set & TDEP_VERSION)
|
||||
t->version = tdep->version;
|
||||
if (tdep->set & TDEP_COMM)
|
||||
strcpy(t->comm, tdep->comm);
|
||||
|
||||
if (t->comm[0] != '\0')
|
||||
t->status = TRAPSINK_NOT_IN_SERVICE;
|
||||
|
||||
/* look whether we should activate */
|
||||
if (tdep->status == 4) {
|
||||
if (t->status == TRAPSINK_NOT_READY) {
|
||||
if (t->socket != -1)
|
||||
(void)close(t->socket);
|
||||
free(t);
|
||||
return (SNMP_ERR_INCONS_VALUE);
|
||||
}
|
||||
t->status = TRAPSINK_ACTIVE;
|
||||
}
|
||||
|
||||
INSERT_OBJECT_OID(t, &trapsink_list);
|
||||
|
||||
tdep->rb |= TDEP_CREATE;
|
||||
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
static void
|
||||
trapsink_free(struct trapsink *t)
|
||||
{
|
||||
TAILQ_REMOVE(&trapsink_list, t, link);
|
||||
if (t->socket != -1)
|
||||
(void)close(t->socket);
|
||||
free(t);
|
||||
}
|
||||
|
||||
static int
|
||||
trapsink_modify(struct trapsink *t, struct trapsink_dep *tdep)
|
||||
{
|
||||
tdep->rb_status = t->status;
|
||||
tdep->rb_version = t->version;
|
||||
strcpy(tdep->rb_comm, t->comm);
|
||||
|
||||
if (tdep->set & TDEP_STATUS) {
|
||||
/* if we are active and should move to not_in_service do
|
||||
* this first */
|
||||
if (tdep->status == 2 && tdep->rb_status == TRAPSINK_ACTIVE) {
|
||||
t->status = TRAPSINK_NOT_IN_SERVICE;
|
||||
tdep->rb |= TDEP_MODIFY;
|
||||
}
|
||||
}
|
||||
|
||||
if (tdep->set & TDEP_VERSION)
|
||||
t->version = tdep->version;
|
||||
if (tdep->set & TDEP_COMM)
|
||||
strcpy(t->comm, tdep->comm);
|
||||
|
||||
if (tdep->set & TDEP_STATUS) {
|
||||
/* if we were inactive and should go active - do this now */
|
||||
if (tdep->status == 1 && tdep->rb_status != TRAPSINK_ACTIVE) {
|
||||
if (t->comm[0] == '\0') {
|
||||
t->status = tdep->rb_status;
|
||||
t->version = tdep->rb_version;
|
||||
strcpy(t->comm, tdep->rb_comm);
|
||||
return (SNMP_ERR_INCONS_VALUE);
|
||||
}
|
||||
t->status = TRAPSINK_ACTIVE;
|
||||
tdep->rb |= TDEP_MODIFY;
|
||||
}
|
||||
}
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
static int
|
||||
trapsink_unmodify(struct trapsink *t, struct trapsink_dep *tdep)
|
||||
{
|
||||
if (tdep->set & TDEP_STATUS)
|
||||
t->status = tdep->rb_status;
|
||||
if (tdep->set & TDEP_VERSION)
|
||||
t->version = tdep->rb_version;
|
||||
if (tdep->set & TDEP_COMM)
|
||||
strcpy(t->comm, tdep->rb_comm);
|
||||
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
static void
|
||||
trapsink_finish(struct snmp_context *ctx __unused, int fail, void *arg)
|
||||
{
|
||||
struct trapsink *t = arg;
|
||||
|
||||
if (!fail)
|
||||
trapsink_free(t);
|
||||
}
|
||||
|
||||
static int
|
||||
trapsink_destroy(struct snmp_context *ctx, struct trapsink *t,
|
||||
struct trapsink_dep *tdep)
|
||||
{
|
||||
if (snmp_set_atfinish(ctx, trapsink_finish, t))
|
||||
return (SNMP_ERR_RES_UNAVAIL);
|
||||
t->status = TRAPSINK_DESTROY;
|
||||
tdep->rb_status = t->status;
|
||||
tdep->rb |= TDEP_DESTROY;
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
static int
|
||||
trapsink_undestroy(struct trapsink *t, struct trapsink_dep *tdep)
|
||||
{
|
||||
t->status = tdep->rb_status;
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
static int
|
||||
trapsink_dep(struct snmp_context *ctx, struct snmp_dependency *dep,
|
||||
enum snmp_depop op)
|
||||
{
|
||||
struct trapsink_dep *tdep = (struct trapsink_dep *)dep;
|
||||
struct trapsink *t;
|
||||
|
||||
t = FIND_OBJECT_OID(&trapsink_list, &dep->idx, 0);
|
||||
|
||||
switch (op) {
|
||||
|
||||
case SNMP_DEPOP_COMMIT:
|
||||
if (tdep->set & TDEP_STATUS) {
|
||||
switch (tdep->status) {
|
||||
|
||||
case 1:
|
||||
case 2:
|
||||
if (t == NULL)
|
||||
return (SNMP_ERR_INCONS_VALUE);
|
||||
return (trapsink_modify(t, tdep));
|
||||
|
||||
case 4:
|
||||
case 5:
|
||||
if (t != NULL)
|
||||
return (SNMP_ERR_INCONS_VALUE);
|
||||
return (trapsink_create(tdep));
|
||||
|
||||
case 6:
|
||||
if (t == NULL)
|
||||
return (SNMP_ERR_NOERROR);
|
||||
return (trapsink_destroy(ctx, t, tdep));
|
||||
}
|
||||
} else if (tdep->set != 0)
|
||||
return (trapsink_modify(t, tdep));
|
||||
|
||||
return (SNMP_ERR_NOERROR);
|
||||
|
||||
case SNMP_DEPOP_ROLLBACK:
|
||||
if (tdep->rb & TDEP_CREATE) {
|
||||
trapsink_free(t);
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
if (tdep->rb & TDEP_MODIFY)
|
||||
return (trapsink_unmodify(t, tdep));
|
||||
if(tdep->rb & TDEP_DESTROY)
|
||||
return (trapsink_undestroy(t, tdep));
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
abort();
|
||||
}
|
||||
|
||||
int
|
||||
op_trapsink(struct snmp_context *ctx, struct snmp_value *value,
|
||||
u_int sub, u_int iidx, enum snmp_op op)
|
||||
{
|
||||
struct trapsink *t;
|
||||
u_char ipa[4];
|
||||
int32_t port;
|
||||
struct asn_oid idx;
|
||||
struct trapsink_dep *tdep;
|
||||
u_char *p;
|
||||
|
||||
t = NULL; /* gcc */
|
||||
|
||||
switch (op) {
|
||||
|
||||
case SNMP_OP_GETNEXT:
|
||||
if ((t = NEXT_OBJECT_OID(&trapsink_list, &value->var, sub)) == NULL)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
index_append(&value->var, sub, &t->index);
|
||||
break;
|
||||
|
||||
case SNMP_OP_GET:
|
||||
if ((t = FIND_OBJECT_OID(&trapsink_list, &value->var, sub)) == NULL)
|
||||
return (SNMP_ERR_NOSUCHNAME);
|
||||
break;
|
||||
|
||||
case SNMP_OP_SET:
|
||||
if (index_decode(&value->var, sub, iidx, ipa, &port) ||
|
||||
port == 0 || port > 65535)
|
||||
return (SNMP_ERR_NO_CREATION);
|
||||
t = FIND_OBJECT_OID(&trapsink_list, &value->var, sub);
|
||||
|
||||
asn_slice_oid(&idx, &value->var, sub, value->var.len);
|
||||
|
||||
tdep = (struct trapsink_dep *)snmp_dep_lookup(ctx,
|
||||
&oid_begemotTrapSinkTable, &idx,
|
||||
sizeof(*tdep), trapsink_dep);
|
||||
if (tdep == NULL)
|
||||
return (SNMP_ERR_RES_UNAVAIL);
|
||||
|
||||
switch (value->var.subs[sub - 1]) {
|
||||
|
||||
case LEAF_begemotTrapSinkStatus:
|
||||
if (tdep->set & TDEP_STATUS)
|
||||
return (SNMP_ERR_INCONS_VALUE);
|
||||
switch (value->v.integer) {
|
||||
|
||||
case 1:
|
||||
case 2:
|
||||
if (t == NULL)
|
||||
return (SNMP_ERR_INCONS_VALUE);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
case 5:
|
||||
if (t != NULL)
|
||||
return (SNMP_ERR_INCONS_VALUE);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
break;
|
||||
|
||||
default:
|
||||
return (SNMP_ERR_WRONG_VALUE);
|
||||
}
|
||||
tdep->status = value->v.integer;
|
||||
tdep->set |= TDEP_STATUS;
|
||||
return (SNMP_ERR_NOERROR);
|
||||
|
||||
case LEAF_begemotTrapSinkComm:
|
||||
if (tdep->set & TDEP_COMM)
|
||||
return (SNMP_ERR_INCONS_VALUE);
|
||||
if (value->v.octetstring.len == 0 ||
|
||||
value->v.octetstring.len > SNMP_COMMUNITY_MAXLEN)
|
||||
return (SNMP_ERR_WRONG_VALUE);
|
||||
for (p = value->v.octetstring.octets;
|
||||
p < value->v.octetstring.octets + value->v.octetstring.len;
|
||||
p++) {
|
||||
if (!isascii(*p) || !isprint(*p))
|
||||
return (SNMP_ERR_WRONG_VALUE);
|
||||
}
|
||||
tdep->set |= TDEP_COMM;
|
||||
strncpy(tdep->comm, value->v.octetstring.octets,
|
||||
value->v.octetstring.len);
|
||||
tdep->comm[value->v.octetstring.len] = '\0';
|
||||
return (SNMP_ERR_NOERROR);
|
||||
|
||||
case LEAF_begemotTrapSinkVersion:
|
||||
if (tdep->set & TDEP_VERSION)
|
||||
return (SNMP_ERR_INCONS_VALUE);
|
||||
if (value->v.integer != TRAPSINK_V1 &&
|
||||
value->v.integer != TRAPSINK_V2)
|
||||
return (SNMP_ERR_WRONG_VALUE);
|
||||
tdep->version = value->v.integer;
|
||||
tdep->set |= TDEP_VERSION;
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
if (t == NULL)
|
||||
return (SNMP_ERR_INCONS_NAME);
|
||||
else
|
||||
return (SNMP_ERR_NOT_WRITEABLE);
|
||||
|
||||
|
||||
case SNMP_OP_ROLLBACK:
|
||||
case SNMP_OP_COMMIT:
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
switch (value->var.subs[sub - 1]) {
|
||||
|
||||
case LEAF_begemotTrapSinkStatus:
|
||||
value->v.integer = t->status;
|
||||
break;
|
||||
|
||||
case LEAF_begemotTrapSinkComm:
|
||||
return (string_get(value, t->comm, -1));
|
||||
|
||||
case LEAF_begemotTrapSinkVersion:
|
||||
value->v.integer = t->version;
|
||||
break;
|
||||
|
||||
}
|
||||
return (SNMP_ERR_NOERROR);
|
||||
}
|
||||
|
||||
void
|
||||
snmp_send_trap(const struct asn_oid *trap_oid, ...)
|
||||
{
|
||||
struct snmp_pdu pdu;
|
||||
struct trapsink *t;
|
||||
const struct snmp_value *v;
|
||||
va_list ap;
|
||||
u_char *sndbuf;
|
||||
size_t sndlen;
|
||||
ssize_t len;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
va_start(ap, trap_oid);
|
||||
while ((v = va_arg(ap, const struct snmp_value *)) != NULL)
|
||||
pdu.bindings[pdu.nbindings++] = *v;
|
||||
va_end(ap);
|
||||
|
||||
if ((sndbuf = buf_alloc(1)) == NULL) {
|
||||
syslog(LOG_ERR, "trap send buffer: %m");
|
||||
return;
|
||||
}
|
||||
|
||||
snmp_output(&pdu, sndbuf, &sndlen, "TRAP");
|
||||
|
||||
if ((len = send(t->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);
|
||||
}
|
||||
}
|
183
contrib/bsnmp/snmpd/tree.def
Normal file
183
contrib/bsnmp/snmpd/tree.def
Normal file
@ -0,0 +1,183 @@
|
||||
#
|
||||
# Copyright (c) 2001-2003
|
||||
# Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
# All rights reserved.
|
||||
#
|
||||
# Author: Harti Brandt <harti@freebsd.org>
|
||||
#
|
||||
# Redistribution of this software and documentation 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 or documentation 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.
|
||||
# 3. Neither the name of the Institute nor the names of its contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY FRAUNHOFER FOKUS
|
||||
# AND ITS 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
|
||||
# FRAUNHOFER FOKUS OR ITS 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.
|
||||
#
|
||||
# $Begemot: bsnmp/snmpd/tree.def,v 1.34 2002/12/11 15:54:08 hbb Exp $
|
||||
#
|
||||
# System group and private Begemot SNMPd MIB.
|
||||
#
|
||||
(1 internet
|
||||
(2 mgmt
|
||||
(1 mibII
|
||||
(1 system
|
||||
#
|
||||
# The standard System group
|
||||
#
|
||||
(1 sysDescr OCTETSTRING op_system_group GET)
|
||||
(2 sysObjectId OID op_system_group GET)
|
||||
(3 sysUpTime TIMETICKS op_system_group GET)
|
||||
(4 sysContact OCTETSTRING op_system_group GET SET)
|
||||
(5 sysName OCTETSTRING op_system_group GET SET)
|
||||
(6 sysLocation OCTETSTRING op_system_group GET SET)
|
||||
(7 sysServices INTEGER op_system_group GET)
|
||||
(8 sysORLastChange TIMETICKS op_system_group GET)
|
||||
(9 sysORTable
|
||||
(1 sysOREntry : INTEGER op_or_table
|
||||
(1 sysORIndex INTEGER)
|
||||
(2 sysORID OID GET)
|
||||
(3 sysORDescr OCTETSTRING GET)
|
||||
(4 sysORUpTime TIMETICKS GET)
|
||||
))
|
||||
)
|
||||
(11 snmp
|
||||
(1 snmpInPkts COUNTER op_snmp GET)
|
||||
(3 snmpInBadVersions COUNTER op_snmp GET)
|
||||
(4 snmpInBadCommunityNames COUNTER op_snmp GET)
|
||||
(5 snmpInBadCommunityUses COUNTER op_snmp GET)
|
||||
(6 snmpInASNParseErrs COUNTER op_snmp GET)
|
||||
(30 snmpEnableAuthenTraps INTEGER op_snmp GET SET)
|
||||
(31 snmpSilentDrops COUNTER op_snmp GET)
|
||||
(32 snmpProxyDrops COUNTER op_snmp GET)
|
||||
)
|
||||
))
|
||||
#
|
||||
# Private Begemot Stuff
|
||||
#
|
||||
(4 private
|
||||
(1 enterprises
|
||||
(12325 fokus
|
||||
(1 begemot
|
||||
|
||||
#
|
||||
# Daemon infrastructure
|
||||
#
|
||||
(1 begemotSnmpd
|
||||
(1 begemotSnmpdObjects
|
||||
|
||||
#
|
||||
# Configuration
|
||||
#
|
||||
(1 begemotSnmpdConfig
|
||||
(1 begemotSnmpdTransmitBuffer INTEGER op_snmpd_config GET SET)
|
||||
(2 begemotSnmpdReceiveBuffer INTEGER op_snmpd_config GET SET)
|
||||
(3 begemotSnmpdCommunityDisable INTEGER op_snmpd_config GET SET)
|
||||
(4 begemotSnmpdTrap1Addr IPADDRESS op_snmpd_config GET SET)
|
||||
)
|
||||
(2 begemotTrapSinkTable
|
||||
(1 begemotTrapSinkEntry : IPADDRESS INTEGER op_trapsink
|
||||
(1 begemotTrapSinkAddr IPADDRESS)
|
||||
(2 begemotTrapSinkPort INTEGER)
|
||||
(3 begemotTrapSinkStatus INTEGER GET SET)
|
||||
(4 begemotTrapSinkComm OCTETSTRING GET SET)
|
||||
(5 begemotTrapSinkVersion INTEGER GET SET)
|
||||
)
|
||||
)
|
||||
#
|
||||
# Port table
|
||||
#
|
||||
(4 begemotSnmpdPortTable
|
||||
(1 begemotSnmpdPortEntry : IPADDRESS INTEGER op_snmp_port
|
||||
(1 begemotSnmpdPortAddress IPADDRESS)
|
||||
(2 begemotSnmpdPortPort UNSIGNED32)
|
||||
(3 begemotSnmpdPortStatus INTEGER GET SET)
|
||||
))
|
||||
#
|
||||
# Community table
|
||||
#
|
||||
(5 begemotSnmpdCommunityTable
|
||||
(1 begemotSnmpdCommunityEntry : OCTETSTRING UNSIGNED32 op_community
|
||||
(1 begemotSnmpdCommunityModule OCTETSTRING)
|
||||
(2 begemotSnmpdCommunityIndex UNSIGNED32)
|
||||
(3 begemotSnmpdCommunityString OCTETSTRING GET SET)
|
||||
(4 begemotSnmpdCommunityDescr OCTETSTRING GET)
|
||||
))
|
||||
#
|
||||
# Module table
|
||||
#
|
||||
(6 begemotSnmpdModuleTable
|
||||
(1 begemotSnmpdModuleEntry : OCTETSTRING op_modules
|
||||
(1 begemotSnmpdModuleSection OCTETSTRING)
|
||||
(2 begemotSnmpdModulePath OCTETSTRING GET SET)
|
||||
(3 begemotSnmpdModuleComment OCTETSTRING GET)
|
||||
))
|
||||
#
|
||||
# Statistics
|
||||
#
|
||||
(7 begemotSnmpdStats
|
||||
(1 begemotSnmpdStatsNoRxBufs COUNTER op_snmpd_stats GET)
|
||||
(2 begemotSnmpdStatsNoTxBufs COUNTER op_snmpd_stats GET)
|
||||
(3 begemotSnmpdStatsInTooLongPkts COUNTER op_snmpd_stats GET)
|
||||
(4 begemotSnmpdStatsInBadPduTypes COUNTER op_snmpd_stats GET))
|
||||
#
|
||||
# Debugging
|
||||
#
|
||||
(8 begemotSnmpdDebug
|
||||
(1 begemotSnmpdDebugDumpPdus INTEGER op_debug GET SET)
|
||||
(2 begemotSnmpdDebugSnmpTrace UNSIGNED32 op_debug GET SET)
|
||||
(3 begemotSnmpdDebugSyslogPri INTEGER op_debug GET SET))
|
||||
|
||||
#
|
||||
# Local (UNIX domain) port table
|
||||
#
|
||||
(9 begemotSnmpdLocalPortTable
|
||||
(1 begemotSnmpdLocalPortEntry : OCTETSTRING op_local_port
|
||||
(1 begemotSnmpdLocalPortPath OCTETSTRING)
|
||||
(2 begemotSnmpdLocalPortStatus INTEGER GET SET)
|
||||
))
|
||||
)
|
||||
(2 begemotSnmpdDefs
|
||||
(1 begemotSnmpdAgent
|
||||
(1 begemotSnmpdAgentFreeBSD OID op_dummy)
|
||||
)
|
||||
)
|
||||
)
|
||||
))
|
||||
)
|
||||
)
|
||||
(6 snmpV2
|
||||
(3 snmpModules
|
||||
(1 snmpMIB
|
||||
(1 snmpMIBObjects
|
||||
(4 snmpTrap
|
||||
(1 snmpTrapOID OID op_snmp_trap)
|
||||
)
|
||||
(5 snmpTraps
|
||||
(1 coldStart OID op_snmp_trap)
|
||||
(2 warmStart OID op_snmp_trap)
|
||||
(5 authenticationFailure OID op_snmp_trap)
|
||||
)
|
||||
(6 snmpSet
|
||||
(1 snmpSetSerialNo INTEGER op_snmp_set GET SET)
|
||||
)
|
||||
)
|
||||
)
|
||||
))
|
||||
)
|
Loading…
Reference in New Issue
Block a user