diff options
Diffstat (limited to 'eigrpd/eigrp_snmp.c')
-rw-r--r-- | eigrpd/eigrp_snmp.c | 1327 |
1 files changed, 1327 insertions, 0 deletions
diff --git a/eigrpd/eigrp_snmp.c b/eigrpd/eigrp_snmp.c new file mode 100644 index 0000000..5a93042 --- /dev/null +++ b/eigrpd/eigrp_snmp.c @@ -0,0 +1,1327 @@ +/* + * EIGRP SNMP Support. + * Copyright (C) 2013-2014 + * Authors: + * Donnie Savage + * Jan Janovic + * Matej Perina + * Peter Orsag + * Peter Paluch + * + * This file is part of GNU Zebra. + * + * GNU Zebra is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * GNU Zebra is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <zebra.h> + +#ifdef HAVE_SNMP +#include <net-snmp/net-snmp-config.h> +#include <net-snmp/net-snmp-includes.h> + +#include "thread.h" +#include "memory.h" +#include "linklist.h" +#include "prefix.h" +#include "if.h" +#include "table.h" +#include "sockunion.h" +#include "stream.h" +#include "log.h" +#include "sockopt.h" +#include "checksum.h" +#include "md5.h" +#include "keychain.h" +#include "smux.h" + +#include "eigrpd/eigrp_structs.h" +#include "eigrpd/eigrpd.h" +#include "eigrpd/eigrp_interface.h" +#include "eigrpd/eigrp_neighbor.h" +#include "eigrpd/eigrp_packet.h" +#include "eigrpd/eigrp_zebra.h" +#include "eigrpd/eigrp_vty.h" +#include "eigrpd/eigrp_dump.h" +#include "eigrpd/eigrp_network.h" +#include "eigrpd/eigrp_topology.h" +#include "eigrpd/eigrp_fsm.h" +#include "eigrpd/eigrp_snmp.h" + +struct list *eigrp_snmp_iflist; + +/* Declare static local variables for convenience. */ +SNMP_LOCAL_VARIABLES + +/* EIGRP-MIB - 1.3.6.1.4.1.9.9.449.1*/ +#define EIGRPMIB 1,3,6,1,4,1,9,9,449,1 + +/* EIGRP-MIB instances. */ +oid eigrp_oid[] = {EIGRPMIB}; + +/* EIGRP VPN entry */ +#define EIGRPVPNID 1 +#define EIGRPVPNNAME 2 + +/* EIGRP Traffic statistics entry */ +#define EIGRPASNUMBER 1 +#define EIGRPNBRCOUNT 2 +#define EIGRPHELLOSSENT 3 +#define EIGRPHELLOSRCVD 4 +#define EIGRPUPDATESSENT 5 +#define EIGRPUPDATESRCVD 6 +#define EIGRPQUERIESSENT 7 +#define EIGRPQUERIESRCVD 8 +#define EIGRPREPLIESSENT 9 +#define EIGRPREPLIESRCVD 10 +#define EIGRPACKSSENT 11 +#define EIGRPACKSRCVD 12 +#define EIGRPINPUTQHIGHMARK 13 +#define EIGRPINPUTQDROPS 14 +#define EIGRPSIAQUERIESSENT 15 +#define EIGRPSIAQUERIESRCVD 16 +#define EIGRPASROUTERIDTYPE 17 +#define EIGRPASROUTERID 18 +#define EIGRPTOPOROUTES 19 +#define EIGRPHEADSERIAL 20 +#define EIGRPNEXTSERIAL 21 +#define EIGRPXMITPENDREPLIES 22 +#define EIGRPXMITDUMMIES 23 + +/* EIGRP topology entry */ +#define EIGRPDESTNETTYPE 1 +#define EIGRPDESTNET 2 +#define EIGRPDESTNETPREFIXLEN 4 +#define EIGRPACTIVE 5 +#define EIGRPSTUCKINACTIVE 6 +#define EIGRPDESTSUCCESSORS 7 +#define EIGRPFDISTANCE 8 +#define EIGRPROUTEORIGINTYPE 9 +#define EIGRPROUTEORIGINADDRTYPE 10 +#define EIGRPROUTEORIGINADDR 11 +#define EIGRPNEXTHOPADDRESSTYPE 12 +#define EIGRPNEXTHOPADDRESS 13 +#define EIGRPNEXTHOPINTERFACE 14 +#define EIGRPDISTANCE 15 +#define EIGRPREPORTDISTANCE 16 + +/* EIGRP peer entry */ +#define EIGRPHANDLE 1 +#define EIGRPPEERADDRTYPE 2 +#define EIGRPPEERADDR 3 +#define EIGRPPEERIFINDEX 4 +#define EIGRPHOLDTIME 5 +#define EIGRPUPTIME 6 +#define EIGRPSRTT 7 +#define EIGRPRTO 8 +#define EIGRPPKTSENQUEUED 9 +#define EIGRPLASTSEQ 10 +#define EIGRPVERSION 11 +#define EIGRPRETRANS 12 +#define EIGRPRETRIES 13 + +/* EIGRP interface entry */ +#define EIGRPPEERCOUNT 3 +#define EIGRPXMITRELIABLEQ 4 +#define EIGRPXMITUNRELIABLEQ 5 +#define EIGRPMEANSRTT 6 +#define EIGRPPACINGRELIABLE 7 +#define EIGRPPACINGUNRELIABLE 8 +#define EIGRPMFLOWTIMER 9 +#define EIGRPPENDINGROUTES 10 +#define EIGRPHELLOINTERVAL 11 +#define EIGRPXMITNEXTSERIAL 12 +#define EIGRPUMCASTS 13 +#define EIGRPRMCASTS 14 +#define EIGRPUUCASTS 15 +#define EIGRPRUCASTS 16 +#define EIGRPMCASTEXCEPTS 17 +#define EIGRPCRPKTS 18 +#define EIGRPACKSSUPPRESSED 19 +#define EIGRPRETRANSSENT 20 +#define EIGRPOOSRCVD 21 +#define EIGRPAUTHMODE 22 +#define EIGRPAUTHKEYCHAIN 23 + +/* SNMP value hack. */ +#define COUNTER ASN_COUNTER +#define INTEGER ASN_INTEGER +#define GAUGE ASN_GAUGE +#define TIMETICKS ASN_TIMETICKS +#define IPADDRESS ASN_IPADDRESS +#define STRING ASN_OCTET_STR +#define IPADDRESSPREFIXLEN ASN_INTEGER +#define IPADDRESSTYPE ASN_INTEGER +#define INTERFACEINDEXORZERO ASN_INTEGER +#define UINTEGER ASN_UNSIGNED + +/* Hook functions. */ +static uint8_t *eigrpVpnEntry(struct variable *, oid *, size_t *, int, size_t *, + WriteMethod **); +static uint8_t *eigrpTraffStatsEntry(struct variable *, oid *, size_t *, int, + size_t *, WriteMethod **); +static uint8_t *eigrpTopologyEntry(struct variable *, oid *, size_t *, int, + size_t *, WriteMethod **); +static uint8_t *eigrpPeerEntry(struct variable *, oid *, size_t *, int, + size_t *, WriteMethod **); +static uint8_t *eigrpInterfaceEntry(struct variable *, oid *, size_t *, int, + size_t *, WriteMethod **); + + +struct variable eigrp_variables[] = { + /* EIGRP vpn variables */ + {EIGRPVPNID, INTEGER, NOACCESS, eigrpVpnEntry, 4, {1, 1, 1, 1}}, + {EIGRPVPNNAME, STRING, RONLY, eigrpVpnEntry, 4, {1, 1, 1, 2}}, + + /* EIGRP traffic stats variables */ + {EIGRPASNUMBER, + UINTEGER, + NOACCESS, + eigrpTraffStatsEntry, + 4, + {2, 1, 1, 1}}, + {EIGRPNBRCOUNT, UINTEGER, RONLY, eigrpTraffStatsEntry, 4, {2, 1, 1, 2}}, + {EIGRPHELLOSSENT, + COUNTER, + RONLY, + eigrpTraffStatsEntry, + 4, + {2, 1, 1, 3}}, + {EIGRPHELLOSRCVD, + COUNTER, + RONLY, + eigrpTraffStatsEntry, + 4, + {2, 1, 1, 4}}, + {EIGRPUPDATESSENT, + COUNTER, + RONLY, + eigrpTraffStatsEntry, + 4, + {2, 1, 1, 5}}, + {EIGRPUPDATESRCVD, + COUNTER, + RONLY, + eigrpTraffStatsEntry, + 4, + {2, 1, 1, 6}}, + {EIGRPQUERIESSENT, + COUNTER, + RONLY, + eigrpTraffStatsEntry, + 4, + {2, 1, 1, 7}}, + {EIGRPQUERIESRCVD, + COUNTER, + RONLY, + eigrpTraffStatsEntry, + 4, + {2, 1, 1, 8}}, + {EIGRPREPLIESSENT, + COUNTER, + RONLY, + eigrpTraffStatsEntry, + 4, + {2, 1, 1, 9}}, + {EIGRPREPLIESRCVD, + COUNTER, + RONLY, + eigrpTraffStatsEntry, + 4, + {2, 1, 1, 10}}, + {EIGRPACKSSENT, COUNTER, RONLY, eigrpTraffStatsEntry, 4, {2, 1, 1, 11}}, + {EIGRPACKSRCVD, COUNTER, RONLY, eigrpTraffStatsEntry, 4, {2, 1, 1, 12}}, + {EIGRPINPUTQHIGHMARK, + INTEGER, + RONLY, + eigrpTraffStatsEntry, + 4, + {2, 1, 1, 13}}, + {EIGRPINPUTQDROPS, + COUNTER, + RONLY, + eigrpTraffStatsEntry, + 4, + {2, 1, 1, 14}}, + {EIGRPSIAQUERIESSENT, + COUNTER, + RONLY, + eigrpTraffStatsEntry, + 4, + {2, 1, 1, 15}}, + {EIGRPSIAQUERIESRCVD, + COUNTER, + RONLY, + eigrpTraffStatsEntry, + 4, + {2, 1, 1, 16}}, + {EIGRPASROUTERIDTYPE, + IPADDRESSTYPE, + RONLY, + eigrpTraffStatsEntry, + 4, + {2, 1, 1, 17}}, + {EIGRPASROUTERID, + IPADDRESS, + RONLY, + eigrpTraffStatsEntry, + 4, + {2, 1, 1, 18}}, + {EIGRPTOPOROUTES, + COUNTER, + RONLY, + eigrpTraffStatsEntry, + 4, + {2, 1, 1, 19}}, + {EIGRPHEADSERIAL, + COUNTER, + RONLY, + eigrpTraffStatsEntry, + 4, + {2, 1, 1, 20}}, + {EIGRPNEXTSERIAL, + COUNTER, + RONLY, + eigrpTraffStatsEntry, + 4, + {2, 1, 1, 21}}, + {EIGRPXMITPENDREPLIES, + INTEGER, + RONLY, + eigrpTraffStatsEntry, + 4, + {2, 1, 1, 22}}, + {EIGRPXMITDUMMIES, + COUNTER, + RONLY, + eigrpTraffStatsEntry, + 4, + {2, 1, 1, 23}}, + + /* EIGRP topology variables */ + {EIGRPDESTNETTYPE, + IPADDRESSTYPE, + NOACCESS, + eigrpTopologyEntry, + 4, + {3, 1, 1, 1}}, + {EIGRPDESTNET, + IPADDRESSPREFIXLEN, + NOACCESS, + eigrpTopologyEntry, + 4, + {3, 1, 1, 2}}, + {EIGRPDESTNETPREFIXLEN, + IPADDRESSTYPE, + NOACCESS, + eigrpTopologyEntry, + 4, + {3, 1, 1, 4}}, + {EIGRPACTIVE, INTEGER, RONLY, eigrpTopologyEntry, 4, {3, 1, 1, 5}}, + {EIGRPSTUCKINACTIVE, + INTEGER, + RONLY, + eigrpTopologyEntry, + 4, + {3, 1, 1, 6}}, + {EIGRPDESTSUCCESSORS, + INTEGER, + RONLY, + eigrpTopologyEntry, + 4, + {3, 1, 1, 7}}, + {EIGRPFDISTANCE, INTEGER, RONLY, eigrpTopologyEntry, 4, {3, 1, 1, 8}}, + {EIGRPROUTEORIGINTYPE, + STRING, + RONLY, + eigrpTopologyEntry, + 4, + {3, 1, 1, 9}}, + {EIGRPROUTEORIGINADDRTYPE, + IPADDRESSTYPE, + RONLY, + eigrpTopologyEntry, + 4, + {3, 1, 1, 10}}, + {EIGRPROUTEORIGINADDR, + IPADDRESS, + RONLY, + eigrpTopologyEntry, + 4, + {3, 1, 1, 11}}, + {EIGRPNEXTHOPADDRESSTYPE, + IPADDRESSTYPE, + RONLY, + eigrpTopologyEntry, + 4, + {3, 1, 1, 12}}, + {EIGRPNEXTHOPADDRESS, + IPADDRESS, + RONLY, + eigrpTopologyEntry, + 4, + {3, 1, 1, 13}}, + {EIGRPNEXTHOPINTERFACE, + STRING, + RONLY, + eigrpTopologyEntry, + 4, + {3, 1, 1, 14}}, + {EIGRPDISTANCE, INTEGER, RONLY, eigrpTopologyEntry, 4, {3, 1, 1, 15}}, + {EIGRPREPORTDISTANCE, + INTEGER, + RONLY, + eigrpTopologyEntry, + 4, + {3, 1, 1, 16}}, + + /* EIGRP peer variables */ + {EIGRPHANDLE, INTEGER, NOACCESS, eigrpPeerEntry, 4, {4, 1, 1, 1}}, + {EIGRPPEERADDRTYPE, + IPADDRESSTYPE, + RONLY, + eigrpPeerEntry, + 4, + {4, 1, 1, 2}}, + {EIGRPPEERADDR, IPADDRESS, RONLY, eigrpPeerEntry, 4, {4, 1, 1, 3}}, + {EIGRPPEERIFINDEX, + INTERFACEINDEXORZERO, + RONLY, + eigrpPeerEntry, + 4, + {4, 1, 1, 4}}, + {EIGRPHOLDTIME, INTEGER, RONLY, eigrpPeerEntry, 4, {4, 1, 1, 5}}, + {EIGRPUPTIME, STRING, RONLY, eigrpPeerEntry, 4, {4, 1, 1, 6}}, + {EIGRPSRTT, INTEGER, RONLY, eigrpPeerEntry, 4, {4, 1, 1, 7}}, + {EIGRPRTO, INTEGER, RONLY, eigrpPeerEntry, 4, {4, 1, 1, 8}}, + {EIGRPPKTSENQUEUED, INTEGER, RONLY, eigrpPeerEntry, 4, {4, 1, 1, 9}}, + {EIGRPLASTSEQ, INTEGER, RONLY, eigrpPeerEntry, 4, {4, 1, 1, 10}}, + {EIGRPVERSION, STRING, RONLY, eigrpPeerEntry, 4, {4, 1, 1, 11}}, + {EIGRPRETRANS, COUNTER, RONLY, eigrpPeerEntry, 4, {4, 1, 1, 12}}, + {EIGRPRETRIES, INTEGER, RONLY, eigrpPeerEntry, 4, {4, 1, 1, 13}}, + + /* EIGRP interface variables */ + {EIGRPPEERCOUNT, GAUGE, RONLY, eigrpInterfaceEntry, 4, {5, 1, 1, 3}}, + {EIGRPXMITRELIABLEQ, + GAUGE, + RONLY, + eigrpInterfaceEntry, + 4, + {5, 1, 1, 4}}, + {EIGRPXMITUNRELIABLEQ, + GAUGE, + RONLY, + eigrpInterfaceEntry, + 4, + {5, 1, 1, 5}}, + {EIGRPMEANSRTT, INTEGER, RONLY, eigrpInterfaceEntry, 4, {5, 1, 1, 6}}, + {EIGRPPACINGRELIABLE, + INTEGER, + RONLY, + eigrpInterfaceEntry, + 4, + {5, 1, 1, 7}}, + {EIGRPPACINGUNRELIABLE, + INTEGER, + RONLY, + eigrpInterfaceEntry, + 4, + {5, 1, 1, 8}}, + {EIGRPMFLOWTIMER, INTEGER, RONLY, eigrpInterfaceEntry, 4, {5, 1, 1, 9}}, + {EIGRPPENDINGROUTES, + GAUGE, + RONLY, + eigrpInterfaceEntry, + 4, + {5, 1, 1, 10}}, + {EIGRPHELLOINTERVAL, + INTEGER, + RONLY, + eigrpInterfaceEntry, + 4, + {5, 1, 1, 11}}, + {EIGRPXMITNEXTSERIAL, + COUNTER, + RONLY, + eigrpInterfaceEntry, + 4, + {5, 1, 1, 12}}, + {EIGRPUMCASTS, COUNTER, RONLY, eigrpInterfaceEntry, 4, {5, 1, 1, 13}}, + {EIGRPRMCASTS, COUNTER, RONLY, eigrpInterfaceEntry, 4, {5, 1, 1, 14}}, + {EIGRPUUCASTS, COUNTER, RONLY, eigrpInterfaceEntry, 4, {5, 1, 1, 15}}, + {EIGRPRUCASTS, COUNTER, RONLY, eigrpInterfaceEntry, 4, {5, 1, 1, 16}}, + {EIGRPMCASTEXCEPTS, + COUNTER, + RONLY, + eigrpInterfaceEntry, + 4, + {5, 1, 1, 17}}, + {EIGRPCRPKTS, COUNTER, RONLY, eigrpInterfaceEntry, 4, {5, 1, 1, 18}}, + {EIGRPACKSSUPPRESSED, + COUNTER, + RONLY, + eigrpInterfaceEntry, + 4, + {5, 1, 1, 19}}, + {EIGRPRETRANSSENT, + COUNTER, + RONLY, + eigrpInterfaceEntry, + 4, + {5, 1, 1, 20}}, + {EIGRPOOSRCVD, COUNTER, RONLY, eigrpInterfaceEntry, 4, {5, 1, 1, 21}}, + {EIGRPAUTHMODE, INTEGER, RONLY, eigrpInterfaceEntry, 4, {5, 1, 1, 22}}, + {EIGRPAUTHKEYCHAIN, + STRING, + RONLY, + eigrpInterfaceEntry, + 4, + {5, 1, 1, 23}}}; + +static struct eigrp_neighbor *eigrp_snmp_nbr_lookup(struct eigrp *eigrp, + struct in_addr *nbr_addr, + unsigned int *ifindex) +{ + struct listnode *node, *nnode, *node2, *nnode2; + struct eigrp_interface *ei; + struct eigrp_neighbor *nbr; + + for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, ei)) { + for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) { + if (IPV4_ADDR_SAME(&nbr->src, nbr_addr)) { + return nbr; + } + } + } + return NULL; +} + +static struct eigrp_neighbor * +eigrp_snmp_nbr_lookup_next(struct in_addr *nbr_addr, unsigned int *ifindex, + int first) +{ + struct listnode *node, *nnode, *node2, *nnode2; + struct eigrp_interface *ei; + struct eigrp_neighbor *nbr; + struct eigrp_neighbor *min = NULL; + struct eigrp *eigrp; + + eigrp = eigrp_lookup(); + + for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, ei)) { + for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) { + if (first) { + if (!min) + min = nbr; + else if (ntohl(nbr->src.s_addr) + < ntohl(min->src.s_addr)) + min = nbr; + } else if (ntohl(nbr->src.s_addr) + > ntohl(nbr_addr->s_addr)) { + if (!min) + min = nbr; + else if (ntohl(nbr->src.s_addr) + < ntohl(min->src.s_addr)) + min = nbr; + } + } + } + if (min) { + *nbr_addr = min->src; + *ifindex = 0; + return min; + } + return NULL; +} + +static struct eigrp_neighbor *eigrpNbrLookup(struct variable *v, oid *name, + size_t *length, + struct in_addr *nbr_addr, + unsigned int *ifindex, int exact) +{ + unsigned int len; + int first; + struct eigrp_neighbor *nbr; + struct eigrp *eigrp; + + eigrp = eigrp_lookup(); + + if (!eigrp) + return NULL; + + if (exact) { + if (*length != v->namelen + IN_ADDR_SIZE + 1) + return NULL; + + oid2in_addr(name + v->namelen, IN_ADDR_SIZE, nbr_addr); + *ifindex = name[v->namelen + IN_ADDR_SIZE]; + + return eigrp_snmp_nbr_lookup(eigrp, nbr_addr, ifindex); + } else { + first = 0; + len = *length - v->namelen; + + if (len == 0) + first = 1; + + if (len > IN_ADDR_SIZE) + len = IN_ADDR_SIZE; + + oid2in_addr(name + v->namelen, len, nbr_addr); + + len = *length - v->namelen - IN_ADDR_SIZE; + if (len >= 1) + *ifindex = name[v->namelen + IN_ADDR_SIZE]; + + nbr = eigrp_snmp_nbr_lookup_next(nbr_addr, ifindex, first); + + if (nbr) { + *length = v->namelen + IN_ADDR_SIZE + 1; + oid_copy_in_addr(name + v->namelen, nbr_addr); + name[v->namelen + IN_ADDR_SIZE] = *ifindex; + return nbr; + } + } + return NULL; +} + + +static uint8_t *eigrpVpnEntry(struct variable *v, oid *name, size_t *length, + int exact, size_t *var_len, + WriteMethod **write_method) +{ + struct eigrp *eigrp; + + eigrp = eigrp_lookup(); + + /* Check whether the instance identifier is valid */ + if (smux_header_generic(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + + /* Return the current value of the variable */ + switch (v->magic) { + case EIGRPVPNID: /* 1 */ + /* The unique VPN identifier */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPVPNNAME: /* 2 */ + /* The name given to the VPN */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + default: + return NULL; + } + return NULL; +} + +static uint32_t eigrp_neighbor_count(struct eigrp *eigrp) +{ + uint32_t count; + struct eigrp_interface *ei; + struct listnode *node, *node2, *nnode2; + struct eigrp_neighbor *nbr; + + if (eigrp == NULL) { + return 0; + } + + count = 0; + for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) { + for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) { + if (nbr->state == EIGRP_NEIGHBOR_UP) + count++; + } + } + + return count; +} + + +static uint8_t *eigrpTraffStatsEntry(struct variable *v, oid *name, + size_t *length, int exact, size_t *var_len, + WriteMethod **write_method) +{ + struct eigrp *eigrp; + struct eigrp_interface *ei; + struct listnode *node, *nnode; + int counter; + + eigrp = eigrp_lookup(); + + /* Check whether the instance identifier is valid */ + if (smux_header_generic(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + + /* Return the current value of the variable */ + switch (v->magic) { + case EIGRPASNUMBER: /* 1 */ + /* AS-number of this EIGRP instance. */ + if (eigrp) + return SNMP_INTEGER(eigrp->AS); + else + return SNMP_INTEGER(0); + case EIGRPNBRCOUNT: /* 2 */ + /* Neighbor count of this EIGRP instance */ + if (eigrp) + return SNMP_INTEGER(eigrp_neighbor_count(eigrp)); + else + return SNMP_INTEGER(0); + case EIGRPHELLOSSENT: /* 3 */ + /* Hello packets output count */ + if (eigrp) { + counter = 0; + for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, + ei)) { + counter += ei->hello_out; + } + return SNMP_INTEGER(counter); + } else + return SNMP_INTEGER(0); + case EIGRPHELLOSRCVD: /* 4 */ + /* Hello packets input count */ + if (eigrp) { + counter = 0; + for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, + ei)) { + counter += ei->hello_in; + } + return SNMP_INTEGER(counter); + } else + return SNMP_INTEGER(0); + case EIGRPUPDATESSENT: /* 5 */ + /* Update packets output count */ + if (eigrp) { + counter = 0; + for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, + ei)) { + counter += ei->update_out; + } + return SNMP_INTEGER(counter); + } else + return SNMP_INTEGER(0); + case EIGRPUPDATESRCVD: /* 6 */ + /* Update packets input count */ + if (eigrp) { + counter = 0; + for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, + ei)) { + counter += ei->update_in; + } + return SNMP_INTEGER(counter); + } else + return SNMP_INTEGER(0); + case EIGRPQUERIESSENT: /* 7 */ + /* Querry packets output count */ + if (eigrp) { + counter = 0; + for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, + ei)) { + counter += ei->query_out; + } + return SNMP_INTEGER(counter); + } else + return SNMP_INTEGER(0); + case EIGRPQUERIESRCVD: /* 8 */ + /* Querry packets input count */ + if (eigrp) { + counter = 0; + for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, + ei)) { + counter += ei->query_in; + } + return SNMP_INTEGER(counter); + } else + return SNMP_INTEGER(0); + case EIGRPREPLIESSENT: /* 9 */ + /* Reply packets output count */ + if (eigrp) { + counter = 0; + for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, + ei)) { + counter += ei->reply_out; + } + return SNMP_INTEGER(counter); + } else + return SNMP_INTEGER(0); + case EIGRPREPLIESRCVD: /* 10 */ + /* Reply packets input count */ + if (eigrp) { + counter = 0; + for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, + ei)) { + counter += ei->reply_in; + } + return SNMP_INTEGER(counter); + } else + return SNMP_INTEGER(0); + case EIGRPACKSSENT: /* 11 */ + /* Acknowledgement packets output count */ + if (eigrp) { + counter = 0; + for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, + ei)) { + counter += ei->ack_out; + } + return SNMP_INTEGER(counter); + } else + return SNMP_INTEGER(0); + case EIGRPACKSRCVD: /* 12 */ + /* Acknowledgement packets input count */ + if (eigrp) { + counter = 0; + for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, + ei)) { + counter += ei->ack_in; + } + return SNMP_INTEGER(counter); + } else + return SNMP_INTEGER(0); + case EIGRPINPUTQHIGHMARK: /* 13 */ + /* The highest number of EIGRP packets in the input queue */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPINPUTQDROPS: /* 14 */ + /* The number of EIGRP packets dropped from the input queue */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPSIAQUERIESSENT: /* 15 */ + /* SIA querry packets output count */ + if (eigrp) { + counter = 0; + for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, + ei)) { + counter += ei->siaQuery_out; + } + return SNMP_INTEGER(counter); + } else + return SNMP_INTEGER(0); + case EIGRPSIAQUERIESRCVD: /* 16 */ + /* SIA querry packets input count */ + if (eigrp) { + counter = 0; + for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, + ei)) { + counter += ei->siaQuery_in; + } + return SNMP_INTEGER(counter); + } else + return SNMP_INTEGER(0); + case EIGRPASROUTERIDTYPE: /* 17 */ + /* Whether the router ID is set manually or automatically */ + if (eigrp) + if (eigrp->router_id_static != 0) + return SNMP_INTEGER(1); + else + return SNMP_INTEGER(1); + else + return SNMP_INTEGER(0); + case EIGRPASROUTERID: /* 18 */ + /* Router ID for this EIGRP AS */ + if (eigrp) + if (eigrp->router_id_static != 0) + return SNMP_INTEGER(eigrp->router_id_static); + else + return SNMP_INTEGER(eigrp->router_id); + else + return SNMP_INTEGER(0); + case EIGRPTOPOROUTES: /* 19 */ + /* The total number of EIGRP derived routes currently existing + in the topology table for the AS */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPHEADSERIAL: /* 20 */ + /* The serial number of the first route in the internal + sequence for an AS*/ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPNEXTSERIAL: /* 21 */ + /* The serial number that would be assigned to the next new + or changed route in the topology table for the AS*/ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPXMITPENDREPLIES: /* 22 */ + /* Total number of outstanding replies expected to queries + that have been sent to peers in the current AS*/ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPXMITDUMMIES: /* 23 */ + /* Total number of currently existing dummies associated with + * the AS*/ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + default: + return NULL; + } + return NULL; +} + +static uint8_t *eigrpTopologyEntry(struct variable *v, oid *name, + size_t *length, int exact, size_t *var_len, + WriteMethod **write_method) +{ + struct eigrp *eigrp; + + eigrp = eigrp_lookup(); + + /* Check whether the instance identifier is valid */ + if (smux_header_generic(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + + /* Return the current value of the variable */ + switch (v->magic) { + case EIGRPDESTNETTYPE: /* 1 */ + /* The format of the destination IP network number for a single + route in the topology table*/ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPDESTNET: /* 2 */ + /* The destination IP network number for a single route in the + * topology table*/ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPDESTNETPREFIXLEN: /* 4 */ + /* The prefix length associated with the destination IP network + address + for a single route in the topology table in the AS*/ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPACTIVE: /* 5 */ + /* A value of true(1) indicates the route to the destination + network has failed + A value of false(2) indicates the route is stable + (passive).*/ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPSTUCKINACTIVE: /* 6 */ + /* A value of true(1) indicates that that this route which is in + active state + has not received any replies to queries for alternate paths + */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPDESTSUCCESSORS: /* 7 */ + /* Next routing hop for a path to the destination IP network */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPFDISTANCE: /* 8 */ + /* Minimum distance from this router to the destination IP + * network */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPROUTEORIGINTYPE: /* 9 */ + /* Text string describing the internal origin of the EIGRP route + */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPROUTEORIGINADDRTYPE: /* 10 */ + /* The format of the IP address defined as the origin of this + topology route entry */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPROUTEORIGINADDR: /* 11 */ + /* If the origin of the topology route entry is external to this + router, + then this object is the IP address of the router from which + it originated */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPNEXTHOPADDRESSTYPE: /* 12 */ + /* The format of the next hop IP address */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPNEXTHOPADDRESS: /* 13 */ + /* Next hop IP address for the route */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPNEXTHOPINTERFACE: /* 14 */ + /* The interface through which the next hop IP address is + * reached */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPDISTANCE: /* 15 */ + /* The computed distance to the destination network entry from + * this router */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPREPORTDISTANCE: /* 16 */ + /* The computed distance to the destination network in the + topology entry + reported to this router by the originator of this route */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + default: + return NULL; + } + return NULL; +} + +static uint8_t *eigrpPeerEntry(struct variable *v, oid *name, size_t *length, + int exact, size_t *var_len, + WriteMethod **write_method) +{ + struct eigrp *eigrp; + struct eigrp_interface *ei; + struct eigrp_neighbor *nbr; + struct in_addr nbr_addr; + unsigned int ifindex; + + eigrp = eigrp_lookup(); + + /* Check whether the instance identifier is valid */ + if (smux_header_generic(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + + memset(&nbr_addr, 0, sizeof(nbr_addr)); + ifindex = 0; + + nbr = eigrpNbrLookup(v, name, length, &nbr_addr, &ifindex, exact); + if (!nbr) + return NULL; + ei = nbr->ei; + if (!ei) + return NULL; + + /* Return the current value of the variable */ + switch (v->magic) { + case EIGRPHANDLE: /* 1 */ + /* The unique internal identifier for the peer in the AS */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPPEERADDRTYPE: /* 2 */ + /* The format of the remote source IP address used by the peer + */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPPEERADDR: /* 3 */ + /* The source IP address used by the peer */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPPEERIFINDEX: /* 4 */ + /* The ifIndex of the interface on this router */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPHOLDTIME: /* 5 */ + /* How much time must pass without receiving a hello packet from + this + EIGRP peer before this router declares the peer down */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPUPTIME: /* 6 */ + /* The elapsed time since the EIGRP adjacency was first + * established */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPSRTT: /* 7 */ + /* The computed smooth round trip time for packets to and from + * the peer */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPRTO: /* 8 */ + /* The computed retransmission timeout for the peer */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPPKTSENQUEUED: /* 9 */ + /* The number of any EIGRP packets currently enqueued */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPLASTSEQ: /* 10 */ + /* sequence number of the last EIGRP packet sent to this peer */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPVERSION: /* 11 */ + /* The EIGRP version information reported by the remote peer */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPRETRANS: /* 12 */ + /* The cumulative number of retransmissions to this peer */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPRETRIES: /* 13 */ + /* The number of times the current unacknowledged packet has + * been retried */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + default: + return NULL; + } + return NULL; +} + +static uint8_t *eigrpInterfaceEntry(struct variable *v, oid *name, + size_t *length, int exact, size_t *var_len, + WriteMethod **write_method) +{ + struct eigrp *eigrp; + struct listnode *node, *nnode; + struct keychain *keychain; + struct list *keylist; + + eigrp = eigrp_lookup(); + + /* Check whether the instance identifier is valid */ + if (smux_header_generic(v, name, length, exact, var_len, write_method) + == MATCH_FAILED) + return NULL; + + /* Return the current value of the variable */ + switch (v->magic) { + case EIGRPPEERCOUNT: /* 3 */ + /* The number of EIGRP adjacencies currently formed with + peers reached through this interface */ + if (eigrp) { + return SNMP_INTEGER(eigrp_neighbor_count(eigrp)); + } else + return SNMP_INTEGER(0); + case EIGRPXMITRELIABLEQ: /* 4 */ + /* The number of EIGRP packets currently waiting in the reliable + transport transmission queue */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPXMITUNRELIABLEQ: /* 5 */ + /* The number of EIGRP packets currently waiting in the + unreliable + transport transmission queue */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPMEANSRTT: /* 6 */ + /* The average of all the computed smooth round trip time values + for a packet to and from all peers established on this + interface */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPPACINGRELIABLE: /* 7 */ + /* The configured time interval between EIGRP packet + * transmissions */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPPACINGUNRELIABLE: /* 8 */ + /* The configured time interval between EIGRP packet + transmissions + on the interface when the unreliable transport method is used + */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPMFLOWTIMER: /* 9 */ + /* The configured multicast flow control timer value */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPPENDINGROUTES: /* 10 */ + /* The number of queued EIGRP routing updates awaiting + * transmission */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPHELLOINTERVAL: /* 11 */ + /* The configured time interval between Hello packet + * transmissions */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPXMITNEXTSERIAL: /* 12 */ + /* The serial number of the next EIGRP packet that is to be + queued + for transmission */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPUMCASTS: /* 13 */ + /* The total number of unreliable EIGRP multicast packets sent + on this interface */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPRMCASTS: /* 14 */ + /* The total number of reliable EIGRP multicast packets sent + on this interface */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPUUCASTS: /* 15 */ + /* The total number of unreliable EIGRP unicast packets sent + on this interface */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPRUCASTS: /* 16 */ + /* The total number of reliable EIGRP unicast packets sent + on this interface */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPMCASTEXCEPTS: /* 17 */ + /* The total number of EIGRP multicast exception transmissions + */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPCRPKTS: /* 18 */ + /* The total number EIGRP Conditional-Receive packets sent on + * this interface */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPACKSSUPPRESSED: /* 19 */ + /* The total number of individual EIGRP acknowledgement packets + that have been + suppressed and combined in an already enqueued outbound + reliable packet on this interface */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPRETRANSSENT: /* 20 */ + /* The total number EIGRP packet retransmissions sent on the + * interface */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPOOSRCVD: /* 21 */ + /* The total number of out-of-sequence EIGRP packets received */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPAUTHMODE: /* 22 */ + /* The EIGRP authentication mode of the interface */ + if (eigrp) { + return SNMP_INTEGER(1); + } else + return SNMP_INTEGER(0); + case EIGRPAUTHKEYCHAIN: /* 23 */ + /* The name of the authentication key-chain configured + on this interface. */ + keylist = keychain_list_get(); + for (ALL_LIST_ELEMENTS(keylist, node, nnode, keychain)) { + return (uint8_t *)keychain->name; + } + if (eigrp && keychain) { + *var_len = str_len(keychain->name); + return (uint8_t *)keychain->name; + } else + return (uint8_t *)"TEST"; + break; + default: + return NULL; + } + return NULL; +} + +/* Register EIGRP-MIB. */ +void eigrp_snmp_init() +{ + eigrp_snmp_iflist = list_new(); + smux_init(eigrp_om->master); + REGISTER_MIB("ciscoEigrpMIB", eigrp_variables, variable, eigrp_oid); +} +#endif |