Annotation of embedaddon/quagga/bgpd/bgp_snmp.c, revision 1.1.1.3

1.1       misho       1: /* BGP4 SNMP support
                      2:    Copyright (C) 1999, 2000 Kunihiro Ishiguro
                      3: 
                      4: This file is part of GNU Zebra.
                      5: 
                      6: GNU Zebra is free software; you can redistribute it and/or modify it
                      7: under the terms of the GNU General Public License as published by the
                      8: Free Software Foundation; either version 2, or (at your option) any
                      9: later version.
                     10: 
                     11: GNU Zebra is distributed in the hope that it will be useful, but
                     12: WITHOUT ANY WARRANTY; without even the implied warranty of
                     13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     14: General Public License for more details.
                     15: 
                     16: You should have received a copy of the GNU General Public License
                     17: along with GNU Zebra; see the file COPYING.  If not, write to the Free
                     18: Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
                     19: 02111-1307, USA.  */
                     20: 
                     21: #include <zebra.h>
                     22: 
                     23: #ifdef HAVE_SNMP
                     24: #include <net-snmp/net-snmp-config.h>
                     25: #include <net-snmp/net-snmp-includes.h>
                     26: 
                     27: #include "if.h"
                     28: #include "log.h"
                     29: #include "prefix.h"
                     30: #include "command.h"
                     31: #include "thread.h"
                     32: #include "smux.h"
1.1.1.3 ! misho      33: #include "filter.h"
1.1       misho      34: 
                     35: #include "bgpd/bgpd.h"
                     36: #include "bgpd/bgp_table.h"
                     37: #include "bgpd/bgp_aspath.h"
                     38: #include "bgpd/bgp_attr.h"
                     39: #include "bgpd/bgp_route.h"
                     40: #include "bgpd/bgp_fsm.h"
                     41: #include "bgpd/bgp_snmp.h"
1.1.1.3 ! misho      42: 
1.1       misho      43: /* BGP4-MIB described in RFC1657. */
                     44: #define BGP4MIB 1,3,6,1,2,1,15
                     45: 
                     46: /* BGP TRAP. */
                     47: #define BGPESTABLISHED                 1
                     48: #define BGPBACKWARDTRANSITION          2       
                     49: 
                     50: /* BGP MIB bgpVersion. */
                     51: #define BGPVERSION                           0
                     52: 
                     53: /* BGP MIB bgpLocalAs. */
                     54: #define BGPLOCALAS                           0
                     55: 
                     56: /* BGP MIB bgpPeerTable. */
                     57: #define BGPPEERIDENTIFIER                     1
                     58: #define BGPPEERSTATE                          2
                     59: #define BGPPEERADMINSTATUS                    3
                     60: #define BGPPEERNEGOTIATEDVERSION              4
                     61: #define BGPPEERLOCALADDR                      5
                     62: #define BGPPEERLOCALPORT                      6
                     63: #define BGPPEERREMOTEADDR                     7
                     64: #define BGPPEERREMOTEPORT                     8
                     65: #define BGPPEERREMOTEAS                       9
                     66: #define BGPPEERINUPDATES                     10
                     67: #define BGPPEEROUTUPDATES                    11
                     68: #define BGPPEERINTOTALMESSAGES               12
                     69: #define BGPPEEROUTTOTALMESSAGES              13
                     70: #define BGPPEERLASTERROR                     14
                     71: #define BGPPEERFSMESTABLISHEDTRANSITIONS     15
                     72: #define BGPPEERFSMESTABLISHEDTIME            16
                     73: #define BGPPEERCONNECTRETRYINTERVAL          17
                     74: #define BGPPEERHOLDTIME                      18
                     75: #define BGPPEERKEEPALIVE                     19
                     76: #define BGPPEERHOLDTIMECONFIGURED            20
                     77: #define BGPPEERKEEPALIVECONFIGURED           21
1.1.1.3 ! misho      78: #define BGPPEERMINROUTEADVERTISEMENTINTERVAL 22
        !            79: #define BGPPEERINUPDATEELAPSEDTIME           23
1.1       misho      80: 
                     81: /* BGP MIB bgpIdentifier. */
                     82: #define BGPIDENTIFIER                         0
                     83: 
                     84: /* BGP MIB bgpRcvdPathAttrTable */
                     85: #define BGPPATHATTRPEER                       1
                     86: #define BGPPATHATTRDESTNETWORK                2
                     87: #define BGPPATHATTRORIGIN                     3
                     88: #define BGPPATHATTRASPATH                     4
                     89: #define BGPPATHATTRNEXTHOP                    5
                     90: #define BGPPATHATTRINTERASMETRIC              6
                     91: 
                     92: /* BGP MIB bgp4PathAttrTable. */
                     93: #define BGP4PATHATTRPEER                      1
                     94: #define BGP4PATHATTRIPADDRPREFIXLEN           2
                     95: #define BGP4PATHATTRIPADDRPREFIX              3
                     96: #define BGP4PATHATTRORIGIN                    4
                     97: #define BGP4PATHATTRASPATHSEGMENT             5
                     98: #define BGP4PATHATTRNEXTHOP                   6
                     99: #define BGP4PATHATTRMULTIEXITDISC             7
                    100: #define BGP4PATHATTRLOCALPREF                 8
                    101: #define BGP4PATHATTRATOMICAGGREGATE           9
                    102: #define BGP4PATHATTRAGGREGATORAS             10
                    103: #define BGP4PATHATTRAGGREGATORADDR           11
                    104: #define BGP4PATHATTRCALCLOCALPREF            12
                    105: #define BGP4PATHATTRBEST                     13
                    106: #define BGP4PATHATTRUNKNOWN                  14
                    107: 
                    108: /* SNMP value hack. */
                    109: #define INTEGER ASN_INTEGER
                    110: #define INTEGER32 ASN_INTEGER
                    111: #define COUNTER32 ASN_COUNTER
                    112: #define OCTET_STRING ASN_OCTET_STR
                    113: #define IPADDRESS ASN_IPADDRESS
                    114: #define GAUGE32 ASN_UNSIGNED
1.1.1.3 ! misho     115: 
1.1       misho     116: /* Declare static local variables for convenience. */
                    117: SNMP_LOCAL_VARIABLES
                    118: 
                    119: /* BGP-MIB instances. */
                    120: oid bgp_oid [] = { BGP4MIB };
1.1.1.2   misho     121: oid bgp_trap_oid [] = { BGP4MIB, 0 };
1.1       misho     122: 
                    123: /* IP address 0.0.0.0. */
1.1.1.3 ! misho     124: static struct in_addr bgp_empty_addr = { .s_addr = 0 };
1.1       misho     125: 
                    126: /* Hook functions. */
                    127: static u_char *bgpVersion (struct variable *, oid [], size_t *, int,
                    128:                           size_t *, WriteMethod **);
                    129: static u_char *bgpLocalAs (struct variable *, oid [], size_t *,
                    130:                           int, size_t *, WriteMethod **);
                    131: static u_char *bgpPeerTable (struct variable *, oid [], size_t *,
                    132:                             int, size_t *, WriteMethod **);
                    133: static u_char *bgpRcvdPathAttrTable (struct variable *, oid [], size_t *,
                    134:                                     int, size_t *, WriteMethod **);
                    135: static u_char *bgpIdentifier (struct variable *, oid [], size_t *,
                    136:                              int, size_t *, WriteMethod **);
                    137: static u_char *bgp4PathAttrTable (struct variable *, oid [], size_t *,
                    138:                                  int, size_t *, WriteMethod **);
                    139: /* static u_char *bgpTraps (); */
                    140: 
                    141: struct variable bgp_variables[] = 
                    142: {
                    143:   /* BGP version. */
                    144:   {BGPVERSION,                OCTET_STRING, RONLY, bgpVersion,
                    145:    1, {1}},
                    146:   /* BGP local AS. */
                    147:   {BGPLOCALAS,                INTEGER, RONLY, bgpLocalAs,
                    148:    1, {2}},
                    149:   /* BGP peer table. */
                    150:   {BGPPEERIDENTIFIER,         IPADDRESS, RONLY, bgpPeerTable,
                    151:    3, {3, 1, 1}},
                    152:   {BGPPEERSTATE,              INTEGER, RONLY, bgpPeerTable,
                    153:    3, {3, 1, 2}},
                    154:   {BGPPEERADMINSTATUS,        INTEGER, RWRITE, bgpPeerTable,
                    155:    3, {3, 1, 3}},
                    156:   {BGPPEERNEGOTIATEDVERSION,  INTEGER32, RONLY, bgpPeerTable,
                    157:    3, {3, 1, 4}},
                    158:   {BGPPEERLOCALADDR,          IPADDRESS, RONLY, bgpPeerTable,
                    159:    3, {3, 1, 5}},
                    160:   {BGPPEERLOCALPORT,          INTEGER, RONLY, bgpPeerTable,
                    161:    3, {3, 1, 6}},
                    162:   {BGPPEERREMOTEADDR,         IPADDRESS, RONLY, bgpPeerTable,
                    163:    3, {3, 1, 7}},
                    164:   {BGPPEERREMOTEPORT,         INTEGER, RONLY, bgpPeerTable,
                    165:    3, {3, 1, 8}},
                    166:   {BGPPEERREMOTEAS,           INTEGER, RONLY, bgpPeerTable,
                    167:    3, {3, 1, 9}},
                    168:   {BGPPEERINUPDATES,          COUNTER32, RONLY, bgpPeerTable,
                    169:    3, {3, 1, 10}},
                    170:   {BGPPEEROUTUPDATES,         COUNTER32, RONLY, bgpPeerTable,
                    171:    3, {3, 1, 11}},
                    172:   {BGPPEERINTOTALMESSAGES,    COUNTER32, RONLY, bgpPeerTable,
                    173:    3, {3, 1, 12}},
                    174:   {BGPPEEROUTTOTALMESSAGES,   COUNTER32, RONLY, bgpPeerTable,
                    175:    3, {3, 1, 13}},
                    176:   {BGPPEERLASTERROR,          OCTET_STRING, RONLY, bgpPeerTable,
                    177:    3, {3, 1, 14}},
                    178:   {BGPPEERFSMESTABLISHEDTRANSITIONS, COUNTER32, RONLY, bgpPeerTable,
                    179:    3, {3, 1, 15}},
                    180:   {BGPPEERFSMESTABLISHEDTIME, GAUGE32, RONLY, bgpPeerTable,
                    181:    3, {3, 1, 16}},
                    182:   {BGPPEERCONNECTRETRYINTERVAL, INTEGER, RWRITE, bgpPeerTable,
                    183:    3, {3, 1, 17}},
                    184:   {BGPPEERHOLDTIME,           INTEGER, RONLY, bgpPeerTable,
                    185:    3, {3, 1, 18}},
                    186:   {BGPPEERKEEPALIVE,          INTEGER, RONLY, bgpPeerTable,
                    187:    3, {3, 1, 19}},
                    188:   {BGPPEERHOLDTIMECONFIGURED, INTEGER, RWRITE, bgpPeerTable,
                    189:    3, {3, 1, 20}},
                    190:   {BGPPEERKEEPALIVECONFIGURED, INTEGER, RWRITE, bgpPeerTable,
                    191:    3, {3, 1, 21}},
                    192:   {BGPPEERMINROUTEADVERTISEMENTINTERVAL, INTEGER, RWRITE, bgpPeerTable,
                    193:    3, {3, 1, 23}},
                    194:   {BGPPEERINUPDATEELAPSEDTIME, GAUGE32, RONLY, bgpPeerTable,
                    195:    3, {3, 1, 24}},
                    196:   /* BGP identifier. */
                    197:   {BGPIDENTIFIER,             IPADDRESS, RONLY, bgpIdentifier,
                    198:    1, {4}},
                    199:   /* BGP received path attribute table. */
                    200:   {BGPPATHATTRPEER,           IPADDRESS, RONLY, bgpRcvdPathAttrTable,
                    201:    3, {5, 1, 1}},
                    202:   {BGPPATHATTRDESTNETWORK,    IPADDRESS, RONLY, bgpRcvdPathAttrTable,
                    203:    3, {5, 1, 2}},
                    204:   {BGPPATHATTRORIGIN,         INTEGER, RONLY, bgpRcvdPathAttrTable,
                    205:    3, {5, 1, 3}},
                    206:   {BGPPATHATTRASPATH,         OCTET_STRING, RONLY, bgpRcvdPathAttrTable,
                    207:    3, {5, 1, 4}},
                    208:   {BGPPATHATTRNEXTHOP,        IPADDRESS, RONLY, bgpRcvdPathAttrTable,
                    209:    3, {5, 1, 5}},
                    210:   {BGPPATHATTRINTERASMETRIC,  INTEGER32, RONLY, bgpRcvdPathAttrTable,
                    211:    3, {5, 1, 6}},
                    212:   /* BGP-4 received path attribute table. */
                    213:   {BGP4PATHATTRPEER, IPADDRESS, RONLY, bgp4PathAttrTable,
                    214:    3, {6, 1, 1}},
                    215:   {BGP4PATHATTRIPADDRPREFIXLEN, INTEGER, RONLY, bgp4PathAttrTable,
                    216:    3, {6, 1, 2}},
                    217:   {BGP4PATHATTRIPADDRPREFIX,  IPADDRESS, RONLY, bgp4PathAttrTable,
                    218:    3, {6, 1, 3}},
                    219:   {BGP4PATHATTRORIGIN,        INTEGER, RONLY, bgp4PathAttrTable,
                    220:    3, {6, 1, 4}},
                    221:   {BGP4PATHATTRASPATHSEGMENT, OCTET_STRING, RONLY, bgp4PathAttrTable,
                    222:    3, {6, 1, 5}},
                    223:   {BGP4PATHATTRNEXTHOP,       IPADDRESS, RONLY, bgp4PathAttrTable,
                    224:    3, {6, 1, 6}},
                    225:   {BGP4PATHATTRMULTIEXITDISC, INTEGER, RONLY, bgp4PathAttrTable,
                    226:    3, {6, 1, 7}},
                    227:   {BGP4PATHATTRLOCALPREF,     INTEGER, RONLY, bgp4PathAttrTable,
                    228:    3, {6, 1, 8}},
                    229:   {BGP4PATHATTRATOMICAGGREGATE, INTEGER, RONLY, bgp4PathAttrTable,
                    230:    3, {6, 1, 9}},
                    231:   {BGP4PATHATTRAGGREGATORAS,  INTEGER, RONLY, bgp4PathAttrTable,
                    232:    3, {6, 1, 10}},
                    233:   {BGP4PATHATTRAGGREGATORADDR, IPADDRESS, RONLY, bgp4PathAttrTable,
                    234:    3, {6, 1, 11}},
                    235:   {BGP4PATHATTRCALCLOCALPREF, INTEGER, RONLY, bgp4PathAttrTable,
                    236:    3, {6, 1, 12}},
                    237:   {BGP4PATHATTRBEST,          INTEGER, RONLY, bgp4PathAttrTable,
                    238:    3, {6, 1, 13}},
                    239:   {BGP4PATHATTRUNKNOWN,       OCTET_STRING, RONLY, bgp4PathAttrTable,
                    240:    3, {6, 1, 14}},
                    241: };
                    242: 
1.1.1.3 ! misho     243: 
1.1       misho     244: static u_char *
                    245: bgpVersion (struct variable *v, oid name[], size_t *length, int exact,
                    246:            size_t *var_len, WriteMethod **write_method)
                    247: {
                    248:   static u_char version;
                    249: 
                    250:   if (smux_header_generic(v, name, length, exact, var_len, write_method)
                    251:       == MATCH_FAILED)
                    252:     return NULL;
                    253: 
                    254:   /* Retrun BGP version.  Zebra bgpd only support version 4. */
                    255:   version = (0x80 >> (BGP_VERSION_4 - 1));
                    256: 
                    257:   /* Return octet string length 1. */
                    258:   *var_len = 1;
                    259:   return (u_char *)&version;
                    260: }
                    261: 
                    262: static u_char *
                    263: bgpLocalAs (struct variable *v, oid name[], size_t *length,
                    264:            int exact, size_t *var_len, WriteMethod **write_method)
                    265: {
                    266:   struct bgp *bgp;
                    267: 
                    268:   if (smux_header_generic(v, name, length, exact, var_len, write_method)
                    269:       == MATCH_FAILED)
                    270:     return NULL;
                    271: 
                    272:   /* Get BGP structure. */
                    273:   bgp = bgp_get_default ();
                    274:   if (! bgp)
                    275:     return NULL;
                    276: 
                    277:   return SNMP_INTEGER (bgp->as);
                    278: }
                    279: 
                    280: static struct peer *
                    281: peer_lookup_addr_ipv4 (struct in_addr *src)
                    282: {
                    283:   struct bgp *bgp;
                    284:   struct peer *peer;
                    285:   struct listnode *node;
                    286:   struct in_addr addr;
                    287:   int ret;
                    288: 
                    289:   bgp = bgp_get_default ();
                    290:   if (! bgp)
                    291:     return NULL;
                    292: 
                    293:   for (ALL_LIST_ELEMENTS_RO (bgp->peer, node, peer))
                    294:     {
                    295:       ret = inet_pton (AF_INET, peer->host, &addr);
                    296:       if (ret > 0)
                    297:        {
                    298:          if (IPV4_ADDR_SAME (&addr, src))
                    299:            return peer;
                    300:        }
                    301:     }
                    302:   return NULL;
                    303: }
                    304: 
                    305: static struct peer *
                    306: bgp_peer_lookup_next (struct in_addr *src)
                    307: {
                    308:   struct bgp *bgp;
                    309:   struct peer *peer;
                    310:   struct listnode *node;
                    311:   struct in_addr *p;
                    312:   union sockunion su;
                    313:   int ret;
                    314: 
                    315:   memset (&su, 0, sizeof (union sockunion));
                    316: 
                    317:   bgp = bgp_get_default ();
                    318:   if (! bgp)
                    319:     return NULL;
                    320: 
                    321:   for (ALL_LIST_ELEMENTS_RO (bgp->peer, node, peer))
                    322:     {
                    323:       ret = inet_pton (AF_INET, peer->host, &su.sin.sin_addr);
                    324:       if (ret > 0)
                    325:        {
                    326:          p = &su.sin.sin_addr;
                    327: 
                    328:          if (ntohl (p->s_addr) > ntohl (src->s_addr))
                    329:            {
                    330:              src->s_addr = p->s_addr;
                    331:              return peer;
                    332:            }
                    333:        }
                    334:     }
                    335:   return NULL;
                    336: }
                    337: 
1.1.1.3 ! misho     338: /* 1.3.6.1.2.1.15.3.1.x  = 10 */
        !           339: #define PEERTAB_NAMELEN 10
        !           340: 
1.1       misho     341: static struct peer *
                    342: bgpPeerTable_lookup (struct variable *v, oid name[], size_t *length, 
                    343:                     struct in_addr *addr, int exact)
                    344: {
                    345:   struct peer *peer = NULL;
1.1.1.3 ! misho     346:   size_t namelen = v ? v->namelen : PEERTAB_NAMELEN;
1.1       misho     347:   int len;
                    348: 
                    349:   if (exact)
                    350:     {
                    351:       /* Check the length. */
1.1.1.3 ! misho     352:       if (*length - namelen != sizeof (struct in_addr))
1.1       misho     353:        return NULL;
                    354: 
1.1.1.3 ! misho     355:       oid2in_addr (name + namelen, IN_ADDR_SIZE, addr);
1.1       misho     356: 
                    357:       peer = peer_lookup_addr_ipv4 (addr);
                    358:       return peer;
                    359:     }
                    360:   else
                    361:     {
1.1.1.3 ! misho     362:       len = *length - namelen;
1.1       misho     363:       if (len > 4) len = 4;
                    364:       
1.1.1.3 ! misho     365:       oid2in_addr (name + namelen, len, addr);
1.1       misho     366:       
                    367:       peer = bgp_peer_lookup_next (addr);
                    368: 
                    369:       if (peer == NULL)
                    370:        return NULL;
                    371: 
1.1.1.3 ! misho     372:       oid_copy_addr (name + namelen, addr, sizeof (struct in_addr));
        !           373:       *length = sizeof (struct in_addr) + namelen;
1.1       misho     374: 
                    375:       return peer;
                    376:     }
                    377:   return NULL;
                    378: }
                    379: 
                    380: /* BGP write methods. */
                    381: static int
                    382: write_bgpPeerTable (int action, u_char *var_val,
                    383:                    u_char var_val_type, size_t var_val_len,
1.1.1.3 ! misho     384:                    u_char *statP, oid *name, size_t length)
1.1       misho     385: {
                    386:   struct in_addr addr;
                    387:   struct peer *peer;
                    388:   long intval;
1.1.1.3 ! misho     389: 
1.1       misho     390:   if (var_val_type != ASN_INTEGER) 
                    391:     {
                    392:       return SNMP_ERR_WRONGTYPE;
                    393:     }
                    394:   if (var_val_len != sizeof (long)) 
                    395:     {
                    396:       return SNMP_ERR_WRONGLENGTH;
                    397:     }
                    398: 
1.1.1.3 ! misho     399:   intval = *(long *)var_val;
1.1       misho     400: 
                    401:   memset (&addr, 0, sizeof (struct in_addr));
                    402: 
1.1.1.3 ! misho     403:   peer = bgpPeerTable_lookup (NULL, name, &length, &addr, 1);
1.1       misho     404:   if (! peer)
                    405:     return SNMP_ERR_NOSUCHNAME;
                    406: 
1.1.1.3 ! misho     407:   if (action != SNMP_MSG_INTERNAL_SET_COMMIT)
        !           408:     return SNMP_ERR_NOERROR;
1.1       misho     409: 
1.1.1.3 ! misho     410:   zlog_info ("%s: SNMP write .%ld = %ld",
        !           411:              peer->host, (long)name[PEERTAB_NAMELEN - 1], intval);
        !           412: 
        !           413:   switch (name[PEERTAB_NAMELEN - 1])
1.1       misho     414:     {
                    415:     case BGPPEERADMINSTATUS:
                    416: #define BGP_PeerAdmin_stop  1
                    417: #define BGP_PeerAdmin_start 2
                    418:       /* When the peer is established,   */
                    419:       if (intval == BGP_PeerAdmin_stop)
                    420:        BGP_EVENT_ADD (peer, BGP_Stop);
                    421:       else if (intval == BGP_PeerAdmin_start)
                    422:        ;                       /* Do nothing. */
                    423:       else
                    424:        return SNMP_ERR_NOSUCHNAME;
                    425:       break;
                    426:     case BGPPEERCONNECTRETRYINTERVAL:
                    427:       SET_FLAG (peer->config, PEER_CONFIG_CONNECT);
                    428:       peer->connect = intval;
                    429:       peer->v_connect = intval;
                    430:       break;
                    431:     case BGPPEERHOLDTIMECONFIGURED:
                    432:       SET_FLAG (peer->config, PEER_CONFIG_TIMER);
                    433:       peer->holdtime = intval;
                    434:       peer->v_holdtime = intval;
                    435:       break;
                    436:     case BGPPEERKEEPALIVECONFIGURED:
                    437:       SET_FLAG (peer->config, PEER_CONFIG_TIMER);
                    438:       peer->keepalive = intval;
                    439:       peer->v_keepalive = intval;
                    440:       break;
                    441:     case BGPPEERMINROUTEADVERTISEMENTINTERVAL:
                    442:       peer->v_routeadv = intval;
                    443:       break;
                    444:     }
                    445:   return SNMP_ERR_NOERROR;
                    446: }
                    447: 
                    448: static u_char *
                    449: bgpPeerTable (struct variable *v, oid name[], size_t *length,
                    450:              int exact, size_t *var_len, WriteMethod **write_method)
                    451: {
                    452:   static struct in_addr addr;
                    453:   struct peer *peer;
                    454: 
1.1.1.2   misho     455:   if (smux_header_table(v, name, length, exact, var_len, write_method)
                    456:       == MATCH_FAILED)
                    457:     return NULL;
1.1       misho     458:   memset (&addr, 0, sizeof (struct in_addr));
                    459: 
                    460:   peer = bgpPeerTable_lookup (v, name, length, &addr, exact);
                    461:   if (! peer)
                    462:     return NULL;
                    463: 
                    464:   switch (v->magic)
                    465:     {
                    466:     case BGPPEERIDENTIFIER:
                    467:       return SNMP_IPADDRESS (peer->remote_id);
                    468:       break;
                    469:     case BGPPEERSTATE:
                    470:       return SNMP_INTEGER (peer->status);
                    471:       break;
                    472:     case BGPPEERADMINSTATUS:
                    473:       *write_method = write_bgpPeerTable;
                    474: #define BGP_PeerAdmin_stop  1
                    475: #define BGP_PeerAdmin_start 2
                    476:       if (CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN))
                    477:        return SNMP_INTEGER (BGP_PeerAdmin_stop);
                    478:       else
                    479:        return SNMP_INTEGER (BGP_PeerAdmin_start);
                    480:       break;
                    481:     case BGPPEERNEGOTIATEDVERSION:
                    482:       return SNMP_INTEGER (BGP_VERSION_4);
                    483:       break;
                    484:     case BGPPEERLOCALADDR:
                    485:       if (peer->su_local)
                    486:        return SNMP_IPADDRESS (peer->su_local->sin.sin_addr);
                    487:       else
                    488:        return SNMP_IPADDRESS (bgp_empty_addr);
                    489:       break;
                    490:     case BGPPEERLOCALPORT:
                    491:       if (peer->su_local)
                    492:        return SNMP_INTEGER (ntohs (peer->su_local->sin.sin_port));
                    493:       else
                    494:        return SNMP_INTEGER (0);
                    495:       break;
                    496:     case BGPPEERREMOTEADDR:
                    497:       if (peer->su_remote)
                    498:        return SNMP_IPADDRESS (peer->su_remote->sin.sin_addr);
                    499:       else
                    500:        return SNMP_IPADDRESS (bgp_empty_addr);
                    501:       break;
                    502:     case BGPPEERREMOTEPORT:
                    503:       if (peer->su_remote)
                    504:        return SNMP_INTEGER (ntohs (peer->su_remote->sin.sin_port));
                    505:       else
                    506:        return SNMP_INTEGER (0);
                    507:       break;
                    508:     case BGPPEERREMOTEAS:
                    509:       return SNMP_INTEGER (peer->as);
                    510:       break;
                    511:     case BGPPEERINUPDATES:
                    512:       return SNMP_INTEGER (peer->update_in);
                    513:       break;
                    514:     case BGPPEEROUTUPDATES:
                    515:       return SNMP_INTEGER (peer->update_out);
                    516:       break;
                    517:     case BGPPEERINTOTALMESSAGES:
                    518:       return SNMP_INTEGER (peer->open_in + peer->update_in
                    519:                           + peer->keepalive_in + peer->notify_in
                    520:                           + peer->refresh_in + peer->dynamic_cap_in);
                    521:       break;
                    522:     case BGPPEEROUTTOTALMESSAGES:
                    523:       return SNMP_INTEGER (peer->open_out + peer->update_out
                    524:                           + peer->keepalive_out + peer->notify_out
                    525:                           + peer->refresh_out + peer->dynamic_cap_out);
                    526:       break;
                    527:     case BGPPEERLASTERROR:
                    528:       {
                    529:        static u_char lasterror[2];
                    530:        lasterror[0] = peer->notify.code;
                    531:        lasterror[1] = peer->notify.subcode;
                    532:        *var_len = 2;
                    533:        return (u_char *)&lasterror;
                    534:       }
                    535:       break;
                    536:     case BGPPEERFSMESTABLISHEDTRANSITIONS:
                    537:       return SNMP_INTEGER (peer->established);
                    538:       break;
                    539:     case BGPPEERFSMESTABLISHEDTIME:
                    540:       if (peer->uptime == 0)
                    541:        return SNMP_INTEGER (0);
                    542:       else
                    543:        return SNMP_INTEGER (bgp_clock () - peer->uptime);
                    544:       break;
                    545:     case BGPPEERCONNECTRETRYINTERVAL:
                    546:       *write_method = write_bgpPeerTable;
                    547:       return SNMP_INTEGER (peer->v_connect);
                    548:       break;
                    549:     case BGPPEERHOLDTIME:
                    550:       return SNMP_INTEGER (peer->v_holdtime);
                    551:       break;
                    552:     case BGPPEERKEEPALIVE:
                    553:       return SNMP_INTEGER (peer->v_keepalive);
                    554:       break;
                    555:     case BGPPEERHOLDTIMECONFIGURED:
                    556:       *write_method = write_bgpPeerTable;
                    557:       if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
                    558:        return SNMP_INTEGER (peer->holdtime);
                    559:       else
                    560:        return SNMP_INTEGER (peer->v_holdtime);
                    561:       break;
                    562:     case BGPPEERKEEPALIVECONFIGURED:
                    563:       *write_method = write_bgpPeerTable;
                    564:       if (CHECK_FLAG (peer->config, PEER_CONFIG_TIMER))
                    565:        return SNMP_INTEGER (peer->keepalive);
                    566:       else
                    567:        return SNMP_INTEGER (peer->v_keepalive);
                    568:       break;
                    569:     case BGPPEERMINROUTEADVERTISEMENTINTERVAL:
                    570:       *write_method = write_bgpPeerTable;
                    571:       return SNMP_INTEGER (peer->v_routeadv);
                    572:       break;
                    573:     case BGPPEERINUPDATEELAPSEDTIME:
                    574:       if (peer->update_time == 0)
                    575:        return SNMP_INTEGER (0);
                    576:       else
                    577:        return SNMP_INTEGER (bgp_clock () - peer->update_time);
                    578:       break;
                    579:     default:
                    580:       return NULL;
                    581:       break;
                    582:     }  
                    583:   return NULL;
                    584: }
                    585: 
                    586: static u_char *
                    587: bgpIdentifier (struct variable *v, oid name[], size_t *length,
                    588:               int exact, size_t *var_len, WriteMethod **write_method)
                    589: {
                    590:   struct bgp *bgp;
                    591: 
                    592:   if (smux_header_generic(v, name, length, exact, var_len, write_method)
                    593:       == MATCH_FAILED)
                    594:     return NULL;
                    595: 
                    596:   bgp = bgp_get_default ();
                    597:   if (!bgp)
                    598:     return NULL;
                    599: 
                    600:   return SNMP_IPADDRESS (bgp->router_id);
                    601: }
                    602: 
                    603: static u_char *
                    604: bgpRcvdPathAttrTable (struct variable *v, oid name[], size_t *length,
                    605:                      int exact, size_t *var_len, WriteMethod **write_method)
                    606: {
                    607:   /* Received Path Attribute Table.  This table contains, one entry
                    608:      per path to a network, path attributes received from all peers
                    609:      running BGP version 3 or less.  This table is obsolete, having
                    610:      been replaced in functionality with the bgp4PathAttrTable.  */
                    611:   return NULL;
                    612: }
                    613: 
                    614: static struct bgp_info *
                    615: bgp4PathAttrLookup (struct variable *v, oid name[], size_t *length,
                    616:                    struct bgp *bgp, struct prefix_ipv4 *addr, int exact)
                    617: {
                    618:   oid *offset;
                    619:   int offsetlen;
                    620:   struct bgp_info *binfo;
                    621:   struct bgp_info *min;
                    622:   struct bgp_node *rn;
                    623:   union sockunion su;
                    624:   unsigned int len;
                    625:   struct in_addr paddr;
                    626: 
                    627: #define BGP_PATHATTR_ENTRY_OFFSET \
                    628:           (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE)
                    629: 
                    630:   if (exact)
                    631:     {
                    632:       if (*length - v->namelen != BGP_PATHATTR_ENTRY_OFFSET)
                    633:        return NULL;
                    634: 
                    635:       /* Set OID offset for prefix. */
                    636:       offset = name + v->namelen;
                    637:       oid2in_addr (offset, IN_ADDR_SIZE, &addr->prefix);
                    638:       offset += IN_ADDR_SIZE;
                    639: 
                    640:       /* Prefix length. */
                    641:       addr->prefixlen = *offset;
                    642:       offset++;
                    643: 
                    644:       /* Peer address. */
                    645:       su.sin.sin_family = AF_INET;
                    646:       oid2in_addr (offset, IN_ADDR_SIZE, &su.sin.sin_addr);
                    647: 
                    648:       /* Lookup node. */
                    649:       rn = bgp_node_lookup (bgp->rib[AFI_IP][SAFI_UNICAST], 
                    650:                              (struct prefix *) addr);
                    651:       if (rn)
                    652:        {
                    653:          bgp_unlock_node (rn);
                    654: 
                    655:          for (binfo = rn->info; binfo; binfo = binfo->next)
                    656:            if (sockunion_same (&binfo->peer->su, &su))
                    657:              return binfo;
                    658:        }
                    659:     }
                    660:   else
                    661:     {
                    662:       offset = name + v->namelen;
                    663:       offsetlen = *length - v->namelen;
                    664:       len = offsetlen;
                    665: 
                    666:       if (offsetlen == 0)
                    667:        rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_UNICAST]);
                    668:       else
                    669:        {
                    670:          if (len > IN_ADDR_SIZE)
                    671:            len = IN_ADDR_SIZE;
                    672:       
                    673:          oid2in_addr (offset, len, &addr->prefix);
                    674: 
                    675:          offset += IN_ADDR_SIZE;
                    676:          offsetlen -= IN_ADDR_SIZE;
                    677: 
                    678:          if (offsetlen > 0)
                    679:            addr->prefixlen = *offset;
                    680:          else
                    681:            addr->prefixlen = len * 8;
                    682: 
                    683:          rn = bgp_node_get (bgp->rib[AFI_IP][SAFI_UNICAST],
                    684:                               (struct prefix *) addr);
                    685: 
                    686:          offset++;
                    687:          offsetlen--;
                    688:        }
                    689: 
                    690:       if (offsetlen > 0)
                    691:        {
                    692:          len = offsetlen;
                    693:          if (len > IN_ADDR_SIZE)
                    694:            len = IN_ADDR_SIZE;
                    695: 
                    696:          oid2in_addr (offset, len, &paddr);
                    697:        }
                    698:       else
                    699:        paddr.s_addr = 0;
                    700: 
                    701:       if (! rn)
                    702:        return NULL;
                    703: 
                    704:       do
                    705:        {
                    706:          min = NULL;
                    707: 
                    708:          for (binfo = rn->info; binfo; binfo = binfo->next)
                    709:            {
                    710:              if (binfo->peer->su.sin.sin_family == AF_INET
                    711:                  && ntohl (paddr.s_addr) 
                    712:                  < ntohl (binfo->peer->su.sin.sin_addr.s_addr))
                    713:                {
                    714:                  if (min)
                    715:                    {
                    716:                      if (ntohl (binfo->peer->su.sin.sin_addr.s_addr) 
                    717:                          < ntohl (min->peer->su.sin.sin_addr.s_addr))
                    718:                        min = binfo;
                    719:                    }
                    720:                  else
                    721:                    min = binfo;
                    722:                }
                    723:            }
                    724: 
                    725:          if (min)
                    726:            {
                    727:              *length = v->namelen + BGP_PATHATTR_ENTRY_OFFSET;
                    728: 
                    729:              offset = name + v->namelen;
                    730:              oid_copy_addr (offset, &rn->p.u.prefix4, IN_ADDR_SIZE);
                    731:              offset += IN_ADDR_SIZE;
                    732:              *offset = rn->p.prefixlen;
                    733:              offset++;
                    734:              oid_copy_addr (offset, &min->peer->su.sin.sin_addr, 
                    735:                             IN_ADDR_SIZE);
                    736:              addr->prefix = rn->p.u.prefix4;
                    737:              addr->prefixlen = rn->p.prefixlen;
                    738: 
                    739:              bgp_unlock_node (rn);
                    740: 
                    741:              return min;
                    742:            }
                    743: 
                    744:          paddr.s_addr = 0;
                    745:        }
                    746:       while ((rn = bgp_route_next (rn)) != NULL);
                    747:     }
                    748:   return NULL;
                    749: }
                    750: 
                    751: static u_char *
                    752: bgp4PathAttrTable (struct variable *v, oid name[], size_t *length,
                    753:                   int exact, size_t *var_len, WriteMethod **write_method)
                    754: {
                    755:   struct bgp *bgp;
                    756:   struct bgp_info *binfo;
                    757:   struct prefix_ipv4 addr;
                    758:   
                    759:   bgp = bgp_get_default ();
                    760:   if (! bgp)
                    761:     return NULL;
                    762: 
1.1.1.2   misho     763:   if (smux_header_table(v, name, length, exact, var_len, write_method)
                    764:       == MATCH_FAILED)
                    765:     return NULL;
1.1       misho     766:   memset (&addr, 0, sizeof (struct prefix_ipv4));
                    767: 
                    768:   binfo = bgp4PathAttrLookup (v, name, length, bgp, &addr, exact);
                    769:   if (! binfo)
                    770:     return NULL;
                    771: 
                    772:   switch (v->magic)
                    773:     {
                    774:     case BGP4PATHATTRPEER:     /* 1 */
                    775:       return SNMP_IPADDRESS (binfo->peer->su.sin.sin_addr);
                    776:       break;
                    777:     case BGP4PATHATTRIPADDRPREFIXLEN: /* 2 */
                    778:       return SNMP_INTEGER (addr.prefixlen);
                    779:       break;
                    780:     case BGP4PATHATTRIPADDRPREFIX: /* 3 */
                    781:       return SNMP_IPADDRESS (addr.prefix);
                    782:       break;
                    783:     case BGP4PATHATTRORIGIN:   /* 4 */
                    784:       return SNMP_INTEGER (binfo->attr->origin);
                    785:       break;
                    786:     case BGP4PATHATTRASPATHSEGMENT: /* 5 */
                    787:       return aspath_snmp_pathseg (binfo->attr->aspath, var_len);
                    788:       break;
                    789:     case BGP4PATHATTRNEXTHOP:  /* 6 */
                    790:       return SNMP_IPADDRESS (binfo->attr->nexthop);
                    791:       break;
                    792:     case BGP4PATHATTRMULTIEXITDISC: /* 7 */
                    793:       return SNMP_INTEGER (binfo->attr->med);
                    794:       break;
                    795:     case BGP4PATHATTRLOCALPREF:        /* 8 */
                    796:       return SNMP_INTEGER (binfo->attr->local_pref);
                    797:       break;
                    798:     case BGP4PATHATTRATOMICAGGREGATE: /* 9 */
                    799:       return SNMP_INTEGER (1);
                    800:       break;
                    801:     case BGP4PATHATTRAGGREGATORAS: /* 10 */
                    802:       if (binfo->attr->extra)
                    803:         return SNMP_INTEGER (binfo->attr->extra->aggregator_as);
                    804:       else
                    805:         return SNMP_INTEGER (0);
                    806:       break;
                    807:     case BGP4PATHATTRAGGREGATORADDR: /* 11 */
                    808:       if (binfo->attr->extra)
                    809:         return SNMP_IPADDRESS (binfo->attr->extra->aggregator_addr);
                    810:       else
                    811:         return SNMP_INTEGER (0);
                    812:       break;
                    813:     case BGP4PATHATTRCALCLOCALPREF: /* 12 */
                    814:       return SNMP_INTEGER (-1);
                    815:       break;
                    816:     case BGP4PATHATTRBEST:     /* 13 */
                    817: #define BGP4_PathAttrBest_false 1
                    818: #define BGP4_PathAttrBest_true  2
                    819:       if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
                    820:        return SNMP_INTEGER (BGP4_PathAttrBest_true);
                    821:       else
                    822:        return SNMP_INTEGER (BGP4_PathAttrBest_false);
                    823:       break;
                    824:     case BGP4PATHATTRUNKNOWN:  /* 14 */
                    825:       *var_len = 0;
                    826:       return NULL;
                    827:       break;
                    828:     }
                    829:   return NULL;
                    830: }
1.1.1.3 ! misho     831: 
1.1       misho     832: /* BGP Traps. */
                    833: struct trap_object bgpTrapList[] =
                    834: {
1.1.1.2   misho     835:   {3, {3, 1, BGPPEERLASTERROR}},
                    836:   {3, {3, 1, BGPPEERSTATE}}
1.1       misho     837: };
                    838: 
                    839: void
                    840: bgpTrapEstablished (struct peer *peer)
                    841: {
                    842:   int ret;
                    843:   struct in_addr addr;
                    844:   oid index[sizeof (oid) * IN_ADDR_SIZE];
                    845: 
                    846:   ret = inet_aton (peer->host, &addr);
                    847:   if (ret == 0)
                    848:     return;
                    849: 
                    850:   oid_copy_addr (index, &addr, IN_ADDR_SIZE);
                    851: 
1.1.1.2   misho     852:   smux_trap (bgp_variables, sizeof bgp_variables / sizeof (struct variable),
                    853:             bgp_trap_oid, sizeof bgp_trap_oid / sizeof (oid),
                    854:             bgp_oid, sizeof bgp_oid / sizeof (oid),
1.1       misho     855:             index, IN_ADDR_SIZE,
                    856:             bgpTrapList, sizeof bgpTrapList / sizeof (struct trap_object),
1.1.1.2   misho     857:             BGPESTABLISHED);
1.1       misho     858: }
                    859: 
                    860: void
                    861: bgpTrapBackwardTransition (struct peer *peer)
                    862: {
                    863:   int ret;
                    864:   struct in_addr addr;
                    865:   oid index[sizeof (oid) * IN_ADDR_SIZE];
                    866: 
                    867:   ret = inet_aton (peer->host, &addr);
                    868:   if (ret == 0)
                    869:     return;
                    870: 
                    871:   oid_copy_addr (index, &addr, IN_ADDR_SIZE);
                    872: 
1.1.1.2   misho     873:   smux_trap (bgp_variables, sizeof bgp_variables / sizeof (struct variable),
                    874:             bgp_trap_oid, sizeof bgp_trap_oid / sizeof (oid),
                    875:             bgp_oid, sizeof bgp_oid / sizeof (oid),
1.1       misho     876:             index, IN_ADDR_SIZE,
                    877:             bgpTrapList, sizeof bgpTrapList / sizeof (struct trap_object),
1.1.1.2   misho     878:             BGPBACKWARDTRANSITION);
1.1       misho     879: }
                    880: 
                    881: void
                    882: bgp_snmp_init (void)
                    883: {
                    884:   smux_init (bm->master);
                    885:   REGISTER_MIB("mibII/bgp", bgp_variables, variable, bgp_oid);
                    886: }
                    887: #endif /* HAVE_SNMP */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>