From 8046ba6ec4d6e87bf8da6563c0f3e5e66c4652b3 Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Thu, 31 May 2012 13:30:28 +0200 Subject: snmp: let handlers accept OID from a lesser prefix Most table handlers do not expect to be given an OID whose prefix is outside what they can handle. This is not a problem with the SMUX implementation since it always correct the OID such that the prefix matches. However, this is not the case for the AgentX implementation. A new function, smux_header_table() is used to do this normalization. --- bgpd/bgp_snmp.c | 7 ++++++- lib/smux.h | 2 ++ lib/snmp.c | 20 ++++++++++++++++++++ ospf6d/ospf6_snmp.c | 8 ++++++++ ospfd/ospf_snmp.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ ripd/rip_snmp.c | 12 ++++++++++++ zebra/zebra_snmp.c | 8 ++++++++ 7 files changed, 104 insertions(+), 1 deletion(-) diff --git a/bgpd/bgp_snmp.c b/bgpd/bgp_snmp.c index 36fd4ef4..c8f2aa54 100644 --- a/bgpd/bgp_snmp.c +++ b/bgpd/bgp_snmp.c @@ -455,7 +455,9 @@ bgpPeerTable (struct variable *v, oid name[], size_t *length, static struct in_addr addr; struct peer *peer; - *write_method = NULL; + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; memset (&addr, 0, sizeof (struct in_addr)); peer = bgpPeerTable_lookup (v, name, length, &addr, exact); @@ -765,6 +767,9 @@ bgp4PathAttrTable (struct variable *v, oid name[], size_t *length, if (! bgp) return NULL; + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; memset (&addr, 0, sizeof (struct prefix_ipv4)); binfo = bgp4PathAttrLookup (v, name, length, bgp, &addr, exact); diff --git a/lib/smux.h b/lib/smux.h index b29fdc72..72b4eaf0 100644 --- a/lib/smux.h +++ b/lib/smux.h @@ -75,6 +75,8 @@ extern void smux_register_mib(const char *, struct variable *, size_t, int, oid [], size_t); extern int smux_header_generic (struct variable *, oid [], size_t *, int, size_t *, WriteMethod **); +extern int smux_header_table (struct variable *, oid *, size_t *, + int, size_t *, WriteMethod **); /* For traps, three OID are provided: diff --git a/lib/snmp.c b/lib/snmp.c index d7b1d953..79595a1e 100644 --- a/lib/snmp.c +++ b/lib/snmp.c @@ -110,4 +110,24 @@ smux_header_generic (struct variable *v, oid *name, size_t *length, int exact, return MATCH_SUCCEEDED; } + +int +smux_header_table (struct variable *v, oid *name, size_t *length, int exact, + size_t *var_len, WriteMethod **write_method) +{ + /* If the requested OID name is less than OID prefix we + handle, adjust it to our prefix. */ + if ((oid_compare (name, *length, v->name, v->namelen)) < 0) + { + if (exact) + return MATCH_FAILED; + oid_copy(name, v->name, v->namelen); + *length = v->namelen; + } + + *write_method = 0; + *var_len = sizeof(long); + + return MATCH_SUCCEEDED; +} #endif /* HAVE_SNMP */ diff --git a/ospf6d/ospf6_snmp.c b/ospf6d/ospf6_snmp.c index 11b733b8..d252f549 100644 --- a/ospf6d/ospf6_snmp.c +++ b/ospf6d/ospf6_snmp.c @@ -306,6 +306,10 @@ ospfv3AreaEntry (struct variable *v, oid *name, size_t *length, if (ospf6 == NULL) return NULL; + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + len = *length - v->namelen; len = (len >= sizeof (u_int32_t) ? sizeof (u_int32_t) : 0); if (exact && len != sizeof (u_int32_t)) @@ -372,6 +376,10 @@ ospfv3AreaLsdbEntry (struct variable *v, oid *name, size_t *length, struct ospf6_area *oa; struct listnode *node; + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + memset (&area_id, 0, sizeof (struct in_addr)); type = 0; memset (&id, 0, sizeof (struct in_addr)); diff --git a/ospfd/ospf_snmp.c b/ospfd/ospf_snmp.c index c8416de6..1daf0d6a 100644 --- a/ospfd/ospf_snmp.c +++ b/ospfd/ospf_snmp.c @@ -704,6 +704,10 @@ ospfAreaEntry (struct variable *v, oid *name, size_t *length, int exact, struct ospf_area *area; struct in_addr addr; + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + memset (&addr, 0, sizeof (struct in_addr)); area = ospfAreaLookup (v, name, length, &addr, exact); @@ -847,6 +851,10 @@ ospfStubAreaEntry (struct variable *v, oid *name, size_t *length, struct ospf_area *area; struct in_addr addr; + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + memset (&addr, 0, sizeof (struct in_addr)); area = ospfStubAreaLookup (v, name, length, &addr, exact); @@ -1078,6 +1086,10 @@ ospfLsdbEntry (struct variable *v, oid *name, size_t *length, int exact, struct in_addr router_id; struct ospf *ospf; + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + /* INDEX { ospfLsdbAreaId, ospfLsdbType, ospfLsdbLsid, ospfLsdbRouterId } */ @@ -1240,6 +1252,10 @@ ospfAreaRangeEntry (struct variable *v, oid *name, size_t *length, int exact, struct in_addr mask; struct ospf *ospf; + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + /* Check OSPF instance. */ ospf = ospf_lookup (); if (ospf == NULL) @@ -1344,6 +1360,10 @@ ospfHostEntry (struct variable *v, oid *name, size_t *length, int exact, struct in_addr addr; struct ospf *ospf; + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + /* Check OSPF instance. */ ospf = ospf_lookup (); if (ospf == NULL) @@ -1679,6 +1699,10 @@ ospfIfEntry (struct variable *v, oid *name, size_t *length, int exact, struct ospf_interface *oi; struct ospf *ospf; + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + ifindex = 0; memset (&ifaddr, 0, sizeof (struct in_addr)); @@ -1847,6 +1871,10 @@ ospfIfMetricEntry (struct variable *v, oid *name, size_t *length, int exact, struct ospf_interface *oi; struct ospf *ospf; + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + ifindex = 0; memset (&ifaddr, 0, sizeof (struct in_addr)); @@ -2039,6 +2067,10 @@ ospfVirtIfEntry (struct variable *v, oid *name, size_t *length, int exact, struct in_addr area_id; struct in_addr neighbor; + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + memset (&area_id, 0, sizeof (struct in_addr)); memset (&neighbor, 0, sizeof (struct in_addr)); @@ -2272,6 +2304,10 @@ ospfNbrEntry (struct variable *v, oid *name, size_t *length, int exact, struct ospf_neighbor *nbr; struct ospf_interface *oi; + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + memset (&nbr_addr, 0, sizeof (struct in_addr)); ifindex = 0; @@ -2334,6 +2370,10 @@ ospfVirtNbrEntry (struct variable *v, oid *name, size_t *length, int exact, struct in_addr neighbor; struct ospf *ospf; + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + memset (&area_id, 0, sizeof (struct in_addr)); memset (&neighbor, 0, sizeof (struct in_addr)); @@ -2482,6 +2522,10 @@ ospfExtLsdbEntry (struct variable *v, oid *name, size_t *length, int exact, struct in_addr router_id; struct ospf *ospf; + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + type = OSPF_AS_EXTERNAL_LSA; memset (&ls_id, 0, sizeof (struct in_addr)); memset (&router_id, 0, sizeof (struct in_addr)); @@ -2533,6 +2577,10 @@ static u_char * ospfAreaAggregateEntry (struct variable *v, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method) { + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + /* Return the current value of the variable */ switch (v->magic) { diff --git a/ripd/rip_snmp.c b/ripd/rip_snmp.c index 803ac856..090ebfae 100644 --- a/ripd/rip_snmp.c +++ b/ripd/rip_snmp.c @@ -345,6 +345,10 @@ rip2IfStatEntry (struct variable *v, oid name[], size_t *length, static struct in_addr addr; static long valid = SNMP_VALID; + if (smux_header_table(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + memset (&addr, 0, sizeof (struct in_addr)); /* Lookup interface. */ @@ -448,6 +452,10 @@ rip2IfConfAddress (struct variable *v, oid name[], size_t *length, struct interface *ifp; struct rip_interface *ri; + if (smux_header_table(v, name, length, exact, val_len, write_method) + == MATCH_FAILED) + return NULL; + memset (&addr, 0, sizeof (struct in_addr)); /* Lookup interface. */ @@ -518,6 +526,10 @@ rip2PeerTable (struct variable *v, oid name[], size_t *length, struct rip_peer *peer; + if (smux_header_table(v, name, length, exact, val_len, write_method) + == MATCH_FAILED) + return NULL; + memset (&addr, 0, sizeof (struct in_addr)); /* Lookup interface. */ diff --git a/zebra/zebra_snmp.c b/zebra/zebra_snmp.c index 3dbfb587..f52bbcb8 100644 --- a/zebra/zebra_snmp.c +++ b/zebra/zebra_snmp.c @@ -451,6 +451,10 @@ ipFwTable (struct variable *v, oid objid[], size_t *objid_len, static struct in_addr netmask; struct nexthop *nexthop; + if (smux_header_table(v, objid, objid_len, exact, val_len, write_method) + == MATCH_FAILED) + return NULL; + get_fwtable_route_node(v, objid, objid_len, exact, &np, &rib); if (!np) return NULL; @@ -549,6 +553,10 @@ static u_char * ipCidrTable (struct variable *v, oid objid[], size_t *objid_len, int exact, size_t *val_len, WriteMethod **write_method) { + if (smux_header_table(v, objid, objid_len, exact, val_len, write_method) + == MATCH_FAILED) + return NULL; + switch (v->magic) { case IPCIDRROUTEDEST: -- cgit v1.2.1