summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/bsnmp/FREEBSD-upgrade3
-rw-r--r--contrib/bsnmp/NEWS21
-rw-r--r--contrib/bsnmp/README12
-rw-r--r--contrib/bsnmp/TODO16
-rw-r--r--contrib/bsnmp/VERSION2
-rw-r--r--contrib/bsnmp/gensnmptree/gensnmptree.12
-rw-r--r--contrib/bsnmp/gensnmptree/gensnmptree.c2
-rw-r--r--contrib/bsnmp/lib/asn1.32
-rw-r--r--contrib/bsnmp/lib/asn1.c14
-rw-r--r--contrib/bsnmp/lib/asn1.h2
-rw-r--r--contrib/bsnmp/lib/bsnmpagent.32
-rw-r--r--contrib/bsnmp/lib/bsnmpclient.322
-rw-r--r--contrib/bsnmp/lib/bsnmplib.32
-rw-r--r--contrib/bsnmp/lib/snmp.c60
-rw-r--r--contrib/bsnmp/lib/snmp.h4
-rw-r--r--contrib/bsnmp/lib/snmpagent.c2
-rw-r--r--contrib/bsnmp/lib/snmpagent.h2
-rw-r--r--contrib/bsnmp/lib/snmpclient.c30
-rw-r--r--contrib/bsnmp/lib/snmpclient.h10
-rw-r--r--contrib/bsnmp/lib/snmppriv.h2
-rw-r--r--contrib/bsnmp/snmp_mibII/mibII.c6
-rw-r--r--contrib/bsnmp/snmp_mibII/mibII.h2
-rw-r--r--contrib/bsnmp/snmp_mibII/mibII_ifmib.c2
-rw-r--r--contrib/bsnmp/snmp_mibII/mibII_ifstack.c2
-rw-r--r--contrib/bsnmp/snmp_mibII/mibII_interfaces.c2
-rw-r--r--contrib/bsnmp/snmp_mibII/mibII_ip.c2
-rw-r--r--contrib/bsnmp/snmp_mibII/mibII_ipaddr.c2
-rw-r--r--contrib/bsnmp/snmp_mibII/mibII_nettomedia.c2
-rw-r--r--contrib/bsnmp/snmp_mibII/mibII_rcvaddr.c2
-rw-r--r--contrib/bsnmp/snmp_mibII/mibII_route.c2
-rw-r--r--contrib/bsnmp/snmp_mibII/mibII_tcp.c2
-rw-r--r--contrib/bsnmp/snmp_mibII/mibII_tree.def2
-rw-r--r--contrib/bsnmp/snmp_mibII/mibII_udp.c2
-rw-r--r--contrib/bsnmp/snmp_mibII/snmp_mibII.32
-rw-r--r--contrib/bsnmp/snmp_mibII/snmp_mibII.h2
-rw-r--r--contrib/bsnmp/snmpd/BEGEMOT-MIB.txt2
-rw-r--r--contrib/bsnmp/snmpd/BEGEMOT-SNMPD.txt93
-rw-r--r--contrib/bsnmp/snmpd/FOKUS-MIB.txt2
-rw-r--r--contrib/bsnmp/snmpd/action.c293
-rw-r--r--contrib/bsnmp/snmpd/bsnmpd.12
-rw-r--r--contrib/bsnmp/snmpd/config.c2
-rw-r--r--contrib/bsnmp/snmpd/export.c2
-rw-r--r--contrib/bsnmp/snmpd/main.c929
-rw-r--r--contrib/bsnmp/snmpd/snmpd.config2
-rw-r--r--contrib/bsnmp/snmpd/snmpd.h108
-rwxr-xr-xcontrib/bsnmp/snmpd/snmpd.sh2
-rw-r--r--contrib/bsnmp/snmpd/snmpmod.318
-rw-r--r--contrib/bsnmp/snmpd/snmpmod.h14
-rw-r--r--contrib/bsnmp/snmpd/trans_lsock.c611
-rw-r--r--contrib/bsnmp/snmpd/trans_lsock.h63
-rw-r--r--contrib/bsnmp/snmpd/trans_udp.c313
-rw-r--r--contrib/bsnmp/snmpd/trans_udp.h54
-rw-r--r--contrib/bsnmp/snmpd/trap.c2
-rw-r--r--contrib/bsnmp/snmpd/tree.def17
54 files changed, 2124 insertions, 651 deletions
diff --git a/contrib/bsnmp/FREEBSD-upgrade b/contrib/bsnmp/FREEBSD-upgrade
index fff2784c39e5..71e220e3c662 100644
--- a/contrib/bsnmp/FREEBSD-upgrade
+++ b/contrib/bsnmp/FREEBSD-upgrade
@@ -8,8 +8,9 @@ environments besides FreeBSD.
Import should be done by:
1. unpack distribution into clean directory
+ tar xvf bsnmp-X.Y.tar.gz --exclude-from=FREEBSD-Xlist
- 2. remove all unneeded files
+ 2. remove all unneeded new files (and update FREEBSD-Xlist)
3. cvs import \
-m "Virgin import of bsnmpd X.Y" \
diff --git a/contrib/bsnmp/NEWS b/contrib/bsnmp/NEWS
index 3d0ca120fa09..01281ecdb481 100644
--- a/contrib/bsnmp/NEWS
+++ b/contrib/bsnmp/NEWS
@@ -1,3 +1,24 @@
+09-Dec-2003
+ First step on factoring out the transport mapping stuff into
+ loadable modules.
+
+ Local stream sockets that check the clients privileges.
+
+03-Dec-2003
+ Bump version to 1.5 but leave library version intact.
+
+03-Dec-2003
+ Now works with libbegemot polling stuff instead of libisc.
+ Use --with-libbegemot[=path] to configure.
+
+03-Dec-2003
+ Fix parsing of non-minimal ASN.1 integers. They are now disallowed.
+ Non-minimal lengths are allowed.
+
+ Remove copyright clause 3 everywhere.
+
+ Make an autoconf build infrastructure.
+
08-Nov-2003
WARNS=6 fixed.
diff --git a/contrib/bsnmp/README b/contrib/bsnmp/README
index 85ab2edfb724..25d09263fce0 100644
--- a/contrib/bsnmp/README
+++ b/contrib/bsnmp/README
@@ -1,4 +1,4 @@
-Mon Nov 10 09:50:22 CET 2003
+Fri Dec 5 15:01:16 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,
@@ -13,16 +13,16 @@ One basic loadable module is provided together with the daemon:
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
+ configure [--with-libbegemot[=path]]
+ 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.
+line. An example configuration file is provided. Use --with-libbegemot
+to use libbegemot instead of libisc.
Running
-------
diff --git a/contrib/bsnmp/TODO b/contrib/bsnmp/TODO
index 5b3054431ef3..732c82c06296 100644
--- a/contrib/bsnmp/TODO
+++ b/contrib/bsnmp/TODO
@@ -1,5 +1,17 @@
snmpd_mibII:
- handle HC counters by periodically polling the kernel counters.
-snmpd_netgraph:
- - make some tables writeable
+snmpd:
+ - rethink transports a little bit: make them loadable and make
+ a private subtree for transports:
+ OK. Table not writeable yet.
+
+ There should be a transport table that is indexed by the transport name.
+ This table can be used to load/unload transports at run time.
+ OK. Table not writeable yet.
+
+ Then there can be a port table that is indexed by transport name and
+ port name. Plus a transport-specific table indexed by port name only.
+
+ The transport table could contain a column of type OID that points
+ to the transport-specific table.
diff --git a/contrib/bsnmp/VERSION b/contrib/bsnmp/VERSION
index c068b2447cc2..941c59621300 100644
--- a/contrib/bsnmp/VERSION
+++ b/contrib/bsnmp/VERSION
@@ -1 +1 @@
-1.4
+1.5a
diff --git a/contrib/bsnmp/gensnmptree/gensnmptree.1 b/contrib/bsnmp/gensnmptree/gensnmptree.1
index 2970355df2bf..9704debb0dd6 100644
--- a/contrib/bsnmp/gensnmptree/gensnmptree.1
+++ b/contrib/bsnmp/gensnmptree/gensnmptree.1
@@ -28,7 +28,7 @@
.\" 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 $
+.\" $Begemot: bsnmp/gensnmptree/gensnmptree.1,v 1.2 2003/12/03 09:56:57 hbb Exp $
.\"
.\" Author: Harti Brandt <harti@freebsd.org>
.\"
diff --git a/contrib/bsnmp/gensnmptree/gensnmptree.c b/contrib/bsnmp/gensnmptree/gensnmptree.c
index 5c400e3d7a74..981614483262 100644
--- a/contrib/bsnmp/gensnmptree/gensnmptree.c
+++ b/contrib/bsnmp/gensnmptree/gensnmptree.c
@@ -30,7 +30,7 @@
* 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 $
+ * $Begemot: bsnmp/gensnmptree/gensnmptree.c,v 1.36 2003/12/03 09:56:57 hbb Exp $
*
* Generate OID table from table description.
*
diff --git a/contrib/bsnmp/lib/asn1.3 b/contrib/bsnmp/lib/asn1.3
index 3751e50cdb1c..ec01b9a01d90 100644
--- a/contrib/bsnmp/lib/asn1.3
+++ b/contrib/bsnmp/lib/asn1.3
@@ -30,7 +30,7 @@
.\" 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 $
+.\" $Begemot: bsnmp/lib/asn1.3,v 1.3 2003/12/02 15:45:48 hbb Exp $
.\"
.Dd August 15, 2002
.Dt asn1 3
diff --git a/contrib/bsnmp/lib/asn1.c b/contrib/bsnmp/lib/asn1.c
index 533b9dd6bce6..75d5300639d2 100644
--- a/contrib/bsnmp/lib/asn1.c
+++ b/contrib/bsnmp/lib/asn1.c
@@ -30,7 +30,7 @@
* 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 $
+ * $Begemot: bsnmp/lib/asn1.c,v 1.27 2003/12/08 17:11:58 hbb Exp $
*
* ASN.1 for SNMP.
*/
@@ -244,6 +244,13 @@ asn_get_real_integer(struct asn_buf *b, asn_len_t len, int64_t *vp)
err = ASN_ERR_OK;
if (len > 8)
err = ASN_ERR_RANGE;
+ else if (len > 1 &&
+ ((*b->asn_cptr == 0x00 && (b->asn_cptr[1] & 0x80) == 0) ||
+ (*b->asn_cptr == 0xff && (b->asn_cptr[1] & 0x80) == 0x80))) {
+ asn_error(b, "non-minimal integer");
+ err = ASN_ERR_BADLEN;
+ }
+
if (*b->asn_cptr & 0x80)
neg = 1;
val = 0;
@@ -332,6 +339,10 @@ asn_get_real_unsigned(struct asn_buf *b, asn_len_t len, u_int64_t *vp)
/* negative integer or too larger */
*vp = 0xffffffffffffffffULL;
err = ASN_ERR_RANGE;
+ } else if (len > 1 &&
+ *b->asn_cptr == 0x00 && (b->asn_cptr[1] & 0x80) == 0) {
+ asn_error(b, "non-minimal unsigned");
+ err = ASN_ERR_BADLEN;
}
while (len--) {
@@ -718,7 +729,6 @@ asn_get_sequence(struct asn_buf *b, asn_len_t *len)
return (ASN_ERR_OK);
}
-
/*
* Application types
*
diff --git a/contrib/bsnmp/lib/asn1.h b/contrib/bsnmp/lib/asn1.h
index 83a31e530594..0c21fe491026 100644
--- a/contrib/bsnmp/lib/asn1.h
+++ b/contrib/bsnmp/lib/asn1.h
@@ -30,7 +30,7 @@
* 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 $
+ * $Begemot: bsnmp/lib/asn1.h,v 1.17 2003/12/02 15:52:37 hbb Exp $
*
* ASN.1 for SNMP
*/
diff --git a/contrib/bsnmp/lib/bsnmpagent.3 b/contrib/bsnmp/lib/bsnmpagent.3
index a9a8104013cb..ad2f62838d2c 100644
--- a/contrib/bsnmp/lib/bsnmpagent.3
+++ b/contrib/bsnmp/lib/bsnmpagent.3
@@ -30,7 +30,7 @@
.\" 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 $
+.\" $Begemot: bsnmp/lib/bsnmpagent.3,v 1.2 2003/12/02 16:13:45 hbb Exp $
.\"
.Dd August 16, 2002
.Dt bsnmpagent 3
diff --git a/contrib/bsnmp/lib/bsnmpclient.3 b/contrib/bsnmp/lib/bsnmpclient.3
index f4a7eac62a7f..a4996c4a9430 100644
--- a/contrib/bsnmp/lib/bsnmpclient.3
+++ b/contrib/bsnmp/lib/bsnmpclient.3
@@ -30,7 +30,7 @@
.\" 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 $
+.\" $Begemot: bsnmp/lib/bsnmpclient.3,v 1.5 2003/12/08 17:11:58 hbb Exp $
.\"
.Dd August 15, 2002
.Dt bsnmpclient 3
@@ -107,7 +107,7 @@ that use SNMP versions 1 or 2. Most of the routines use a
.Bd -literal -offset indent
struct snmp_client {
enum snmp_version version;
- int local; /* use local socket */
+ int trans; /* transport type to use */
/* these two are read-only for the application */
char *cport; /* port number as string */
@@ -147,13 +147,19 @@ 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
+.It Va trans
+If this is
+.Dv SNMP_TRANS_LOC_DGRAM
+a local datagram socket is used.
+If it is
+.Dv SNMP_TRANS_LOC_STREAM
+a local stream socket is used.
+For
+.Dv SNMP_TRANS_UDP
+a UDP socket is created.
+It uses the
.Va chost
-field as the path to the server's socket.
+field as the path to the server's socket for local sockets.
.It Va cport
The SNMP agent's UDP port number. This may be a symbolic port number (from
.Pa /etc/services
diff --git a/contrib/bsnmp/lib/bsnmplib.3 b/contrib/bsnmp/lib/bsnmplib.3
index 13f96516ad96..8f7fcb435d21 100644
--- a/contrib/bsnmp/lib/bsnmplib.3
+++ b/contrib/bsnmp/lib/bsnmplib.3
@@ -30,7 +30,7 @@
.\" 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 $
+.\" $Begemot: bsnmp/lib/bsnmplib.3,v 1.3 2003/12/02 16:14:28 hbb Exp $
.\"
.Dd August 15, 2002
.Dt bsnmplib 3
diff --git a/contrib/bsnmp/lib/snmp.c b/contrib/bsnmp/lib/snmp.c
index 786bf8cd4048..3369dd32383b 100644
--- a/contrib/bsnmp/lib/snmp.c
+++ b/contrib/bsnmp/lib/snmp.c
@@ -30,7 +30,7 @@
* 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.c,v 1.34 2003/01/28 13:44:34 hbb Exp $
+ * $Begemot: bsnmp/lib/snmp.c,v 1.37 2003/12/08 17:11:58 hbb Exp $
*
* SNMP
*/
@@ -432,6 +432,64 @@ snmp_pdu_decode(struct asn_buf *b, struct snmp_pdu *pdu, int32_t *ip)
}
/*
+ * Check whether what we have is the complete PDU by snooping at the
+ * enclosing structure header. This returns:
+ * -1 if there are ASN.1 errors
+ * 0 if we need more data
+ * > 0 the length of this PDU
+ */
+int
+snmp_pdu_snoop(const struct asn_buf *b0)
+{
+ u_int length;
+ asn_len_t len;
+ struct asn_buf b = *b0;
+
+ /* <0x10|0x20> <len> <data...> */
+
+ if (b.asn_len == 0)
+ return (0);
+ if (b.asn_cptr[0] != (ASN_TYPE_SEQUENCE | ASN_TYPE_CONSTRUCTED)) {
+ asn_error(&b, "bad sequence type %u", b.asn_cptr[0]);
+ return (-1);
+ }
+ b.asn_len--;
+ b.asn_cptr++;
+
+ if (b.asn_len == 0)
+ return (0);
+
+ if (*b.asn_cptr & 0x80) {
+ /* long length */
+ length = *b.asn_cptr++ & 0x7f;
+ b.asn_len--;
+ if (length == 0) {
+ asn_error(&b, "indefinite length not supported");
+ return (-1);
+ }
+ if (length > ASN_MAXLENLEN) {
+ asn_error(&b, "long length too long (%u)", length);
+ return (-1);
+ }
+ if (length > b.asn_len)
+ return (0);
+ len = 0;
+ while (length--) {
+ len = (len << 8) | *b.asn_cptr++;
+ b.asn_len--;
+ }
+ } else {
+ len = *b.asn_cptr++;
+ b.asn_len--;
+ }
+
+ if (len > b.asn_len)
+ return (0);
+
+ return (len + b.asn_cptr - b0->asn_cptr);
+}
+
+/*
* Encode the SNMP PDU without the variable bindings field.
* We do this the rather uneffective way by
* moving things around and assuming that the length field will never
diff --git a/contrib/bsnmp/lib/snmp.h b/contrib/bsnmp/lib/snmp.h
index 30b1e2c8b6cf..86a36e7a270b 100644
--- a/contrib/bsnmp/lib/snmp.h
+++ b/contrib/bsnmp/lib/snmp.h
@@ -30,7 +30,7 @@
* 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 $
+ * $Begemot: bsnmp/lib/snmp.h,v 1.29 2003/12/08 17:11:58 hbb Exp $
*
* Header file for SNMP functions.
*/
@@ -164,6 +164,8 @@ 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);
+int snmp_pdu_snoop(const struct asn_buf *);
+
void snmp_pdu_dump(const struct snmp_pdu *pdu);
extern void (*snmp_error)(const char *, ...);
diff --git a/contrib/bsnmp/lib/snmpagent.c b/contrib/bsnmp/lib/snmpagent.c
index 19ac661a2f54..c03b606f4262 100644
--- a/contrib/bsnmp/lib/snmpagent.c
+++ b/contrib/bsnmp/lib/snmpagent.c
@@ -30,7 +30,7 @@
* 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.c,v 1.14 2003/01/30 11:23:00 hbb Exp $
+ * $Begemot: bsnmp/lib/snmpagent.c,v 1.16 2003/12/03 09:55:58 hbb Exp $
*
* SNMP Agent functions
*/
diff --git a/contrib/bsnmp/lib/snmpagent.h b/contrib/bsnmp/lib/snmpagent.h
index a854138981c0..cd89456329aa 100644
--- a/contrib/bsnmp/lib/snmpagent.h
+++ b/contrib/bsnmp/lib/snmpagent.h
@@ -30,7 +30,7 @@
* 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 $
+ * $Begemot: bsnmp/lib/snmpagent.h,v 1.10 2003/12/03 09:55:58 hbb Exp $
*
* Header file for SNMP functions. This requires snmp.h to be included.
*/
diff --git a/contrib/bsnmp/lib/snmpclient.c b/contrib/bsnmp/lib/snmpclient.c
index e1206b06d2f8..ce3b2c07167c 100644
--- a/contrib/bsnmp/lib/snmpclient.c
+++ b/contrib/bsnmp/lib/snmpclient.c
@@ -31,7 +31,7 @@
* 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.c,v 1.24 2003/01/28 13:44:34 hbb Exp $
+ * $Begemot: bsnmp/lib/snmpclient.c,v 1.27 2003/12/08 17:11:58 hbb Exp $
*
* Support functions for SNMP clients.
*/
@@ -826,7 +826,7 @@ snmp_client_init(struct snmp_client *c)
memset(c, 0, sizeof(*c));
c->version = SNMP_V2c;
- c->local = 0;
+ c->trans = SNMP_TRANS_UDP;
c->chost = NULL;
c->cport = NULL;
@@ -941,6 +941,7 @@ open_client_local(const char *path)
{
struct sockaddr_un sa;
char *ptr;
+ int stype;
if (snmp_client.chost == NULL) {
if ((snmp_client.chost = malloc(1 + sizeof(DEFAULT_LOCAL)))
@@ -960,7 +961,12 @@ open_client_local(const char *path)
strcpy(snmp_client.chost, path);
}
- if ((snmp_client.fd = socket(PF_LOCAL, SOCK_DGRAM, 0)) == -1) {
+ if (snmp_client.trans == SNMP_TRANS_LOC_DGRAM)
+ stype = SOCK_DGRAM;
+ else
+ stype = SOCK_STREAM;
+
+ if ((snmp_client.fd = socket(PF_LOCAL, stype, 0)) == -1) {
seterr("%s", strerror(errno));
return (-1);
}
@@ -1028,12 +1034,22 @@ snmp_open(const char *host, const char *port, const char *readcomm,
strlcpy(snmp_client.write_community, writecomm,
sizeof(snmp_client.write_community));
- if (!snmp_client.local) {
+ switch (snmp_client.trans) {
+
+ case SNMP_TRANS_UDP:
if (open_client_udp(host, port))
return (-1);
- } else {
+ break;
+
+ case SNMP_TRANS_LOC_DGRAM:
+ case SNMP_TRANS_LOC_STREAM:
if (open_client_local(host))
return (-1);
+ break;
+
+ default:
+ seterr("bad transport mapping");
+ return (-1);
}
tout.tv_sec = 0;
tout.tv_usec = 0;
@@ -1042,7 +1058,7 @@ snmp_open(const char *host, const char *port, const char *readcomm,
seterr("%s", strerror(errno));
(void)close(snmp_client.fd);
snmp_client.fd = -1;
- if (snmp_client.local)
+ if (snmp_client.local_path[0] != '\0')
(void)remove(snmp_client.local_path);
return (-1);
}
@@ -1075,7 +1091,7 @@ snmp_close(void)
if (snmp_client.fd != -1) {
(void)close(snmp_client.fd);
snmp_client.fd = -1;
- if (snmp_client.local)
+ if (snmp_client.local_path[0] != '\0')
(void)remove(snmp_client.local_path);
}
while(!LIST_EMPTY(&sent_pdus)){
diff --git a/contrib/bsnmp/lib/snmpclient.h b/contrib/bsnmp/lib/snmpclient.h
index 700d020700e8..80acb1481a4e 100644
--- a/contrib/bsnmp/lib/snmpclient.h
+++ b/contrib/bsnmp/lib/snmpclient.h
@@ -31,7 +31,7 @@
* 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 $
+ * $Begemot: bsnmp/lib/snmpclient.h,v 1.17 2003/12/08 17:11:58 hbb Exp $
*/
#ifndef _BSNMP_SNMPCLIENT_H
#define _BSNMP_SNMPCLIENT_H
@@ -47,6 +47,12 @@
#define SNMP_LOCAL_PATH "/tmp/snmpXXXXXXXXXXXXXX"
+/*
+ * transport methods
+ */
+#define SNMP_TRANS_UDP 0
+#define SNMP_TRANS_LOC_DGRAM 1
+#define SNMP_TRANS_LOC_STREAM 2
/* type of callback function for responses
* this callback function is responsible for free() any memory associated with
@@ -68,7 +74,7 @@ typedef void (*snmp_timeout_stop_f)(void *timeout_id);
*/
struct snmp_client {
enum snmp_version version;
- int local; /* use local socket */
+ int trans; /* which transport to use */
/* these two are read-only for the application */
char *cport; /* port number as string */
diff --git a/contrib/bsnmp/lib/snmppriv.h b/contrib/bsnmp/lib/snmppriv.h
index 82189f0c34b4..9fb66aad7f2e 100644
--- a/contrib/bsnmp/lib/snmppriv.h
+++ b/contrib/bsnmp/lib/snmppriv.h
@@ -30,7 +30,7 @@
* 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 $
+ * $Begemot: bsnmp/lib/snmppriv.h,v 1.8 2003/12/03 09:55:58 hbb Exp $
*
* Private functions.
*/
diff --git a/contrib/bsnmp/snmp_mibII/mibII.c b/contrib/bsnmp/snmp_mibII/mibII.c
index 74817948bd81..ae38b6f95a20 100644
--- a/contrib/bsnmp/snmp_mibII/mibII.c
+++ b/contrib/bsnmp/snmp_mibII/mibII.c
@@ -30,7 +30,7 @@
* 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.c,v 1.16 2003/01/28 13:44:34 hbb Exp $
+ * $Begemot: bsnmp/snmp_mibII/mibII.c,v 1.17 2003/12/03 10:01:19 hbb Exp $
*
* Implementation of the standard interfaces and ip MIB.
*/
@@ -978,11 +978,15 @@ mib_fetch_rtab(int af, int info, int arg, size_t *lenp)
name[4] = info;
name[5] = arg;
+ *lenp = 0;
+
if (sysctl(name, 6, NULL, lenp, NULL, 0) == -1) {
syslog(LOG_ERR, "sysctl estimate (%d,%d,%d,%d,%d,%d): %m",
name[0], name[1], name[2], name[3], name[4], name[5]);
return (NULL);
}
+ if (*lenp == 0)
+ return (NULL);
if ((buf = malloc(*lenp)) == NULL) {
syslog(LOG_ERR, "sysctl buffer: %m");
diff --git a/contrib/bsnmp/snmp_mibII/mibII.h b/contrib/bsnmp/snmp_mibII/mibII.h
index 89ccd05c797f..6e8cd993c764 100644
--- a/contrib/bsnmp/snmp_mibII/mibII.h
+++ b/contrib/bsnmp/snmp_mibII/mibII.h
@@ -30,7 +30,7 @@
* 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 $
+ * $Begemot: bsnmp/snmp_mibII/mibII.h,v 1.12 2003/12/03 10:01:19 hbb Exp $
*
* Implementation of the interfaces and IP groups of MIB-II.
*/
diff --git a/contrib/bsnmp/snmp_mibII/mibII_ifmib.c b/contrib/bsnmp/snmp_mibII/mibII_ifmib.c
index 1f09d59d3f4b..24a57f8f0930 100644
--- a/contrib/bsnmp/snmp_mibII/mibII_ifmib.c
+++ b/contrib/bsnmp/snmp_mibII/mibII_ifmib.c
@@ -30,7 +30,7 @@
* 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 $
+ * $Begemot: bsnmp/snmp_mibII/mibII_ifmib.c,v 1.8 2003/12/03 10:01:19 hbb Exp $
*
* Interfaces group.
*/
diff --git a/contrib/bsnmp/snmp_mibII/mibII_ifstack.c b/contrib/bsnmp/snmp_mibII/mibII_ifstack.c
index 93aa259ea645..b19ea4e221e3 100644
--- a/contrib/bsnmp/snmp_mibII/mibII_ifstack.c
+++ b/contrib/bsnmp/snmp_mibII/mibII_ifstack.c
@@ -30,7 +30,7 @@
* 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 $
+ * $Begemot: bsnmp/snmp_mibII/mibII_ifstack.c,v 1.6 2003/12/03 10:01:19 hbb Exp $
*
* ifStackTable. Read-only.
*/
diff --git a/contrib/bsnmp/snmp_mibII/mibII_interfaces.c b/contrib/bsnmp/snmp_mibII/mibII_interfaces.c
index 02a90caa36c0..a0023bd0056b 100644
--- a/contrib/bsnmp/snmp_mibII/mibII_interfaces.c
+++ b/contrib/bsnmp/snmp_mibII/mibII_interfaces.c
@@ -30,7 +30,7 @@
* 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 $
+ * $Begemot: bsnmp/snmp_mibII/mibII_interfaces.c,v 1.10 2003/12/03 10:01:19 hbb Exp $
*
* Interfaces group.
*/
diff --git a/contrib/bsnmp/snmp_mibII/mibII_ip.c b/contrib/bsnmp/snmp_mibII/mibII_ip.c
index d0d25904cd17..8b638e336c8a 100644
--- a/contrib/bsnmp/snmp_mibII/mibII_ip.c
+++ b/contrib/bsnmp/snmp_mibII/mibII_ip.c
@@ -30,7 +30,7 @@
* 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 $
+ * $Begemot: bsnmp/snmp_mibII/mibII_ip.c,v 1.9 2003/12/03 10:01:19 hbb Exp $
*
* ip group scalars.
*/
diff --git a/contrib/bsnmp/snmp_mibII/mibII_ipaddr.c b/contrib/bsnmp/snmp_mibII/mibII_ipaddr.c
index 0cc593663abe..a0050f6c7bec 100644
--- a/contrib/bsnmp/snmp_mibII/mibII_ipaddr.c
+++ b/contrib/bsnmp/snmp_mibII/mibII_ipaddr.c
@@ -30,7 +30,7 @@
* 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 $
+ * $Begemot: bsnmp/snmp_mibII/mibII_ipaddr.c,v 1.7 2003/12/03 10:01:19 hbb Exp $
*
* IP address table. This table is writeable!
*
diff --git a/contrib/bsnmp/snmp_mibII/mibII_nettomedia.c b/contrib/bsnmp/snmp_mibII/mibII_nettomedia.c
index e8a791994350..bafa6e1cda74 100644
--- a/contrib/bsnmp/snmp_mibII/mibII_nettomedia.c
+++ b/contrib/bsnmp/snmp_mibII/mibII_nettomedia.c
@@ -30,7 +30,7 @@
* 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 $
+ * $Begemot: bsnmp/snmp_mibII/mibII_nettomedia.c,v 1.7 2003/12/03 10:01:19 hbb Exp $
*
* Read-only implementation of the Arp table (ipNetToMediaTable)
*
diff --git a/contrib/bsnmp/snmp_mibII/mibII_rcvaddr.c b/contrib/bsnmp/snmp_mibII/mibII_rcvaddr.c
index 7226e1019000..e257f17f9496 100644
--- a/contrib/bsnmp/snmp_mibII/mibII_rcvaddr.c
+++ b/contrib/bsnmp/snmp_mibII/mibII_rcvaddr.c
@@ -30,7 +30,7 @@
* 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 $
+ * $Begemot: bsnmp/snmp_mibII/mibII_rcvaddr.c,v 1.8 2003/12/03 10:01:19 hbb Exp $
*
* Interface receive address table.
*/
diff --git a/contrib/bsnmp/snmp_mibII/mibII_route.c b/contrib/bsnmp/snmp_mibII/mibII_route.c
index d2683ce6f7a1..e220de9af129 100644
--- a/contrib/bsnmp/snmp_mibII/mibII_route.c
+++ b/contrib/bsnmp/snmp_mibII/mibII_route.c
@@ -30,7 +30,7 @@
* 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 $
+ * $Begemot: bsnmp/snmp_mibII/mibII_route.c,v 1.4 2003/12/03 10:01:19 hbb Exp $
*
* Routing table
*/
diff --git a/contrib/bsnmp/snmp_mibII/mibII_tcp.c b/contrib/bsnmp/snmp_mibII/mibII_tcp.c
index f4509f958078..ec2c5fd06ce6 100644
--- a/contrib/bsnmp/snmp_mibII/mibII_tcp.c
+++ b/contrib/bsnmp/snmp_mibII/mibII_tcp.c
@@ -30,7 +30,7 @@
* 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 $
+ * $Begemot: bsnmp/snmp_mibII/mibII_tcp.c,v 1.5 2003/12/03 10:01:19 hbb Exp $
*
* tcp
*/
diff --git a/contrib/bsnmp/snmp_mibII/mibII_tree.def b/contrib/bsnmp/snmp_mibII/mibII_tree.def
index 63842641e1eb..fabc6b524a60 100644
--- a/contrib/bsnmp/snmp_mibII/mibII_tree.def
+++ b/contrib/bsnmp/snmp_mibII/mibII_tree.def
@@ -30,7 +30,7 @@
# 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 $
+# $Begemot: bsnmp/snmp_mibII/mibII_tree.def,v 1.11 2003/12/03 10:01:19 hbb Exp $
#
# Definition of the standard interfaces and ip trees.
#
diff --git a/contrib/bsnmp/snmp_mibII/mibII_udp.c b/contrib/bsnmp/snmp_mibII/mibII_udp.c
index 232bc45b4cff..0dde816027cc 100644
--- a/contrib/bsnmp/snmp_mibII/mibII_udp.c
+++ b/contrib/bsnmp/snmp_mibII/mibII_udp.c
@@ -30,7 +30,7 @@
* 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 $
+ * $Begemot: bsnmp/snmp_mibII/mibII_udp.c,v 1.5 2003/12/03 10:01:19 hbb Exp $
*
* udp
*/
diff --git a/contrib/bsnmp/snmp_mibII/snmp_mibII.3 b/contrib/bsnmp/snmp_mibII/snmp_mibII.3
index 62b354da0484..1d7018a76bbf 100644
--- a/contrib/bsnmp/snmp_mibII/snmp_mibII.3
+++ b/contrib/bsnmp/snmp_mibII/snmp_mibII.3
@@ -30,7 +30,7 @@
.\" 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 $
+.\" $Begemot: bsnmp/snmp_mibII/snmp_mibII.3,v 1.2 2003/12/03 10:01:19 hbb Exp $
.\"
.Dd August 19, 2002
.Dt snmp_mibII 3
diff --git a/contrib/bsnmp/snmp_mibII/snmp_mibII.h b/contrib/bsnmp/snmp_mibII/snmp_mibII.h
index 79423cbd4cc5..7efba8635cba 100644
--- a/contrib/bsnmp/snmp_mibII/snmp_mibII.h
+++ b/contrib/bsnmp/snmp_mibII/snmp_mibII.h
@@ -30,7 +30,7 @@
* 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 $
+ * $Begemot: bsnmp/snmp_mibII/snmp_mibII.h,v 1.14 2003/12/03 10:01:19 hbb Exp $
*
* Implementation of the interfaces and IP groups of MIB-II.
*/
diff --git a/contrib/bsnmp/snmpd/BEGEMOT-MIB.txt b/contrib/bsnmp/snmpd/BEGEMOT-MIB.txt
index f2822763777e..73268bb69bb5 100644
--- a/contrib/bsnmp/snmpd/BEGEMOT-MIB.txt
+++ b/contrib/bsnmp/snmpd/BEGEMOT-MIB.txt
@@ -30,7 +30,7 @@
-- 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: bsnmp/snmpd/BEGEMOT-MIB.txt,v 1.4 2003/12/03 10:08:47 hbb Exp $
--
-- Begemot private definitions and root.
--
diff --git a/contrib/bsnmp/snmpd/BEGEMOT-SNMPD.txt b/contrib/bsnmp/snmpd/BEGEMOT-SNMPD.txt
index 8c0996b11562..76fcbd59c4f0 100644
--- a/contrib/bsnmp/snmpd/BEGEMOT-SNMPD.txt
+++ b/contrib/bsnmp/snmpd/BEGEMOT-SNMPD.txt
@@ -30,7 +30,7 @@
-- 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: bsnmp/snmpd/BEGEMOT-SNMPD.txt,v 1.21 2003/12/09 12:28:52 hbb Exp $
--
-- Begemot Private SNMPd MIB.
--
@@ -134,6 +134,19 @@ begemotSnmpdTrap1Addr OBJECT-TYPE
"The trap sink for v1 traps."
::= { begemotSnmpdConfig 4 }
+begemotSnmpdVersionEnable OBJECT-TYPE
+ SYNTAX Unsigned32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The SNMP versions that the agent processes. The following
+ bits are defined:
+
+ 0x00000001 - SNMPv1
+ 0x00000002 - SNMPv2c"
+ DEFVAL { 0x3 }
+ ::= { begemotSnmpdConfig 5 }
+
--
-- Trap destinations
--
@@ -423,6 +436,8 @@ begemotSnmpdDebugSnmpTrace OBJECT-TYPE
0x00000004 trace SET operator
0x00000008 trace dependency processing
0x00000010 trace node finding
+ 0x10000000 log ASN1 errors
+ 0x20000000 log SNMP errors
Individual values can be or-ed together."
DEFVAL { 0 }
::= { begemotSnmpdDebug 2 }
@@ -461,6 +476,7 @@ begemotSnmpdLocalPortEntry OBJECT-TYPE
BegemotSnmpdLocalPortEntry ::= SEQUENCE {
begemotSnmpdLocalPortPath OCTET STRING,
begemotSnmpdLocalPortStatus INTEGER
+ begemotSnmpdLocalPortType INTEGER
}
begemotSnmpdLocalPortPath OBJECT-TYPE
@@ -479,4 +495,79 @@ begemotSnmpdLocalPortStatus OBJECT-TYPE
"Set status to 1 to create entry, set it to 2 to delete it."
::= { begemotSnmpdLocalPortEntry 2 }
+begemotSnmpdLocalPortType OBJECT-TYPE
+ SYNTAX INTEGER {
+ dgram-unpriv(1),
+ dgram-priv(2),
+ stream-unpriv(3),
+ stream-priv(4)
+ }
+ MAX-ACCESS read-create
+ STATUS current
+ DESCRIPTION
+ "Type of the port. If the type is unpriv SET operations
+ are allowed from all clients if the community matches. For
+ priv SET operations are allowed only from peers with uid
+ zero. If the daemon cannot determine the peer uid it disallows
+ the SET operation for -priv ports."
+ ::= { begemotSnmpdLocalPortEntry 3 }
+
+--
+-- Transport mapping table
+--
+begemotSnmpdTransportMappings OBJECT IDENTIFIER ::= { begemotSnmpdObjects 10 }
+
+begemotSnmpdTransportTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF BegemotSnmpdTransportEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "A table containing all the currently loaded transport mappings."
+ ::= { begemotSnmpdTransportMappings 1 }
+
+begemotSnmpdTransportEntry OBJECT-TYPE
+ SYNTAX BegemotSnmpdTransportEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "An entry in the table with the transport mappings."
+ INDEX { begemotSnmpdTransportName }
+ ::= { begemotSnmpdTransportTable 1 }
+
+BegemotSnmpdTransportEntry ::= SEQUENCE {
+ begemotSnmpdTransportName OCTET STRING,
+ begemotSnmpdTransportStatus INTEGER
+ begemotSnmpdTransportOid OBJECT IDENTIFIER
+}
+
+begemotSnmpdTransportName OBJECT-TYPE
+ SYNTAX OCTET STRING (SIZE(1..256))
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "The name of the mapping."
+ ::= { begemotSnmpdTransportEntry 1 }
+
+begemotSnmpdTransportStatus OBJECT-TYPE
+ SYNTAX RowStatus
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Used to create/activate/destroy the entry."
+ ::= { begemotSnmpdTransportEntry 2 }
+
+begemotSnmpdTransportOid OBJECT-TYPE
+ SYNTAX OBJECT IDENTIFIER
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "A pointer to the group with the transport-dependend stuff."
+ ::= { begemotSnmpdTransportEntry 3 }
+
+--
+-- XXX These should go into their own MIB
+--
+begemotSnmpdTransUdp OBJECT IDENTIFIER ::= { begemotSnmpdTransportMappings 2 }
+begemotSnmpdTransLsock OBJECT IDENTIFIER ::= { begemotSnmpdTransportMappings 3 }
+
END
diff --git a/contrib/bsnmp/snmpd/FOKUS-MIB.txt b/contrib/bsnmp/snmpd/FOKUS-MIB.txt
index c0939babee88..767ace75f6e2 100644
--- a/contrib/bsnmp/snmpd/FOKUS-MIB.txt
+++ b/contrib/bsnmp/snmpd/FOKUS-MIB.txt
@@ -30,7 +30,7 @@
-- 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: bsnmp/snmpd/FOKUS-MIB.txt,v 1.4 2003/12/03 10:08:47 hbb Exp $
--
-- Begemot private definitions and fokus root.
--
diff --git a/contrib/bsnmp/snmpd/action.c b/contrib/bsnmp/snmpd/action.c
index 7c87beaf445e..0fee3b9aaaa0 100644
--- a/contrib/bsnmp/snmpd/action.c
+++ b/contrib/bsnmp/snmpd/action.c
@@ -30,7 +30,7 @@
* 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/action.c,v 1.53 2003/01/28 13:44:35 hbb Exp $
+ * $Begemot: bsnmp/snmpd/action.c,v 1.56 2003/12/09 12:28:52 hbb Exp $
*
* Variable access for SNMPd
*/
@@ -557,6 +557,9 @@ op_snmpd_config(struct snmp_context *ctx, struct snmp_value *value,
break;
case LEAF_begemotSnmpdTrap1Addr:
return (ip_get(value, snmpd.trap1addr));
+ case LEAF_begemotSnmpdVersionEnable:
+ value->v.uint32 = snmpd.version_enable;
+ break;
default:
return (SNMP_ERR_NOSUCHNAME);
}
@@ -595,6 +598,16 @@ op_snmpd_config(struct snmp_context *ctx, struct snmp_value *value,
case LEAF_begemotSnmpdTrap1Addr:
return (ip_save(value, ctx, snmpd.trap1addr));
+
+ case LEAF_begemotSnmpdVersionEnable:
+ if (community != COMM_INITIALIZE)
+ return (SNMP_ERR_NOT_WRITEABLE);
+ ctx->scratch->int1 = snmpd.version_enable;
+ if (value->v.uint32 == 0 ||
+ (value->v.uint32 & ~VERS_ENABLE_ALL))
+ return (SNMP_ERR_WRONG_VALUE);
+ snmpd.version_enable = value->v.uint32;
+ return (SNMP_ERR_NOERROR);
}
abort();
@@ -613,6 +626,9 @@ op_snmpd_config(struct snmp_context *ctx, struct snmp_value *value,
case LEAF_begemotSnmpdTrap1Addr:
ip_rollback(ctx, snmpd.trap1addr);
return (SNMP_ERR_NOERROR);
+ case LEAF_begemotSnmpdVersionEnable:
+ snmpd.version_enable = ctx->scratch->int1;
+ return (SNMP_ERR_NOERROR);
}
abort();
@@ -626,6 +642,8 @@ op_snmpd_config(struct snmp_context *ctx, struct snmp_value *value,
case LEAF_begemotSnmpdTrap1Addr:
ip_commit(ctx);
return (SNMP_ERR_NOERROR);
+ case LEAF_begemotSnmpdVersionEnable:
+ return (SNMP_ERR_NOERROR);
}
abort();
}
@@ -703,203 +721,6 @@ op_community(struct snmp_context *ctx, struct snmp_value *value,
}
/*
- * Port table
- */
-int
-op_snmp_port(struct snmp_context *ctx, struct snmp_value *value,
- u_int sub, u_int iidx, enum snmp_op op)
-{
- asn_subid_t which = value->var.subs[sub-1];
- struct snmp_port *p;
- u_int8_t addr[4];
- u_int32_t port;
-
- switch (op) {
-
- case SNMP_OP_GETNEXT:
- if ((p = NEXT_OBJECT_OID(&snmp_port_list, &value->var, sub))
- == NULL)
- return (SNMP_ERR_NOSUCHNAME);
- index_append(&value->var, sub, &p->index);
- break;
-
- case SNMP_OP_GET:
- if ((p = FIND_OBJECT_OID(&snmp_port_list, &value->var, sub))
- == NULL)
- return (SNMP_ERR_NOSUCHNAME);
- break;
-
- case SNMP_OP_SET:
- p = FIND_OBJECT_OID(&snmp_port_list, &value->var, sub);
- ctx->scratch->int1 = (p != NULL);
-
- if (which != LEAF_begemotSnmpdPortStatus)
- abort();
- if (!TRUTH_OK(value->v.integer))
- return (SNMP_ERR_WRONG_VALUE);
-
- ctx->scratch->int2 = TRUTH_GET(value->v.integer);
-
- if (ctx->scratch->int2) {
- /* open an SNMP port */
- if (p != NULL)
- /* already open - do nothing */
- return (SNMP_ERR_NOERROR);
-
- if (index_decode(&value->var, sub, iidx, addr, &port))
- return (SNMP_ERR_NO_CREATION);
- return (open_snmp_port(addr, port, &p));
-
- } else {
- /* close SNMP port - do in commit */
- }
- return (SNMP_ERR_NOERROR);
-
- case SNMP_OP_ROLLBACK:
- p = FIND_OBJECT_OID(&snmp_port_list, &value->var, sub);
- if (ctx->scratch->int1 == 0) {
- /* did not exist */
- if (ctx->scratch->int2 == 1) {
- /* created */
- if (p != NULL)
- close_snmp_port(p);
- }
- }
- return (SNMP_ERR_NOERROR);
-
- case SNMP_OP_COMMIT:
- p = FIND_OBJECT_OID(&snmp_port_list, &value->var, sub);
- if (ctx->scratch->int1 == 1) {
- /* did exist */
- if (ctx->scratch->int2 == 0) {
- /* delete */
- if (p != NULL)
- close_snmp_port(p);
- }
- }
- return (SNMP_ERR_NOERROR);
-
- default:
- abort();
- }
-
- /*
- * Come here to fetch the value
- */
- switch (which) {
-
- case LEAF_begemotSnmpdPortStatus:
- value->v.integer = 1;
- break;
-
- default:
- abort();
- }
-
- return (SNMP_ERR_NOERROR);
-}
-
-/*
- * Local port table
- */
-int
-op_local_port(struct snmp_context *ctx, struct snmp_value *value,
- u_int sub, u_int iidx, enum snmp_op op)
-{
- asn_subid_t which = value->var.subs[sub-1];
- struct local_port *p;
- u_char *name;
- size_t namelen;
-
- switch (op) {
-
- case SNMP_OP_GETNEXT:
- if ((p = NEXT_OBJECT_OID(&local_port_list, &value->var, sub))
- == NULL)
- return (SNMP_ERR_NOSUCHNAME);
- index_append(&value->var, sub, &p->index);
- break;
-
- case SNMP_OP_GET:
- if ((p = FIND_OBJECT_OID(&local_port_list, &value->var, sub))
- == NULL)
- return (SNMP_ERR_NOSUCHNAME);
- break;
-
- case SNMP_OP_SET:
- p = FIND_OBJECT_OID(&local_port_list, &value->var, sub);
- ctx->scratch->int1 = (p != NULL);
-
- if (which != LEAF_begemotSnmpdLocalPortStatus)
- abort();
- if (!TRUTH_OK(value->v.integer))
- return (SNMP_ERR_WRONG_VALUE);
-
- ctx->scratch->int2 = TRUTH_GET(value->v.integer);
-
- if (ctx->scratch->int2) {
- /* open a local port */
- if (p != NULL)
- /* already open - do nothing */
- return (SNMP_ERR_NOERROR);
-
- if (index_decode(&value->var, sub, iidx,
- &name, &namelen))
- return (SNMP_ERR_NO_CREATION);
- return (open_local_port(name, namelen, &p));
-
- } else {
- /* close local port - do in commit */
- }
- return (SNMP_ERR_NOERROR);
-
- case SNMP_OP_ROLLBACK:
- p = FIND_OBJECT_OID(&local_port_list, &value->var, sub);
- if (ctx->scratch->int1 == 0) {
- /* did not exist */
- if (ctx->scratch->int2 == 1) {
- /* created */
- if (p != NULL)
- close_local_port(p);
- }
- }
- return (SNMP_ERR_NOERROR);
-
- case SNMP_OP_COMMIT:
- p = FIND_OBJECT_OID(&local_port_list, &value->var, sub);
- if (ctx->scratch->int1 == 1) {
- /* did exist */
- if (ctx->scratch->int2 == 0) {
- /* delete */
- if (p != NULL)
- close_local_port(p);
- }
- }
- return (SNMP_ERR_NOERROR);
-
- default:
- abort();
- }
-
- /*
- * Come here to fetch the value
- */
- switch (which) {
-
- case LEAF_begemotSnmpdLocalPortStatus:
- value->v.integer = 1;
- break;
-
- default:
- abort();
- }
-
- return (SNMP_ERR_NOERROR);
-}
-
-
-
-/*
* Module table.
*/
struct module_dep {
@@ -1143,3 +964,79 @@ op_snmp_set(struct snmp_context *ctx __unused, struct snmp_value *value,
}
abort();
}
+
+/*
+ * Transport table
+ */
+int
+op_transport_table(struct snmp_context *ctx __unused, struct snmp_value *value,
+ u_int sub, u_int iidx, enum snmp_op op)
+{
+ asn_subid_t which = value->var.subs[sub - 1];
+ struct transport *t;
+ u_char *tname, *ptr;
+ size_t tnamelen;
+
+ switch (op) {
+
+ case SNMP_OP_GETNEXT:
+ if ((t = NEXT_OBJECT_OID(&transport_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(&transport_list, &value->var, sub))
+ == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ break;
+
+ case SNMP_OP_SET:
+ t = FIND_OBJECT_OID(&transport_list, &value->var, sub);
+ if (which != LEAF_begemotSnmpdTransportStatus) {
+ if (t == NULL)
+ return (SNMP_ERR_NO_CREATION);
+ return (SNMP_ERR_NOT_WRITEABLE);
+ }
+
+ /* the errors in the next few statements can only happen when
+ * t is NULL, hence the NO_CREATION error. */
+ if (index_decode(&value->var, sub, iidx,
+ &tname, &tnamelen))
+ return (SNMP_ERR_NO_CREATION);
+
+ /* check the section name */
+ if (tnamelen >= TRANS_NAMELEN || tnamelen == 0) {
+ free(tname);
+ return (SNMP_ERR_NO_CREATION);
+ }
+ for (ptr = tname; ptr < tname + tnamelen; ptr++) {
+ if (!isascii(*ptr) || !isalnum(*ptr)) {
+ free(tname);
+ return (SNMP_ERR_NO_CREATION);
+ }
+ }
+
+ /* for now */
+ return (SNMP_ERR_NOT_WRITEABLE);
+
+ case SNMP_OP_ROLLBACK:
+ case SNMP_OP_COMMIT:
+ return (SNMP_ERR_NOERROR);
+ default:
+ abort();
+ }
+
+ switch (which) {
+
+ case LEAF_begemotSnmpdTransportStatus:
+ value->v.integer = 1;
+ break;
+
+ case LEAF_begemotSnmpdTransportOid:
+ memcpy(&value->v.oid, &t->vtab->id, sizeof(t->vtab->id));
+ break;
+ }
+ return (SNMP_ERR_NOERROR);
+}
diff --git a/contrib/bsnmp/snmpd/bsnmpd.1 b/contrib/bsnmp/snmpd/bsnmpd.1
index 01c7a1c52e99..334ac1891a15 100644
--- a/contrib/bsnmp/snmpd/bsnmpd.1
+++ b/contrib/bsnmp/snmpd/bsnmpd.1
@@ -30,7 +30,7 @@
.\" 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 $
+.\" $Begemot: bsnmp/snmpd/bsnmpd.1,v 1.1 2003/12/03 10:08:33 hbb Exp $
.\"
.Dd August 15, 2002
.Dt SNMPD 1
diff --git a/contrib/bsnmp/snmpd/config.c b/contrib/bsnmp/snmpd/config.c
index e247797ff69e..4001156276f1 100644
--- a/contrib/bsnmp/snmpd/config.c
+++ b/contrib/bsnmp/snmpd/config.c
@@ -30,7 +30,7 @@
* 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/config.c,v 1.18 2003/03/11 15:30:01 hbb Exp $
+ * $Begemot: bsnmp/snmpd/config.c,v 1.19 2003/12/03 10:08:47 hbb Exp $
*
* Parse configuration file.
*/
diff --git a/contrib/bsnmp/snmpd/export.c b/contrib/bsnmp/snmpd/export.c
index 4cebdb330b10..12a981a2be4d 100644
--- a/contrib/bsnmp/snmpd/export.c
+++ b/contrib/bsnmp/snmpd/export.c
@@ -30,7 +30,7 @@
* 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 $
+ * $Begemot: bsnmp/snmpd/export.c,v 1.6 2003/12/03 10:08:47 hbb Exp $
*
* Support functions for modules.
*/
diff --git a/contrib/bsnmp/snmpd/main.c b/contrib/bsnmp/snmpd/main.c
index 1568b4b34c89..1a528ac44991 100644
--- a/contrib/bsnmp/snmpd/main.c
+++ b/contrib/bsnmp/snmpd/main.c
@@ -30,13 +30,13 @@
* 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/main.c,v 1.76 2003/01/28 13:44:35 hbb Exp $
+ * $Begemot: bsnmp/snmpd/main.c,v 1.82 2003/12/09 12:28:52 hbb Exp $
*
* SNMPd main stuff.
*/
#include <sys/param.h>
#include <sys/un.h>
-#include <sys/stat.h>
+#include <sys/ucred.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
@@ -49,8 +49,6 @@
#include <signal.h>
#include <dlfcn.h>
#include <inttypes.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
#include "snmpmod.h"
#include "snmpd.h"
@@ -82,6 +80,7 @@ struct snmpd snmpd = {
0, /* comm_dis */
0, /* auth_traps */
{0, 0, 0, 0}, /* trap1addr */
+ VERS_ENABLE_ALL,/* version_enable */
};
struct snmpd_stats snmpd_stats;
@@ -126,20 +125,14 @@ static int nprogargs;
u_int community;
static struct community *comm;
-/* list of all IP ports we are listening on */
-struct snmp_port_list snmp_port_list =
- TAILQ_HEAD_INITIALIZER(snmp_port_list);
-
-/* list of all local ports we are listening on */
-struct local_port_list local_port_list =
- TAILQ_HEAD_INITIALIZER(local_port_list);
-
/* file names */
static char config_file[MAXPATHLEN + 1];
static char pid_file[MAXPATHLEN + 1];
+#ifndef USE_LIBBEGEMOT
/* event context */
static evContext evctx;
+#endif
/* signal mask */
static sigset_t blocked_sigs;
@@ -178,6 +171,12 @@ options:\n\
-p file specify pid file\n\
";
+/* transports */
+extern const struct transport_def udp_trans;
+extern const struct transport_def lsock_trans;
+
+struct transport_list transport_list = TAILQ_HEAD_INITIALIZER(transport_list);
+
/* forward declarations */
static void snmp_printf_func(const char *fmt, ...);
static void snmp_error_func(const char *err, ...);
@@ -192,7 +191,7 @@ buf_alloc(int tx)
{
void *buf;
- if ((buf = malloc(tx ? snmpd.txbuf : (snmpd.rxbuf + 1))) == NULL) {
+ if ((buf = malloc(tx ? snmpd.txbuf : snmpd.rxbuf)) == NULL) {
syslog(LOG_CRIT, "cannot allocate buffer");
if (tx)
snmpd_stats.noTxbuf++;
@@ -204,19 +203,19 @@ buf_alloc(int tx)
}
/*
- * Return the buffer size. (one more for RX).
+ * Return the buffer size.
*/
size_t
buf_size(int tx)
{
- return (tx ? snmpd.txbuf : (snmpd.rxbuf + 1));
+ return (tx ? snmpd.txbuf : snmpd.rxbuf);
}
/*
* Prepare a PDU for output
*/
void
-snmp_output(struct snmp_v1_pdu *pdu, u_char *sndbuf, size_t *sndlen,
+snmp_output(struct snmp_pdu *pdu, u_char *sndbuf, size_t *sndlen,
const char *dest)
{
struct asn_buf resp_b;
@@ -236,55 +235,36 @@ snmp_output(struct snmp_v1_pdu *pdu, u_char *sndbuf, size_t *sndlen,
}
/*
- * Send a PDU to a given port
- */
-void
-snmp_send_port(const struct asn_oid *port, struct snmp_v1_pdu *pdu,
- const struct sockaddr *addr, socklen_t addrlen)
-{
- struct snmp_port *p;
- u_char *sndbuf;
- size_t sndlen;
- ssize_t len;
-
- TAILQ_FOREACH(p, &snmp_port_list, link)
- if (asn_compare_oid(port, &p->index) == 0)
- break;
-
- if (p == 0)
- return;
-
- if ((sndbuf = buf_alloc(1)) == NULL)
- return;
-
- snmp_output(pdu, sndbuf, &sndlen, "SNMP PROXY");
-
- if ((len = sendto(p->sock, sndbuf, sndlen, 0, addr, addrlen)) == -1)
- syslog(LOG_ERR, "sendto: %m");
- else if ((size_t)len != sndlen)
- syslog(LOG_ERR, "sendto: short write %zu/%zu",
- sndlen, (size_t)len);
-
- free(sndbuf);
-}
-
-/*
* SNMP input. Start: decode the PDU, find the community.
*/
enum snmpd_input_err
snmp_input_start(const u_char *buf, size_t len, const char *source,
- struct snmp_v1_pdu *pdu, int32_t *ip)
+ struct snmp_pdu *pdu, int32_t *ip, size_t *pdulen)
{
struct asn_buf b;
enum snmp_code code;
enum snmpd_input_err ret;
-
- snmpd_stats.inPkts++;
+ int sret;
b.asn_cptr = buf;
b.asn_len = len;
+
+ /* look whether we have enough bytes for the entire PDU. */
+ switch (sret = snmp_pdu_snoop(&b)) {
+
+ case 0:
+ return (SNMPD_INPUT_TRUNC);
+
+ case -1:
+ snmpd_stats.inASNParseErrs++;
+ return (SNMPD_INPUT_FAILED);
+ }
+ b.asn_len = *pdulen = (size_t)sret;
+
code = snmp_pdu_decode(&b, pdu, ip);
+ snmpd_stats.inPkts++;
+
ret = SNMPD_INPUT_OK;
switch (code) {
@@ -293,6 +273,7 @@ snmp_input_start(const u_char *buf, size_t len, const char *source,
return (SNMPD_INPUT_FAILED);
case SNMP_CODE_BADVERS:
+ bad_vers:
snmpd_stats.inBadVersions++;
return (SNMPD_INPUT_FAILED);
@@ -312,6 +293,21 @@ snmp_input_start(const u_char *buf, size_t len, const char *source,
break;
case SNMP_CODE_OK:
+ switch (pdu->version) {
+
+ case SNMP_V1:
+ if (!(snmpd.version_enable & VERS_ENABLE_V1))
+ goto bad_vers;
+ break;
+
+ case SNMP_V2c:
+ if (!(snmpd.version_enable & VERS_ENABLE_V2C))
+ goto bad_vers;
+ break;
+
+ case SNMP_Verr:
+ goto bad_vers;
+ }
break;
}
@@ -449,13 +445,143 @@ snmp_input_finish(struct snmp_pdu *pdu, const u_char *rcvbuf, size_t rcvlen,
abort();
}
+/*
+ * Insert a port into the right place in the transport's table of ports
+ */
+void
+trans_insert_port(struct transport *t, struct tport *port)
+{
+ struct tport *p;
+
+ TAILQ_FOREACH(p, &t->table, link) {
+ if (asn_compare_oid(&p->index, &port->index) > 0) {
+ TAILQ_INSERT_BEFORE(p, port, link);
+ return;
+ }
+ }
+ port->transport = t;
+ TAILQ_INSERT_TAIL(&t->table, port, link);
+}
+
+/*
+ * Remove a port from a transport's list
+ */
+void
+trans_remove_port(struct tport *port)
+{
+
+ TAILQ_REMOVE(&port->transport->table, port, link);
+}
+
+/*
+ * Find a port on a transport's list
+ */
+struct tport *
+trans_find_port(struct transport *t, const struct asn_oid *idx, u_int sub)
+{
+
+ return (FIND_OBJECT_OID(&t->table, idx, sub));
+}
+
+/*
+ * Find next port on a transport's list
+ */
+struct tport *
+trans_next_port(struct transport *t, const struct asn_oid *idx, u_int sub)
+{
+
+ return (NEXT_OBJECT_OID(&t->table, idx, sub));
+}
+
+/*
+ * Return first port
+ */
+struct tport *
+trans_first_port(struct transport *t)
+{
+
+ return (TAILQ_FIRST(&t->table));
+}
+
+/*
+ * Iterate through all ports until a function returns a 0.
+ */
+struct tport *
+trans_iter_port(struct transport *t, int (*func)(struct tport *, intptr_t),
+ intptr_t arg)
+{
+ struct tport *p;
+
+ TAILQ_FOREACH(p, &t->table, link)
+ if (func(p, arg) == 0)
+ return (p);
+ return (NULL);
+}
+
+/*
+ * Register a transport
+ */
+int
+trans_register(const struct transport_def *def, struct transport **pp)
+{
+ u_int i;
+ char or_descr[256];
+
+ if ((*pp = malloc(sizeof(**pp))) == NULL)
+ return (SNMP_ERR_GENERR);
+
+ /* construct index */
+ (*pp)->index.len = strlen(def->name) + 1;
+ (*pp)->index.subs[0] = strlen(def->name);
+ for (i = 0; i < (*pp)->index.subs[0]; i++)
+ (*pp)->index.subs[i + 1] = def->name[i];
+
+ (*pp)->vtab = def;
+
+ if (FIND_OBJECT_OID(&transport_list, &(*pp)->index, 0) != NULL) {
+ free(*pp);
+ return (SNMP_ERR_INCONS_VALUE);
+ }
+
+ /* register module */
+ snprintf(or_descr, sizeof(or_descr), "%s transport mapping", def->name);
+ if (((*pp)->or_index = or_register(&def->id, or_descr, NULL)) == 0) {
+ free(*pp);
+ return (SNMP_ERR_GENERR);
+ }
+
+ INSERT_OBJECT_OID((*pp), &transport_list);
+
+ TAILQ_INIT(&(*pp)->table);
+
+ return (SNMP_ERR_NOERROR);
+}
+
+/*
+ * Unregister transport
+ */
+int
+trans_unregister(struct transport *t)
+{
+ if (!TAILQ_EMPTY(&t->table))
+ return (SNMP_ERR_INCONS_VALUE);
+
+ or_unregister(t->or_index);
+ TAILQ_REMOVE(&transport_list, t, link);
+ return (SNMP_ERR_NOERROR);
+}
/*
* File descriptor support
*/
+#ifdef USE_LIBBEGEMOT
+static void
+input(int fd, int mask __unused, void *uap)
+#else
static void
input(evContext ctx __unused, void *uap, int fd, int mask __unused)
+#endif
{
struct fdesc *f = uap;
@@ -467,10 +593,17 @@ fd_suspend(void *p)
{
struct fdesc *f = p;
+#ifdef USE_LIBBEGEMOT
+ if (f->id >= 0) {
+ poll_unregister(f->id);
+ f->id = -1;
+ }
+#else
if (evTestID(f->id)) {
(void)evDeselectFD(evctx, f->id);
evInitID(&f->id);
}
+#endif
}
int
@@ -479,6 +612,16 @@ fd_resume(void *p)
struct fdesc *f = p;
int err;
+#ifdef USE_LIBBEGEMOT
+ if (f->id >= 0)
+ return (0);
+ if ((f->fd = poll_register(f->fd, input, f, POLL_IN)) < 0) {
+ err = errno;
+ syslog(LOG_ERR, "select fd %d: %m", f->fd);
+ errno = err;
+ return (-1);
+ }
+#else
if (evTestID(f->id))
return (0);
if (evSelectFD(evctx, f->fd, EV_READ, input, f, &f->id)) {
@@ -487,6 +630,7 @@ fd_resume(void *p)
errno = err;
return (-1);
}
+#endif
return (0);
}
@@ -506,7 +650,11 @@ fd_select(int fd, void (*func)(int, void *), void *udata, struct lmodule *mod)
f->func = func;
f->udata = udata;
f->owner = mod;
+#ifdef USE_LIBBEGEMOT
+ f->id = -1;
+#else
evInitID(&f->id);
+#endif
if (fd_resume(f)) {
err = errno;
@@ -542,56 +690,237 @@ fd_flush(struct lmodule *mod)
fd_deselect(t);
t = t1;
}
-
}
-
/*
- * Input from UDP socket
+ * Consume a message from the input buffer
*/
static void
-do_input(int fd, const struct asn_oid *port_index,
- struct sockaddr *ret, socklen_t *retlen)
+snmp_input_consume(struct port_input *pi)
{
- u_char *resbuf, embuf[100];
- u_char *sndbuf;
- size_t sndlen;
- ssize_t len;
- struct snmp_v1_pdu pdu;
- enum snmpd_input_err ierr, ferr;
- enum snmpd_proxy_err perr;
- int32_t vi;
-
- if ((resbuf = buf_alloc(0)) == NULL) {
- (void)recvfrom(fd, embuf, sizeof(embuf), 0, ret, retlen);
+ if (!pi->stream) {
+ /* always consume everything */
+ pi->length = 0;
return;
}
- if ((len = recvfrom(fd, resbuf, buf_size(0), 0, ret, retlen)) == -1) {
- free(resbuf);
+ if (pi->consumed >= pi->length) {
+ /* all bytes consumed */
+ pi->length = 0;
return;
}
- if (len == 0) {
- free(resbuf);
+ memmove(pi->buf, pi->buf + pi->consumed, pi->length - pi->consumed);
+ pi->length -= pi->consumed;
+}
+
+struct credmsg {
+ struct cmsghdr hdr;
+ struct cmsgcred cred;
+};
+
+static void
+check_priv(struct port_input *pi, struct msghdr *msg)
+{
+ struct credmsg *cmsg;
+ struct xucred ucred;
+ socklen_t ucredlen;
+
+ pi->priv = 0;
+
+ if (msg->msg_controllen == sizeof(*cmsg)) {
+ /* process explicitely sends credentials */
+
+ cmsg = (struct credmsg *)msg->msg_control;
+ pi->priv = (cmsg->cred.cmcred_euid == 0);
return;
}
- if ((size_t)len == buf_size(0)) {
- free(resbuf);
+
+ /* ok, obtain the accept time credentials */
+ ucredlen = sizeof(ucred);
+
+ if (getsockopt(pi->fd, 0, LOCAL_PEERCRED, &ucred, &ucredlen) == 0 &&
+ ucredlen >= sizeof(ucred) && ucred.cr_version == XUCRED_VERSION)
+ pi->priv = (ucred.cr_uid == 0);
+}
+
+/*
+ * Input from a stream socket.
+ */
+static int
+recv_stream(struct port_input *pi)
+{
+ struct msghdr msg;
+ struct iovec iov[1];
+ ssize_t len;
+ struct credmsg cmsg;
+
+ if (pi->buf == NULL) {
+ /* no buffer yet - allocate one */
+ if ((pi->buf = buf_alloc(0)) == NULL) {
+ /* ups - could not get buffer. Return an error
+ * the caller must close the transport. */
+ return (-1);
+ }
+ pi->buflen = buf_size(0);
+ pi->consumed = 0;
+ pi->length = 0;
+ }
+
+ /* try to get a message */
+ msg.msg_name = pi->peer;
+ msg.msg_namelen = pi->peerlen;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ if (pi->cred) {
+ msg.msg_control = &cmsg;
+ msg.msg_controllen = sizeof(cmsg);
+
+ cmsg.hdr.cmsg_len = sizeof(cmsg);
+ cmsg.hdr.cmsg_level = SOL_SOCKET;
+ cmsg.hdr.cmsg_type = SCM_CREDS;
+ } else {
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ }
+ msg.msg_flags = 0;
+
+ iov[0].iov_base = pi->buf + pi->length;
+ iov[0].iov_len = pi->buflen - pi->length;
+
+ len = recvmsg(pi->fd, &msg, 0);
+
+ if (len == -1 || len == 0)
+ /* receive error */
+ return (-1);
+
+ pi->length += len;
+
+ if (pi->cred)
+ check_priv(pi, &msg);
+
+ return (0);
+}
+
+/*
+ * Input from a datagram socket.
+ * Each receive should return one datagram.
+ */
+static int
+recv_dgram(struct port_input *pi)
+{
+ u_char embuf[1000];
+ struct msghdr msg;
+ struct iovec iov[1];
+ ssize_t len;
+ struct credmsg cmsg;
+
+ if (pi->buf == NULL) {
+ /* no buffer yet - allocate one */
+ if ((pi->buf = buf_alloc(0)) == NULL) {
+ /* ups - could not get buffer. Read away input
+ * and drop it */
+ (void)recvfrom(pi->fd, embuf, sizeof(embuf),
+ 0, NULL, NULL);
+ /* return error */
+ return (-1);
+ }
+ pi->buflen = buf_size(0);
+ }
+
+ /* try to get a message */
+ msg.msg_name = pi->peer;
+ msg.msg_namelen = pi->peerlen;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ if (pi->cred) {
+ msg.msg_control = &cmsg;
+ msg.msg_controllen = sizeof(cmsg);
+
+ cmsg.hdr.cmsg_len = sizeof(cmsg);
+ cmsg.hdr.cmsg_level = SOL_SOCKET;
+ cmsg.hdr.cmsg_type = SCM_CREDS;
+ } else {
+ msg.msg_control = NULL;
+ msg.msg_controllen = NULL;
+ }
+ msg.msg_flags = 0;
+
+ iov[0].iov_base = pi->buf;
+ iov[0].iov_len = pi->buflen;
+
+ len = recvmsg(pi->fd, &msg, 0);
+
+ if (len == -1 || len == 0)
+ /* receive error */
+ return (-1);
+
+ if (msg.msg_flags & MSG_TRUNC) {
+ /* truncated - drop */
snmpd_stats.silentDrops++;
snmpd_stats.inTooLong++;
- return;
+ return (-1);
}
+ pi->length = (size_t)len;
+
+ if (pi->cred)
+ check_priv(pi, &msg);
+
+ return (0);
+}
+
+/*
+ * Input from a socket
+ */
+int
+snmpd_input(struct port_input *pi, struct tport *tport)
+{
+ u_char *sndbuf;
+ size_t sndlen;
+ struct snmp_pdu pdu;
+ enum snmpd_input_err ierr, ferr;
+ enum snmpd_proxy_err perr;
+ int32_t vi;
+ int ret;
+ ssize_t slen;
+
+ /* get input depending on the transport */
+ if (pi->stream) {
+ ret = recv_stream(pi);
+ } else {
+ ret = recv_dgram(pi);
+ }
+
+ if (ret == -1)
+ return (-1);
+
/*
* Handle input
*/
- ierr = snmp_input_start(resbuf, (size_t)len, "SNMP", &pdu, &vi);
+ ierr = snmp_input_start(pi->buf, pi->length, "SNMP", &pdu, &vi,
+ &pi->consumed);
+ if (ierr == SNMPD_INPUT_TRUNC) {
+ /* need more bytes. This is ok only for streaming transports.
+ * but only if we have not reached bufsiz yet. */
+ if (pi->stream) {
+ if (pi->length == buf_size(0)) {
+ snmpd_stats.silentDrops++;
+ return (-1);
+ }
+ return (0);
+ }
+ snmpd_stats.silentDrops++;
+ return (-1);
+ }
/* can't check for bad SET pdus here, because a proxy may have to
* check the access first. We don't want to return an error response
* to a proxy PDU with a wrong community */
if (ierr == SNMPD_INPUT_FAILED) {
- free(resbuf);
- return;
+ /* for streaming transports this is fatal */
+ if (pi->stream)
+ return (-1);
+ snmp_input_consume(pi);
+ return (0);
}
/*
@@ -599,41 +928,41 @@ do_input(int fd, const struct asn_oid *port_index,
* the hand it over to the module.
*/
if (comm->owner != NULL && comm->owner->config->proxy != NULL) {
- perr = (*comm->owner->config->proxy)(&pdu, port_index,
- ret, *retlen, ierr, vi);
+ perr = (*comm->owner->config->proxy)(&pdu, tport->transport,
+ &tport->index, pi->peer, pi->peerlen, ierr, vi, pi->priv);
switch (perr) {
case SNMPD_PROXY_OK:
- free(resbuf);
- return;
+ snmp_input_consume(pi);
+ return (0);
case SNMPD_PROXY_REJ:
break;
case SNMPD_PROXY_DROP:
- free(resbuf);
+ snmp_input_consume(pi);
snmp_pdu_free(&pdu);
snmpd_stats.proxyDrops++;
- return;
+ return (0);
case SNMPD_PROXY_BADCOMM:
- free(resbuf);
+ snmp_input_consume(pi);
snmp_pdu_free(&pdu);
snmpd_stats.inBadCommunityNames++;
if (snmpd.auth_traps)
snmp_send_trap(&oid_authenticationFailure,
NULL);
- return;
+ return (0);
case SNMPD_PROXY_BADCOMMUSE:
- free(resbuf);
+ snmp_input_consume(pi);
snmp_pdu_free(&pdu);
snmpd_stats.inBadCommunityUses++;
if (snmpd.auth_traps)
snmp_send_trap(&oid_authenticationFailure,
NULL);
- return;
+ return (0);
}
}
@@ -646,21 +975,22 @@ do_input(int fd, const struct asn_oid *port_index,
snmpd_stats.silentDrops++;
snmpd_stats.inBadPduTypes++;
snmp_pdu_free(&pdu);
- free(resbuf);
- return;
+ snmp_input_consume(pi);
+ return (0);
}
/*
* Check community
*/
- if (community != COMM_WRITE &&
- (pdu.type == SNMP_PDU_SET || community != COMM_READ)) {
+ if ((pi->cred && !pi->priv && pdu.type == SNMP_PDU_SET) ||
+ (community != COMM_WRITE &&
+ (pdu.type == SNMP_PDU_SET || community != COMM_READ))) {
snmpd_stats.inBadCommunityUses++;
snmp_pdu_free(&pdu);
- free(resbuf);
+ snmp_input_consume(pi);
if (snmpd.auth_traps)
snmp_send_trap(&oid_authenticationFailure, NULL);
- return;
+ return (0);
}
/*
@@ -669,271 +999,87 @@ do_input(int fd, const struct asn_oid *port_index,
if ((sndbuf = buf_alloc(1)) == NULL) {
snmpd_stats.silentDrops++;
snmp_pdu_free(&pdu);
- free(resbuf);
- return;
+ snmp_input_consume(pi);
+ return (0);
}
- ferr = snmp_input_finish(&pdu, resbuf, len, sndbuf, &sndlen, "SNMP",
- ierr, vi, NULL);
+ ferr = snmp_input_finish(&pdu, pi->buf, pi->length,
+ sndbuf, &sndlen, "SNMP", ierr, vi, NULL);
if (ferr == SNMPD_INPUT_OK) {
- if ((len = sendto(fd, sndbuf, sndlen, 0, ret, *retlen)) == -1)
+ slen = sendto(pi->fd, sndbuf, sndlen, 0, pi->peer, pi->peerlen);
+ if (slen == -1)
syslog(LOG_ERR, "sendto: %m");
- else if ((size_t)len != sndlen)
+ else if ((size_t)slen != sndlen)
syslog(LOG_ERR, "sendto: short write %zu/%zu",
- sndlen, (size_t)len);
+ sndlen, (size_t)slen);
}
snmp_pdu_free(&pdu);
free(sndbuf);
- free(resbuf);
-}
+ snmp_input_consume(pi);
-static void
-ssock_input(int fd, void *udata)
-{
- struct snmp_port *p = udata;
-
- p->retlen = sizeof(p->ret);
- do_input(fd, &p->index, (struct sockaddr *)&p->ret, &p->retlen);
-}
-
-static void
-lsock_input(int fd, void *udata)
-{
- struct local_port *p = udata;
-
- p->retlen = sizeof(p->ret);
- do_input(fd, &p->index, (struct sockaddr *)&p->ret, &p->retlen);
-}
-
-
-/*
- * Create a UDP socket and bind it to the given port
- */
-static int
-init_snmp(struct snmp_port *p)
-{
- struct sockaddr_in addr;
- u_int32_t ip;
-
- if ((p->sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
- syslog(LOG_ERR, "creating UDP socket: %m");
- return (SNMP_ERR_RES_UNAVAIL);
- }
- ip = (p->addr[0] << 24) | (p->addr[1] << 16) | (p->addr[2] << 8) |
- p->addr[3];
- memset(&addr, 0, sizeof(addr));
- addr.sin_addr.s_addr = htonl(ip);
- addr.sin_port = htons(p->port);
- addr.sin_family = AF_INET;
- addr.sin_len = sizeof(addr);
- if (bind(p->sock, (struct sockaddr *)&addr, sizeof(addr))) {
- if (errno == EADDRNOTAVAIL) {
- close(p->sock);
- p->sock = -1;
- return (SNMP_ERR_INCONS_NAME);
- }
- syslog(LOG_ERR, "bind: %s:%u %m", inet_ntoa(addr.sin_addr),
- p->port);
- close(p->sock);
- p->sock = -1;
- return (SNMP_ERR_GENERR);
- }
- if ((p->id = fd_select(p->sock, ssock_input, p, NULL)) == NULL) {
- close(p->sock);
- p->sock = -1;
- return (SNMP_ERR_GENERR);
- }
- return (SNMP_ERR_NOERROR);
+ return (0);
}
-
/*
- * Create a new SNMP Port object and start it, if we are not
- * in initialisation mode. The arguments are in host byte order.
+ * Send a PDU to a given port
*/
-int
-open_snmp_port(u_int8_t *addr, u_int32_t port, struct snmp_port **pp)
+void
+snmp_send_port(void *targ, const struct asn_oid *port, struct snmp_pdu *pdu,
+ const struct sockaddr *addr, socklen_t addrlen)
{
- struct snmp_port *snmp, *p;
- int err;
-
- if (port > 0xffff)
- return (SNMP_ERR_NO_CREATION);
- if ((snmp = malloc(sizeof(*snmp))) == NULL)
- return (SNMP_ERR_GENERR);
- snmp->addr[0] = addr[0];
- snmp->addr[1] = addr[1];
- snmp->addr[2] = addr[2];
- snmp->addr[3] = addr[3];
- snmp->port = port;
- snmp->sock = -1;
- snmp->id = NULL;
- snmp->index.len = 5;
- snmp->index.subs[0] = addr[0];
- snmp->index.subs[1] = addr[1];
- snmp->index.subs[2] = addr[2];
- snmp->index.subs[3] = addr[3];
- snmp->index.subs[4] = port;
+ struct transport *trans = targ;
+ struct tport *tp;
+ u_char *sndbuf;
+ size_t sndlen;
+ ssize_t len;
- /*
- * Insert it into the right place
- */
- TAILQ_FOREACH(p, &snmp_port_list, link) {
- if (asn_compare_oid(&p->index, &snmp->index) > 0) {
- TAILQ_INSERT_BEFORE(p, snmp, link);
+ TAILQ_FOREACH(tp, &trans->table, link)
+ if (asn_compare_oid(port, &tp->index) == 0)
break;
- }
- }
- if (p == NULL)
- TAILQ_INSERT_TAIL(&snmp_port_list, snmp, link);
-
- if (community != COMM_INITIALIZE &&
- (err = init_snmp(snmp)) != SNMP_ERR_NOERROR) {
- TAILQ_REMOVE(&snmp_port_list, snmp, link);
- free(snmp);
- return (err);
- }
- *pp = snmp;
- return (SNMP_ERR_NOERROR);
-}
-
-/*
- * Close an SNMP port
- */
-void
-close_snmp_port(struct snmp_port *snmp)
-{
- if (snmp->id != NULL)
- fd_deselect(snmp->id);
- if (snmp->sock >= 0)
- (void)close(snmp->sock);
+ if (tp == 0)
+ return;
- TAILQ_REMOVE(&snmp_port_list, snmp, link);
- free(snmp);
-}
+ if ((sndbuf = buf_alloc(1)) == NULL)
+ return;
-/*
- * Create a local socket
- */
-static int
-init_local(struct local_port *p)
-{
- struct sockaddr_un sa;
+ snmp_output(pdu, sndbuf, &sndlen, "SNMP PROXY");
- if ((p->sock = socket(PF_LOCAL, SOCK_DGRAM, 0)) < 0) {
- syslog(LOG_ERR, "creating local socket: %m");
- return (SNMP_ERR_RES_UNAVAIL);
- }
- strcpy(sa.sun_path, p->name);
- sa.sun_family = AF_LOCAL;
- sa.sun_len = strlen(p->name) + offsetof(struct sockaddr_un, sun_path);
+ len = trans->vtab->send(tp, sndbuf, sndlen, addr, addrlen);
- (void)remove(p->name);
+ if (len == -1)
+ syslog(LOG_ERR, "sendto: %m");
+ else if ((size_t)len != sndlen)
+ syslog(LOG_ERR, "sendto: short write %zu/%zu",
+ sndlen, (size_t)len);
- if (bind(p->sock, (struct sockaddr *)&sa, sizeof(sa))) {
- if (errno == EADDRNOTAVAIL) {
- close(p->sock);
- p->sock = -1;
- return (SNMP_ERR_INCONS_NAME);
- }
- syslog(LOG_ERR, "bind: %s %m", p->name);
- close(p->sock);
- p->sock = -1;
- return (SNMP_ERR_GENERR);
- }
- if (chmod(p->name, 0666) == -1)
- syslog(LOG_WARNING, "chmod(%s,0666): %m", p->name);
- if ((p->id = fd_select(p->sock, lsock_input, p, NULL)) == NULL) {
- (void)remove(p->name);
- close(p->sock);
- p->sock = -1;
- return (SNMP_ERR_GENERR);
- }
- return (SNMP_ERR_NOERROR);
+ free(sndbuf);
}
/*
- * Open a local port
- */
-int
-open_local_port(u_char *name, size_t namelen, struct local_port **pp)
-{
- struct local_port *port, *p;
- size_t u;
- int err;
- struct sockaddr_un sa;
-
- if (namelen == 0 || namelen + 1 > sizeof(sa.sun_path)) {
- free(name);
- return (SNMP_ERR_BADVALUE);
- }
- if ((port = malloc(sizeof(*port))) == NULL) {
- free(name);
- return (SNMP_ERR_GENERR);
- }
- if ((port->name = malloc(namelen + 1)) == NULL) {
- free(name);
- free(port);
- return (SNMP_ERR_GENERR);
- }
- strncpy(port->name, name, namelen);
- port->name[namelen] = '\0';
-
- port->sock = -1;
- port->id = NULL;
- port->index.len = namelen + 1;
- port->index.subs[0] = namelen;
- for (u = 0; u < namelen; u++)
- port->index.subs[u + 1] = name[u];
-
- /*
- * Insert it into the right place
- */
- TAILQ_FOREACH(p, &local_port_list, link) {
- if (asn_compare_oid(&p->index, &port->index) > 0) {
- TAILQ_INSERT_BEFORE(p, port, link);
- break;
- }
- }
- if (p == NULL)
- TAILQ_INSERT_TAIL(&local_port_list, port, link);
-
- if (community != COMM_INITIALIZE &&
- (err = init_local(port)) != SNMP_ERR_NOERROR) {
- TAILQ_REMOVE(&local_port_list, port, link);
- free(port->name);
- free(port);
- return (err);
- }
-
- *pp = p;
-
- return (SNMP_ERR_NOERROR);
-}
-
-/*
- * Close a local port
+ * Close an input source
*/
void
-close_local_port(struct local_port *port)
+snmpd_input_close(struct port_input *pi)
{
- if (port->id != NULL)
- fd_deselect(port->id);
- if (port->sock >= 0)
- (void)close(port->sock);
- (void)remove(port->name);
-
- TAILQ_REMOVE(&local_port_list, port, link);
- free(port->name);
- free(port);
+ if (pi->id != NULL)
+ fd_deselect(pi->id);
+ if (pi->fd >= 0)
+ (void)close(pi->fd);
+ if (pi->buf != NULL)
+ free(pi->buf);
}
/*
* Dump internal state.
*/
+#ifdef USE_LIBBEGEMOT
+static void
+info_func(void)
+#else
static void
info_func(evContext ctx __unused, void *uap __unused, const void *tag __unused)
+#endif
{
struct lmodule *m;
u_int i;
@@ -964,9 +1110,14 @@ info_func(evContext ctx __unused, void *uap __unused, const void *tag __unused)
/*
* Re-read configuration
*/
+#ifdef USE_LIBBEGEMOT
+static void
+config_func(void)
+#else
static void
config_func(evContext ctx __unused, void *uap __unused,
const void *tag __unused)
+#endif
{
struct lmodule *m;
@@ -985,26 +1136,24 @@ config_func(evContext ctx __unused, void *uap __unused,
static void
onusr1(int s __unused)
{
+
work |= WORK_DOINFO;
}
static void
onhup(int s __unused)
{
+
work |= WORK_RECONFIG;
}
static void
onterm(int s __unused)
{
- struct local_port *p;
-
- TAILQ_FOREACH(p, &local_port_list, link)
- (void)remove(p->name);
+ /* allow clean-up */
exit(0);
}
-
static void
init_sigs(void)
{
@@ -1066,6 +1215,15 @@ term(void)
(void)unlink(pid_file);
}
+static void
+trans_stop(void)
+{
+ struct transport *t;
+
+ TAILQ_FOREACH(t, &transport_list, link)
+ (void)t->vtab->stop(1);
+}
+
/*
* Define a macro from the command line
*/
@@ -1130,7 +1288,7 @@ getsubopt1(char **arg, const char *const *options, char **valp, char **optp)
*arg = ptr;
for (i = 0; *options != NULL; options++, i++)
- if (strcmp(suboptarg, *options) == 0)
+ if (strcmp(*optp, *options) == 0)
return (i);
return (-1);
}
@@ -1141,11 +1299,11 @@ main(int argc, char *argv[])
int opt;
FILE *fp;
int background = 1;
- struct snmp_port *p;
- struct local_port *pl;
+ struct tport *p;
const char *prefix = "snmpd";
struct lmodule *m;
char *value, *option;
+ struct transport *t;
#define DBG_DUMP 0
#define DBG_EVENTS 1
@@ -1268,22 +1426,40 @@ main(int argc, char *argv[])
snprintf(config_file, sizeof(config_file), PATH_CONFIG, prefix);
init_actvals();
+
+ start_tick = get_ticks();
+ this_tick = get_ticks();
+
+ /* start transports */
+ if (atexit(trans_stop) == -1) {
+ syslog(LOG_ERR, "atexit failed: %m");
+ exit(1);
+ }
+ if (udp_trans.start() != SNMP_ERR_NOERROR)
+ syslog(LOG_WARNING, "cannot start UDP transport");
+ if (lsock_trans.start() != SNMP_ERR_NOERROR)
+ syslog(LOG_WARNING, "cannot start LSOCK transport");
+
if (read_config(config_file, NULL)) {
syslog(LOG_ERR, "error in config file");
exit(1);
}
+#ifdef USE_LIBBEGEMOT
+ if (debug.evdebug > 0)
+ rpoll_trace = 1;
+#else
if (evCreate(&evctx)) {
syslog(LOG_ERR, "evCreate: %m");
exit(1);
}
if (debug.evdebug > 0)
evSetDebug(evctx, 10, stderr);
+#endif
- TAILQ_FOREACH(p, &snmp_port_list, link)
- (void)init_snmp(p);
- TAILQ_FOREACH(pl, &local_port_list, link)
- (void)init_local(pl);
+ TAILQ_FOREACH(t, &transport_list, link)
+ TAILQ_FOREACH(p, &t->table, link)
+ t->vtab->init_port(p);
init_sigs();
@@ -1293,12 +1469,13 @@ main(int argc, char *argv[])
if ((fp = fopen(pid_file, "w")) != NULL) {
fprintf(fp, "%u", getpid());
fclose(fp);
- atexit(term);
+ if (atexit(term) == -1) {
+ syslog(LOG_ERR, "atexit failed: %m");
+ (void)remove(pid_file);
+ exit(0);
+ }
}
- start_tick = get_ticks();
- this_tick = get_ticks();
-
if (or_register(&oid_snmpMIB, "The MIB module for SNMPv2 entities.",
NULL) == 0) {
syslog(LOG_ERR, "cannot register SNMPv2 MIB");
@@ -1319,13 +1496,16 @@ main(int argc, char *argv[])
}
for (;;) {
+#ifndef USE_LIBBEGEMOT
evEvent event;
+#endif
struct lmodule *mod;
TAILQ_FOREACH(mod, &lmodules, link)
if (mod->config->idle != NULL)
(*mod->config->idle)();
+#ifndef USE_LIBBEGEMOT
if (evGetNext(evctx, &event, EV_WAIT) == 0) {
if (evDispatch(evctx, event))
syslog(LOG_ERR, "evDispatch: %m");
@@ -1333,29 +1513,42 @@ main(int argc, char *argv[])
syslog(LOG_ERR, "evGetNext: %m");
exit(1);
}
+#else
+ poll_dispatch(1);
+#endif
if (work != 0) {
block_sigs();
if (work & WORK_DOINFO) {
+#ifdef USE_LIBBEGEMOT
+ info_func();
+#else
if (evWaitFor(evctx, &work, info_func,
NULL, NULL) == -1) {
syslog(LOG_ERR, "evWaitFor: %m");
exit(1);
}
+#endif
}
if (work & WORK_RECONFIG) {
+#ifdef USE_LIBBEGEMOT
+ config_func();
+#else
if (evWaitFor(evctx, &work, config_func,
NULL, NULL) == -1) {
syslog(LOG_ERR, "evWaitFor: %m");
exit(1);
}
+#endif
}
work = 0;
unblock_sigs();
+#ifndef USE_LIBBEGEMOT
if (evDo(evctx, &work) == -1) {
syslog(LOG_ERR, "evDo: %m");
exit(1);
}
+#endif
}
}
@@ -1377,9 +1570,14 @@ get_ticks()
/*
* Timer support
*/
+#ifdef USE_LIBBEGEMOT
+static void
+tfunc(int tid __unused, void *uap)
+#else
static void
tfunc(evContext ctx __unused, void *uap, struct timespec due __unused,
struct timespec inter __unused)
+#endif
{
struct timer *tp = uap;
@@ -1395,14 +1593,28 @@ void *
timer_start(u_int ticks, void (*func)(void *), void *udata, struct lmodule *mod)
{
struct timer *tp;
+#ifdef USE_LIBBEGEMOT
+ struct timeval due;
+#else
struct timespec due;
+#endif
if ((tp = malloc(sizeof(struct timer))) == NULL) {
syslog(LOG_CRIT, "out of memory for timer");
exit(1);
}
+#ifdef USE_LIBBEGEMOT
+ (void)gettimeofday(&due, NULL);
+ due.tv_sec += ticks / 100;
+ due.tv_usec += (ticks % 100) * 10000;
+ if (due.tv_usec >= 1000000) {
+ due.tv_sec++;
+ due.tv_usec -= 1000000;
+ }
+#else
due = evAddTime(evNowTime(),
- evConsTime(ticks / 100, (ticks % 100) * 10000));
+ evConsTime(ticks / 100, (ticks % 100) * 10000));
+#endif
tp->udata = udata;
tp->owner = mod;
@@ -1410,11 +1622,19 @@ timer_start(u_int ticks, void (*func)(void *), void *udata, struct lmodule *mod)
LIST_INSERT_HEAD(&timer_list, tp, link);
+#ifdef USE_LIBBEGEMOT
+ if ((tp->id = poll_start_timer(due.tv_sec * 1000 + due.tv_usec / 1000,
+ 0, tfunc, tp)) < 0) {
+ syslog(LOG_ERR, "cannot set timer: %m");
+ exit(1);
+ }
+#else
if (evSetTimer(evctx, tfunc, tp, due, evConsTime(0, 0), &tp->id)
== -1) {
syslog(LOG_ERR, "cannot set timer: %m");
exit(1);
}
+#endif
return (tp);
}
@@ -1424,10 +1644,14 @@ timer_stop(void *p)
struct timer *tp = p;
LIST_REMOVE(tp, link);
+#ifdef USE_LIBBEGEMOT
+ poll_stop_timer(tp->id);
+#else
if (evClearTimer(evctx, tp->id) == -1) {
syslog(LOG_ERR, "cannot stop timer: %m");
exit(1);
}
+#endif
free(p);
}
@@ -1488,10 +1712,13 @@ snmp_error_func(const char *err, ...)
char errbuf[1000];
va_list ap;
+ if (!(snmp_trace & LOG_SNMP_ERRORS))
+ return;
+
va_start(ap, err);
snprintf(errbuf, sizeof(errbuf), "SNMP: ");
- vsnprintf(errbuf+strlen(errbuf), sizeof(errbuf)-strlen(errbuf),
- err, ap);
+ vsnprintf(errbuf + strlen(errbuf),
+ sizeof(errbuf) - strlen(errbuf), err, ap);
va_end(ap);
syslog(LOG_ERR, "%s", errbuf);
@@ -1519,18 +1746,22 @@ asn_error_func(const struct asn_buf *b, const char *err, ...)
va_list ap;
u_int i;
+ if (!(snmp_trace & LOG_ASN1_ERRORS))
+ return;
+
va_start(ap, err);
snprintf(errbuf, sizeof(errbuf), "ASN.1: ");
- vsnprintf(errbuf+strlen(errbuf), sizeof(errbuf)-strlen(errbuf),
- err, ap);
+ vsnprintf(errbuf + strlen(errbuf),
+ sizeof(errbuf) - strlen(errbuf), err, ap);
va_end(ap);
if (b != NULL) {
- snprintf(errbuf+strlen(errbuf), sizeof(errbuf)-strlen(errbuf),
- " at");
+ snprintf(errbuf + strlen(errbuf),
+ sizeof(errbuf) - strlen(errbuf), " at");
for (i = 0; b->asn_len > i; i++)
- snprintf(errbuf+strlen(errbuf),
- sizeof(errbuf)-strlen(errbuf), " %02x", b->asn_cptr[i]);
+ snprintf(errbuf + strlen(errbuf),
+ sizeof(errbuf) - strlen(errbuf),
+ " %02x", b->asn_cptr[i]);
}
syslog(LOG_ERR, "%s", errbuf);
diff --git a/contrib/bsnmp/snmpd/snmpd.config b/contrib/bsnmp/snmpd/snmpd.config
index 128b020132e7..3b2e2f578f61 100644
--- a/contrib/bsnmp/snmpd/snmpd.config
+++ b/contrib/bsnmp/snmpd/snmpd.config
@@ -30,7 +30,7 @@
# 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 $
+# $Begemot: bsnmp/snmpd/snmpd.config,v 1.12 2003/12/03 10:08:47 hbb Exp $
#
# Example configuration file.
#
diff --git a/contrib/bsnmp/snmpd/snmpd.h b/contrib/bsnmp/snmpd/snmpd.h
index 5c8e78f4a459..d8cf5a16c3e4 100644
--- a/contrib/bsnmp/snmpd/snmpd.h
+++ b/contrib/bsnmp/snmpd/snmpd.h
@@ -30,15 +30,24 @@
* 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 $
+ * $Begemot: bsnmp/snmpd/snmpd.h,v 1.23 2003/12/09 12:28:53 hbb Exp $
*
* Private SNMPd data and functions.
*/
#include <sys/queue.h>
+#ifdef USE_LIBBEGEMOT
+#include <rpoll.h>
+#else
#include <isc/eventlib.h>
+#endif
#define PATH_SYSCONFIG "/etc:/usr/etc:/usr/local/etc"
+#ifdef USE_LIBBEGEMOT
+#define evTimerID int
+#define evFileID int
+#endif
+
/*************************************************************
*
* Communities
@@ -140,43 +149,80 @@ void lm_start(struct lmodule *);
*
* SNMP ports
*/
-struct snmp_port {
- u_int8_t addr[4];/* host byteorder */
- u_int16_t port; /* host byteorder */
+/*
+ * Common input stuff
+ */
+struct port_input {
+ int fd; /* socket */
+ void *id; /* evSelect handle */
- int sock; /* the socket */
- void * id; /* evSelect handle */
+ int stream : 1; /* stream socket */
+ int cred : 1; /* want credentials */
- struct sockaddr_in ret; /* the return address */
- socklen_t retlen; /* length of that address */
+ struct sockaddr *peer; /* last received packet */
+ socklen_t peerlen;
+ int priv : 1; /* peer is privileged */
- TAILQ_ENTRY(snmp_port) link;
+ u_char *buf; /* receive buffer */
+ size_t buflen; /* buffer length */
+ size_t length; /* received length */
+ size_t consumed; /* how many bytes used */
+};
- struct asn_oid index;
+struct tport {
+ struct asn_oid index; /* table index of this tp point */
+ TAILQ_ENTRY(tport) link; /* table link */
+ struct transport *transport; /* who handles this */
};
-TAILQ_HEAD(snmp_port_list, snmp_port);
-extern struct snmp_port_list snmp_port_list;
+TAILQ_HEAD(tport_list, tport);
-void close_snmp_port(struct snmp_port *);
-int open_snmp_port(u_int8_t *, u_int32_t, struct snmp_port **);
+int snmpd_input(struct port_input *, struct tport *);
+void snmpd_input_close(struct port_input *);
-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 */
+/*
+ * Transport domain
+ */
+#define TRANS_NAMELEN 64
- TAILQ_ENTRY(local_port) link;
+struct transport_def {
+ const char *name; /* name of this transport */
+ struct asn_oid id; /* OBJID of this transport */
- struct asn_oid index;
+ int (*start)(void);
+ int (*stop)(int);
+
+ void (*close_port)(struct tport *);
+ int (*init_port)(struct tport *);
+
+ ssize_t (*send)(struct tport *, const u_char *, size_t,
+ const struct sockaddr *, size_t);
};
-TAILQ_HEAD(local_port_list, local_port);
-extern struct local_port_list local_port_list;
+struct transport {
+ struct asn_oid index; /* transport table index */
+ TAILQ_ENTRY(transport) link; /* ... and link */
+ u_int or_index; /* registration index */
+
+ struct tport_list table; /* list of open ports */
+
+ const struct transport_def *vtab;
+};
+
+TAILQ_HEAD(transport_list, transport);
+extern struct transport_list transport_list;
-void close_local_port(struct local_port *);
-int open_local_port(u_char *, size_t, struct local_port **);
+void trans_insert_port(struct transport *, struct tport *);
+void trans_remove_port(struct tport *);
+struct tport *trans_find_port(struct transport *,
+ const struct asn_oid *, u_int);
+struct tport *trans_next_port(struct transport *,
+ const struct asn_oid *, u_int);
+struct tport *trans_first_port(struct transport *);
+struct tport *trans_iter_port(struct transport *,
+ int (*)(struct tport *, intptr_t), intptr_t);
+
+int trans_register(const struct transport_def *, struct transport **);
+int trans_unregister(struct transport *);
/*************************************************************
*
@@ -197,9 +243,16 @@ struct snmpd {
/* source address for V1 traps */
u_char trap1addr[4];
+
+ /* version enable flags */
+ uint32_t version_enable;
};
extern struct snmpd snmpd;
+#define VERS_ENABLE_V1 0x00000001
+#define VERS_ENABLE_V2C 0x00000002
+#define VERS_ENABLE_ALL 0x00000003
+
/*
* The debug group
*/
@@ -275,3 +328,6 @@ 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);
+
+#define LOG_ASN1_ERRORS 0x10000000
+#define LOG_SNMP_ERRORS 0x20000000
diff --git a/contrib/bsnmp/snmpd/snmpd.sh b/contrib/bsnmp/snmpd/snmpd.sh
index 86ec962d0159..3cd6d51da7f0 100755
--- a/contrib/bsnmp/snmpd/snmpd.sh
+++ b/contrib/bsnmp/snmpd/snmpd.sh
@@ -31,7 +31,7 @@
# 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 $
+# $Begemot: bsnmp/snmpd/snmpd.sh,v 1.2 2003/12/03 10:08:47 hbb Exp $
#
# SNMPd startup script
#
diff --git a/contrib/bsnmp/snmpd/snmpmod.3 b/contrib/bsnmp/snmpd/snmpmod.3
index 143d12d2fab8..be0136c89402 100644
--- a/contrib/bsnmp/snmpd/snmpmod.3
+++ b/contrib/bsnmp/snmpd/snmpmod.3
@@ -30,7 +30,7 @@
.\" 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 $
+.\" $Begemot: bsnmp/snmpd/snmpmod.3,v 1.5 2003/12/08 16:55:58 hbb Exp $
.\"
.Dd August 16, 2002
.Dt snmpmod 3
@@ -166,7 +166,7 @@ Begemot SNMP library
.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"
+ "struct snmp_pdu *pdu" "int32_t *ip" "size_t *pdulen"
.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" \
@@ -175,8 +175,8 @@ Begemot SNMP library
.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"
+.Fn snmp_send_port "void *trans" "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
@@ -245,7 +245,7 @@ a global symbol
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 *,
+typedef enum snmpd_proxy_err (*proxy_err_f)(struct snmp_pdu *, void *,
const struct asn_oid *, const struct sockaddr *, socklen_t,
enum snmpd_input_err, int32_t);
@@ -657,6 +657,12 @@ 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.
+.It Er SNMPD_INPUT_TRUNC
+The buffer appears to contain a valid begin of a PDU, but is too short.
+For streaming transports this means that the caller must save what he
+already has and trying to obtain more input and reissue this input to
+the function. For datagram transports this means that part of the
+datagram was lost and the input should be ignored.
.El
.Pp
The function
@@ -680,7 +686,7 @@ takes a PDU and encodes it.
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.
+the transport and the index in the port table) to the given address.
.Pp
The function
.Fn snmp_send_trap
diff --git a/contrib/bsnmp/snmpd/snmpmod.h b/contrib/bsnmp/snmpd/snmpmod.h
index 5e4cbbd32838..2f262415521a 100644
--- a/contrib/bsnmp/snmpd/snmpmod.h
+++ b/contrib/bsnmp/snmpd/snmpmod.h
@@ -30,7 +30,7 @@
* 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 $
+ * $Begemot: bsnmp/snmpd/snmpmod.h,v 1.25 2003/12/08 16:55:58 hbb Exp $
*
* SNMP daemon data and functions exported to modules.
*/
@@ -199,6 +199,8 @@ enum snmpd_input_err {
SNMPD_INPUT_VALRANGE,
/* value has bad encoding */
SNMPD_INPUT_VALBADENC,
+ /* need more data (truncated packet) */
+ SNMPD_INPUT_TRUNC,
};
/*
@@ -228,9 +230,9 @@ struct snmp_module {
void (*start)(void);
/* proxy a PDU */
- enum snmpd_proxy_err (*proxy)(struct snmp_v1_pdu *,
+ enum snmpd_proxy_err (*proxy)(struct snmp_pdu *, void *,
const struct asn_oid *, const struct sockaddr *, socklen_t,
- enum snmpd_input_err, int32_t);
+ enum snmpd_input_err, int32_t, int);
/* the tree this module is going to server */
const struct snmp_node *tree;
@@ -320,15 +322,15 @@ 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 *);
+ struct snmp_pdu *, int32_t *, size_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 *,
+void snmp_output(struct snmp_pdu *, u_char *, size_t *, const char *);
+void snmp_send_port(void *, const struct asn_oid *, struct snmp_pdu *,
const struct sockaddr *, socklen_t);
/* sending traps */
diff --git a/contrib/bsnmp/snmpd/trans_lsock.c b/contrib/bsnmp/snmpd/trans_lsock.c
new file mode 100644
index 000000000000..1e0da59f4573
--- /dev/null
+++ b/contrib/bsnmp/snmpd/trans_lsock.c
@@ -0,0 +1,611 @@
+/*
+ * Copyright (c) 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/trans_lsock.c,v 1.3 2003/12/09 12:28:53 hbb Exp $
+ *
+ * Local domain socket transport
+ */
+#include <sys/types.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <syslog.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "snmpmod.h"
+#include "snmpd.h"
+#include "trans_lsock.h"
+#include "tree.h"
+#include "oid.h"
+
+static const struct asn_oid
+ oid_begemotSnmpdLocalPortTable = OIDX_begemotSnmpdLocalPortTable;
+
+static int lsock_start(void);
+static int lsock_stop(int);
+static void lsock_close_port(struct tport *);
+static int lsock_init_port(struct tport *);
+static ssize_t lsock_send(struct tport *, const u_char *, size_t,
+ const struct sockaddr *, size_t);
+
+/* exported */
+const struct transport_def lsock_trans = {
+ "lsock",
+ OIDX_begemotSnmpdTransLsock,
+ lsock_start,
+ lsock_stop,
+ lsock_close_port,
+ lsock_init_port,
+ lsock_send
+};
+static struct transport *my_trans;
+
+static int
+lsock_remove(struct tport *tp, intptr_t arg __unused)
+{
+ struct lsock_port *port = (struct lsock_port *)tp;
+
+ (void)remove(port->name);
+
+ return (-1);
+}
+
+static int
+lsock_stop(int force)
+{
+
+ if (my_trans != NULL) {
+ if (!force && trans_first_port(my_trans) != NULL)
+ return (SNMP_ERR_GENERR);
+ trans_iter_port(my_trans, lsock_remove, NULL);
+ return (trans_unregister(my_trans));
+ }
+ return (SNMP_ERR_NOERROR);
+}
+
+static int
+lsock_start(void)
+{
+ return (trans_register(&lsock_trans, &my_trans));
+}
+
+/*
+ * Open a local port. If this is a datagram socket create also the
+ * one and only peer.
+ */
+static int
+lsock_open_port(u_char *name, size_t namelen, struct lsock_port **pp,
+ int type)
+{
+ struct lsock_port *port;
+ struct lsock_peer *peer = NULL;
+ int is_stream, need_cred;
+ size_t u;
+ int err;
+ struct sockaddr_un sa;
+
+ if (namelen == 0 || namelen + 1 > sizeof(sa.sun_path)) {
+ free(name);
+ return (SNMP_ERR_BADVALUE);
+ }
+ switch (type) {
+ case LOCP_DGRAM_UNPRIV:
+ is_stream = 0;
+ need_cred = 0;
+ break;
+
+ case LOCP_DGRAM_PRIV:
+ is_stream = 0;
+ need_cred = 1;
+ break;
+
+ case LOCP_STREAM_UNPRIV:
+ is_stream = 1;
+ need_cred = 0;
+ break;
+
+ case LOCP_STREAM_PRIV:
+ is_stream = 1;
+ need_cred = 1;
+ break;
+
+ default:
+ free(name);
+ return (SNMP_ERR_BADVALUE);
+ }
+
+ if ((port = malloc(sizeof(*port))) == NULL) {
+ free(name);
+ return (SNMP_ERR_GENERR);
+ }
+ memset(port, 0, sizeof(*port));
+ if (!is_stream) {
+ if ((peer = malloc(sizeof(*peer))) == NULL) {
+ free(name);
+ free(port);
+ return (SNMP_ERR_GENERR);
+ }
+ memset(peer, 0, sizeof(*peer));
+ }
+ if ((port->name = malloc(namelen + 1)) == NULL) {
+ free(name);
+ free(port);
+ if (!is_stream)
+ free(peer);
+ return (SNMP_ERR_GENERR);
+ }
+ strncpy(port->name, name, namelen);
+ port->name[namelen] = '\0';
+
+ port->type = type;
+ port->str_sock = -1;
+ LIST_INIT(&port->peers);
+
+ port->tport.index.len = namelen + 1;
+ port->tport.index.subs[0] = namelen;
+ for (u = 0; u < namelen; u++)
+ port->tport.index.subs[u + 1] = name[u];
+
+ if (peer != NULL) {
+ LIST_INSERT_HEAD(&port->peers, peer, link);
+
+ peer->port = port;
+
+ peer->input.fd = -1;
+ peer->input.id = NULL;
+ peer->input.stream = is_stream;
+ peer->input.cred = need_cred;
+ peer->input.peer = (struct sockaddr *)&peer->peer;
+ }
+
+ trans_insert_port(my_trans, &port->tport);
+
+ if (community != COMM_INITIALIZE &&
+ (err = lsock_init_port(&port->tport)) != SNMP_ERR_NOERROR) {
+ lsock_close_port(&port->tport);
+ return (err);
+ }
+
+ *pp = port;
+
+ return (SNMP_ERR_NOERROR);
+}
+
+/*
+ * Close a local domain peer
+ */
+static void
+lsock_peer_close(struct lsock_peer *peer)
+{
+
+ LIST_REMOVE(peer, link);
+ snmpd_input_close(&peer->input);
+ free(peer);
+}
+
+/*
+ * Close a local port
+ */
+static void
+lsock_close_port(struct tport *tp)
+{
+ struct lsock_port *port = (struct lsock_port *)tp;
+ struct lsock_peer *peer;
+
+ if (port->str_id != NULL)
+ fd_deselect(port->str_id);
+ if (port->str_sock >= 0)
+ (void)close(port->str_sock);
+ (void)remove(port->name);
+
+ trans_remove_port(tp);
+
+ while ((peer = LIST_FIRST(&port->peers)) != NULL)
+ lsock_peer_close(peer);
+
+ free(port->name);
+ free(port);
+}
+
+/*
+ * Input on a local socket (either datagram or stream)
+ */
+static void
+lsock_input(int fd __unused, void *udata)
+{
+ struct lsock_peer *peer = udata;
+ struct lsock_port *p = peer->port;
+
+ peer->input.peerlen = sizeof(peer->peer);
+ if (snmpd_input(&peer->input, &p->tport) == -1 && peer->input.stream)
+ /* framing or other input error */
+ lsock_peer_close(peer);
+}
+
+/*
+ * A UNIX domain listening socket is ready. This means we have a peer
+ * that we need to accept
+ */
+static void
+lsock_listen_input(int fd, void *udata)
+{
+ struct lsock_port *p = udata;
+ struct lsock_peer *peer;
+
+ if ((peer = malloc(sizeof(*peer))) == NULL) {
+ syslog(LOG_WARNING, "%s: peer malloc failed", p->name);
+ (void)close(accept(fd, NULL, NULL));
+ return;
+ }
+ memset(peer, 0, sizeof(*peer));
+
+ peer->port = p;
+
+ peer->input.stream = 1;
+ peer->input.cred = (p->type == LOCP_DGRAM_PRIV ||
+ p->type == LOCP_STREAM_PRIV);
+ peer->input.peerlen = sizeof(peer->peer);
+ peer->input.peer = (struct sockaddr *)&peer->peer;
+
+ peer->input.fd = accept(fd, peer->input.peer, &peer->input.peerlen);
+ if (peer->input.fd == -1) {
+ syslog(LOG_WARNING, "%s: accept failed: %m", p->name);
+ free(peer);
+ return;
+ }
+
+ if ((peer->input.id = fd_select(peer->input.fd, lsock_input,
+ peer, NULL)) == NULL) {
+ close(peer->input.fd);
+ free(peer);
+ return;
+ }
+
+ LIST_INSERT_HEAD(&p->peers, peer, link);
+}
+
+/*
+ * Create a local socket
+ */
+static int
+lsock_init_port(struct tport *tp)
+{
+ struct lsock_port *p = (struct lsock_port *)tp;
+ struct sockaddr_un sa;
+
+ if (p->type == LOCP_STREAM_PRIV || p->type == LOCP_STREAM_UNPRIV) {
+ if ((p->str_sock = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0) {
+ syslog(LOG_ERR, "creating local socket: %m");
+ return (SNMP_ERR_RES_UNAVAIL);
+ }
+
+ strcpy(sa.sun_path, p->name);
+ sa.sun_family = AF_LOCAL;
+ sa.sun_len = strlen(p->name) +
+ offsetof(struct sockaddr_un, sun_path);
+
+ (void)remove(p->name);
+
+ if (bind(p->str_sock, (struct sockaddr *)&sa, sizeof(sa))) {
+ if (errno == EADDRNOTAVAIL) {
+ close(p->str_sock);
+ p->str_sock = -1;
+ return (SNMP_ERR_INCONS_NAME);
+ }
+ syslog(LOG_ERR, "bind: %s %m", p->name);
+ close(p->str_sock);
+ p->str_sock = -1;
+ return (SNMP_ERR_GENERR);
+ }
+ if (chmod(p->name, 0666) == -1)
+ syslog(LOG_WARNING, "chmod(%s,0666): %m", p->name);
+
+ if (listen(p->str_sock, 10) == -1) {
+ syslog(LOG_ERR, "listen: %s %m", p->name);
+ (void)remove(p->name);
+ close(p->str_sock);
+ p->str_sock = -1;
+ return (SNMP_ERR_GENERR);
+ }
+
+ p->str_id = fd_select(p->str_sock, lsock_listen_input, p, NULL);
+ if (p->str_id == NULL) {
+ (void)remove(p->name);
+ close(p->str_sock);
+ p->str_sock = -1;
+ return (SNMP_ERR_GENERR);
+ }
+ } else {
+ struct lsock_peer *peer;
+
+ peer = LIST_FIRST(&p->peers);
+
+ if ((peer->input.fd = socket(PF_LOCAL, SOCK_DGRAM, 0)) < 0) {
+ syslog(LOG_ERR, "creating local socket: %m");
+ return (SNMP_ERR_RES_UNAVAIL);
+ }
+
+ strcpy(sa.sun_path, p->name);
+ sa.sun_family = AF_LOCAL;
+ sa.sun_len = strlen(p->name) +
+ offsetof(struct sockaddr_un, sun_path);
+
+ (void)remove(p->name);
+
+ if (bind(peer->input.fd, (struct sockaddr *)&sa, sizeof(sa))) {
+ if (errno == EADDRNOTAVAIL) {
+ close(peer->input.fd);
+ peer->input.fd = -1;
+ return (SNMP_ERR_INCONS_NAME);
+ }
+ syslog(LOG_ERR, "bind: %s %m", p->name);
+ close(peer->input.fd);
+ peer->input.fd = -1;
+ return (SNMP_ERR_GENERR);
+ }
+ if (chmod(p->name, 0666) == -1)
+ syslog(LOG_WARNING, "chmod(%s,0666): %m", p->name);
+
+ peer->input.id = fd_select(peer->input.fd, lsock_input,
+ peer, NULL);
+ if (peer->input.id == NULL) {
+ (void)remove(p->name);
+ close(peer->input.fd);
+ peer->input.fd = -1;
+ return (SNMP_ERR_GENERR);
+ }
+ }
+ return (SNMP_ERR_NOERROR);
+}
+
+/*
+ * Send something
+ */
+static ssize_t
+lsock_send(struct tport *tp, const u_char *buf, size_t len,
+ const struct sockaddr *addr, size_t addrlen)
+{
+ struct lsock_port *p = (struct lsock_port *)tp;
+ struct lsock_peer *peer;
+
+ if (p->type == LOCP_DGRAM_PRIV || p->type == LOCP_DGRAM_UNPRIV) {
+ peer = LIST_FIRST(&p->peers);
+
+ } else {
+ /* search for the peer */
+ LIST_FOREACH(peer, &p->peers, link)
+ if (peer->input.peerlen == addrlen &&
+ memcmp(peer->input.peer, addr, addrlen) == 0)
+ break;
+ if (peer == NULL) {
+ errno = ENOTCONN;
+ return (-1);
+ }
+ }
+
+ return (sendto(peer->input.fd, buf, len, 0, addr, addrlen));
+}
+
+/*
+ * Dependency to create a lsock port
+ */
+struct lsock_dep {
+ struct snmp_dependency dep;
+
+ /* index (path name) */
+ u_char *path;
+ size_t pathlen;
+
+ /* the port */
+ struct lsock_port *port;
+
+ /* which of the fields are set */
+ u_int set;
+
+ /* type of the port */
+ int type;
+
+ /* status */
+ int status;
+};
+#define LD_TYPE 0x01
+#define LD_STATUS 0x02
+#define LD_CREATE 0x04 /* rollback create */
+
+/*
+ * Finish handler for deleting a port - this cannot fail :-)
+ */
+static void
+lsock_del(struct snmp_context *ctx __unused, int fail, void *arg)
+{
+ struct lsock_dep *ld = (struct lsock_dep *)(void *)arg;
+
+ if (!fail)
+ lsock_close_port(&ld->port->tport);
+}
+
+/*
+ * dependency handler for lsock ports
+ */
+static int
+lsock_func(struct snmp_context *ctx, struct snmp_dependency *dep,
+ enum snmp_depop op)
+{
+ struct lsock_dep *ld = (struct lsock_dep *)(void *)dep;
+ int err = SNMP_ERR_NOERROR;
+
+ switch (op) {
+
+ case SNMP_DEPOP_COMMIT:
+ if (!(ld->set & LD_STATUS))
+ err = SNMP_ERR_BADVALUE;
+ else if (ld->port == NULL) {
+ if (!ld->status)
+ err = SNMP_ERR_BADVALUE;
+
+ else {
+ /* create */
+ err = lsock_open_port(ld->path, ld->pathlen,
+ &ld->port, ld->type);
+ if (err == SNMP_ERR_NOERROR)
+ ld->set |= LD_CREATE;
+ }
+ } else if (!ld->status) {
+ /* delete - hard to roll back so defer to
+ * finish handler */
+ if (snmp_set_atfinish(ctx, lsock_del, ld->port))
+ err = SNMP_ERR_RES_UNAVAIL;
+ } else
+ /* modify - read-only */
+ err = SNMP_ERR_READONLY;
+
+ free(ld->path);
+ ld->path = NULL;
+ return (err);
+
+ case SNMP_DEPOP_ROLLBACK:
+ if (ld->set & LD_CREATE) {
+ /* was create */
+ lsock_close_port(&ld->port->tport);
+ }
+ return (SNMP_ERR_NOERROR);
+ }
+ abort();
+}
+
+/*
+ * Local port table
+ */
+int
+op_lsock_port(struct snmp_context *ctx, struct snmp_value *value,
+ u_int sub, u_int iidx, enum snmp_op op)
+{
+ asn_subid_t which = value->var.subs[sub-1];
+ struct lsock_port *p;
+ u_char *name;
+ size_t namelen;
+ struct lsock_dep *ld;
+ struct asn_oid didx;
+
+ switch (op) {
+
+ case SNMP_OP_GETNEXT:
+ if ((p = (struct lsock_port *)trans_next_port(my_trans,
+ &value->var, sub)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ index_append(&value->var, sub, &p->tport.index);
+ break;
+
+ case SNMP_OP_GET:
+ if ((p = (struct lsock_port *)trans_find_port(my_trans,
+ &value->var, sub)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ break;
+
+ case SNMP_OP_SET:
+ p = (struct lsock_port *)trans_find_port(my_trans,
+ &value->var, sub);
+
+ if (index_decode(&value->var, sub, iidx, &name, &namelen))
+ return (SNMP_ERR_NO_CREATION);
+
+ asn_slice_oid(&didx, &value->var, sub, value->var.len);
+ if ((ld = (struct lsock_dep *)(void *)snmp_dep_lookup(ctx,
+ &oid_begemotSnmpdLocalPortTable, &didx, sizeof(*ld),
+ lsock_func)) == NULL) {
+ free(name);
+ return (SNMP_ERR_GENERR);
+ }
+
+ if (ld->path == NULL) {
+ ld->path = name;
+ ld->pathlen = namelen;
+ } else {
+ free(name);
+ }
+ ld->port = p;
+
+ switch (which) {
+
+ case LEAF_begemotSnmpdLocalPortStatus:
+ if (ld->set & LD_STATUS)
+ return (SNMP_ERR_INCONS_VALUE);
+ if (!TRUTH_OK(value->v.integer))
+ return (SNMP_ERR_WRONG_VALUE);
+
+ ld->status = TRUTH_GET(value->v.integer);
+ ld->set |= LD_STATUS;
+ break;
+
+ case LEAF_begemotSnmpdLocalPortType:
+ if (ld->set & LD_TYPE)
+ return (SNMP_ERR_INCONS_VALUE);
+ if (value->v.integer < 1 || value->v.integer > 4)
+ return (SNMP_ERR_WRONG_VALUE);
+
+ ld->type = value->v.integer;
+ ld->set |= LD_TYPE;
+ break;
+ }
+ return (SNMP_ERR_NOERROR);
+
+ case SNMP_OP_ROLLBACK:
+ case SNMP_OP_COMMIT:
+ return (SNMP_ERR_NOERROR);
+
+ default:
+ abort();
+ }
+
+ /*
+ * Come here to fetch the value
+ */
+ switch (which) {
+
+ case LEAF_begemotSnmpdLocalPortStatus:
+ value->v.integer = 1;
+ break;
+
+ case LEAF_begemotSnmpdLocalPortType:
+ value->v.integer = p->type;
+ break;
+
+ default:
+ abort();
+ }
+
+ return (SNMP_ERR_NOERROR);
+}
diff --git a/contrib/bsnmp/snmpd/trans_lsock.h b/contrib/bsnmp/snmpd/trans_lsock.h
new file mode 100644
index 000000000000..d32964c45ac7
--- /dev/null
+++ b/contrib/bsnmp/snmpd/trans_lsock.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 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/trans_lsock.h,v 1.2 2003/12/09 12:28:53 hbb Exp $
+ *
+ * Local domain socket transport
+ */
+
+enum locp {
+ LOCP_DGRAM_UNPRIV = 1,
+ LOCP_DGRAM_PRIV = 2,
+ LOCP_STREAM_UNPRIV = 3,
+ LOCP_STREAM_PRIV = 4,
+};
+struct lsock_peer {
+ LIST_ENTRY(lsock_peer) link;
+ struct port_input input;
+ struct sockaddr_un peer;
+ struct lsock_port *port; /* parent port */
+};
+
+struct lsock_port {
+ struct tport tport; /* must begin with this */
+
+ char *name; /* unix path name */
+ enum locp type; /* type of port */
+
+ int str_sock; /* stream socket */
+ void *str_id; /* select handle */
+
+ LIST_HEAD(, lsock_peer) peers;
+};
+
+extern const struct transport_def lsock_trans;
diff --git a/contrib/bsnmp/snmpd/trans_udp.c b/contrib/bsnmp/snmpd/trans_udp.c
new file mode 100644
index 000000000000..c55c4e1b5a30
--- /dev/null
+++ b/contrib/bsnmp/snmpd/trans_udp.c
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 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/trans_udp.c,v 1.3 2003/12/09 12:28:53 hbb Exp $
+ *
+ * UDP transport
+ */
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <syslog.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "snmpmod.h"
+#include "snmpd.h"
+#include "trans_udp.h"
+#include "tree.h"
+#include "oid.h"
+
+static int udp_start(void);
+static int udp_stop(int);
+static void udp_close_port(struct tport *);
+static int udp_init_port(struct tport *);
+static ssize_t udp_send(struct tport *, const u_char *, size_t,
+ const struct sockaddr *, size_t);
+
+/* exported */
+const struct transport_def udp_trans = {
+ "udp",
+ OIDX_begemotSnmpdTransUdp,
+ udp_start,
+ udp_stop,
+ udp_close_port,
+ udp_init_port,
+ udp_send
+};
+static struct transport *my_trans;
+
+static int
+udp_start(void)
+{
+ return (trans_register(&udp_trans, &my_trans));
+}
+
+static int
+udp_stop(int force __unused)
+{
+ if (my_trans != NULL)
+ if (trans_unregister(my_trans) != 0)
+ return (SNMP_ERR_GENERR);
+ return (SNMP_ERR_NOERROR);
+}
+
+/*
+ * A UDP port is ready
+ */
+static void
+udp_input(int fd __unused, void *udata)
+{
+ struct udp_port *p = udata;
+
+ p->input.peerlen = sizeof(p->ret);
+ snmpd_input(&p->input, &p->tport);
+}
+
+/*
+ * Create a UDP socket and bind it to the given port
+ */
+static int
+udp_init_port(struct tport *tp)
+{
+ struct udp_port *p = (struct udp_port *)tp;
+ struct sockaddr_in addr;
+ u_int32_t ip;
+
+ if ((p->input.fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
+ syslog(LOG_ERR, "creating UDP socket: %m");
+ return (SNMP_ERR_RES_UNAVAIL);
+ }
+ ip = (p->addr[0] << 24) | (p->addr[1] << 16) | (p->addr[2] << 8) |
+ p->addr[3];
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_addr.s_addr = htonl(ip);
+ addr.sin_port = htons(p->port);
+ addr.sin_family = AF_INET;
+ addr.sin_len = sizeof(addr);
+ if (bind(p->input.fd, (struct sockaddr *)&addr, sizeof(addr))) {
+ if (errno == EADDRNOTAVAIL) {
+ close(p->input.fd);
+ p->input.fd = -1;
+ return (SNMP_ERR_INCONS_NAME);
+ }
+ syslog(LOG_ERR, "bind: %s:%u %m", inet_ntoa(addr.sin_addr),
+ p->port);
+ close(p->input.fd);
+ p->input.fd = -1;
+ return (SNMP_ERR_GENERR);
+ }
+ if ((p->input.id = fd_select(p->input.fd, udp_input,
+ p, NULL)) == NULL) {
+ close(p->input.fd);
+ p->input.fd = -1;
+ return (SNMP_ERR_GENERR);
+ }
+ return (SNMP_ERR_NOERROR);
+}
+
+/*
+ * Create a new SNMP Port object and start it, if we are not
+ * in initialisation mode. The arguments are in host byte order.
+ */
+static int
+udp_open_port(u_int8_t *addr, u_int32_t udp_port, struct udp_port **pp)
+{
+ struct udp_port *port;
+ int err;
+
+ if (udp_port > 0xffff)
+ return (SNMP_ERR_NO_CREATION);
+ if ((port = malloc(sizeof(*port))) == NULL)
+ return (SNMP_ERR_GENERR);
+ memset(port, 0, sizeof(*port));
+
+ /* initialize common part */
+ port->tport.index.len = 5;
+ port->tport.index.subs[0] = addr[0];
+ port->tport.index.subs[1] = addr[1];
+ port->tport.index.subs[2] = addr[2];
+ port->tport.index.subs[3] = addr[3];
+ port->tport.index.subs[4] = udp_port;
+
+ port->addr[0] = addr[0];
+ port->addr[1] = addr[1];
+ port->addr[2] = addr[2];
+ port->addr[3] = addr[3];
+ port->port = udp_port;
+
+ port->input.fd = -1;
+ port->input.id = NULL;
+ port->input.stream = 0;
+ port->input.cred = 0;
+ port->input.peer = (struct sockaddr *)&port->ret;
+ port->input.peerlen = sizeof(port->ret);
+
+ trans_insert_port(my_trans, &port->tport);
+
+ if (community != COMM_INITIALIZE &&
+ (err = udp_init_port(&port->tport)) != SNMP_ERR_NOERROR) {
+ udp_close_port(&port->tport);
+ return (err);
+ }
+ *pp = port;
+ return (SNMP_ERR_NOERROR);
+}
+
+/*
+ * Close an SNMP port
+ */
+static void
+udp_close_port(struct tport *tp)
+{
+ struct udp_port *port = (struct udp_port *)tp;
+
+ snmpd_input_close(&port->input);
+ trans_remove_port(tp);
+ free(port);
+}
+
+/*
+ * Send something
+ */
+static ssize_t
+udp_send(struct tport *tp, const u_char *buf, size_t len,
+ const struct sockaddr *addr, size_t addrlen)
+{
+ struct udp_port *p = (struct udp_port *)tp;
+
+ return (sendto(p->input.fd, buf, len, 0, addr, addrlen));
+}
+
+/*
+ * Port table
+ */
+int
+op_snmp_port(struct snmp_context *ctx, struct snmp_value *value,
+ u_int sub, u_int iidx, enum snmp_op op)
+{
+ asn_subid_t which = value->var.subs[sub-1];
+ struct udp_port *p;
+ u_int8_t addr[4];
+ u_int32_t port;
+
+ switch (op) {
+
+ case SNMP_OP_GETNEXT:
+ if ((p = (struct udp_port *)trans_next_port(my_trans,
+ &value->var, sub)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ index_append(&value->var, sub, &p->tport.index);
+ break;
+
+ case SNMP_OP_GET:
+ if ((p = (struct udp_port *)trans_find_port(my_trans,
+ &value->var, sub)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ break;
+
+ case SNMP_OP_SET:
+ p = (struct udp_port *)trans_find_port(my_trans,
+ &value->var, sub);
+ ctx->scratch->int1 = (p != NULL);
+
+ if (which != LEAF_begemotSnmpdPortStatus)
+ abort();
+ if (!TRUTH_OK(value->v.integer))
+ return (SNMP_ERR_WRONG_VALUE);
+
+ ctx->scratch->int2 = TRUTH_GET(value->v.integer);
+
+ if (ctx->scratch->int2) {
+ /* open an SNMP port */
+ if (p != NULL)
+ /* already open - do nothing */
+ return (SNMP_ERR_NOERROR);
+
+ if (index_decode(&value->var, sub, iidx, addr, &port))
+ return (SNMP_ERR_NO_CREATION);
+ return (udp_open_port(addr, port, &p));
+
+ } else {
+ /* close SNMP port - do in commit */
+ }
+ return (SNMP_ERR_NOERROR);
+
+ case SNMP_OP_ROLLBACK:
+ p = (struct udp_port *)trans_find_port(my_trans,
+ &value->var, sub);
+ if (ctx->scratch->int1 == 0) {
+ /* did not exist */
+ if (ctx->scratch->int2 == 1) {
+ /* created */
+ if (p != NULL)
+ udp_close_port(&p->tport);
+ }
+ }
+ return (SNMP_ERR_NOERROR);
+
+ case SNMP_OP_COMMIT:
+ p = (struct udp_port *)trans_find_port(my_trans,
+ &value->var, sub);
+ if (ctx->scratch->int1 == 1) {
+ /* did exist */
+ if (ctx->scratch->int2 == 0) {
+ /* delete */
+ if (p != NULL)
+ udp_close_port(&p->tport);
+ }
+ }
+ return (SNMP_ERR_NOERROR);
+
+ default:
+ abort();
+ }
+
+ /*
+ * Come here to fetch the value
+ */
+ switch (which) {
+
+ case LEAF_begemotSnmpdPortStatus:
+ value->v.integer = 1;
+ break;
+
+ default:
+ abort();
+ }
+
+ return (SNMP_ERR_NOERROR);
+}
diff --git a/contrib/bsnmp/snmpd/trans_udp.h b/contrib/bsnmp/snmpd/trans_udp.h
new file mode 100644
index 000000000000..0731882dbfb7
--- /dev/null
+++ b/contrib/bsnmp/snmpd/trans_udp.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 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/trans_udp.h,v 1.2 2003/12/09 12:28:53 hbb Exp $
+ *
+ * UDP transport
+ */
+struct udp_port {
+ struct tport tport; /* must begin with this */
+
+ uint8_t addr[4]; /* host byteorder */
+ uint16_t port; /* host byteorder */
+
+ struct port_input input; /* common input stuff */
+
+ struct sockaddr_in ret; /* the return address */
+};
+
+/* argument for open call */
+struct udp_open {
+ uint8_t addr[4]; /* host byteorder */
+ uint16_t port; /* host byteorder */
+};
+
+extern const struct transport_def udp_trans;
diff --git a/contrib/bsnmp/snmpd/trap.c b/contrib/bsnmp/snmpd/trap.c
index 4853ea9d2160..2dd6b82b90b6 100644
--- a/contrib/bsnmp/snmpd/trap.c
+++ b/contrib/bsnmp/snmpd/trap.c
@@ -30,7 +30,7 @@
* 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 $
+ * $Begemot: bsnmp/snmpd/trap.c,v 1.6 2003/12/03 10:08:47 hbb Exp $
*
* TrapSinkTable
*/
diff --git a/contrib/bsnmp/snmpd/tree.def b/contrib/bsnmp/snmpd/tree.def
index 355a5a006d37..9fec0c9cb23d 100644
--- a/contrib/bsnmp/snmpd/tree.def
+++ b/contrib/bsnmp/snmpd/tree.def
@@ -30,7 +30,7 @@
# 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 $
+# $Begemot: bsnmp/snmpd/tree.def,v 1.37 2003/12/09 12:28:53 hbb Exp $
#
# System group and private Begemot SNMPd MIB.
#
@@ -90,6 +90,7 @@
(2 begemotSnmpdReceiveBuffer INTEGER op_snmpd_config GET SET)
(3 begemotSnmpdCommunityDisable INTEGER op_snmpd_config GET SET)
(4 begemotSnmpdTrap1Addr IPADDRESS op_snmpd_config GET SET)
+ (5 begemotSnmpdVersionEnable UNSIGNED32 op_snmpd_config GET SET)
)
(2 begemotTrapSinkTable
(1 begemotTrapSinkEntry : IPADDRESS INTEGER op_trapsink
@@ -148,10 +149,22 @@
# Local (UNIX domain) port table
#
(9 begemotSnmpdLocalPortTable
- (1 begemotSnmpdLocalPortEntry : OCTETSTRING op_local_port
+ (1 begemotSnmpdLocalPortEntry : OCTETSTRING op_lsock_port
(1 begemotSnmpdLocalPortPath OCTETSTRING)
(2 begemotSnmpdLocalPortStatus INTEGER GET SET)
+ (3 begemotSnmpdLocalPortType INTEGER GET SET)
))
+
+ (10 begemotSnmpdTransportMappings
+ (1 begemotSnmpdTransportTable
+ (1 begemotSnmpdTransportEntry : OCTETSTRING op_transport_table
+ (1 begemotSnmpdTransportName OCTETSTRING)
+ (2 begemotSnmpdTransportStatus INTEGER GET)
+ (3 begemotSnmpdTransportOid OID GET)
+ ))
+ (2 begemotSnmpdTransUdp OID op_transport_dummy)
+ (3 begemotSnmpdTransLsock OID op_transport_dummy)
+ )
)
(2 begemotSnmpdDefs
(1 begemotSnmpdAgent