summaryrefslogtreecommitdiffstats
path: root/contrib/bsnmp/lib
diff options
context:
space:
mode:
authorharti <harti@FreeBSD.org>2005-05-23 11:19:11 +0000
committerharti <harti@FreeBSD.org>2005-05-23 11:19:11 +0000
commita585c860e6a23a65af9f6a881ca7c5686cad63a4 (patch)
tree72add746df3bdc73ab6efb3b2c8f858844a53220 /contrib/bsnmp/lib
parent8bf5d359a297f85eced632d52abdb72d334412c5 (diff)
downloadFreeBSD-src-a585c860e6a23a65af9f6a881ca7c5686cad63a4.zip
FreeBSD-src-a585c860e6a23a65af9f6a881ca7c5686cad63a4.tar.gz
Virgin import of bsnmpd 1.10
Diffstat (limited to 'contrib/bsnmp/lib')
-rw-r--r--contrib/bsnmp/lib/bsnmpclient.332
-rw-r--r--contrib/bsnmp/lib/snmpclient.c250
-rw-r--r--contrib/bsnmp/lib/snmpclient.h5
3 files changed, 226 insertions, 61 deletions
diff --git a/contrib/bsnmp/lib/bsnmpclient.3 b/contrib/bsnmp/lib/bsnmpclient.3
index 9775ef2..e932eba 100644
--- a/contrib/bsnmp/lib/bsnmpclient.3
+++ b/contrib/bsnmp/lib/bsnmpclient.3
@@ -1,4 +1,7 @@
.\"
+.\" Copyright (c) 2004-2005
+.\" Hartmut Brandt.
+.\" All rights reserved.
.\" Copyright (c) 2001-2003
.\" Fraunhofer Institute for Open Communication Systems (FhG Fokus).
.\" All rights reserved.
@@ -26,9 +29,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $Begemot: bsnmp/lib/bsnmpclient.3,v 1.8 2005/02/25 11:55:58 brandt_h Exp $
+.\" $Begemot: bsnmp/lib/bsnmpclient.3,v 1.9 2005/05/23 11:10:12 brandt_h Exp $
.\"
-.Dd August 15, 2002
+.Dd May 23, 2005
.Dt BSNMPCLIENT 3
.Os
.Sh NAME
@@ -44,6 +47,7 @@
.Nm snmp_pdu_check ,
.Nm snmp_pdu_send ,
.Nm snmp_oid_append ,
+.Nm snmp_parse_server ,
.Nm snmp_receive ,
.Nm snmp_table_cb_f ,
.Nm snmp_table_fetch ,
@@ -87,6 +91,8 @@ Begemot SNMP library
.Ft int
.Fn snmp_oid_append "struct asn_oid *oid" "const char *fmt" "..."
.Ft int
+.Fn snmp_parse_server "struct snmp_client *sc" "const char *str"
+.Ft int
.Fn snmp_receive "int blocking"
.Ft typedef void
.Fn (*snmp_table_cb_f) "void *list" "void *arg" "int res"
@@ -571,6 +577,28 @@ PDU is returned in
.Fa resp .
If no reponse could be received after all timeouts and retries, the function
returns -1. If a response was received 0 is returned.
+.Pp
+The function
+.Fn snmp_parse_server
+is used to parse an SNMP server specification string and fill in the
+fields of a
+.Vt struct snmp_client .
+The syntax of a server specification is
+.Pp
+.D1 [trans::][community@][server][:port]
+.Pp
+where
+.Va trans
+is the transport name (one of udp, stream or dgram),
+.Va community
+is the string to be used for both the read and the write community,
+.Va server
+is the server's host name in case of UDP and the path name in case
+of a local socket, and
+.Va port
+is the port in case of UDP transport.
+The function returns 0 in the case of success and return -1 and sets
+the error string in case of an error.
.Sh DIAGNOSTICS
If an error occures in any of the function an error indication as described
above is returned. Additionally the function sets a printable error string
diff --git a/contrib/bsnmp/lib/snmpclient.c b/contrib/bsnmp/lib/snmpclient.c
index dd1ce76..cfea071 100644
--- a/contrib/bsnmp/lib/snmpclient.c
+++ b/contrib/bsnmp/lib/snmpclient.c
@@ -1,4 +1,7 @@
/*
+ * Copyright (c) 2004-2005
+ * Hartmut Brandt.
+ * All rights reserved.
* Copyright (c) 2001-2003
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
* All rights reserved.
@@ -27,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Begemot: bsnmp/lib/snmpclient.c,v 1.29 2004/08/06 08:46:57 brandt Exp $
+ * $Begemot: bsnmp/lib/snmpclient.c,v 1.31 2005/05/23 11:10:13 brandt_h Exp $
*
* Support functions for SNMP clients.
*/
@@ -115,12 +118,12 @@ struct tabwork {
* Set the error string
*/
static void
-seterr(const char *fmt, ...)
+seterr(struct snmp_client *sc, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
- vsnprintf(snmp_client.error, sizeof(snmp_client.error), fmt, ap);
+ vsnprintf(sc->error, sizeof(sc->error), fmt, ap);
va_end(ap);
}
@@ -186,11 +189,11 @@ table_find(struct tabwork *work, const struct asn_oid *var)
/* Not found create new one */
if ((e = malloc(work->descr->entry_size)) == NULL) {
- seterr("no memory for table entry");
+ seterr(&snmp_client, "no memory for table entry");
return (NULL);
}
if ((w = malloc(sizeof(*w))) == NULL) {
- seterr("no memory for table entry");
+ seterr(&snmp_client, "no memory for table entry");
free(e);
return (NULL);
}
@@ -204,11 +207,12 @@ table_find(struct tabwork *work, const struct asn_oid *var)
case SNMP_SYNTAX_INTEGER:
if (var->len < p + 1) {
- seterr("bad index: need integer");
+ seterr(&snmp_client, "bad index: need integer");
goto err;
}
if (var->subs[p] > INT32_MAX) {
- seterr("bad index: integer too large");
+ seterr(&snmp_client,
+ "bad index: integer too large");
goto err;
}
*(int32_t *)(void *)((u_char *)e +
@@ -217,21 +221,25 @@ table_find(struct tabwork *work, const struct asn_oid *var)
case SNMP_SYNTAX_OCTETSTRING:
if (var->len < p + 1) {
- seterr("bad index: need string length");
+ seterr(&snmp_client,
+ "bad index: need string length");
goto err;
}
len = var->subs[p++];
if (var->len < p + len) {
- seterr("bad index: string too short");
+ seterr(&snmp_client,
+ "bad index: string too short");
goto err;
}
if ((ptr = malloc(len + 1)) == NULL) {
- seterr("no memory for index string");
+ seterr(&snmp_client,
+ "no memory for index string");
goto err;
}
for (j = 0; j < len; j++) {
if (var->subs[p] > UCHAR_MAX) {
- seterr("bad index: char too large");
+ seterr(&snmp_client,
+ "bad index: char too large");
free(ptr);
goto err;
}
@@ -247,12 +255,14 @@ table_find(struct tabwork *work, const struct asn_oid *var)
case SNMP_SYNTAX_OID:
if (var->len < p + 1) {
- seterr("bad index: need oid length");
+ seterr(&snmp_client,
+ "bad index: need oid length");
goto err;
}
oid.len = var->subs[p++];
if (var->len < p + oid.len) {
- seterr("bad index: oid too short");
+ seterr(&snmp_client,
+ "bad index: oid too short");
goto err;
}
for (j = 0; j < oid.len; j++)
@@ -263,12 +273,14 @@ table_find(struct tabwork *work, const struct asn_oid *var)
case SNMP_SYNTAX_IPADDRESS:
if (var->len < p + 4) {
- seterr("bad index: need ip-address");
+ seterr(&snmp_client,
+ "bad index: need ip-address");
goto err;
}
for (j = 0; j < 4; j++) {
if (var->subs[p] > 0xff) {
- seterr("bad index: ipaddress too large");
+ seterr(&snmp_client,
+ "bad index: ipaddress too large");
goto err;
}
((u_char *)e +
@@ -279,11 +291,13 @@ table_find(struct tabwork *work, const struct asn_oid *var)
case SNMP_SYNTAX_GAUGE:
if (var->len < p + 1) {
- seterr("bad index: need unsigned");
+ seterr(&snmp_client,
+ "bad index: need unsigned");
goto err;
}
if (var->subs[p] > UINT32_MAX) {
- seterr("bad index: unsigned too large");
+ seterr(&snmp_client,
+ "bad index: unsigned too large");
goto err;
}
*(uint32_t *)(void *)((u_char *)e +
@@ -357,7 +371,7 @@ table_value(const struct snmp_table *descr, struct entry *e,
/* check syntax */
if (b->syntax != descr->entries[i].syntax) {
- seterr("bad syntax (%u instead of %u)", b->syntax,
+ seterr(&snmp_client, "bad syntax (%u instead of %u)", b->syntax,
descr->entries[i].syntax);
return (-1);
}
@@ -371,7 +385,7 @@ table_value(const struct snmp_table *descr, struct entry *e,
case SNMP_SYNTAX_OCTETSTRING:
if ((ptr = malloc(b->v.octetstring.len + 1)) == NULL) {
- seterr("no memory for string");
+ seterr(&snmp_client, "no memory for string");
return (-1);
}
memcpy(ptr, b->v.octetstring.octets, b->v.octetstring.len);
@@ -460,7 +474,7 @@ table_check_response(struct tabwork *work, const struct snmp_pdu *resp)
/* EOT */
return (0);
/* Error */
- seterr("error fetching table: status=%d index=%d",
+ seterr(&snmp_client, "error fetching table: status=%d index=%d",
resp->error_status, resp->error_index);
return (-1);
}
@@ -470,11 +484,13 @@ table_check_response(struct tabwork *work, const struct snmp_pdu *resp)
if (!asn_is_suboid(&work->descr->last_change, &b->var) ||
b->var.len != work->descr->last_change.len + 1 ||
b->var.subs[work->descr->last_change.len] != 0) {
- seterr("last_change: bad response");
+ seterr(&snmp_client,
+ "last_change: bad response");
return (-1);
}
if (b->syntax != SNMP_SYNTAX_TIMETICKS) {
- seterr("last_change: bad syntax %u", b->syntax);
+ seterr(&snmp_client,
+ "last_change: bad syntax %u", b->syntax);
return (-1);
}
if (work->first) {
@@ -483,7 +499,8 @@ table_check_response(struct tabwork *work, const struct snmp_pdu *resp)
} else if (work->last_change != b->v.uint32) {
if (++work->iter >= work->descr->max_iter) {
- seterr("max iteration count exceeded");
+ seterr(&snmp_client,
+ "max iteration count exceeded");
return (-1);
}
table_free(work, 1);
@@ -517,12 +534,13 @@ table_check_cons(struct tabwork *work)
work->descr->req_mask) {
if (work->descr->last_change.len == 0) {
if (++work->iter >= work->descr->max_iter) {
- seterr("max iteration count exceeded");
+ seterr(&snmp_client,
+ "max iteration count exceeded");
return (-1);
}
return (-2);
}
- seterr("inconsistency detected %llx %llx",
+ seterr(&snmp_client, "inconsistency detected %llx %llx",
e->found, work->descr->req_mask);
return (-1);
}
@@ -608,7 +626,7 @@ table_cb(struct snmp_pdu *req __unused, struct snmp_pdu *resp, void *arg)
if (resp == NULL) {
/* timeout */
- seterr("no response to fetch table request");
+ seterr(&snmp_client, "no response to fetch table request");
table_free(work, 1);
work->callback(work->table, work->arg, -1);
free(work);
@@ -686,7 +704,7 @@ snmp_table_fetch_async(const struct snmp_table *descr, void *list,
struct tabwork *work;
if ((work = malloc(sizeof(*work))) == NULL) {
- seterr("%s", strerror(errno));
+ seterr(&snmp_client, "%s", strerror(errno));
return (-1);
}
@@ -859,14 +877,14 @@ open_client_udp(const char *host, const char *port)
if (snmp_client.chost == NULL) {
if ((snmp_client.chost = malloc(1 + sizeof(DEFAULT_HOST)))
== NULL) {
- seterr("%s", strerror(errno));
+ 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("%s", strerror(errno));
+ seterr(&snmp_client, "%s", strerror(errno));
return (-1);
}
free(snmp_client.chost);
@@ -876,14 +894,14 @@ open_client_udp(const char *host, const char *port)
if (snmp_client.cport == NULL) {
if ((snmp_client.cport = malloc(1 + sizeof(DEFAULT_PORT)))
== NULL) {
- seterr("%s", strerror(errno));
+ 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("%s", strerror(errno));
+ seterr(&snmp_client, "%s", strerror(errno));
return (-1);
}
free(snmp_client.cport);
@@ -899,7 +917,8 @@ open_client_udp(const char *host, const char *port)
hints.ai_protocol = 0;
error = getaddrinfo(snmp_client.chost, snmp_client.cport, &hints, &res0);
if (error != 0) {
- seterr("%s: %s", snmp_client.chost, gai_strerror(error));
+ seterr(&snmp_client, "%s: %s", snmp_client.chost,
+ gai_strerror(error));
return (-1);
}
res = res0;
@@ -907,14 +926,14 @@ open_client_udp(const char *host, const char *port)
if ((snmp_client.fd = socket(res->ai_family, res->ai_socktype,
res->ai_protocol)) == -1) {
if ((res = res->ai_next) == NULL) {
- seterr("%s", strerror(errno));
+ 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("%s", strerror(errno));
+ seterr(&snmp_client, "%s", strerror(errno));
freeaddrinfo(res0);
return (-1);
}
@@ -944,14 +963,14 @@ open_client_local(const char *path)
if (snmp_client.chost == NULL) {
if ((snmp_client.chost = malloc(1 + sizeof(DEFAULT_LOCAL)))
== NULL) {
- seterr("%s", strerror(errno));
+ seterr(&snmp_client, "%s", strerror(errno));
return (-1);
}
strcpy(snmp_client.chost, DEFAULT_LOCAL);
}
if (path != NULL) {
if ((ptr = malloc(1 + strlen(path))) == NULL) {
- seterr("%s", strerror(errno));
+ seterr(&snmp_client, "%s", strerror(errno));
return (-1);
}
free(snmp_client.chost);
@@ -965,7 +984,7 @@ open_client_local(const char *path)
stype = SOCK_STREAM;
if ((snmp_client.fd = socket(PF_LOCAL, stype, 0)) == -1) {
- seterr("%s", strerror(errno));
+ seterr(&snmp_client, "%s", strerror(errno));
return (-1);
}
@@ -973,7 +992,7 @@ open_client_local(const char *path)
"%s", SNMP_LOCAL_PATH);
if (mktemp(snmp_client.local_path) == NULL) {
- seterr("%s", strerror(errno));
+ seterr(&snmp_client, "%s", strerror(errno));
(void)close(snmp_client.fd);
snmp_client.fd = -1;
return (-1);
@@ -984,7 +1003,7 @@ open_client_local(const char *path)
strcpy(sa.sun_path, snmp_client.local_path);
if (bind(snmp_client.fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
- seterr("%s", strerror(errno));
+ seterr(&snmp_client, "%s", strerror(errno));
(void)close(snmp_client.fd);
snmp_client.fd = -1;
(void)remove(snmp_client.local_path);
@@ -999,7 +1018,7 @@ open_client_local(const char *path)
sa.sun_path[sizeof(sa.sun_path) - 1] = '\0';
if (connect(snmp_client.fd, (struct sockaddr *)&sa, sa.sun_len) == -1) {
- seterr("%s", strerror(errno));
+ seterr(&snmp_client, "%s", strerror(errno));
(void)close(snmp_client.fd);
snmp_client.fd = -1;
(void)remove(snmp_client.local_path);
@@ -1020,7 +1039,7 @@ snmp_open(const char *host, const char *port, const char *readcomm,
/* still open ? */
if (snmp_client.fd != -1) {
errno = EBUSY;
- seterr("%s", strerror(errno));
+ seterr(&snmp_client, "%s", strerror(errno));
return (-1);
}
@@ -1046,14 +1065,14 @@ snmp_open(const char *host, const char *port, const char *readcomm,
break;
default:
- seterr("bad transport mapping");
+ 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("%s", strerror(errno));
+ seterr(&snmp_client, "%s", strerror(errno));
(void)close(snmp_client.fd);
snmp_client.fd = -1;
if (snmp_client.local_path[0] != '\0')
@@ -1175,7 +1194,7 @@ snmp_send_packet(struct snmp_pdu * pdu)
ssize_t ret;
if ((buf = malloc(snmp_client.txbuflen)) == NULL) {
- seterr("%s", strerror(errno));
+ seterr(&snmp_client, "%s", strerror(errno));
return (-1);
}
@@ -1184,7 +1203,7 @@ snmp_send_packet(struct snmp_pdu * pdu)
b.asn_ptr = buf;
b.asn_len = snmp_client.txbuflen;
if (snmp_pdu_encode(pdu, &b)) {
- seterr("%s", strerror(errno));
+ seterr(&snmp_client, "%s", strerror(errno));
free(buf);
return (-1);
}
@@ -1193,7 +1212,7 @@ snmp_send_packet(struct snmp_pdu * pdu)
snmp_pdu_dump(pdu);
if ((ret = send(snmp_client.fd, buf, b.asn_ptr - buf, 0)) == -1) {
- seterr("%s", strerror(errno));
+ seterr(&snmp_client, "%s", strerror(errno));
free(buf);
return (-1);
}
@@ -1238,7 +1257,7 @@ snmp_pdu_send(struct snmp_pdu *pdu, snmp_send_cb_f func, void *arg)
int32_t id;
if ((listentry = malloc(sizeof(struct sent_pdu))) == NULL) {
- seterr("%s", strerror(errno));
+ seterr(&snmp_client, "%s", strerror(errno));
return (-1);
}
@@ -1296,7 +1315,7 @@ snmp_receive_packet(struct snmp_pdu *pdu, struct timeval *tv)
#endif
if ((buf = malloc(snmp_client.rxbuflen)) == NULL) {
- seterr("%s", strerror(errno));
+ seterr(&snmp_client, "%s", strerror(errno));
return (-1);
}
dopoll = setpoll = 0;
@@ -1307,14 +1326,16 @@ snmp_receive_packet(struct snmp_pdu *pdu, struct timeval *tv)
/* wait with timeout */
if (setsockopt(snmp_client.fd, SOL_SOCKET, SO_RCVTIMEO,
tv, sizeof(*tv)) == -1) {
- seterr("setsockopt: %s", strerror(errno));
+ 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("getsockopt: %s", strerror(errno));
+ seterr(&snmp_client, "getsockopt: %s",
+ strerror(errno));
free(buf);
return (-1);
}
@@ -1330,7 +1351,8 @@ snmp_receive_packet(struct snmp_pdu *pdu, struct timeval *tv)
/* poll */
dopoll = 1;
if ((flags = fcntl(snmp_client.fd, F_GETFL, 0)) == -1) {
- seterr("fcntl: %s", strerror(errno));
+ seterr(&snmp_client, "fcntl: %s",
+ strerror(errno));
free(buf);
return (-1);
}
@@ -1338,7 +1360,8 @@ snmp_receive_packet(struct snmp_pdu *pdu, struct timeval *tv)
setpoll = 1;
flags |= O_NONBLOCK;
if (fcntl(snmp_client.fd, F_SETFL, flags) == -1) {
- seterr("fcntl: %s", strerror(errno));
+ seterr(&snmp_client, "fcntl: %s",
+ strerror(errno));
free(buf);
return (-1);
}
@@ -1364,14 +1387,14 @@ snmp_receive_packet(struct snmp_pdu *pdu, struct timeval *tv)
free(buf);
if (errno == EAGAIN || errno == EWOULDBLOCK)
return (0);
- seterr("recv: %s", strerror(saved_errno));
+ 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("recv: socket closed by peer");
+ seterr(&snmp_client, "recv: socket closed by peer");
errno = EPIPE;
return (-1);
}
@@ -1380,7 +1403,7 @@ snmp_receive_packet(struct snmp_pdu *pdu, struct timeval *tv)
abuf.asn_len = ret;
if (SNMP_CODE_OK != (ret = snmp_pdu_decode(&abuf, pdu, &ip))) {
- seterr("snmp_decode_pdu: failed %d", ret);
+ seterr(&snmp_client, "snmp_decode_pdu: failed %d", ret);
free(buf);
return (-1);
}
@@ -1428,7 +1451,7 @@ snmp_receive(int blocking)
resp = malloc(sizeof(struct snmp_pdu));
if (resp == NULL) {
- seterr("no memory for returning PDU");
+ seterr(&snmp_client, "no memory for returning PDU");
return (-1) ;
}
@@ -1614,11 +1637,23 @@ snmp_dialog(struct snmp_v1_pdu *req, struct snmp_v1_pdu *resp)
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(req)) == -1)
+ if ((reqid = snmp_send_packet(&pdu)) == -1)
return (-1);
for (;;) {
(void)gettimeofday(&tv, NULL);
@@ -1641,7 +1676,7 @@ snmp_dialog(struct snmp_v1_pdu *req, struct snmp_v1_pdu *resp)
}
}
errno = ETIMEDOUT;
- seterr("retry count exceeded");
+ seterr(&snmp_client, "retry count exceeded");
return (-1);
}
@@ -1684,3 +1719,102 @@ snmp_client_set_port(struct snmp_client *cl, const char *p)
}
return (0);
}
+
+/*
+ * 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/contrib/bsnmp/lib/snmpclient.h b/contrib/bsnmp/lib/snmpclient.h
index 34574d2..e137b4c 100644
--- a/contrib/bsnmp/lib/snmpclient.h
+++ b/contrib/bsnmp/lib/snmpclient.h
@@ -27,7 +27,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Begemot: bsnmp/lib/snmpclient.h,v 1.18 2004/08/06 08:46:57 brandt Exp $
+ * $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
@@ -181,4 +181,7 @@ int snmp_table_fetch_async(const struct snmp_table *, 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 */
OpenPOWER on IntegriCloud