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

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

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