summaryrefslogtreecommitdiffstats
path: root/contrib/bsnmp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bsnmp')
-rw-r--r--contrib/bsnmp/gensnmpdef/gensnmpdef.c11
-rw-r--r--contrib/bsnmp/lib/snmp.c6
-rw-r--r--contrib/bsnmp/lib/snmpclient.c11
-rw-r--r--contrib/bsnmp/snmp_mibII/BEGEMOT-IP-MIB.txt3
-rw-r--r--contrib/bsnmp/snmp_mibII/mibII.c22
-rw-r--r--contrib/bsnmp/snmp_mibII/mibII_interfaces.c6
-rw-r--r--contrib/bsnmp/snmp_mibII/snmp_mibII.34
-rw-r--r--contrib/bsnmp/snmp_usm/usm_snmp.c6
-rw-r--r--contrib/bsnmp/snmpd/BEGEMOT-MIB.txt3
-rw-r--r--contrib/bsnmp/snmpd/FOKUS-MIB.txt3
-rw-r--r--contrib/bsnmp/snmpd/main.c205
-rw-r--r--contrib/bsnmp/snmpd/snmpd.h1
-rw-r--r--contrib/bsnmp/snmpd/trans_lsock.c82
-rw-r--r--contrib/bsnmp/snmpd/trans_udp.c137
-rw-r--r--contrib/bsnmp/snmpd/trans_udp.h3
15 files changed, 268 insertions, 235 deletions
diff --git a/contrib/bsnmp/gensnmpdef/gensnmpdef.c b/contrib/bsnmp/gensnmpdef/gensnmpdef.c
index 32c835d..b0bfdaf 100644
--- a/contrib/bsnmp/gensnmpdef/gensnmpdef.c
+++ b/contrib/bsnmp/gensnmpdef/gensnmpdef.c
@@ -126,9 +126,11 @@ open_node(const SmiNode *n, u_int level, SmiNode **last)
while (level < n->oidlen - 1) {
if (level >= cut) {
+ n1 = smiGetNodeByOID(level + 1, n->oid);
+ if (n1 == NULL)
+ continue;
pindent(level);
printf("(%u", n->oid[level]);
- n1 = smiGetNodeByOID(level + 1, n->oid);
printf(" ");
print_name(n1);
printf("\n");
@@ -397,12 +399,11 @@ static void
save_typdef(char *name)
{
struct tdef *t;
- t = malloc(sizeof(struct tdef));
+ t = calloc(1, sizeof(struct tdef));
if (t == NULL)
err(1, NULL);
- memset(t, 0 , sizeof(struct tdef));
t->name = name;
SLIST_INSERT_HEAD(&tdefs, t, link);
}
@@ -559,7 +560,11 @@ main(int argc, char *argv[])
level = 0;
last = NULL;
for (opt = 0; opt < argc; opt++) {
+ if (mods[opt] == NULL) /* smiGetModule failed above */
+ continue;
n = smiGetFirstNode(mods[opt], SMI_NODEKIND_ANY);
+ if (n == NULL)
+ continue;
for (;;) {
if (do_typedef == 0) {
level = open_node(n, level, &last);
diff --git a/contrib/bsnmp/lib/snmp.c b/contrib/bsnmp/lib/snmp.c
index 68f46f9..d86f88a 100644
--- a/contrib/bsnmp/lib/snmp.c
+++ b/contrib/bsnmp/lib/snmp.c
@@ -1154,8 +1154,11 @@ snmp_pdu_dump(const struct snmp_pdu *pdu)
void
snmp_value_free(struct snmp_value *value)
{
- if (value->syntax == SNMP_SYNTAX_OCTETSTRING)
+
+ if (value->syntax == SNMP_SYNTAX_OCTETSTRING) {
free(value->v.octetstring.octets);
+ value->v.octetstring.octets = NULL;
+ }
value->syntax = SNMP_SYNTAX_NULL;
}
@@ -1216,6 +1219,7 @@ snmp_pdu_free(struct snmp_pdu *pdu)
for (i = 0; i < pdu->nbindings; i++)
snmp_value_free(&pdu->bindings[i]);
+ pdu->nbindings = 0;
}
/*
diff --git a/contrib/bsnmp/lib/snmpclient.c b/contrib/bsnmp/lib/snmpclient.c
index 90b7d4a..10c58f5 100644
--- a/contrib/bsnmp/lib/snmpclient.c
+++ b/contrib/bsnmp/lib/snmpclient.c
@@ -728,8 +728,11 @@ snmp_table_fetch_async(const struct snmp_table *descr, void *list,
work->last_change = 0;
table_init_pdu(descr, &work->pdu);
- if (snmp_pdu_send(&work->pdu, table_cb, work) == -1)
+ if (snmp_pdu_send(&work->pdu, table_cb, work) == -1) {
+ free(work);
+ work = NULL;
return (-1);
+ }
return (0);
}
@@ -1231,7 +1234,7 @@ snmp_send_packet(struct snmp_pdu * pdu)
struct asn_buf b;
ssize_t ret;
- if ((buf = malloc(snmp_client.txbuflen)) == NULL) {
+ if ((buf = calloc(1, snmp_client.txbuflen)) == NULL) {
seterr(&snmp_client, "%s", strerror(errno));
return (-1);
}
@@ -1256,7 +1259,7 @@ snmp_send_packet(struct snmp_pdu * pdu)
}
free(buf);
- return pdu->request_id;
+ return (pdu->request_id);
}
/*
@@ -1352,7 +1355,7 @@ snmp_receive_packet(struct snmp_pdu *pdu, struct timeval *tv)
socklen_t optlen;
#endif
- if ((buf = malloc(snmp_client.rxbuflen)) == NULL) {
+ if ((buf = calloc(1, snmp_client.rxbuflen)) == NULL) {
seterr(&snmp_client, "%s", strerror(errno));
return (-1);
}
diff --git a/contrib/bsnmp/snmp_mibII/BEGEMOT-IP-MIB.txt b/contrib/bsnmp/snmp_mibII/BEGEMOT-IP-MIB.txt
index 761876a..29f7844 100644
--- a/contrib/bsnmp/snmp_mibII/BEGEMOT-IP-MIB.txt
+++ b/contrib/bsnmp/snmp_mibII/BEGEMOT-IP-MIB.txt
@@ -54,6 +54,9 @@ begemotIp MODULE-IDENTITY
E-mail: harti@freebsd.org"
DESCRIPTION
"The MIB for IP stuff that is not in the official IP MIBs."
+ REVISION "200602130000Z"
+ DESCRIPTION
+ "Initial revision."
::= { begemot 3 }
begemotIpObjects OBJECT IDENTIFIER ::= { begemotIp 1 }
diff --git a/contrib/bsnmp/snmp_mibII/mibII.c b/contrib/bsnmp/snmp_mibII/mibII.c
index 85c61d5..e66a951 100644
--- a/contrib/bsnmp/snmp_mibII/mibII.c
+++ b/contrib/bsnmp/snmp_mibII/mibII.c
@@ -265,7 +265,7 @@ mib_if_admin(struct mibif *ifp, int up)
{
struct ifreq ifr;
- strncpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
+ strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
if (ioctl(mib_netsock, SIOCGIFFLAGS, &ifr) == -1) {
syslog(LOG_ERR, "SIOCGIFFLAGS(%s): %m", ifp->name);
return (-1);
@@ -319,7 +319,7 @@ fetch_generic_mib(struct mibif *ifp, const struct ifmibdata *old)
name[5] = IFDATA_GENERAL;
len = sizeof(ifp->mib);
- if (sysctl(name, 6, &ifp->mib, &len, NULL, 0) == -1) {
+ if (sysctl(name, nitems(name), &ifp->mib, &len, NULL, 0) == -1) {
if (errno != ENOENT)
syslog(LOG_WARNING, "sysctl(ifmib, %s) failed %m",
ifp->name);
@@ -480,7 +480,7 @@ mib_fetch_ifmib(struct mibif *ifp)
name[3] = IFMIB_IFDATA;
name[4] = ifp->sysindex;
name[5] = IFDATA_LINKSPECIFIC;
- if (sysctl(name, 6, NULL, &len, NULL, 0) == -1) {
+ if (sysctl(name, nitems(name), NULL, &len, NULL, 0) == -1) {
syslog(LOG_WARNING, "sysctl linkmib estimate (%s): %m",
ifp->name);
if (ifp->specmib != NULL) {
@@ -506,7 +506,7 @@ mib_fetch_ifmib(struct mibif *ifp)
ifp->specmib = newmib;
ifp->specmiblen = len;
}
- if (sysctl(name, 6, ifp->specmib, &len, NULL, 0) == -1) {
+ if (sysctl(name, nitems(name), ifp->specmib, &len, NULL, 0) == -1) {
syslog(LOG_WARNING, "sysctl linkmib (%s): %m", ifp->name);
if (ifp->specmib != NULL) {
ifp->specmib = NULL;
@@ -515,7 +515,7 @@ mib_fetch_ifmib(struct mibif *ifp)
}
out:
- strncpy(irr.ifr_name, ifp->name, sizeof(irr.ifr_name));
+ strlcpy(irr.ifr_name, ifp->name, sizeof(irr.ifr_name));
irr.ifr_buffer.buffer = MIBIF_PRIV(ifp)->alias;
irr.ifr_buffer.length = sizeof(MIBIF_PRIV(ifp)->alias);
if (ioctl(mib_netsock, SIOCGIFDESCR, &irr) == -1) {
@@ -902,7 +902,7 @@ mib_refresh_iflist(void)
for (idx = 1; idx <= count; idx++) {
name[4] = idx;
len = sizeof(mib);
- if (sysctl(name, 6, &mib, &len, NULL, 0) == -1) {
+ if (sysctl(name, nitems(name), &mib, &len, NULL, 0) == -1) {
if (errno == ENOENT)
continue;
syslog(LOG_ERR, "ifmib(%u): %m", idx);
@@ -1213,7 +1213,7 @@ mib_fetch_rtab(int af, int info, int arg, size_t *lenp)
*lenp = 0;
/* initial estimate */
- if (sysctl(name, 6, NULL, lenp, NULL, 0) == -1) {
+ if (sysctl(name, nitems(name), 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);
@@ -1230,7 +1230,7 @@ mib_fetch_rtab(int af, int info, int arg, size_t *lenp)
}
buf = newbuf;
- if (sysctl(name, 6, buf, lenp, NULL, 0) == 0)
+ if (sysctl(name, nitems(name), buf, lenp, NULL, 0) == 0)
break;
if (errno != ENOMEM) {
@@ -1384,7 +1384,7 @@ siocaifaddr(char *ifname, struct in_addr addr, struct in_addr mask,
struct sockaddr_in *sa;
memset(&addreq, 0, sizeof(addreq));
- strncpy(addreq.ifra_name, ifname, sizeof(addreq.ifra_name));
+ strlcpy(addreq.ifra_name, ifname, sizeof(addreq.ifra_name));
sa = (struct sockaddr_in *)(void *)&addreq.ifra_addr;
sa->sin_family = AF_INET;
@@ -1414,7 +1414,7 @@ siocdifaddr(const char *ifname, struct in_addr addr)
struct sockaddr_in *sa;
memset(&delreq, 0, sizeof(delreq));
- strncpy(delreq.ifr_name, ifname, sizeof(delreq.ifr_name));
+ strlcpy(delreq.ifr_name, ifname, sizeof(delreq.ifr_name));
sa = (struct sockaddr_in *)(void *)&delreq.ifr_addr;
sa->sin_family = AF_INET;
sa->sin_len = sizeof(*sa);
@@ -1433,7 +1433,7 @@ verify_ifa(const char *name, struct mibifa *ifa)
struct sockaddr_in *sa;
memset(&req, 0, sizeof(req));
- strncpy(req.ifr_name, name, sizeof(req.ifr_name));
+ strlcpy(req.ifr_name, name, sizeof(req.ifr_name));
sa = (struct sockaddr_in *)(void *)&req.ifr_addr;
sa->sin_family = AF_INET;
sa->sin_len = sizeof(*sa);
diff --git a/contrib/bsnmp/snmp_mibII/mibII_interfaces.c b/contrib/bsnmp/snmp_mibII/mibII_interfaces.c
index c0f61c7..03ca28c 100644
--- a/contrib/bsnmp/snmp_mibII/mibII_interfaces.c
+++ b/contrib/bsnmp/snmp_mibII/mibII_interfaces.c
@@ -77,7 +77,7 @@ ifchange_func(struct snmp_context *ctx __unused, struct snmp_dependency *dep,
switch (op) {
case SNMP_DEPOP_COMMIT:
- strncpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
+ strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
if (ioctl(mib_netsock, SIOCGIFFLAGS, &ifr) == -1) {
syslog(LOG_ERR, "GIFFLAGS(%s): %m", ifp->name);
return (SNMP_ERR_GENERR);
@@ -95,7 +95,7 @@ ifchange_func(struct snmp_context *ctx __unused, struct snmp_dependency *dep,
ifc->rb |= IFRB_FLAGS;
}
if (ifc->rb & IFRB_FLAGS) {
- strncpy(ifr1.ifr_name, ifp->name, sizeof(ifr1.ifr_name));
+ strlcpy(ifr1.ifr_name, ifp->name, sizeof(ifr1.ifr_name));
if (ioctl(mib_netsock, SIOCGIFFLAGS, &ifr1) == -1) {
syslog(LOG_ERR, "GIFFLAGS(%s): %m", ifp->name);
return (SNMP_ERR_GENERR);
@@ -116,7 +116,7 @@ ifchange_func(struct snmp_context *ctx __unused, struct snmp_dependency *dep,
case SNMP_DEPOP_ROLLBACK:
if (ifc->rb & IFRB_FLAGS) {
- strncpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
+ strlcpy(ifr.ifr_name, ifp->name, sizeof(ifr.ifr_name));
ifr.ifr_flags = ifc->rb_flags;
if (ioctl(mib_netsock, SIOCSIFFLAGS, &ifr) == -1) {
syslog(LOG_ERR, "SIFFLAGS(%s): %m", ifp->name);
diff --git a/contrib/bsnmp/snmp_mibII/snmp_mibII.3 b/contrib/bsnmp/snmp_mibII/snmp_mibII.3
index 36653e6..09a9145 100644
--- a/contrib/bsnmp/snmp_mibII/snmp_mibII.3
+++ b/contrib/bsnmp/snmp_mibII/snmp_mibII.3
@@ -31,7 +31,7 @@
.\"
.\" $Begemot: bsnmp/snmp_mibII/snmp_mibII.3,v 1.10 2005/10/04 08:46:52 brandt_h Exp $
.\"
-.Dd October 4, 2005
+.Dd January 4, 2017
.Dt SNMP_MIBII 3
.Os
.Sh NAME
@@ -63,6 +63,8 @@
.Sh LIBRARY
.Pq begemotSnmpdModulePath."mibII" = "@MODPATH@snmp_mibII.so"
.Sh SYNOPSIS
+.In net/if.h
+.In net/if_mib.h
.In bsnmp/snmpmod.h
.In bsnmp/snmp_mibII.h
.Ft typedef void
diff --git a/contrib/bsnmp/snmp_usm/usm_snmp.c b/contrib/bsnmp/snmp_usm/usm_snmp.c
index 6ed639a..a6c7b86 100644
--- a/contrib/bsnmp/snmp_usm/usm_snmp.c
+++ b/contrib/bsnmp/snmp_usm/usm_snmp.c
@@ -169,8 +169,12 @@ op_usm_users(struct snmp_context *ctx, struct snmp_value *val,
val->var.subs[sub - 1] != LEAF_usmUserCloneFrom)
return (SNMP_ERR_NOSUCHNAME);
+ /*
+ * XXX (ngie): need to investigate the MIB to determine how
+ * this is possible given some of the transitions below.
+ */
if (community != COMM_INITIALIZE &&
- uuser->type == StorageType_readOnly)
+ uuser != NULL && uuser->type == StorageType_readOnly)
return (SNMP_ERR_NOT_WRITEABLE);
switch (val->var.subs[sub - 1]) {
diff --git a/contrib/bsnmp/snmpd/BEGEMOT-MIB.txt b/contrib/bsnmp/snmpd/BEGEMOT-MIB.txt
index 9d99eab..d7f6099 100644
--- a/contrib/bsnmp/snmpd/BEGEMOT-MIB.txt
+++ b/contrib/bsnmp/snmpd/BEGEMOT-MIB.txt
@@ -54,6 +54,9 @@ begemot MODULE-IDENTITY
E-mail: harti@freebsd.org"
DESCRIPTION
"The root of the Begemot subtree of the fokus tree."
+ REVISION "200201300000Z"
+ DESCRIPTION
+ "Initial revision."
::= { fokus 1 }
END
diff --git a/contrib/bsnmp/snmpd/FOKUS-MIB.txt b/contrib/bsnmp/snmpd/FOKUS-MIB.txt
index d4671e8..f356d14 100644
--- a/contrib/bsnmp/snmpd/FOKUS-MIB.txt
+++ b/contrib/bsnmp/snmpd/FOKUS-MIB.txt
@@ -52,6 +52,9 @@ fokus MODULE-IDENTITY
E-mail: harti@freebsd.org"
DESCRIPTION
"The root of the Fokus enterprises tree."
+ REVISION "200202050000Z"
+ DESCRIPTION
+ "Initial revision."
::= { enterprises 12325 }
END
diff --git a/contrib/bsnmp/snmpd/main.c b/contrib/bsnmp/snmpd/main.c
index 2ab8bbd..a2053e8 100644
--- a/contrib/bsnmp/snmpd/main.c
+++ b/contrib/bsnmp/snmpd/main.c
@@ -1024,154 +1024,6 @@ snmp_input_consume(struct port_input *pi)
pi->length -= pi->consumed;
}
-static void
-check_priv_dgram(struct port_input *pi, struct sockcred *cred)
-{
-
- /* process explicitly sends credentials */
- if (cred)
- pi->priv = (cred->sc_euid == 0);
- else
- pi->priv = 0;
-}
-
-static void
-check_priv_stream(struct port_input *pi)
-{
- struct xucred ucred;
- socklen_t ucredlen;
-
- /* 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);
- else
- pi->priv = 0;
-}
-
-/*
- * Input from a stream socket.
- */
-static int
-recv_stream(struct port_input *pi)
-{
- struct msghdr msg;
- struct iovec iov[1];
- ssize_t len;
-
- 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;
- 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_stream(pi);
-
- return (0);
-}
-
-/*
- * Input from a datagram socket.
- * Each receive should return one datagram.
- */
-static int
-recv_dgram(struct port_input *pi, struct in_addr *laddr)
-{
- u_char embuf[1000];
- char cbuf[CMSG_SPACE(SOCKCREDSIZE(CMGROUP_MAX)) +
- CMSG_SPACE(sizeof(struct in_addr))];
- struct msghdr msg;
- struct iovec iov[1];
- ssize_t len;
- struct cmsghdr *cmsg;
- struct sockcred *cred = NULL;
-
- 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;
- memset(cbuf, 0, sizeof(cbuf));
- msg.msg_control = cbuf;
- msg.msg_controllen = sizeof(cbuf);
- 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 (-1);
- }
-
- pi->length = (size_t)len;
-
- for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
- cmsg = CMSG_NXTHDR(&msg, cmsg)) {
- if (cmsg->cmsg_level == IPPROTO_IP &&
- cmsg->cmsg_type == IP_RECVDSTADDR)
- memcpy(laddr, CMSG_DATA(cmsg), sizeof(struct in_addr));
- if (cmsg->cmsg_level == SOL_SOCKET &&
- cmsg->cmsg_type == SCM_CREDS)
- cred = (struct sockcred *)CMSG_DATA(cmsg);
- }
-
- if (pi->cred)
- check_priv_dgram(pi, cred);
-
- return (0);
-}
-
/*
* Input from a socket
*/
@@ -1183,43 +1035,13 @@ snmpd_input(struct port_input *pi, struct tport *tport)
struct snmp_pdu pdu;
enum snmpd_input_err ierr, ferr;
enum snmpd_proxy_err perr;
+ ssize_t ret, slen;
int32_t vi;
- int ret;
- ssize_t slen;
#ifdef USE_TCPWRAPPERS
char client[16];
#endif
- struct msghdr msg;
- struct iovec iov[1];
- char cbuf[CMSG_SPACE(sizeof(struct in_addr))];
- struct cmsghdr *cmsgp;
-
- /* get input depending on the transport */
- if (pi->stream) {
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
-
- ret = recv_stream(pi);
- } else {
- struct in_addr *laddr;
-
- memset(cbuf, 0, CMSG_SPACE(sizeof(struct in_addr)));
- msg.msg_control = cbuf;
- msg.msg_controllen = CMSG_SPACE(sizeof(struct in_addr));
- cmsgp = CMSG_FIRSTHDR(&msg);
- cmsgp->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
- cmsgp->cmsg_level = IPPROTO_IP;
- cmsgp->cmsg_type = IP_SENDSRCADDR;
- laddr = (struct in_addr *)CMSG_DATA(cmsgp);
-
- ret = recv_dgram(pi, laddr);
-
- if (laddr->s_addr == 0) {
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- }
- }
+ ret = tport->transport->vtab->recv(tport, pi);
if (ret == -1)
return (-1);
@@ -1362,21 +1184,15 @@ snmpd_input(struct port_input *pi, struct tport *tport)
sndbuf, &sndlen, "SNMP", ierr, vi, NULL);
if (ferr == SNMPD_INPUT_OK) {
- msg.msg_name = pi->peer;
- msg.msg_namelen = pi->peerlen;
- msg.msg_iov = iov;
- msg.msg_iovlen = 1;
- msg.msg_flags = 0;
- iov[0].iov_base = sndbuf;
- iov[0].iov_len = sndlen;
-
- slen = sendmsg(pi->fd, &msg, 0);
+ slen = tport->transport->vtab->send(tport, sndbuf, sndlen,
+ pi->peer, pi->peerlen);
if (slen == -1)
- syslog(LOG_ERR, "sendmsg: %m");
+ syslog(LOG_ERR, "send*: %m");
else if ((size_t)slen != sndlen)
- syslog(LOG_ERR, "sendmsg: short write %zu/%zu",
- sndlen, (size_t)slen);
+ syslog(LOG_ERR, "send*: short write %zu/%zu", sndlen,
+ (size_t)slen);
}
+
snmp_pdu_free(&pdu);
free(sndbuf);
snmp_input_consume(pi);
@@ -2508,13 +2324,12 @@ lm_load(const char *path, const char *section)
}
m->handle = NULL;
m->flags = 0;
- strcpy(m->section, section);
+ strlcpy(m->section, section, sizeof(m->section));
- if ((m->path = malloc(strlen(path) + 1)) == NULL) {
+ if ((m->path = strdup(path)) == NULL) {
syslog(LOG_ERR, "lm_load: %m");
goto err;
}
- strcpy(m->path, path);
/*
* Make index
diff --git a/contrib/bsnmp/snmpd/snmpd.h b/contrib/bsnmp/snmpd/snmpd.h
index 009b2e7..6afbc96 100644
--- a/contrib/bsnmp/snmpd/snmpd.h
+++ b/contrib/bsnmp/snmpd/snmpd.h
@@ -193,6 +193,7 @@ struct transport_def {
ssize_t (*send)(struct tport *, const u_char *, size_t,
const struct sockaddr *, size_t);
+ ssize_t (*recv)(struct tport *, struct port_input *);
};
struct transport {
struct asn_oid index; /* transport table index */
diff --git a/contrib/bsnmp/snmpd/trans_lsock.c b/contrib/bsnmp/snmpd/trans_lsock.c
index 6c168ac..a390839 100644
--- a/contrib/bsnmp/snmpd/trans_lsock.c
+++ b/contrib/bsnmp/snmpd/trans_lsock.c
@@ -33,6 +33,7 @@
#include <sys/types.h>
#include <sys/queue.h>
#include <sys/stat.h>
+#include <sys/ucred.h>
#include <sys/un.h>
#include <errno.h>
@@ -58,6 +59,7 @@ 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);
+static ssize_t lsock_recv(struct tport *, struct port_input *);
/* exported */
const struct transport_def lsock_trans = {
@@ -67,7 +69,8 @@ const struct transport_def lsock_trans = {
lsock_stop,
lsock_close_port,
lsock_init_port,
- lsock_send
+ lsock_send,
+ lsock_recv
};
static struct transport *my_trans;
@@ -302,10 +305,9 @@ lsock_init_port(struct tport *tp)
return (SNMP_ERR_RES_UNAVAIL);
}
- strcpy(sa.sun_path, p->name);
+ strlcpy(sa.sun_path, p->name, sizeof(sa.sun_path));
sa.sun_family = AF_LOCAL;
- sa.sun_len = strlen(p->name) +
- offsetof(struct sockaddr_un, sun_path);
+ sa.sun_len = SUN_LEN(&sa);
(void)remove(p->name);
@@ -357,10 +359,9 @@ lsock_init_port(struct tport *tp)
return (SNMP_ERR_GENERR);
}
- strcpy(sa.sun_path, p->name);
+ strlcpy(sa.sun_path, p->name, sizeof(sa.sun_path));
sa.sun_family = AF_LOCAL;
- sa.sun_len = strlen(p->name) +
- offsetof(struct sockaddr_un, sun_path);
+ sa.sun_len = SUN_LEN(&sa);
(void)remove(p->name);
@@ -418,6 +419,73 @@ lsock_send(struct tport *tp, const u_char *buf, size_t len,
return (sendto(peer->input.fd, buf, len, 0, addr, addrlen));
}
+static void
+check_priv_stream(struct port_input *pi)
+{
+ struct xucred ucred;
+ socklen_t ucredlen;
+
+ /* 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);
+ else
+ pi->priv = 0;
+}
+
+/*
+ * Receive something
+ */
+static ssize_t
+lsock_recv(struct tport *tp __unused, struct port_input *pi)
+{
+ struct msghdr msg;
+ struct iovec iov[1];
+ ssize_t len;
+
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+
+ 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;
+ 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_stream(pi);
+
+ return (0);
+}
+
/*
* Dependency to create a lsock port
*/
diff --git a/contrib/bsnmp/snmpd/trans_udp.c b/contrib/bsnmp/snmpd/trans_udp.c
index a41d3f0..5c9a7fd 100644
--- a/contrib/bsnmp/snmpd/trans_udp.c
+++ b/contrib/bsnmp/snmpd/trans_udp.c
@@ -32,7 +32,9 @@
*/
#include <sys/types.h>
#include <sys/queue.h>
+#include <sys/ucred.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <syslog.h>
#include <string.h>
@@ -54,6 +56,7 @@ 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);
+static ssize_t udp_recv(struct tport *, struct port_input *);
/* exported */
const struct transport_def udp_trans = {
@@ -63,7 +66,8 @@ const struct transport_def udp_trans = {
udp_stop,
udp_close_port,
udp_init_port,
- udp_send
+ udp_send,
+ udp_recv
};
static struct transport *my_trans;
@@ -116,13 +120,15 @@ udp_init_port(struct tport *tp)
addr.sin_port = htons(p->port);
addr.sin_family = AF_INET;
addr.sin_len = sizeof(addr);
- if (addr.sin_addr.s_addr == INADDR_ANY &&
- setsockopt(p->input.fd, IPPROTO_IP, IP_RECVDSTADDR, &on,
- sizeof(on)) == -1) {
- syslog(LOG_ERR, "setsockopt(IP_RECVDSTADDR): %m");
- close(p->input.fd);
- p->input.fd = -1;
- return (SNMP_ERR_GENERR);
+ if (addr.sin_addr.s_addr == INADDR_ANY) {
+ if (setsockopt(p->input.fd, IPPROTO_IP, IP_RECVDSTADDR, &on,
+ sizeof(on)) == -1) {
+ syslog(LOG_ERR, "setsockopt(IP_RECVDSTADDR): %m");
+ close(p->input.fd);
+ p->input.fd = -1;
+ return (SNMP_ERR_GENERR);
+ }
+ p->recvdstaddr = true;
}
if (bind(p->input.fd, (struct sockaddr *)&addr, sizeof(addr))) {
if (errno == EADDRNOTAVAIL) {
@@ -214,8 +220,121 @@ 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;
+ struct cmsghdr *cmsg;
+ struct msghdr msg;
+ char cbuf[CMSG_SPACE(sizeof(struct in_addr))];
+ struct iovec iov;
+
+ iov.iov_base = __DECONST(void*, buf);
+ iov.iov_len = len;
+
+ msg.msg_flags = 0;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_name = __DECONST(void *, addr);
+ msg.msg_namelen = addrlen;
+
+ if (p->recvdstaddr) {
+ msg.msg_control = cbuf;
+ msg.msg_controllen = sizeof(cbuf);
+
+ cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_level = IPPROTO_IP;
+ cmsg->cmsg_type = IP_SENDSRCADDR;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
+ memcpy(CMSG_DATA(cmsg), &p->dstaddr, sizeof(struct in_addr));
+ } else {
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ }
+
+ return (sendmsg(p->input.fd, &msg, 0));
+}
+
+static void
+check_priv_dgram(struct port_input *pi, struct sockcred *cred)
+{
+
+ /* process explicitly sends credentials */
+ if (cred)
+ pi->priv = (cred->sc_euid == 0);
+ else
+ pi->priv = 0;
+}
+
+/*
+ * Input from a datagram socket.
+ * Each receive should return one datagram.
+ */
+static ssize_t
+udp_recv(struct tport *tp, struct port_input *pi)
+{
+ u_char embuf[1000];
+ char cbuf[CMSG_SPACE(SOCKCREDSIZE(CMGROUP_MAX)) +
+ CMSG_SPACE(sizeof(struct in_addr))];
+ struct udp_port *p = (struct udp_port *)tp;
+ struct msghdr msg;
+ struct iovec iov[1];
+ ssize_t len;
+ struct cmsghdr *cmsg;
+ struct sockcred *cred = NULL;
+
+ 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;
+ memset(cbuf, 0, sizeof(cbuf));
+ msg.msg_control = cbuf;
+ msg.msg_controllen = sizeof(cbuf);
+ 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 (-1);
+ }
+
+ pi->length = (size_t)len;
+
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
+ cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ if (cmsg->cmsg_level == IPPROTO_IP &&
+ cmsg->cmsg_type == IP_RECVDSTADDR)
+ memcpy(&p->dstaddr, CMSG_DATA(cmsg),
+ sizeof(struct in_addr));
+ if (cmsg->cmsg_level == SOL_SOCKET &&
+ cmsg->cmsg_type == SCM_CREDS)
+ cred = (struct sockcred *)CMSG_DATA(cmsg);
+ }
+
+ if (pi->cred)
+ check_priv_dgram(pi, cred);
- return (sendto(p->input.fd, buf, len, 0, addr, addrlen));
+ return (0);
}
/*
diff --git a/contrib/bsnmp/snmpd/trans_udp.h b/contrib/bsnmp/snmpd/trans_udp.h
index d383711..2f50e2a 100644
--- a/contrib/bsnmp/snmpd/trans_udp.h
+++ b/contrib/bsnmp/snmpd/trans_udp.h
@@ -39,6 +39,9 @@ struct udp_port {
struct port_input input; /* common input stuff */
struct sockaddr_in ret; /* the return address */
+
+ bool recvdstaddr; /* IP_RECVDSTADDR is on */
+ struct in_addr dstaddr; /* address the request was sent to */
};
/* argument for open call */
OpenPOWER on IntegriCloud