summaryrefslogtreecommitdiff
path: root/usr.sbin/snmpd
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2012-10-01 11:36:56 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2012-10-01 11:36:56 +0000
commit33bae3ed38b7dab44bf5ed7a6da6af4772428773 (patch)
tree7924fcd94a7613d88c741b04a9c0313e7bf1c828 /usr.sbin/snmpd
parent0bdfecfa92bc2adfbcdf936c4065b2fcd08dbad4 (diff)
Support the 0.0.0.0 and 255.255.255.255 IPv4 addresses in the ipAddrTable.
This fixes an issue which aborted the address traversal / SNMP walk when an "any"/0.0.0.0 address was configured on an interface. The problem was found with a pppoe(4) device that is typically configured with 0.0.0.0 on startup. Found and fix tested by Gerhard Roth
Diffstat (limited to 'usr.sbin/snmpd')
-rw-r--r--usr.sbin/snmpd/mib.c25
-rw-r--r--usr.sbin/snmpd/mps.c27
-rw-r--r--usr.sbin/snmpd/snmpd.h4
3 files changed, 40 insertions, 16 deletions
diff --git a/usr.sbin/snmpd/mib.c b/usr.sbin/snmpd/mib.c
index 68ddc7c2f20..d00fb5456c4 100644
--- a/usr.sbin/snmpd/mib.c
+++ b/usr.sbin/snmpd/mib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mib.c,v 1.60 2012/09/20 20:11:58 yuo Exp $ */
+/* $OpenBSD: mib.c,v 1.61 2012/10/01 11:36:55 reyk Exp $ */
/*
* Copyright (c) 2012 Joel Knight <joel@openbsd.org>
@@ -3139,15 +3139,22 @@ mib_ipaddrtable(struct oid *oid, struct ber_oid *o, struct ber_oid *no)
}
mps_decodeinaddr(no, &addr.sin_addr, OIDIDX_ipAddr + 1);
- if (addr.sin_addr.s_addr == INADDR_ANY)
+ if (o->bo_n <= (OIDIDX_ipAddr + 1))
ka = kr_getaddr(NULL);
else
ka = kr_getnextaddr((struct sockaddr *)&addr);
- if (ka == NULL || ka->addr.sa.sa_family != AF_INET)
- addr.sin_addr.s_addr = 0;
- else
+ if (ka == NULL || ka->addr.sa.sa_family != AF_INET) {
+ /*
+ * Encode invalid "last address" marker which will tell
+ * mib_ipaddr() to fail and the SNMP engine to find the
+ * next OID.
+ */
+ mps_encodeinaddr(no, NULL, OIDIDX_ipAddr + 1);
+ } else {
+ /* Encode real IPv4 address */
addr.sin_addr.s_addr = ka->addr.sin.sin_addr.s_addr;
- mps_encodeinaddr(no, &addr.sin_addr, OIDIDX_ipAddr + 1);
+ mps_encodeinaddr(no, &addr.sin_addr, OIDIDX_ipAddr + 1);
+ }
smi_oidlen(o);
return (no);
@@ -3165,7 +3172,11 @@ mib_ipaddr(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
addr.sin_family = AF_INET;
addr.sin_len = sizeof(addr);
- mps_decodeinaddr(o, &addr.sin_addr, OIDIDX_ipAddr + 1);
+ if (mps_decodeinaddr(o, &addr.sin_addr, OIDIDX_ipAddr + 1) == -1) {
+ /* Strip invalid address and fail */
+ o->bo_n = OIDIDX_ipAddr + 1;
+ return (1);
+ }
ka = kr_getaddr((struct sockaddr *)&addr);
if (ka == NULL || ka->addr.sa.sa_family != AF_INET)
return (1);
diff --git a/usr.sbin/snmpd/mps.c b/usr.sbin/snmpd/mps.c
index 9f6a4129652..e913b000c5b 100644
--- a/usr.sbin/snmpd/mps.c
+++ b/usr.sbin/snmpd/mps.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mps.c,v 1.16 2012/09/17 16:43:59 reyk Exp $ */
+/* $OpenBSD: mps.c,v 1.17 2012/10/01 11:36:55 reyk Exp $ */
/*
* Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org>
@@ -333,16 +333,23 @@ mps_table(struct oid *oid, struct ber_oid *o, struct ber_oid *no)
void
mps_encodeinaddr(struct ber_oid *o, struct in_addr *addr, int offset)
{
- u_int32_t a = htole32(addr->s_addr);
+ u_int32_t a, i;
o->bo_n = offset;
- o->bo_id[o->bo_n++] = a & 0xff;
- o->bo_id[o->bo_n++] = (a >> 8) & 0xff;
- o->bo_id[o->bo_n++] = (a >> 16) & 0xff;
- o->bo_id[o->bo_n++] = (a >> 24) & 0xff;
+ if (addr != NULL) {
+ a = htole32(addr->s_addr);
+ o->bo_id[o->bo_n++] = a & 0xff;
+ o->bo_id[o->bo_n++] = (a >> 8) & 0xff;
+ o->bo_id[o->bo_n++] = (a >> 16) & 0xff;
+ o->bo_id[o->bo_n++] = (a >> 24) & 0xff;
+ } else {
+ /* Create an invalid "last address" marker (5 bytes) */
+ for (i = 0; i < 5; i++)
+ o->bo_id[o->bo_n++] = 0xff;
+ }
}
-void
+int
mps_decodeinaddr(struct ber_oid *o, struct in_addr *addr, int offset)
{
u_int32_t a;
@@ -352,4 +359,10 @@ mps_decodeinaddr(struct ber_oid *o, struct in_addr *addr, int offset)
((o->bo_id[offset + 2] & 0xff) << 16) |
((o->bo_id[offset + 3] & 0xff) << 24);
addr->s_addr = letoh32(a);
+
+ /* Detect invalid address */
+ if ((o->bo_n - offset) > 4)
+ return (-1);
+
+ return (0);
}
diff --git a/usr.sbin/snmpd/snmpd.h b/usr.sbin/snmpd/snmpd.h
index 8f112433353..50c3c6efeae 100644
--- a/usr.sbin/snmpd/snmpd.h
+++ b/usr.sbin/snmpd/snmpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: snmpd.h,v 1.38 2012/09/18 08:29:09 reyk Exp $ */
+/* $OpenBSD: snmpd.h,v 1.39 2012/10/01 11:36:55 reyk Exp $ */
/*
* Copyright (c) 2007, 2008, 2012 Reyk Floeter <reyk@openbsd.org>
@@ -495,7 +495,7 @@ int mps_setint(struct oid *, struct ber_oid *,
int mps_getts(struct oid *, struct ber_oid *,
struct ber_element **);
void mps_encodeinaddr(struct ber_oid *, struct in_addr *, int);
-void mps_decodeinaddr(struct ber_oid *, struct in_addr *, int);
+int mps_decodeinaddr(struct ber_oid *, struct in_addr *, int);
struct ber_oid *mps_table(struct oid *, struct ber_oid *, struct ber_oid *);
/* pf.c */