diff options
-rw-r--r-- | bgpd/bgp_snmp.c | 9 | ||||
-rw-r--r-- | lib/agentx.c | 82 | ||||
-rw-r--r-- | lib/smux.c | 9 | ||||
-rw-r--r-- | lib/smux.h | 31 | ||||
-rw-r--r-- | ospfd/ospf_snmp.c | 17 |
5 files changed, 137 insertions, 11 deletions
diff --git a/bgpd/bgp_snmp.c b/bgpd/bgp_snmp.c index 73406d59..36fd4ef4 100644 --- a/bgpd/bgp_snmp.c +++ b/bgpd/bgp_snmp.c @@ -118,6 +118,7 @@ SNMP_LOCAL_VARIABLES /* BGP-MIB instances. */ oid bgp_oid [] = { BGP4MIB }; +oid bgp_trap_oid [] = { BGP4MIB, 0 }; /* IP address 0.0.0.0. */ static struct in_addr bgp_empty_addr = {0}; @@ -850,7 +851,9 @@ bgpTrapEstablished (struct peer *peer) oid_copy_addr (index, &addr, IN_ADDR_SIZE); - smux_trap (bgp_oid, sizeof bgp_oid / sizeof (oid), + smux_trap (bgp_variables, sizeof bgp_variables / sizeof (struct variable), + bgp_trap_oid, sizeof bgp_trap_oid / sizeof (oid), + bgp_oid, sizeof bgp_oid / sizeof (oid), index, IN_ADDR_SIZE, bgpTrapList, sizeof bgpTrapList / sizeof (struct trap_object), BGPESTABLISHED); @@ -869,7 +872,9 @@ bgpTrapBackwardTransition (struct peer *peer) oid_copy_addr (index, &addr, IN_ADDR_SIZE); - smux_trap (bgp_oid, sizeof bgp_oid / sizeof (oid), + smux_trap (bgp_variables, sizeof bgp_variables / sizeof (struct variable), + bgp_trap_oid, sizeof bgp_trap_oid / sizeof (oid), + bgp_oid, sizeof bgp_oid / sizeof (oid), index, IN_ADDR_SIZE, bgpTrapList, sizeof bgpTrapList / sizeof (struct trap_object), BGPBACKWARDTRANSITION); diff --git a/lib/agentx.c b/lib/agentx.c index 2358581f..be6b4320 100644 --- a/lib/agentx.c +++ b/lib/agentx.c @@ -122,11 +122,91 @@ smux_register_mib (const char *descr, struct variable *var, } int -smux_trap (const oid *name, size_t namelen, +smux_trap (struct variable *vp, size_t vp_len, + const oid *ename, size_t enamelen, + const oid *name, size_t namelen, const oid *iname, size_t inamelen, const struct trap_object *trapobj, size_t trapobjlen, u_char sptrap) { + oid objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 }; + size_t objid_snmptrap_len = sizeof objid_snmptrap / sizeof (oid); + oid notification_oid[MAX_OID_LEN]; + size_t notification_oid_len; + unsigned int i; + + netsnmp_variable_list *notification_vars = NULL; + if (!agentx_enabled) return 0; + + /* snmpTrapOID */ + oid_copy (notification_oid, ename, enamelen); + notification_oid[enamelen] = sptrap; + notification_oid_len = enamelen + 1; + snmp_varlist_add_variable (¬ification_vars, + objid_snmptrap, objid_snmptrap_len, + ASN_OBJECT_ID, + (u_char *) notification_oid, + notification_oid_len * sizeof(oid)); + + /* Provided bindings */ + for (i = 0; i < trapobjlen; i++) + { + unsigned int j; + oid oid[MAX_OID_LEN]; + size_t oid_len, onamelen; + u_char *val; + size_t val_len; + WriteMethod *wm = NULL; + struct variable cvp; + + /* Make OID. */ + if (trapobj[i].namelen > 0) + { + /* Columnar object */ + onamelen = trapobj[i].namelen; + oid_copy (oid, name, namelen); + oid_copy (oid + namelen, trapobj[i].name, onamelen); + oid_copy (oid + namelen + onamelen, iname, inamelen); + oid_len = namelen + onamelen + inamelen; + } + else + { + /* Scalar object */ + onamelen = trapobj[i].namelen * (-1); + oid_copy (oid, name, namelen); + oid_copy (oid + namelen, trapobj[i].name, onamelen); + oid[onamelen + namelen] = 0; + oid_len = namelen + onamelen + 1; + } + + /* Locate the appropriate function and type in the MIB registry. */ + for (j = 0; j < vp_len; j++) + { + if (oid_compare (trapobj[i].name, onamelen, vp[j].name, vp[j].namelen) != 0) + continue; + /* We found the appropriate variable in the MIB registry. */ + oid_copy(cvp.name, name, namelen); + oid_copy(cvp.name + namelen, vp[j].name, vp[j].namelen); + cvp.namelen = namelen + vp[j].namelen; + cvp.type = vp[j].type; + cvp.magic = vp[j].magic; + cvp.acl = vp[j].acl; + cvp.findVar = vp[j].findVar; + /* Grab the result. */ + val = cvp.findVar (&cvp, oid, &oid_len, 1, &val_len, &wm); + if (!val) break; + snmp_varlist_add_variable (¬ification_vars, + oid, oid_len, + vp[j].type, + val, + val_len); + break; + } + } + + + send_v2trap (notification_vars); + snmp_free_varbind (notification_vars); return 1; } @@ -968,8 +968,15 @@ smux_open (int sock) return send (sock, buf, (ptr - buf), 0); } +/* `ename` is ignored. Instead of using the provided enterprise OID, + the SMUX peer is used. This keep compatibility with the previous + versions of Quagga. + + All other fields are used as they are intended. */ int -smux_trap (const oid *name, size_t namelen, +smux_trap (struct variable *vp, size_t vp_len, + const oid *ename, size_t enamelen, + const oid *name, size_t namelen, const oid *iname, size_t inamelen, const struct trap_object *trapobj, size_t trapobjlen, u_char sptrap) @@ -75,9 +75,34 @@ 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_trap (const oid *, size_t, const oid *, size_t, - const struct trap_object *, - size_t, u_char); + +/* For traps, three OID are provided: + + 1. The enterprise OID to use (the last argument will be appended to + it to form the SNMP trap OID) + + 2. The base OID for objects to be sent in traps. + + 3. The index OID for objects to be sent in traps. This index is used + to designate a particular instance of a column. + + The provided trap object contains the bindings to be sent with the + trap. The base OID will be prefixed to the provided OID and, if the + length is positive, the requested OID is assumed to be a columnar + object and the index OID will be appended. + + The two first arguments are the MIB registry used to locate the trap + objects. + + The use of the arguments may differ depending on the implementation + used. +*/ +extern int smux_trap (struct variable *, size_t, + const oid *, size_t, + const oid *, size_t, + const oid *, size_t, + const struct trap_object *, size_t, + u_char); extern int oid_compare (oid *, int, oid *, int); extern void oid2in_addr (oid [], int, struct in_addr *); diff --git a/ospfd/ospf_snmp.c b/ospfd/ospf_snmp.c index b2d56860..c8416de6 100644 --- a/ospfd/ospf_snmp.c +++ b/ospfd/ospf_snmp.c @@ -210,6 +210,7 @@ SNMP_LOCAL_VARIABLES /* OSPF-MIB instances. */ oid ospf_oid [] = { OSPF2MIB }; +oid ospf_trap_oid [] = { OSPF2MIB, 16, 2 }; /* Not reverse mappable! */ /* IP address 0.0.0.0. */ static struct in_addr ospf_empty_addr = {0}; @@ -2612,7 +2613,9 @@ ospfTrapNbrStateChange (struct ospf_neighbor *on) oid_copy_addr (index, &(on->address.u.prefix4), IN_ADDR_SIZE); index[IN_ADDR_SIZE] = 0; - smux_trap (ospf_oid, sizeof ospf_oid / sizeof (oid), + smux_trap (ospf_variables, sizeof ospf_variables / sizeof (struct variable), + ospf_trap_oid, sizeof ospf_trap_oid / sizeof (oid), + ospf_oid, sizeof ospf_oid / sizeof (oid), index, IN_ADDR_SIZE + 1, ospfNbrTrapList, sizeof ospfNbrTrapList / sizeof (struct trap_object), @@ -2629,7 +2632,9 @@ ospfTrapVirtNbrStateChange (struct ospf_neighbor *on) oid_copy_addr (index, &(on->address.u.prefix4), IN_ADDR_SIZE); index[IN_ADDR_SIZE] = 0; - smux_trap (ospf_oid, sizeof ospf_oid / sizeof (oid), + smux_trap (ospf_variables, sizeof ospf_variables / sizeof (struct variable), + ospf_trap_oid, sizeof ospf_trap_oid / sizeof (oid), + ospf_oid, sizeof ospf_oid / sizeof (oid), index, IN_ADDR_SIZE + 1, ospfVirtNbrTrapList, sizeof ospfVirtNbrTrapList / sizeof (struct trap_object), @@ -2648,7 +2653,9 @@ ospfTrapIfStateChange (struct ospf_interface *oi) oid_copy_addr (index, &(oi->address->u.prefix4), IN_ADDR_SIZE); index[IN_ADDR_SIZE] = 0; - smux_trap (ospf_oid, sizeof ospf_oid / sizeof (oid), + smux_trap (ospf_variables, sizeof ospf_variables / sizeof (struct variable), + ospf_trap_oid, sizeof ospf_trap_oid / sizeof (oid), + ospf_oid, sizeof ospf_oid / sizeof (oid), index, IN_ADDR_SIZE + 1, ospfIfTrapList, sizeof ospfIfTrapList / sizeof (struct trap_object), @@ -2665,7 +2672,9 @@ ospfTrapVirtIfStateChange (struct ospf_interface *oi) oid_copy_addr (index, &(oi->address->u.prefix4), IN_ADDR_SIZE); index[IN_ADDR_SIZE] = 0; - smux_trap (ospf_oid, sizeof ospf_oid / sizeof (oid), + smux_trap (ospf_variables, sizeof ospf_variables / sizeof (struct variable), + ospf_trap_oid, sizeof ospf_trap_oid / sizeof (oid), + ospf_oid, sizeof ospf_oid / sizeof (oid), index, IN_ADDR_SIZE + 1, ospfVirtIfTrapList, sizeof ospfVirtIfTrapList / sizeof (struct trap_object), |