summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am4
-rw-r--r--configure.in6
-rw-r--r--daemon/Makefile.am14
-rw-r--r--daemon/rrdbotd.c3
-rw-r--r--daemon/snmpclient.c967
-rw-r--r--daemon/snmpclient.h187
6 files changed, 12 insertions, 1169 deletions
diff --git a/Makefile.am b/Makefile.am
index 16fa9ed..f4cd183 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
-EXTRA_DIST = graphics html tools
-SUBDIRS = src
+EXTRA_DIST = common
+SUBDIRS = bsnmp daemon
dist-hook:
rm -rf `find $(distdir)/ -name .svn`
diff --git a/configure.in b/configure.in
index 53d234e..7c21b67 100644
--- a/configure.in
+++ b/configure.in
@@ -5,7 +5,7 @@ AM_INIT_AUTOMAKE(rrdui, 0.2)
LDFLAGS="$LDFLAGS -L/usr/local/lib"
CFLAGS="$CFLAGS -I/usr/local/include"
-AC_CONFIG_SRCDIR([src/rrdbotd.c])
+AC_CONFIG_SRCDIR([daemon/rrdbotd.c])
AM_CONFIG_HEADER([config.h])
# Debug mode
@@ -40,6 +40,6 @@ dnl TODO: AC_CHECK_HEADERS
AC_MSG_RESULT()
AC_CONFIG_FILES([Makefile
- src/Makefile
- src/bsnmp/Makefile])
+ daemon/Makefile
+ bsnmp/Makefile])
AC_OUTPUT
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index fa8144a..c83aabe 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -1,11 +1,11 @@
-SUBDIRS = bsnmp
sbin_PROGRAMS = rrdbotd
-rrdbotd_SOURCES = rrdbotd.c rrdbotd.h config.c \
+rrdbotd_SOURCES = rrdbotd.c rrdbotd.h config.c usuals.h \
snmp-help.c snmp-engine.c rrd-update.c \
- common/server-mainloop.c common/server-mainloop.h \
- common/sock-any.h common/sock-any.c \
- usuals.h common/stringx.h common/stringx.c common/hash.h common/hash.c
-rrdbotd_CFLAGS = -I${top_srcdir}/src/common/ -I${top_srcdir} -Ibsnmp
-rrdbotd_LDADD = $(top_builddir)/src/bsnmp/libbsnmp-custom.a
+ ../common/server-mainloop.c ../common/server-mainloop.h \
+ ../common/sock-any.h ../common/sock-any.c \
+ ../common/stringx.h ../common/stringx.c \
+ ../common/hash.h ../common/hash.c
+rrdbotd_CFLAGS = -I${top_srcdir}/common/ -I${top_srcdir}/bsnmp/ -I${top_srcdir}
+rrdbotd_LDADD = $(top_builddir)/bsnmp/libbsnmp-custom.a
diff --git a/daemon/rrdbotd.c b/daemon/rrdbotd.c
index 95ab092..f9952bb 100644
--- a/daemon/rrdbotd.c
+++ b/daemon/rrdbotd.c
@@ -49,9 +49,6 @@
#include "stringx.h"
#include "rrdbotd.h"
-/* TODO: Temporary */
-#include "snmpclient.h"
-
/* -----------------------------------------------------------------------------
* GLOBALS
*/
diff --git a/daemon/snmpclient.c b/daemon/snmpclient.c
deleted file mode 100644
index 5d316ad..0000000
--- a/daemon/snmpclient.c
+++ /dev/null
@@ -1,967 +0,0 @@
-/*
- * Copyright (c) 2004-2005
- * Hartmut Brandt.
- * All rights reserved.
- * Copyright (c) 2001-2003
- * Fraunhofer Institute for Open Communication Systems (FhG Fokus).
- * All rights reserved.
- *
- * Author: Harti Brandt <harti@freebsd.org>
- * Kendy Kutzner
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Begemot: bsnmp/lib/snmpclient.c,v 1.31 2005/05/23 11:10:13 brandt_h Exp $
- *
- * Support functions for SNMP clients.
- */
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/queue.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <stdint.h>
-#include <limits.h>
-#ifdef HAVE_ERR_H
-#include <err.h>
-#endif
-
-#include "asn1.h"
-#include "snmp.h"
-#include "snmpclient.h"
-#include "snmppriv.h"
-
-/* ---------------------------------------------------------------------------- */
-
-#define LIST_EMPTY(head) ((head)->lh_first == NULL)
-#define LIST_FIRST(head) ((head)->lh_first)
-#define LIST_NEXT(elm, field) ((elm)->field.le_next)
-#define LIST_FOREACH(var, head, field) \
- for ((var) = LIST_FIRST((head)); \
- (var); \
- (var) = LIST_NEXT((var), field))
-
-
-/* ---------------------------------------------------------------------------- */
-
-/* global context */
-struct snmp_client snmp_client;
-
-/* List of all outstanding requests */
-struct sent_pdu {
- int reqid;
- struct snmp_pdu *pdu;
- struct timeval time;
- u_int retrycount;
- snmp_send_cb_f callback;
- void *arg;
- void *timeout_id;
- LIST_ENTRY(sent_pdu) entries;
-};
-LIST_HEAD(sent_pdu_list, sent_pdu);
-
-static struct sent_pdu_list sent_pdus;
-
-/*
- * Set the error string
- */
-static void
-seterr(struct snmp_client *sc, const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- vsnprintf(sc->error, sizeof(sc->error), fmt, ap);
- va_end(ap);
-}
-
-/*
- * Initialize a client structure
- */
-void
-snmp_client_init(struct snmp_client *c)
-{
- memset(c, 0, sizeof(*c));
-
- c->version = SNMP_V2c;
- c->trans = SNMP_TRANS_UDP;
- c->chost = NULL;
- c->cport = NULL;
-
- strcpy(c->read_community, "public");
- strcpy(c->write_community, "private");
-
- c->timeout.tv_sec = 3;
- c->timeout.tv_usec = 0;
- c->retries = 3;
- c->dump_pdus = 0;
- c->txbuflen = c->rxbuflen = 10000;
-
- c->fd = -1;
-
- c->max_reqid = INT32_MAX;
- c->min_reqid = 0;
- c->next_reqid = 0;
-}
-
-
-/*
- * Open UDP client socket
- */
-static int
-open_client_udp(const char *host, const char *port)
-{
- int error;
- char *ptr;
- struct addrinfo hints, *res0, *res;
-
- /* copy host- and portname */
- if (snmp_client.chost == NULL) {
- if ((snmp_client.chost = malloc(1 + sizeof(DEFAULT_HOST)))
- == NULL) {
- seterr(&snmp_client, "%s", strerror(errno));
- return (-1);
- }
- strcpy(snmp_client.chost, DEFAULT_HOST);
- }
- if (host != NULL) {
- if ((ptr = malloc(1 + strlen(host))) == NULL) {
- seterr(&snmp_client, "%s", strerror(errno));
- return (-1);
- }
- free(snmp_client.chost);
- snmp_client.chost = ptr;
- strcpy(snmp_client.chost, host);
- }
- if (snmp_client.cport == NULL) {
- if ((snmp_client.cport = malloc(1 + sizeof(DEFAULT_PORT)))
- == NULL) {
- seterr(&snmp_client, "%s", strerror(errno));
- return (-1);
- }
- strcpy(snmp_client.cport, DEFAULT_PORT);
- }
- if (port != NULL) {
- if ((ptr = malloc(1 + strlen(port))) == NULL) {
- seterr(&snmp_client, "%s", strerror(errno));
- return (-1);
- }
- free(snmp_client.cport);
- snmp_client.cport = ptr;
- strcpy(snmp_client.cport, port);
- }
-
- /* open connection */
- memset(&hints, 0, sizeof(hints));
- hints.ai_flags = AI_CANONNAME;
- hints.ai_family = AF_INET;
- hints.ai_socktype = SOCK_DGRAM;
- hints.ai_protocol = 0;
- error = getaddrinfo(snmp_client.chost, snmp_client.cport, &hints, &res0);
- if (error != 0) {
- seterr(&snmp_client, "%s: %s", snmp_client.chost,
- gai_strerror(error));
- return (-1);
- }
- res = res0;
- for (;;) {
- if ((snmp_client.fd = socket(res->ai_family, res->ai_socktype,
- res->ai_protocol)) == -1) {
- if ((res = res->ai_next) == NULL) {
- seterr(&snmp_client, "%s", strerror(errno));
- freeaddrinfo(res0);
- return (-1);
- }
- } else if (connect(snmp_client.fd, res->ai_addr,
- res->ai_addrlen) == -1) {
- if ((res = res->ai_next) == NULL) {
- seterr(&snmp_client, "%s", strerror(errno));
- freeaddrinfo(res0);
- return (-1);
- }
- } else
- break;
- }
- freeaddrinfo(res0);
- return (0);
-}
-
-/*
- * SNMP_OPEN
- */
-int
-snmp_open(const char *host, const char *port, const char *readcomm,
- const char *writecomm)
-{
- struct timeval tout;
-
- /* still open ? */
- if (snmp_client.fd != -1) {
- errno = EBUSY;
- seterr(&snmp_client, "%s", strerror(errno));
- return (-1);
- }
-
- /* copy community strings */
- if (readcomm != NULL) {
- strncpy(snmp_client.read_community, readcomm,
- sizeof(snmp_client.read_community));
- snmp_client.read_community[sizeof(snmp_client.read_community) - 1] = 0;
- }
- if (writecomm != NULL) {
- strncpy(snmp_client.write_community, writecomm,
- sizeof(snmp_client.write_community));
- snmp_client.write_community[sizeof(snmp_client.write_community) - 1] = 0;
- }
-
- switch (snmp_client.trans) {
-
- case SNMP_TRANS_UDP:
- if (open_client_udp(host, port))
- return (-1);
- break;
-
- default:
- seterr(&snmp_client, "bad transport mapping");
- return (-1);
- }
- tout.tv_sec = 0;
- tout.tv_usec = 0;
- if (setsockopt(snmp_client.fd, SOL_SOCKET, SO_SNDTIMEO,
- &tout, sizeof(struct timeval)) == -1) {
- seterr(&snmp_client, "%s", strerror(errno));
- (void)close(snmp_client.fd);
- snmp_client.fd = -1;
- if (snmp_client.local_path[0] != '\0')
- (void)remove(snmp_client.local_path);
- return (-1);
- }
-
- /* initialize list */
- LIST_INIT(&sent_pdus);
-
- return (0);
-}
-
-
-/*
- * SNMP_CLOSE
- *
- * closes connection to snmp server
- * - function cannot fail
- * - clears connection
- * - clears list of sent pdus
- *
- * input:
- * void
- * return:
- * void
- */
-void
-snmp_close(void)
-{
- struct sent_pdu *p1;
-
- if (snmp_client.fd != -1) {
- (void)close(snmp_client.fd);
- snmp_client.fd = -1;
- if (snmp_client.local_path[0] != '\0')
- (void)remove(snmp_client.local_path);
- }
- while(!LIST_EMPTY(&sent_pdus)){
- p1 = LIST_FIRST(&sent_pdus);
- if (p1->timeout_id != NULL)
- snmp_client.timeout_stop(p1->timeout_id);
- LIST_REMOVE(p1, entries);
- free(p1);
- }
- free(snmp_client.chost);
- free(snmp_client.cport);
-}
-
-/*
- * initialize a snmp_pdu structure
- */
-void
-snmp_pdu_create(struct snmp_pdu *pdu, u_int op)
-{
- memset(pdu,0,sizeof(struct snmp_pdu));
- if (op == SNMP_PDU_SET)
- strncpy(pdu->community, snmp_client.write_community,
- sizeof(pdu->community));
- else
- strncpy(pdu->community, snmp_client.read_community,
- sizeof(pdu->community));
- pdu->community[sizeof(pdu->community) - 1] = 0;
-
-
- pdu->type = op;
- pdu->version = snmp_client.version;
- pdu->error_status = 0;
- pdu->error_index = 0;
- pdu->nbindings = 0;
-}
-
-/* add pairs of (struct asn_oid, enum snmp_syntax) to an existing pdu */
-/* added 10/04/02 by kek: check for MAX_BINDINGS */
-int
-snmp_add_binding(struct snmp_v1_pdu *pdu, ...)
-{
- va_list ap;
- const struct asn_oid *oid;
- u_int ret;
-
- va_start(ap, pdu);
-
- ret = pdu->nbindings;
- while ((oid = va_arg(ap, const struct asn_oid *)) != NULL) {
- if (pdu->nbindings >= SNMP_MAX_BINDINGS){
- va_end(ap);
- return (-1);
- }
- pdu->bindings[pdu->nbindings].var = *oid;
- pdu->bindings[pdu->nbindings].syntax =
- va_arg(ap, enum snmp_syntax);
- pdu->nbindings++;
- }
- va_end(ap);
- return (ret);
-}
-
-
-static int32_t
-snmp_next_reqid(struct snmp_client * c)
-{
- int32_t i;
-
- i = c->next_reqid;
- if (c->next_reqid >= c->max_reqid)
- c->next_reqid = c->min_reqid;
- else
- c->next_reqid++;
- return (i);
-}
-
-/*
- * Send request and return request id.
- */
-static int32_t
-snmp_send_packet(struct snmp_pdu * pdu)
-{
- u_char *buf;
- struct asn_buf b;
- ssize_t ret;
-
- if ((buf = malloc(snmp_client.txbuflen)) == NULL) {
- seterr(&snmp_client, "%s", strerror(errno));
- return (-1);
- }
-
- pdu->request_id = snmp_next_reqid(&snmp_client);
-
- b.asn_ptr = buf;
- b.asn_len = snmp_client.txbuflen;
- if (snmp_pdu_encode(pdu, &b)) {
- seterr(&snmp_client, "%s", strerror(errno));
- free(buf);
- return (-1);
- }
-
- if (snmp_client.dump_pdus)
- snmp_pdu_dump(pdu);
-
- if ((ret = send(snmp_client.fd, buf, b.asn_ptr - buf, 0)) == -1) {
- seterr(&snmp_client, "%s", strerror(errno));
- free(buf);
- return (-1);
- }
- free(buf);
-
- return pdu->request_id;
-}
-
-/*
- * to be called when a snmp request timed out
- */
-static void
-snmp_timeout(void * listentry_ptr)
-{
- struct sent_pdu *listentry = listentry_ptr;
-
-#if 0
- warnx("snmp request %i timed out, attempt (%i/%i)",
- listentry->reqid, listentry->retrycount, snmp_client.retries);
-#endif
-
- listentry->retrycount++;
- if (listentry->retrycount > snmp_client.retries) {
- /* there is no answer at all */
- LIST_REMOVE(listentry, entries);
- listentry->callback(listentry->pdu, NULL, listentry->arg);
- free(listentry);
- } else {
- /* try again */
- /* new request with new request ID */
- listentry->reqid = snmp_send_packet(listentry->pdu);
- listentry->timeout_id =
- snmp_client.timeout_start(&snmp_client.timeout,
- snmp_timeout, listentry);
- }
-}
-
-int32_t
-snmp_pdu_send(struct snmp_pdu *pdu, snmp_send_cb_f func, void *arg)
-{
- struct sent_pdu *listentry;
- int32_t id;
-
- if ((listentry = malloc(sizeof(struct sent_pdu))) == NULL) {
- seterr(&snmp_client, "%s", strerror(errno));
- return (-1);
- }
-
- /* here we really send */
- if ((id = snmp_send_packet(pdu)) == -1) {
- free(listentry);
- return (-1);
- }
-
- /* add entry to list of sent PDUs */
- listentry->pdu = pdu;
- if (gettimeofday(&listentry->time, NULL) == -1)
- warn("gettimeofday() failed");
-
- listentry->reqid = pdu->request_id;
- listentry->callback = func;
- listentry->arg = arg;
- listentry->retrycount=1;
- listentry->timeout_id =
- snmp_client.timeout_start(&snmp_client.timeout, snmp_timeout,
- listentry);
-
- LIST_INSERT_HEAD(&sent_pdus, listentry, entries);
-
- return (id);
-}
-
-/*
- * Receive an SNMP packet.
- *
- * tv controls how we wait for a packet: if tv is a NULL pointer,
- * the receive blocks forever, if tv points to a structure with all
- * members 0 the socket is polled, in all other cases tv specifies the
- * maximum time to wait for a packet.
- *
- * Return:
- * -1 on errors
- * 0 on timeout
- * +1 if packet received
- */
-static int
-snmp_receive_packet(struct snmp_pdu *pdu, struct timeval *tv)
-{
- int dopoll, setpoll;
- int flags;
- int saved_errno;
- u_char *buf;
- int ret;
- struct asn_buf abuf;
- int32_t ip;
-#ifdef bsdi
- int optlen;
-#else
- socklen_t optlen;
-#endif
-
- if ((buf = malloc(snmp_client.rxbuflen)) == NULL) {
- seterr(&snmp_client, "%s", strerror(errno));
- return (-1);
- }
- dopoll = setpoll = 0;
- flags = 0;
- if (tv != NULL) {
- /* poll or timeout */
- if (tv->tv_sec != 0 || tv->tv_usec != 0) {
- /* wait with timeout */
- if (setsockopt(snmp_client.fd, SOL_SOCKET, SO_RCVTIMEO,
- tv, sizeof(*tv)) == -1) {
- seterr(&snmp_client, "setsockopt: %s",
- strerror(errno));
- free(buf);
- return (-1);
- }
- optlen = sizeof(*tv);
- if (getsockopt(snmp_client.fd, SOL_SOCKET, SO_RCVTIMEO,
- tv, &optlen) == -1) {
- seterr(&snmp_client, "getsockopt: %s",
- strerror(errno));
- free(buf);
- return (-1);
- }
- /* at this point tv_sec and tv_usec may appear
- * as 0. This happens for timeouts lesser than
- * the clock granularity. The kernel rounds these to
- * 0 and this would result in a blocking receive.
- * Instead of an else we check tv_sec and tv_usec
- * again below and if this rounding happens,
- * switch to a polling receive. */
- }
- if (tv->tv_sec == 0 && tv->tv_usec == 0) {
- /* poll */
- dopoll = 1;
- if ((flags = fcntl(snmp_client.fd, F_GETFL, 0)) == -1) {
- seterr(&snmp_client, "fcntl: %s",
- strerror(errno));
- free(buf);
- return (-1);
- }
- if (!(flags & O_NONBLOCK)) {
- setpoll = 1;
- flags |= O_NONBLOCK;
- if (fcntl(snmp_client.fd, F_SETFL, flags) == -1) {
- seterr(&snmp_client, "fcntl: %s",
- strerror(errno));
- free(buf);
- return (-1);
- }
- }
- }
- }
- ret = recv(snmp_client.fd, buf, snmp_client.rxbuflen, 0);
- saved_errno = errno;
- if (tv != NULL) {
- if (dopoll) {
- if (setpoll) {
- flags &= ~O_NONBLOCK;
- (void)fcntl(snmp_client.fd, F_SETFL, flags);
- }
- } else {
- tv->tv_sec = 0;
- tv->tv_usec = 0;
- (void)setsockopt(snmp_client.fd, SOL_SOCKET, SO_RCVTIMEO,
- tv, sizeof(*tv));
- }
- }
- if (ret == -1) {
- free(buf);
- if (errno == EAGAIN || errno == EWOULDBLOCK)
- return (0);
- seterr(&snmp_client, "recv: %s", strerror(saved_errno));
- return (-1);
- }
- if (ret == 0) {
- /* this happens when we have a streaming socket and the
- * remote side has closed it */
- free(buf);
- seterr(&snmp_client, "recv: socket closed by peer");
- errno = EPIPE;
- return (-1);
- }
-
- abuf.asn_ptr = buf;
- abuf.asn_len = ret;
-
- if (SNMP_CODE_OK != (ret = snmp_pdu_decode(&abuf, pdu, &ip))) {
- seterr(&snmp_client, "snmp_decode_pdu: failed %d", ret);
- free(buf);
- return (-1);
- }
- free(buf);
- if (snmp_client.dump_pdus)
- snmp_pdu_dump(pdu);
-
- return (+1);
-}
-
-static int
-snmp_deliver_packet(struct snmp_pdu * resp)
-{
- struct sent_pdu *listentry;
-
- if (resp->type != SNMP_PDU_RESPONSE) {
- warn("ignoring snmp pdu %u", resp->type);
- return (-1);
- }
-
- LIST_FOREACH(listentry, &sent_pdus, entries)
- if (listentry->reqid == resp->request_id)
- break;
- if (listentry == NULL)
- return (-1);
-
- LIST_REMOVE(listentry, entries);
- listentry->callback(listentry->pdu, resp, listentry->arg);
-
- snmp_client.timeout_stop(listentry->timeout_id);
-
- free(listentry);
- return (0);
-}
-
-int
-snmp_receive(int blocking)
-{
- int ret;
-
- struct timeval tv;
- struct snmp_pdu * resp;
-
- memset(&tv, 0, sizeof(tv));
-
- resp = malloc(sizeof(struct snmp_pdu));
- if (resp == NULL) {
- seterr(&snmp_client, "no memory for returning PDU");
- return (-1) ;
- }
-
- if ((ret = snmp_receive_packet(resp, blocking ? NULL : &tv)) <= 0) {
- free(resp);
- return (ret);
- }
- ret = snmp_deliver_packet(resp);
- snmp_pdu_free(resp);
- free(resp);
- return (ret);
-}
-
-
-/*
- * Check a GETNEXT response. Here we have three possible outcomes: -1 an
- * unexpected error happened. +1 response is ok and is within the table 0
- * response is ok, but is behind the table or error is NOSUCHNAME. The req
- * should point to a template PDU which contains the base OIDs and the
- * syntaxes. This is really only useful to sweep non-sparse tables.
- */
-static int
-ok_getnext(const struct snmp_pdu * req, const struct snmp_pdu * resp)
-{
- u_int i;
-
- if (resp->version != req->version) {
- warnx("SNMP GETNEXT: response has wrong version");
- return (-1);
- }
-
- if (resp->error_status == SNMP_ERR_NOSUCHNAME)
- return (0);
-
- if (resp->error_status != SNMP_ERR_NOERROR) {
- warnx("SNMP GETNEXT: error %d", resp->error_status);
- return (-1);
- }
- if (resp->nbindings != req->nbindings) {
- warnx("SNMP GETNEXT: bad number of bindings in response");
- return (-1);
- }
- for (i = 0; i < req->nbindings; i++) {
- if (!asn_is_suboid(&req->bindings[i].var,
- &resp->bindings[i].var)) {
- if (i != 0)
- warnx("SNMP GETNEXT: inconsistent table "
- "response");
- return (0);
- }
- if (resp->version != SNMP_V1 &&
- resp->bindings[i].syntax == SNMP_SYNTAX_ENDOFMIBVIEW)
- return (0);
-
- if (resp->bindings[i].syntax != req->bindings[i].syntax) {
- warnx("SNMP GETNEXT: bad syntax in response");
- return (0);
- }
- }
- return (1);
-}
-
-/*
- * Check a GET response. Here we have three possible outcomes: -1 an
- * unexpected error happened. +1 response is ok. 0 NOSUCHNAME The req should
- * point to a template PDU which contains the OIDs and the syntaxes. This
- * is only useful for SNMPv1 or single object GETS.
- */
-static int
-ok_get(const struct snmp_pdu * req, const struct snmp_pdu * resp)
-{
- u_int i;
-
- if (resp->version != req->version) {
- warnx("SNMP GET: response has wrong version");
- return (-1);
- }
-
- if (resp->error_status == SNMP_ERR_NOSUCHNAME)
- return (0);
-
- if (resp->error_status != SNMP_ERR_NOERROR) {
- warnx("SNMP GET: error %d", resp->error_status);
- return (-1);
- }
-
- if (resp->nbindings != req->nbindings) {
- warnx("SNMP GET: bad number of bindings in response");
- return (-1);
- }
- for (i = 0; i < req->nbindings; i++) {
- if (asn_compare_oid(&req->bindings[i].var,
- &resp->bindings[i].var) != 0) {
- warnx("SNMP GET: bad OID in response");
- return (-1);
- }
- if (snmp_client.version != SNMP_V1 &&
- (resp->bindings[i].syntax == SNMP_SYNTAX_NOSUCHOBJECT ||
- resp->bindings[i].syntax == SNMP_SYNTAX_NOSUCHINSTANCE))
- return (0);
- if (resp->bindings[i].syntax != req->bindings[i].syntax) {
- warnx("SNMP GET: bad syntax in response");
- return (-1);
- }
- }
- return (1);
-}
-
-/*
- * Check the reponse to a SET PDU. We check: - the error status must be 0 -
- * the number of bindings must be equal in response and request - the
- * syntaxes must be the same in response and request - the OIDs must be the
- * same in response and request
- */
-static int
-ok_set(const struct snmp_pdu * req, const struct snmp_pdu * resp)
-{
- u_int i;
-
- if (resp->version != req->version) {
- warnx("SNMP SET: response has wrong version");
- return (-1);
- }
-
- if (resp->error_status == SNMP_ERR_NOSUCHNAME) {
- warnx("SNMP SET: error %d", resp->error_status);
- return (0);
- }
- if (resp->error_status != SNMP_ERR_NOERROR) {
- warnx("SNMP SET: error %d", resp->error_status);
- return (-1);
- }
-
- if (resp->nbindings != req->nbindings) {
- warnx("SNMP SET: bad number of bindings in response");
- return (-1);
- }
- for (i = 0; i < req->nbindings; i++) {
- if (asn_compare_oid(&req->bindings[i].var,
- &resp->bindings[i].var) != 0) {
- warnx("SNMP SET: wrong OID in response to SET");
- return (-1);
- }
- if (resp->bindings[i].syntax != req->bindings[i].syntax) {
- warnx("SNMP SET: bad syntax in response");
- return (-1);
- }
- }
- return (1);
-}
-
-/*
- * Simple checks for response PDUs against request PDUs. Return values: 1=ok,
- * 0=nosuchname or similar, -1=failure, -2=no response at all
- */
-int
-snmp_pdu_check(const struct snmp_pdu *req,
- const struct snmp_pdu *resp)
-{
- if (resp == NULL)
- return (-2);
-
- switch (req->type) {
-
- case SNMP_PDU_GET:
- return (ok_get(req, resp));
-
- case SNMP_PDU_SET:
- return (ok_set(req, resp));
-
- case SNMP_PDU_GETNEXT:
- return (ok_getnext(req, resp));
-
- }
- errx(1, "%s: bad pdu type %i", __func__, req->type);
-}
-
-int
-snmp_dialog(struct snmp_v1_pdu *req, struct snmp_v1_pdu *resp)
-{
- u_int i;
- int32_t reqid;
- int ret;
- struct timeval tv = snmp_client.timeout;
- struct timeval end;
- struct snmp_pdu pdu;
-
- /*
- * Make a copy of the request and replace the syntaxes by NULL
- * if this is a GET,GETNEXT or GETBULK.
- */
- pdu = *req;
- if (pdu.type == SNMP_PDU_GET || pdu.type == SNMP_PDU_GETNEXT ||
- pdu.type == SNMP_PDU_GETBULK) {
- for (i = 0; i < pdu.nbindings; i++)
- pdu.bindings[i].syntax = SNMP_SYNTAX_NULL;
- }
-
- for (i = 0; i <= snmp_client.retries; i++) {
- (void)gettimeofday(&end, NULL);
- timeradd(&end, &snmp_client.timeout, &end);
- if ((reqid = snmp_send_packet(&pdu)) == -1)
- return (-1);
- for (;;) {
- (void)gettimeofday(&tv, NULL);
- if (timercmp(&end, &tv, <=))
- break;
- timersub(&end, &tv, &tv);
- if ((ret = snmp_receive_packet(resp, &tv)) == 0)
- /* timeout */
- break;
-
- if (ret > 0) {
- if (reqid == resp->request_id)
- return (0);
- /* not for us */
- (void)snmp_deliver_packet(resp);
- }
- if (ret < 0 && errno == EPIPE)
- /* stream closed */
- return (-1);
- }
- }
- errno = ETIMEDOUT;
- seterr(&snmp_client, "retry count exceeded");
- return (-1);
-}
-
-/*
- * parse a server specification
- *
- * [trans::][community@][server][:port]
- */
-int
-snmp_parse_server(struct snmp_client *sc, const char *str)
-{
- const char *p, *s = str;
-
- /* look for a double colon */
- for (p = s; *p != '\0'; p++) {
- if (*p == '\\' && p[1] != '\0') {
- p++;
- continue;
- }
- if (*p == ':' && p[1] == ':')
- break;
- }
- if (*p != '\0') {
- if (p > s) {
- if (p - s == 3 && strncmp(s, "udp", 3) == 0)
- sc->trans = SNMP_TRANS_UDP;
- else if (p - s == 6 && strncmp(s, "stream", 6) == 0)
- sc->trans = SNMP_TRANS_LOC_STREAM;
- else if (p - s == 5 && strncmp(s, "dgram", 5) == 0)
- sc->trans = SNMP_TRANS_LOC_DGRAM;
- else {
- seterr(sc, "unknown SNMP transport '%.*s'",
- (int)(p - s), s);
- return (-1);
- }
- }
- s = p + 2;
- }
-
- /* look for a @ */
- for (p = s; *p != '\0'; p++) {
- if (*p == '\\' && p[1] != '\0') {
- p++;
- continue;
- }
- if (*p == '@')
- break;
- }
-
- if (*p != '\0') {
- if (p - s > SNMP_COMMUNITY_MAXLEN) {
- seterr(sc, "community string too long");
- return (-1);
- }
- strncpy(sc->read_community, s, p - s);
- sc->read_community[p - s] = '\0';
- strncpy(sc->write_community, s, p - s);
- sc->write_community[p - s] = '\0';
- s = p + 1;
- }
-
- /* look for a colon */
- for (p = s; *p != '\0'; p++) {
- if (*p == '\\' && p[1] != '\0') {
- p++;
- continue;
- }
- if (*p == ':')
- break;
- }
-
- if (*p == ':') {
- if (p > s) {
- /* host:port */
- free(sc->chost);
- if ((sc->chost = malloc(p - s + 1)) == NULL) {
- seterr(sc, "%s", strerror(errno));
- return (-1);
- }
- strncpy(sc->chost, s, p - s);
- sc->chost[p - s] = '\0';
- }
- /* port */
- free(sc->cport);
- if ((sc->cport = malloc(strlen(p + 1) + 1)) == NULL) {
- seterr(sc, "%s", strerror(errno));
- return (-1);
- }
- strcpy(sc->cport, p + 1);
-
- } else if (p > s) {
- /* host */
- free(sc->chost);
- if ((sc->chost = malloc(strlen(s) + 1)) == NULL) {
- seterr(sc, "%s", strerror(errno));
- return (-1);
- }
- strcpy(sc->chost, s);
- }
- return (0);
-}
diff --git a/daemon/snmpclient.h b/daemon/snmpclient.h
deleted file mode 100644
index f47493f..0000000
--- a/daemon/snmpclient.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (c) 2001-2003
- * Fraunhofer Institute for Open Communication Systems (FhG Fokus).
- * All rights reserved.
- *
- * Author: Harti Brandt <harti@freebsd.org>
- * Kendy Kutzner
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Begemot: bsnmp/lib/snmpclient.h,v 1.19 2005/05/23 11:10:14 brandt_h Exp $
- */
-#ifndef _BSNMP_SNMPCLIENT_H
-#define _BSNMP_SNMPCLIENT_H
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <netinet/in.h>
-#include <stddef.h>
-
-
-#define SNMP_STRERROR_LEN 200
-
-#define SNMP_LOCAL_PATH "/tmp/snmpXXXXXXXXXXXXXX"
-
-/*
- * 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
- * any of the PDUs. Therefor it may call snmp_pdu_free() */
-typedef void (*snmp_send_cb_f)(struct snmp_pdu *, struct snmp_pdu *, void *);
-
-/* type of callback function for timeouts */
-typedef void (*snmp_timeout_cb_f)(void * );
-
-/* timeout start function */
-typedef void *(*snmp_timeout_start_f)(struct timeval *timeout,
- snmp_timeout_cb_f callback, void *);
-
-/* timeout stop function */
-typedef void (*snmp_timeout_stop_f)(void *timeout_id);
-
-/*
- * Client context.
- */
-struct snmp_client {
- enum snmp_version version;
- int trans; /* which transport to use */
-
- /* these two are read-only for the application */
- char *cport; /* port number as string */
- char *chost; /* host name or IP address as string */
-
- char read_community[SNMP_COMMUNITY_MAXLEN + 1];
- char write_community[SNMP_COMMUNITY_MAXLEN + 1];
-
- struct timeval timeout;
- u_int retries;
-
- int dump_pdus;
-
- size_t txbuflen;
- size_t rxbuflen;
-
- int fd;
-
- int32_t next_reqid;
- int32_t max_reqid;
- int32_t min_reqid;
-
- char error[SNMP_STRERROR_LEN];
-
- snmp_timeout_start_f timeout_start;
- snmp_timeout_stop_f timeout_stop;
-
- char local_path[sizeof(SNMP_LOCAL_PATH)];
-};
-
-/* the global context */
-extern struct snmp_client snmp_client;
-
-/* initizialies a snmp_client structure */
-void snmp_client_init(struct snmp_client *);
-
-/* initialize fields */
-int snmp_client_set_host(struct snmp_client *, const char *);
-int snmp_client_set_port(struct snmp_client *, const char *);
-
-/* open connection to snmp server (hostname or portname can be NULL) */
-int snmp_open(const char *_hostname, const char *_portname,
- const char *_read_community, const char *_write_community);
-
-/* close connection */
-void snmp_close(void);
-
-/* initialize a snmp_pdu structure */
-void snmp_pdu_create(struct snmp_pdu *, u_int _op);
-
-/* add pairs of (struct asn_oid *, enum snmp_syntax) to an existing pdu */
-int snmp_add_binding(struct snmp_pdu *, ...);
-
-/* check wheater the answer is valid or not */
-int snmp_pdu_check(const struct snmp_pdu *_req, const struct snmp_pdu *_resp);
-
-int32_t snmp_pdu_send(struct snmp_pdu *_pdu, snmp_send_cb_f _func, void *_arg);
-
-/* append an index to an oid */
-int snmp_oid_append(struct asn_oid *_oid, const char *_fmt, ...);
-
-/* receive a packet */
-int snmp_receive(int _blocking);
-
-/*
- * This structure is used to describe an SNMP table that is to be fetched.
- * The C-structure that is produced by the fetch function must start with
- * a TAILQ_ENTRY and an u_int64_t.
- */
-struct snmp_table {
- /* base OID of the table */
- struct asn_oid table;
- /* type OID of the LastChange variable for the table if any */
- struct asn_oid last_change;
- /* maximum number of iterations if table has changed */
- u_int max_iter;
- /* size of the C-structure */
- size_t entry_size;
- /* number of index fields */
- u_int index_size;
- /* bit mask of required fields */
- uint64_t req_mask;
-
- /* indexes and columns to fetch. Ended by a NULL syntax entry */
- struct snmp_table_entry {
- /* the column sub-oid, ignored for index fields */
- asn_subid_t subid;
- /* the syntax of the column or index */
- enum snmp_syntax syntax;
- /* offset of the field into the C-structure. For octet strings
- * this points to an u_char * followed by a size_t */
- off_t offset;
-#if defined(__GNUC__) && __GNUC__ < 3
- } entries[0];
-#else
- } entries[];
-#endif
-};
-
-/* callback type for table fetch */
-typedef void (*snmp_table_cb_f)(void *_list, void *_arg, int _res);
-
-/* fetch a table. The argument points to a TAILQ_HEAD */
-int snmp_table_fetch(const struct snmp_table *descr, void *);
-int snmp_table_fetch_async(const struct snmp_table *, void *,
- snmp_table_cb_f, void *);
-
-/* send a request and wait for the response */
-int snmp_dialog(struct snmp_pdu *_req, struct snmp_pdu *_resp);
-
-/* parse a server specification */
-int snmp_parse_server(struct snmp_client *, const char *);
-
-#endif /* _BSNMP_SNMPCLIENT_H */