diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2010-06-11 10:45:38 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2010-06-11 10:45:38 +0000 |
commit | debaf8b38e05822c1adaa08092af3bb6f5103c9a (patch) | |
tree | f8a4ab7e20a00a11cc75bc7979ee580c51014c45 | |
parent | 8fa2f91c818ce45400b30d5e673b6f295dc53682 (diff) |
Implement IP-FORWARD-MIB, ipv4 only for now.
ok reyk@ claudio@
-rw-r--r-- | share/snmp/OPENBSD-SNMPD-CONF.txt | 6 | ||||
-rw-r--r-- | usr.sbin/snmpd/kroute.c | 25 | ||||
-rw-r--r-- | usr.sbin/snmpd/mib.c | 248 | ||||
-rw-r--r-- | usr.sbin/snmpd/mib.h | 42 | ||||
-rw-r--r-- | usr.sbin/snmpd/snmpd.h | 5 |
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 *); |