summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2010-06-11 10:45:38 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2010-06-11 10:45:38 +0000
commitdebaf8b38e05822c1adaa08092af3bb6f5103c9a (patch)
treef8a4ab7e20a00a11cc75bc7979ee580c51014c45
parent8fa2f91c818ce45400b30d5e673b6f295dc53682 (diff)
Implement IP-FORWARD-MIB, ipv4 only for now.
ok reyk@ claudio@
-rw-r--r--share/snmp/OPENBSD-SNMPD-CONF.txt6
-rw-r--r--usr.sbin/snmpd/kroute.c25
-rw-r--r--usr.sbin/snmpd/mib.c248
-rw-r--r--usr.sbin/snmpd/mib.h42
-rw-r--r--usr.sbin/snmpd/snmpd.h5
5 files changed, 321 insertions, 5 deletions
diff --git a/share/snmp/OPENBSD-SNMPD-CONF.txt b/share/snmp/OPENBSD-SNMPD-CONF.txt
index 0efc32faa72..cd70a80051c 100644
--- a/share/snmp/OPENBSD-SNMPD-CONF.txt
+++ b/share/snmp/OPENBSD-SNMPD-CONF.txt
@@ -1,4 +1,4 @@
--- $OpenBSD: OPENBSD-SNMPD-CONF.txt,v 1.1 2008/12/23 18:32:10 reyk Exp $
+-- $OpenBSD: OPENBSD-SNMPD-CONF.txt,v 1.2 2010/06/11 10:45:37 jsg Exp $
--
-- Copyright (c) 2008 Reyk Floeter <reyk@openbsd.org>
--
@@ -50,6 +50,10 @@ IMPORTS
ipMIB
FROM IP-MIB
+ -- IP Forwarding MIB, RFC 4292, April 2006
+ ipForward
+ FROM IP-FORWARD-MIB
+
-- Host Resources MIB, RFC 2790, March 2000
hostResourcesMibModule
FROM HOST-RESOURCES-MIB
diff --git a/usr.sbin/snmpd/kroute.c b/usr.sbin/snmpd/kroute.c
index b852ec634d1..163a199ffd2 100644
--- a/usr.sbin/snmpd/kroute.c
+++ b/usr.sbin/snmpd/kroute.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kroute.c,v 1.13 2010/04/27 15:36:46 claudio Exp $ */
+/* $OpenBSD: kroute.c,v 1.14 2010/06/11 10:45:36 jsg Exp $ */
/*
* Copyright (c) 2007, 2008 Reyk Floeter <reyk@vantronix.net>
@@ -1277,3 +1277,26 @@ add6:
return (0);
}
+
+struct kroute *
+kroute_first(void)
+{
+ struct kroute_node *kn;
+
+ kn = RB_MIN(kroute_tree, &krt);
+ return (&kn->r);
+}
+
+struct kroute *
+kroute_getaddr(in_addr_t prefix, u_int8_t prefixlen, u_int8_t prio, int next)
+{
+ struct kroute_node *kn;
+
+ kn = kroute_find(prefix, prefixlen, prio);
+ if (kn != NULL && next)
+ kn = RB_NEXT(kroute_tree, &krt, kn);
+ if (kn != NULL)
+ return (&kn->r);
+ else
+ return (NULL);
+}
diff --git a/usr.sbin/snmpd/mib.c b/usr.sbin/snmpd/mib.c
index 8a158ad96cb..ef6fcca744b 100644
--- a/usr.sbin/snmpd/mib.c
+++ b/usr.sbin/snmpd/mib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mib.c,v 1.39 2010/04/27 15:37:13 jsg Exp $ */
+/* $OpenBSD: mib.c,v 1.40 2010/06/11 10:45:36 jsg Exp $ */
/*
* Copyright (c) 2007, 2008 Reyk Floeter <reyk@vantronix.net>
@@ -1775,6 +1775,249 @@ mib_ipaddr(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
}
/*
+ * Defined in IP-FORWARD-MIB.txt (rfc4292)
+ */
+
+int mib_ipfnroutes(struct oid *, struct ber_oid *, struct ber_element **);
+struct ber_oid *
+mib_ipfroutetable(struct oid *oid, struct ber_oid *o, struct ber_oid *no);
+int mib_ipfroute(struct oid *, struct ber_oid *, struct ber_element **);
+
+static struct oid ipf_mib[] = {
+ { MIB(ipfMIB), OID_MIB },
+ { MIB(ipfInetCidrRouteNumber), OID_RD, mib_ipfnroutes },
+
+ { MIB(ipfRouteEntIfIndex), OID_TRD, mib_ipfroute, NULL,
+ mib_ipfroutetable },
+ { MIB(ipfRouteEntType), OID_TRD, mib_ipfroute, NULL,
+ mib_ipfroutetable },
+ { MIB(ipfRouteEntProto), OID_TRD, mib_ipfroute, NULL,
+ mib_ipfroutetable },
+ { MIB(ipfRouteEntAge), OID_TRD, mib_ipfroute, NULL,
+ mib_ipfroutetable },
+ { MIB(ipfRouteEntNextHopAS), OID_TRD, mib_ipfroute, NULL,
+ mib_ipfroutetable },
+ { MIB(ipfRouteEntRouteMetric1), OID_TRD, mib_ipfroute, NULL,
+ mib_ipfroutetable },
+ { MIB(ipfRouteEntRouteMetric2), OID_TRD, mib_ipfroute, NULL,
+ mib_ipfroutetable },
+ { MIB(ipfRouteEntRouteMetric3), OID_TRD, mib_ipfroute, NULL,
+ mib_ipfroutetable },
+ { MIB(ipfRouteEntRouteMetric4), OID_TRD, mib_ipfroute, NULL,
+ mib_ipfroutetable },
+ { MIB(ipfRouteEntRouteMetric5), OID_TRD, mib_ipfroute, NULL,
+ mib_ipfroutetable },
+ { MIB(ipfRouteEntStatus), OID_TRD, mib_ipfroute, NULL,
+ mib_ipfroutetable },
+ { MIBEND }
+};
+
+int
+mib_ipfnroutes(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
+{
+ *elm = ber_add_integer(*elm, kr_routenumber());
+ ber_set_header(*elm, BER_CLASS_APPLICATION, SNMP_T_GAUGE32);
+
+ return (0);
+}
+
+struct ber_oid *
+mib_ipfroutetable(struct oid *oid, struct ber_oid *o, struct ber_oid *no)
+{
+ u_int32_t col, id;
+ struct oid a, b;
+ struct sockaddr_in addr;
+ struct kroute *kr;
+ int af, atype, idx;
+ u_int8_t prefixlen;
+ u_int8_t prio;
+
+ bzero(&addr, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_len = sizeof(addr);
+
+ bcopy(&oid->o_id, no, sizeof(*no));
+ id = oid->o_oidlen - 1;
+
+ if (o->bo_n >= oid->o_oidlen) {
+ /*
+ * Compare the requested and the matched OID to see
+ * if we have to iterate to the next element.
+ */
+ bzero(&a, sizeof(a));
+ bcopy(o, &a.o_id, sizeof(struct ber_oid));
+ bzero(&b, sizeof(b));
+ bcopy(&oid->o_id, &b.o_id, sizeof(struct ber_oid));
+ b.o_oidlen--;
+ b.o_flags |= OID_TABLE;
+ if (smi_oid_cmp(&a, &b) == 0) {
+ col = oid->o_oid[id];
+ o->bo_id[id] = col;
+ bcopy(o, no, sizeof(*no));
+ }
+ }
+
+ af = no->bo_id[OIDIDX_ipfInetCidrRoute + 1];
+ mps_decodeinaddr(no, &addr.sin_addr, OIDIDX_ipfInetCidrRoute + 3);
+ prefixlen = o->bo_id[OIDIDX_ipfInetCidrRoute + 7];
+ prio = o->bo_id[OIDIDX_ipfInetCidrRoute + 10];
+
+ if (af == 0)
+ kr = kroute_first();
+ else
+ kr = kroute_getaddr(addr.sin_addr.s_addr, prefixlen, prio, 1);
+
+ if (kr == NULL) {
+ addr.sin_addr.s_addr = 0;
+ prefixlen = 0;
+ prio = 0;
+ addr.sin_family = 0;
+ } else {
+ addr.sin_addr.s_addr = kr->prefix.s_addr;
+ prefixlen = kr->prefixlen;
+ prio = kr->priority;
+ }
+
+ switch(addr.sin_family) {
+ case AF_INET:
+ atype = 1;
+ break;
+ case AF_INET6:
+ atype = 2;
+ break;
+ default:
+ atype = 0;
+ break;
+ }
+ idx = OIDIDX_ipfInetCidrRoute + 1;
+ no->bo_id[idx++] = atype;
+ no->bo_id[idx++] = 0x04;
+ no->bo_n++;
+
+ mps_encodeinaddr(no, &addr.sin_addr, idx);
+ no->bo_id[no->bo_n++] = prefixlen;
+ no->bo_id[no->bo_n++] = 0x02;
+ no->bo_n += 2; /* policy */
+ no->bo_id[OIDIDX_ipfInetCidrRoute + 10] = prio;
+
+ if (kr != NULL) {
+ no->bo_id[no->bo_n++] = atype;
+ no->bo_id[no->bo_n++] = 0x04;
+ mps_encodeinaddr(no, &kr->nexthop, no->bo_n);
+ } else
+ no->bo_n += 2;
+
+ smi_oidlen(o);
+
+ return (no);
+}
+
+int
+mib_ipfroute(struct oid *oid, struct ber_oid *o, struct ber_element **elm)
+{
+ struct ber_element *ber = *elm;
+ struct kroute *kr;
+ struct sockaddr_in addr, nhaddr;
+ int idx = o->bo_id[OIDIDX_ipfInetCidrRoute];
+ int af;
+ u_int8_t prefixlen, prio, type, proto;
+
+
+ bzero(&addr, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_len = sizeof(addr);
+
+ af = o->bo_id[OIDIDX_ipfInetCidrRoute + 1];
+ mps_decodeinaddr(o, &addr.sin_addr, OIDIDX_ipfInetCidrRoute + 3);
+ mps_decodeinaddr(o, &nhaddr.sin_addr, OIDIDX_ipfInetCidrRoute + 23);
+ prefixlen = o->bo_id[OIDIDX_ipfInetCidrRoute + 7];
+ prio = o->bo_id[OIDIDX_ipfInetCidrRoute + 10];
+ kr = kroute_getaddr(addr.sin_addr.s_addr, prefixlen, prio, 0);
+ if (kr == NULL || af == 0) {
+ return (1);
+ }
+
+ /* write OID */
+ ber = ber_add_oid(ber, o);
+
+ switch (idx) {
+ case 7: /* IfIndex */
+ ber = ber_add_integer(ber, kr->if_index);
+ break;
+ case 8: /* Type */
+ if (kr->flags & F_REJECT)
+ type = 2;
+ else if (kr->flags & F_BLACKHOLE)
+ type = 5;
+ else if (kr->flags & F_CONNECTED)
+ type = 3;
+ else
+ type = 4;
+ ber = ber_add_integer(ber, type);
+ break;
+ case 9: /* Proto */
+ switch (kr->priority) {
+ case RTP_CONNECTED:
+ proto = 2;
+ break;
+ case RTP_STATIC:
+ proto = 3;
+ break;
+ case RTP_OSPF:
+ proto = 13;
+ break;
+ case RTP_ISIS:
+ proto = 9;
+ break;
+ case RTP_RIP:
+ proto = 8;
+ break;
+ case RTP_BGP:
+ proto = 14;
+ break;
+ default:
+ if (kr->flags & F_DYNAMIC)
+ proto = 4;
+ else
+ proto = 1; /* not specified */
+ break;
+ }
+ ber = ber_add_integer(ber, proto);
+ break;
+ case 10: /* Age */
+ ber = ber_add_integer(ber, 0);
+ ber_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_GAUGE32);
+ break;
+ case 11: /* NextHopAS */
+ ber = ber_add_integer(ber, 0); /* unknown */
+ ber_set_header(ber, BER_CLASS_APPLICATION, SNMP_T_GAUGE32);
+ break;
+ case 12: /* Metric1 */
+ ber = ber_add_integer(ber, -1); /* XXX */
+ break;
+ case 13: /* Metric2 */
+ ber = ber_add_integer(ber, -1); /* XXX */
+ break;
+ case 14: /* Metric3 */
+ ber = ber_add_integer(ber, -1); /* XXX */
+ break;
+ case 15: /* Metric4 */
+ ber = ber_add_integer(ber, -1); /* XXX */
+ break;
+ case 16: /* Metric5 */
+ ber = ber_add_integer(ber, -1); /* XXX */
+ break;
+ case 17: /* Status */
+ ber = ber_add_integer(ber, 1); /* XXX */
+ break;
+ default:
+ return (-1);
+ }
+
+ return (0);
+}
+
+/*
* Defined in BRIDGE-MIB.txt (rfc1493)
*
* This MIB is required by some NMS to accept the device because
@@ -1858,6 +2101,9 @@ mib_init(void)
/* IP-MIB */
smi_mibtree(ip_mib);
+ /* IP-FORWARD-MIB */
+ smi_mibtree(ipf_mib);
+
/* BRIDGE-MIB */
smi_mibtree(bridge_mib);
diff --git a/usr.sbin/snmpd/mib.h b/usr.sbin/snmpd/mib.h
index c324d632158..5ede7428d89 100644
--- a/usr.sbin/snmpd/mib.h
+++ b/usr.sbin/snmpd/mib.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mib.h,v 1.19 2008/12/23 08:06:10 reyk Exp $ */
+/* $OpenBSD: mib.h,v 1.20 2010/06/11 10:45:36 jsg Exp $ */
/*
* Copyright (c) 2007, 2008 Reyk Floeter <reyk@vantronix.net>
@@ -305,6 +305,31 @@
#define MIB_ipNetToMediaType MIB_ipNetToMediaEntry, 4
#define MIB_ipRoutingDiscards MIB_ipMIB, 23
+/* IP-FORWARD-MIB */
+#define MIB_ipfMIB MIB_ipMIB, 24
+#define MIB_ipfInetCidrRouteNumber MIB_ipfMIB, 6
+#define MIB_ipfInetCidrRouteTable MIB_ipfMIB, 7
+#define MIB_ipfInetCidrRouteEntry MIB_ipfInetCidrRouteTable, 1
+#define OIDIDX_ipfInetCidrRoute 10
+#define MIB_ipfRouteEntDestType MIB_ipfInetCidrRouteEntry, 1
+#define MIB_ipfRouteEntDest MIB_ipfInetCidrRouteEntry, 2
+#define MIB_ipfRouteEntPfxLen MIB_ipfInetCidrRouteEntry, 3
+#define MIB_ipfRouteEntPolicy MIB_ipfInetCidrRouteEntry, 4
+#define MIB_ipfRouteEntNextHopType MIB_ipfInetCidrRouteEntry, 5
+#define MIB_ipfRouteEntNextHop MIB_ipfInetCidrRouteEntry, 6
+#define MIB_ipfRouteEntIfIndex MIB_ipfInetCidrRouteEntry, 7
+#define MIB_ipfRouteEntType MIB_ipfInetCidrRouteEntry, 8
+#define MIB_ipfRouteEntProto MIB_ipfInetCidrRouteEntry, 9
+#define MIB_ipfRouteEntAge MIB_ipfInetCidrRouteEntry, 10
+#define MIB_ipfRouteEntNextHopAS MIB_ipfInetCidrRouteEntry, 11
+#define MIB_ipfRouteEntRouteMetric1 MIB_ipfInetCidrRouteEntry, 12
+#define MIB_ipfRouteEntRouteMetric2 MIB_ipfInetCidrRouteEntry, 13
+#define MIB_ipfRouteEntRouteMetric3 MIB_ipfInetCidrRouteEntry, 14
+#define MIB_ipfRouteEntRouteMetric4 MIB_ipfInetCidrRouteEntry, 15
+#define MIB_ipfRouteEntRouteMetric5 MIB_ipfInetCidrRouteEntry, 16
+#define MIB_ipfRouteEntStatus MIB_ipfInetCidrRouteEntry, 17
+#define MIB_ipfInetCidrRouteDiscards MIB_ipfMIB, 8
+
/* BRIDGE-MIB */
#define MIB_dot1dBridge MIB_mib_2, 17
#define MIB_dot1dBase MIB_dot1dBridge, 1
@@ -715,6 +740,21 @@
{ MIBDECL(ipNetToMediaType) }, \
{ MIBDECL(ipNetToMediaType) }, \
\
+ { MIBDECL(ipfMIB) }, \
+ { MIBDECL(ipfInetCidrRouteNumber) }, \
+ { MIBDECL(ipfInetCidrRouteTable) }, \
+ { MIBDECL(ipfInetCidrRouteEntry) }, \
+ { MIBDECL(ipfRouteEntIfIndex) }, \
+ { MIBDECL(ipfRouteEntType) }, \
+ { MIBDECL(ipfRouteEntProto) }, \
+ { MIBDECL(ipfRouteEntAge) }, \
+ { MIBDECL(ipfRouteEntNextHopAS) }, \
+ { MIBDECL(ipfRouteEntRouteMetric1) }, \
+ { MIBDECL(ipfRouteEntRouteMetric2) }, \
+ { MIBDECL(ipfRouteEntRouteMetric3) }, \
+ { MIBDECL(ipfRouteEntRouteMetric4) }, \
+ { MIBDECL(ipfRouteEntRouteMetric5) }, \
+ { MIBDECL(ipfRouteEntStatus) }, \
{ MIBEND } \
}
diff --git a/usr.sbin/snmpd/snmpd.h b/usr.sbin/snmpd/snmpd.h
index b3599806c31..4feb57170cf 100644
--- a/usr.sbin/snmpd/snmpd.h
+++ b/usr.sbin/snmpd/snmpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: snmpd.h,v 1.28 2010/04/01 14:42:32 claudio Exp $ */
+/* $OpenBSD: snmpd.h,v 1.29 2010/06/11 10:45:36 jsg Exp $ */
/*
* Copyright (c) 2007, 2008 Reyk Floeter <reyk@vantronix.net>
@@ -348,6 +348,9 @@ struct kif *kr_getnextif(u_short);
struct kif_addr *kr_getaddr(struct sockaddr *);
struct kif_addr *kr_getnextaddr(struct sockaddr *);
+struct kroute *kroute_first(void);
+struct kroute *kroute_getaddr(in_addr_t, u_int8_t, u_int8_t, int);
+
/* snmpe.c */
pid_t snmpe(struct snmpd *, int [2]);
void snmpe_debug_elements(struct ber_element *);