summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Bernat <bernat@luffy.cx>2012-05-31 13:30:28 +0200
committerVincent Bernat <bernat@luffy.cx>2012-06-25 19:03:23 +0200
commit8046ba6ec4d6e87bf8da6563c0f3e5e66c4652b3 (patch)
tree1b38b2eae4e1cee042f96a42217b14647159bf0f
parent0ff4b9c96793898429052de576d8da368e48997e (diff)
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.
-rw-r--r--bgpd/bgp_snmp.c7
-rw-r--r--lib/smux.h2
-rw-r--r--lib/snmp.c20
-rw-r--r--ospf6d/ospf6_snmp.c8
-rw-r--r--ospfd/ospf_snmp.c48
-rw-r--r--ripd/rip_snmp.c12
-rw-r--r--zebra/zebra_snmp.c8
7 files changed, 104 insertions, 1 deletions
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: