Annotation of embedaddon/quagga/ospfd/ospf_snmp.c, revision 1.1.1.3

1.1       misho       1: /* OSPFv2 SNMP support
                      2:  * Copyright (C) 2005 6WIND <alain.ritoux@6wind.com>
                      3:  * Copyright (C) 2000 IP Infusion Inc.
                      4:  *
                      5:  * Written by Kunihiro Ishiguro <kunihiro@zebra.org>
                      6:  *
                      7:  * This file is part of GNU Zebra.
                      8:  *
                      9:  * GNU Zebra is free software; you can redistribute it and/or modify it
                     10:  * under the terms of the GNU General Public License as published by the
                     11:  * Free Software Foundation; either version 2, or (at your option) any
                     12:  * later version.
                     13:  *
                     14:  * GNU Zebra is distributed in the hope that it will be useful, but
                     15:  * WITHOUT ANY WARRANTY; without even the implied warranty of
                     16:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     17:  * General Public License for more details.
                     18:  *
                     19:  * You should have received a copy of the GNU General Public License
                     20:  * along with GNU Zebra; see the file COPYING.  If not, write to the Free
                     21:  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
                     22:  * 02111-1307, USA.  
                     23:  */
                     24: 
                     25: #include <zebra.h>
                     26: 
                     27: #ifdef HAVE_SNMP
                     28: #include <net-snmp/net-snmp-config.h>
                     29: #include <net-snmp/net-snmp-includes.h>
                     30: 
                     31: #include "if.h"
                     32: #include "log.h"
                     33: #include "prefix.h"
                     34: #include "table.h"
                     35: #include "command.h"
                     36: #include "memory.h"
                     37: #include "smux.h"
                     38: 
                     39: #include "ospfd/ospfd.h"
                     40: #include "ospfd/ospf_interface.h"
                     41: #include "ospfd/ospf_asbr.h"
                     42: #include "ospfd/ospf_lsa.h"
                     43: #include "ospfd/ospf_lsdb.h"
                     44: #include "ospfd/ospf_abr.h"
                     45: #include "ospfd/ospf_neighbor.h"
                     46: #include "ospfd/ospf_nsm.h"
                     47: #include "ospfd/ospf_flood.h"
                     48: #include "ospfd/ospf_ism.h"
                     49: #include "ospfd/ospf_dump.h"
                     50: #include "ospfd/ospf_snmp.h"
                     51: 
                     52: /* OSPF2-MIB. */
                     53: #define OSPF2MIB 1,3,6,1,2,1,14
                     54: 
                     55: /* OSPF MIB General Group values. */
                     56: #define OSPFROUTERID                     1
                     57: #define OSPFADMINSTAT                    2
                     58: #define OSPFVERSIONNUMBER                3
                     59: #define OSPFAREABDRRTRSTATUS             4
                     60: #define OSPFASBDRRTRSTATUS               5
                     61: #define OSPFEXTERNLSACOUNT               6
                     62: #define OSPFEXTERNLSACKSUMSUM            7
                     63: #define OSPFTOSSUPPORT                   8
                     64: #define OSPFORIGINATENEWLSAS             9
                     65: #define OSPFRXNEWLSAS                    10
                     66: #define OSPFEXTLSDBLIMIT                 11
                     67: #define OSPFMULTICASTEXTENSIONS          12
                     68: #define OSPFEXITOVERFLOWINTERVAL         13
                     69: #define OSPFDEMANDEXTENSIONS             14
                     70: 
                     71: /* OSPF MIB ospfAreaTable. */
                     72: #define OSPFAREAID                       1
                     73: #define OSPFAUTHTYPE                     2
                     74: #define OSPFIMPORTASEXTERN               3
                     75: #define OSPFSPFRUNS                      4
                     76: #define OSPFAREABDRRTRCOUNT              5
                     77: #define OSPFASBDRRTRCOUNT                6
                     78: #define OSPFAREALSACOUNT                 7
                     79: #define OSPFAREALSACKSUMSUM              8
                     80: #define OSPFAREASUMMARY                  9
                     81: #define OSPFAREASTATUS                   10
                     82: 
                     83: /* OSPF MIB ospfStubAreaTable. */
                     84: #define OSPFSTUBAREAID                   1
                     85: #define OSPFSTUBTOS                      2
                     86: #define OSPFSTUBMETRIC                   3
                     87: #define OSPFSTUBSTATUS                   4
                     88: #define OSPFSTUBMETRICTYPE               5
                     89: 
                     90: /* OSPF MIB ospfLsdbTable. */
                     91: #define OSPFLSDBAREAID                   1
                     92: #define OSPFLSDBTYPE                     2
                     93: #define OSPFLSDBLSID                     3
                     94: #define OSPFLSDBROUTERID                 4
                     95: #define OSPFLSDBSEQUENCE                 5
                     96: #define OSPFLSDBAGE                      6
                     97: #define OSPFLSDBCHECKSUM                 7
                     98: #define OSPFLSDBADVERTISEMENT            8
                     99: 
                    100: /* OSPF MIB ospfAreaRangeTable. */
                    101: #define OSPFAREARANGEAREAID              1
                    102: #define OSPFAREARANGENET                 2
                    103: #define OSPFAREARANGEMASK                3
                    104: #define OSPFAREARANGESTATUS              4
                    105: #define OSPFAREARANGEEFFECT              5
                    106: 
                    107: /* OSPF MIB ospfHostTable. */
                    108: #define OSPFHOSTIPADDRESS                1
                    109: #define OSPFHOSTTOS                      2
                    110: #define OSPFHOSTMETRIC                   3
                    111: #define OSPFHOSTSTATUS                   4
                    112: #define OSPFHOSTAREAID                   5
                    113: 
                    114: /* OSPF MIB ospfIfTable. */
                    115: #define OSPFIFIPADDRESS                  1
                    116: #define OSPFADDRESSLESSIF                2
                    117: #define OSPFIFAREAID                     3
                    118: #define OSPFIFTYPE                       4
                    119: #define OSPFIFADMINSTAT                  5
                    120: #define OSPFIFRTRPRIORITY                6
                    121: #define OSPFIFTRANSITDELAY               7
                    122: #define OSPFIFRETRANSINTERVAL            8
                    123: #define OSPFIFHELLOINTERVAL              9
                    124: #define OSPFIFRTRDEADINTERVAL            10
                    125: #define OSPFIFPOLLINTERVAL               11
                    126: #define OSPFIFSTATE                      12
                    127: #define OSPFIFDESIGNATEDROUTER           13
                    128: #define OSPFIFBACKUPDESIGNATEDROUTER     14
                    129: #define OSPFIFEVENTS                     15
                    130: #define OSPFIFAUTHKEY                    16
                    131: #define OSPFIFSTATUS                     17
                    132: #define OSPFIFMULTICASTFORWARDING        18
                    133: #define OSPFIFDEMAND                     19
                    134: #define OSPFIFAUTHTYPE                   20
                    135: 
                    136: /* OSPF MIB ospfIfMetricTable. */
                    137: #define OSPFIFMETRICIPADDRESS            1
                    138: #define OSPFIFMETRICADDRESSLESSIF        2
                    139: #define OSPFIFMETRICTOS                  3
                    140: #define OSPFIFMETRICVALUE                4
                    141: #define OSPFIFMETRICSTATUS               5
                    142: 
                    143: /* OSPF MIB ospfVirtIfTable. */
                    144: #define OSPFVIRTIFAREAID                 1
                    145: #define OSPFVIRTIFNEIGHBOR               2
                    146: #define OSPFVIRTIFTRANSITDELAY           3
                    147: #define OSPFVIRTIFRETRANSINTERVAL        4
                    148: #define OSPFVIRTIFHELLOINTERVAL          5
                    149: #define OSPFVIRTIFRTRDEADINTERVAL        6
                    150: #define OSPFVIRTIFSTATE                  7
                    151: #define OSPFVIRTIFEVENTS                 8
                    152: #define OSPFVIRTIFAUTHKEY                9
                    153: #define OSPFVIRTIFSTATUS                 10
                    154: #define OSPFVIRTIFAUTHTYPE               11
                    155: 
                    156: /* OSPF MIB ospfNbrTable. */
                    157: #define OSPFNBRIPADDR                    1
                    158: #define OSPFNBRADDRESSLESSINDEX          2
                    159: #define OSPFNBRRTRID                     3
                    160: #define OSPFNBROPTIONS                   4
                    161: #define OSPFNBRPRIORITY                  5
                    162: #define OSPFNBRSTATE                     6
                    163: #define OSPFNBREVENTS                    7
                    164: #define OSPFNBRLSRETRANSQLEN             8
                    165: #define OSPFNBMANBRSTATUS                9
                    166: #define OSPFNBMANBRPERMANENCE            10
                    167: #define OSPFNBRHELLOSUPPRESSED           11
                    168: 
                    169: /* OSPF MIB ospfVirtNbrTable. */
                    170: #define OSPFVIRTNBRAREA                  1
                    171: #define OSPFVIRTNBRRTRID                 2
                    172: #define OSPFVIRTNBRIPADDR                3
                    173: #define OSPFVIRTNBROPTIONS               4
                    174: #define OSPFVIRTNBRSTATE                 5
                    175: #define OSPFVIRTNBREVENTS                6
                    176: #define OSPFVIRTNBRLSRETRANSQLEN         7
                    177: #define OSPFVIRTNBRHELLOSUPPRESSED       8
                    178: 
                    179: /* OSPF MIB ospfExtLsdbTable. */
                    180: #define OSPFEXTLSDBTYPE                  1
                    181: #define OSPFEXTLSDBLSID                  2
                    182: #define OSPFEXTLSDBROUTERID              3
                    183: #define OSPFEXTLSDBSEQUENCE              4
                    184: #define OSPFEXTLSDBAGE                   5
                    185: #define OSPFEXTLSDBCHECKSUM              6
                    186: #define OSPFEXTLSDBADVERTISEMENT         7
                    187: 
                    188: /* OSPF MIB ospfAreaAggregateTable. */
                    189: #define OSPFAREAAGGREGATEAREAID          1
                    190: #define OSPFAREAAGGREGATELSDBTYPE        2
                    191: #define OSPFAREAAGGREGATENET             3
                    192: #define OSPFAREAAGGREGATEMASK            4
                    193: #define OSPFAREAAGGREGATESTATUS          5
                    194: #define OSPFAREAAGGREGATEEFFECT          6
                    195: 
                    196: /* SYNTAX Status from OSPF-MIB. */
                    197: #define OSPF_STATUS_ENABLED  1
                    198: #define OSPF_STATUS_DISABLED 2
                    199: 
                    200: /* SNMP value hack. */
                    201: #define COUNTER     ASN_COUNTER
                    202: #define INTEGER     ASN_INTEGER
                    203: #define GAUGE       ASN_GAUGE
                    204: #define TIMETICKS   ASN_TIMETICKS
                    205: #define IPADDRESS   ASN_IPADDRESS
                    206: #define STRING      ASN_OCTET_STR
                    207: 
                    208: /* Declare static local variables for convenience. */
                    209: SNMP_LOCAL_VARIABLES
                    210: 
                    211: /* OSPF-MIB instances. */
                    212: oid ospf_oid [] = { OSPF2MIB };
1.1.1.3 ! misho     213: oid ospf_trap_oid [] = { OSPF2MIB, 16, 2 }; /* Not reverse mappable! */
1.1       misho     214: 
                    215: /* IP address 0.0.0.0. */
                    216: static struct in_addr ospf_empty_addr = {0};
                    217: 
                    218: /* Hook functions. */
                    219: static u_char *ospfGeneralGroup (struct variable *, oid *, size_t *,
                    220:                                 int, size_t *, WriteMethod **);
                    221: static u_char *ospfAreaEntry (struct variable *, oid *, size_t *, int,
                    222:                              size_t *, WriteMethod **);
                    223: static u_char *ospfStubAreaEntry (struct variable *, oid *, size_t *,
                    224:                                  int, size_t *, WriteMethod **);
                    225: static u_char *ospfLsdbEntry (struct variable *, oid *, size_t *, int,
                    226:                              size_t *, WriteMethod **);
                    227: static u_char *ospfAreaRangeEntry (struct variable *, oid *, size_t *, int,
                    228:                                   size_t *, WriteMethod **);
                    229: static u_char *ospfHostEntry (struct variable *, oid *, size_t *, int,
                    230:                              size_t *, WriteMethod **);
                    231: static u_char *ospfIfEntry (struct variable *, oid *, size_t *, int,
                    232:                            size_t *, WriteMethod **);
                    233: static u_char *ospfIfMetricEntry (struct variable *, oid *, size_t *, int,
                    234:                                  size_t *, WriteMethod **);
                    235: static u_char *ospfVirtIfEntry (struct variable *, oid *, size_t *, int,
                    236:                                size_t *, WriteMethod **);
                    237: static u_char *ospfNbrEntry (struct variable *, oid *, size_t *, int,
                    238:                             size_t *, WriteMethod **);
                    239: static u_char *ospfVirtNbrEntry (struct variable *, oid *, size_t *, int,
                    240:                                 size_t *, WriteMethod **);
                    241: static u_char *ospfExtLsdbEntry (struct variable *, oid *, size_t *, int,
                    242:                                 size_t *, WriteMethod **);
                    243: static u_char *ospfAreaAggregateEntry (struct variable *, oid *, size_t *,
                    244:                                       int, size_t *, WriteMethod **);
                    245: 
                    246: struct variable ospf_variables[] = 
                    247: {
                    248:   /* OSPF general variables */
                    249:   {OSPFROUTERID,              IPADDRESS, RWRITE, ospfGeneralGroup,
                    250:    2, {1, 1}},
                    251:   {OSPFADMINSTAT,             INTEGER, RWRITE, ospfGeneralGroup,
                    252:    2, {1, 2}},
                    253:   {OSPFVERSIONNUMBER,         INTEGER, RONLY, ospfGeneralGroup,
                    254:    2, {1, 3}},
                    255:   {OSPFAREABDRRTRSTATUS,      INTEGER, RONLY, ospfGeneralGroup,
                    256:    2, {1, 4}},
                    257:   {OSPFASBDRRTRSTATUS,        INTEGER, RWRITE, ospfGeneralGroup,
                    258:    2, {1, 5}},
                    259:   {OSPFEXTERNLSACOUNT,        GAUGE, RONLY, ospfGeneralGroup,
                    260:    2, {1, 6}},
                    261:   {OSPFEXTERNLSACKSUMSUM,     INTEGER, RONLY, ospfGeneralGroup,
                    262:    2, {1, 7}},
                    263:   {OSPFTOSSUPPORT,            INTEGER, RWRITE, ospfGeneralGroup,
                    264:    2, {1, 8}},
                    265:   {OSPFORIGINATENEWLSAS,      COUNTER, RONLY, ospfGeneralGroup,
                    266:    2, {1, 9}},
                    267:   {OSPFRXNEWLSAS,             COUNTER, RONLY, ospfGeneralGroup,
                    268:    2, {1, 10}},
                    269:   {OSPFEXTLSDBLIMIT,          INTEGER, RWRITE, ospfGeneralGroup,
                    270:    2, {1, 11}},
                    271:   {OSPFMULTICASTEXTENSIONS,   INTEGER, RWRITE, ospfGeneralGroup,
                    272:    2, {1, 12}},
                    273:   {OSPFEXITOVERFLOWINTERVAL,  INTEGER, RWRITE, ospfGeneralGroup,
                    274:    2, {1, 13}},
                    275:   {OSPFDEMANDEXTENSIONS,      INTEGER, RWRITE, ospfGeneralGroup,
                    276:    2, {1, 14}},
                    277: 
                    278:   /* OSPF area data structure. */
                    279:   {OSPFAREAID,                IPADDRESS, RONLY, ospfAreaEntry,
                    280:    3, {2, 1, 1}},
                    281:   {OSPFAUTHTYPE,              INTEGER, RWRITE, ospfAreaEntry,
                    282:    3, {2, 1, 2}},
                    283:   {OSPFIMPORTASEXTERN,        INTEGER, RWRITE, ospfAreaEntry,
                    284:    3, {2, 1, 3}},
                    285:   {OSPFSPFRUNS,               COUNTER, RONLY, ospfAreaEntry,
                    286:    3, {2, 1, 4}},
                    287:   {OSPFAREABDRRTRCOUNT,       GAUGE, RONLY, ospfAreaEntry,
                    288:    3, {2, 1, 5}},
                    289:   {OSPFASBDRRTRCOUNT,         GAUGE, RONLY, ospfAreaEntry,
                    290:    3, {2, 1, 6}},
                    291:   {OSPFAREALSACOUNT,          GAUGE, RONLY, ospfAreaEntry,
                    292:    3, {2, 1, 7}},
                    293:   {OSPFAREALSACKSUMSUM,       INTEGER, RONLY, ospfAreaEntry,
                    294:    3, {2, 1, 8}},
                    295:   {OSPFAREASUMMARY,           INTEGER, RWRITE, ospfAreaEntry,
                    296:    3, {2, 1, 9}},
                    297:   {OSPFAREASTATUS,            INTEGER, RWRITE, ospfAreaEntry,
                    298:    3, {2, 1, 10}},
                    299: 
                    300:   /* OSPF stub area information. */
                    301:   {OSPFSTUBAREAID,            IPADDRESS, RONLY, ospfStubAreaEntry,
                    302:    3, {3, 1, 1}},
                    303:   {OSPFSTUBTOS,               INTEGER, RONLY, ospfStubAreaEntry,
                    304:    3, {3, 1, 2}},
                    305:   {OSPFSTUBMETRIC,            INTEGER, RWRITE, ospfStubAreaEntry,
                    306:    3, {3, 1, 3}},
                    307:   {OSPFSTUBSTATUS,            INTEGER, RWRITE, ospfStubAreaEntry,
                    308:    3, {3, 1, 4}},
                    309:   {OSPFSTUBMETRICTYPE,        INTEGER, RWRITE, ospfStubAreaEntry,
                    310:    3, {3, 1, 5}},
                    311: 
                    312:   /* OSPF link state database. */
                    313:   {OSPFLSDBAREAID,            IPADDRESS, RONLY, ospfLsdbEntry,
                    314:    3, {4, 1, 1}},
                    315:   {OSPFLSDBTYPE,              INTEGER, RONLY, ospfLsdbEntry,
                    316:    3, {4, 1, 2}},
                    317:   {OSPFLSDBLSID,              IPADDRESS, RONLY, ospfLsdbEntry,
                    318:    3, {4, 1, 3}},
                    319:   {OSPFLSDBROUTERID,          IPADDRESS, RONLY, ospfLsdbEntry,
                    320:    3, {4, 1, 4}},
                    321:   {OSPFLSDBSEQUENCE,          INTEGER, RONLY, ospfLsdbEntry,
                    322:    3, {4, 1, 5}},
                    323:   {OSPFLSDBAGE,               INTEGER, RONLY, ospfLsdbEntry,
                    324:    3, {4, 1, 6}},
                    325:   {OSPFLSDBCHECKSUM,          INTEGER, RONLY, ospfLsdbEntry,
                    326:    3, {4, 1, 7}},
                    327:   {OSPFLSDBADVERTISEMENT,     STRING, RONLY, ospfLsdbEntry,
                    328:    3, {4, 1, 8}},
                    329: 
                    330:   /* Area range table. */
                    331:   {OSPFAREARANGEAREAID,       IPADDRESS, RONLY, ospfAreaRangeEntry,
                    332:    3, {5, 1, 1}},
                    333:   {OSPFAREARANGENET,          IPADDRESS, RONLY, ospfAreaRangeEntry,
                    334:    3, {5, 1, 2}},
                    335:   {OSPFAREARANGEMASK,         IPADDRESS, RWRITE, ospfAreaRangeEntry,
                    336:    3, {5, 1, 3}},
                    337:   {OSPFAREARANGESTATUS,       INTEGER, RWRITE, ospfAreaRangeEntry,
                    338:    3, {5, 1, 4}},
                    339:   {OSPFAREARANGEEFFECT,       INTEGER, RWRITE, ospfAreaRangeEntry,
                    340:    3, {5, 1, 5}},
                    341: 
                    342:   /* OSPF host table. */
                    343:   {OSPFHOSTIPADDRESS,         IPADDRESS, RONLY, ospfHostEntry,
                    344:    3, {6, 1, 1}},
                    345:   {OSPFHOSTTOS,               INTEGER, RONLY, ospfHostEntry,
                    346:    3, {6, 1, 2}},
                    347:   {OSPFHOSTMETRIC,            INTEGER, RWRITE, ospfHostEntry,
                    348:    3, {6, 1, 3}},
                    349:   {OSPFHOSTSTATUS,            INTEGER, RWRITE, ospfHostEntry,
                    350:    3, {6, 1, 4}},
                    351:   {OSPFHOSTAREAID,            IPADDRESS, RONLY, ospfHostEntry,
                    352:    3, {6, 1, 5}},
                    353: 
                    354:   /* OSPF interface table. */
                    355:   {OSPFIFIPADDRESS,           IPADDRESS, RONLY, ospfIfEntry,
                    356:    3, {7, 1, 1}},
                    357:   {OSPFADDRESSLESSIF,         INTEGER, RONLY, ospfIfEntry,
                    358:    3, {7, 1, 2}},
                    359:   {OSPFIFAREAID,              IPADDRESS, RWRITE, ospfIfEntry,
                    360:    3, {7, 1, 3}},
                    361:   {OSPFIFTYPE,                INTEGER, RWRITE, ospfIfEntry,
                    362:    3, {7, 1, 4}},
                    363:   {OSPFIFADMINSTAT,           INTEGER, RWRITE, ospfIfEntry,
                    364:    3, {7, 1, 5}},
                    365:   {OSPFIFRTRPRIORITY,         INTEGER, RWRITE, ospfIfEntry,
                    366:    3, {7, 1, 6}},
                    367:   {OSPFIFTRANSITDELAY,        INTEGER, RWRITE, ospfIfEntry,
                    368:    3, {7, 1, 7}},
                    369:   {OSPFIFRETRANSINTERVAL,     INTEGER, RWRITE, ospfIfEntry,
                    370:    3, {7, 1, 8}},
                    371:   {OSPFIFHELLOINTERVAL,       INTEGER, RWRITE, ospfIfEntry,
                    372:    3, {7, 1, 9}},
                    373:   {OSPFIFRTRDEADINTERVAL,     INTEGER, RWRITE, ospfIfEntry,
                    374:    3, {7, 1, 10}},
                    375:   {OSPFIFPOLLINTERVAL,        INTEGER, RWRITE, ospfIfEntry,
                    376:    3, {7, 1, 11}},
                    377:   {OSPFIFSTATE,               INTEGER, RONLY, ospfIfEntry,
                    378:    3, {7, 1, 12}},
                    379:   {OSPFIFDESIGNATEDROUTER,    IPADDRESS, RONLY, ospfIfEntry,
                    380:    3, {7, 1, 13}},
                    381:   {OSPFIFBACKUPDESIGNATEDROUTER, IPADDRESS, RONLY, ospfIfEntry,
                    382:    3, {7, 1, 14}},
                    383:   {OSPFIFEVENTS,              COUNTER, RONLY, ospfIfEntry,
                    384:    3, {7, 1, 15}},
                    385:   {OSPFIFAUTHKEY,             STRING,  RWRITE, ospfIfEntry,
                    386:    3, {7, 1, 16}},
                    387:   {OSPFIFSTATUS,              INTEGER, RWRITE, ospfIfEntry,
                    388:    3, {7, 1, 17}},
                    389:   {OSPFIFMULTICASTFORWARDING, INTEGER, RWRITE, ospfIfEntry,
                    390:    3, {7, 1, 18}},
                    391:   {OSPFIFDEMAND,              INTEGER, RWRITE, ospfIfEntry,
                    392:    3, {7, 1, 19}},
                    393:   {OSPFIFAUTHTYPE,            INTEGER, RWRITE, ospfIfEntry,
                    394:    3, {7, 1, 20}},
                    395: 
                    396:   /* OSPF interface metric table. */
                    397:   {OSPFIFMETRICIPADDRESS,     IPADDRESS, RONLY, ospfIfMetricEntry,
                    398:    3, {8, 1, 1}},
                    399:   {OSPFIFMETRICADDRESSLESSIF, INTEGER, RONLY, ospfIfMetricEntry,
                    400:    3, {8, 1, 2}},
                    401:   {OSPFIFMETRICTOS,           INTEGER, RONLY, ospfIfMetricEntry,
                    402:    3, {8, 1, 3}},
                    403:   {OSPFIFMETRICVALUE,         INTEGER, RWRITE, ospfIfMetricEntry,
                    404:    3, {8, 1, 4}},
                    405:   {OSPFIFMETRICSTATUS,        INTEGER, RWRITE, ospfIfMetricEntry,
                    406:    3, {8, 1, 5}},
                    407: 
                    408:   /* OSPF virtual interface table. */
                    409:   {OSPFVIRTIFAREAID,          IPADDRESS, RONLY, ospfVirtIfEntry,
                    410:    3, {9, 1, 1}},
                    411:   {OSPFVIRTIFNEIGHBOR,        IPADDRESS, RONLY, ospfVirtIfEntry,
                    412:    3, {9, 1, 2}},
                    413:   {OSPFVIRTIFTRANSITDELAY,    INTEGER, RWRITE, ospfVirtIfEntry,
                    414:    3, {9, 1, 3}},
                    415:   {OSPFVIRTIFRETRANSINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry,
                    416:    3, {9, 1, 4}},
                    417:   {OSPFVIRTIFHELLOINTERVAL,   INTEGER, RWRITE, ospfVirtIfEntry,
                    418:    3, {9, 1, 5}},
                    419:   {OSPFVIRTIFRTRDEADINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry,
                    420:    3, {9, 1, 6}},
                    421:   {OSPFVIRTIFSTATE,           INTEGER, RONLY, ospfVirtIfEntry,
                    422:    3, {9, 1, 7}},
                    423:   {OSPFVIRTIFEVENTS,          COUNTER, RONLY, ospfVirtIfEntry,
                    424:    3, {9, 1, 8}},
                    425:   {OSPFVIRTIFAUTHKEY,         STRING,  RWRITE, ospfVirtIfEntry,
                    426:    3, {9, 1, 9}},
                    427:   {OSPFVIRTIFSTATUS,          INTEGER, RWRITE, ospfVirtIfEntry,
                    428:    3, {9, 1, 10}},
                    429:   {OSPFVIRTIFAUTHTYPE,        INTEGER, RWRITE, ospfVirtIfEntry,
                    430:    3, {9, 1, 11}},
                    431: 
                    432:   /* OSPF neighbor table. */
                    433:   {OSPFNBRIPADDR,             IPADDRESS, RONLY, ospfNbrEntry,
                    434:    3, {10, 1, 1}},
                    435:   {OSPFNBRADDRESSLESSINDEX,   INTEGER, RONLY, ospfNbrEntry,
                    436:    3, {10, 1, 2}},
                    437:   {OSPFNBRRTRID,              IPADDRESS, RONLY, ospfNbrEntry,
                    438:    3, {10, 1, 3}},
                    439:   {OSPFNBROPTIONS,            INTEGER, RONLY, ospfNbrEntry,
                    440:    3, {10, 1, 4}},
                    441:   {OSPFNBRPRIORITY,           INTEGER, RWRITE, ospfNbrEntry,
                    442:    3, {10, 1, 5}},
                    443:   {OSPFNBRSTATE,              INTEGER, RONLY, ospfNbrEntry,
                    444:    3, {10, 1, 6}},
                    445:   {OSPFNBREVENTS,             COUNTER, RONLY, ospfNbrEntry,
                    446:    3, {10, 1, 7}},
                    447:   {OSPFNBRLSRETRANSQLEN,      GAUGE, RONLY, ospfNbrEntry,
                    448:    3, {10, 1, 8}},
                    449:   {OSPFNBMANBRSTATUS,         INTEGER, RWRITE, ospfNbrEntry,
                    450:    3, {10, 1, 9}},
                    451:   {OSPFNBMANBRPERMANENCE,     INTEGER, RONLY, ospfNbrEntry,
                    452:    3, {10, 1, 10}},
                    453:   {OSPFNBRHELLOSUPPRESSED,    INTEGER, RONLY, ospfNbrEntry,
                    454:    3, {10, 1, 11}},
                    455: 
                    456:   /* OSPF virtual neighbor table. */
                    457:   {OSPFVIRTNBRAREA,           IPADDRESS, RONLY, ospfVirtNbrEntry,
                    458:    3, {11, 1, 1}},
                    459:   {OSPFVIRTNBRRTRID,          IPADDRESS, RONLY, ospfVirtNbrEntry,
                    460:    3, {11, 1, 2}},
                    461:   {OSPFVIRTNBRIPADDR,         IPADDRESS, RONLY, ospfVirtNbrEntry,
                    462:    3, {11, 1, 3}},
                    463:   {OSPFVIRTNBROPTIONS,        INTEGER, RONLY, ospfVirtNbrEntry,
                    464:    3, {11, 1, 4}},
                    465:   {OSPFVIRTNBRSTATE,          INTEGER, RONLY, ospfVirtNbrEntry,
                    466:    3, {11, 1, 5}},
                    467:   {OSPFVIRTNBREVENTS,         COUNTER, RONLY, ospfVirtNbrEntry,
                    468:    3, {11, 1, 6}},
                    469:   {OSPFVIRTNBRLSRETRANSQLEN,  INTEGER, RONLY, ospfVirtNbrEntry,
                    470:    3, {11, 1, 7}},
                    471:   {OSPFVIRTNBRHELLOSUPPRESSED, INTEGER, RONLY, ospfVirtNbrEntry,
                    472:    3, {11, 1, 8}},
                    473: 
                    474:   /* OSPF link state database, external. */
                    475:   {OSPFEXTLSDBTYPE,           INTEGER, RONLY, ospfExtLsdbEntry,
                    476:    3, {12, 1, 1}},
                    477:   {OSPFEXTLSDBLSID,           IPADDRESS, RONLY, ospfExtLsdbEntry,
                    478:    3, {12, 1, 2}},
                    479:   {OSPFEXTLSDBROUTERID,       IPADDRESS, RONLY, ospfExtLsdbEntry,
                    480:    3, {12, 1, 3}},
                    481:   {OSPFEXTLSDBSEQUENCE,       INTEGER, RONLY, ospfExtLsdbEntry,
                    482:    3, {12, 1, 4}},
                    483:   {OSPFEXTLSDBAGE,            INTEGER, RONLY, ospfExtLsdbEntry,
                    484:    3, {12, 1, 5}},
                    485:   {OSPFEXTLSDBCHECKSUM,       INTEGER, RONLY, ospfExtLsdbEntry,
                    486:    3, {12, 1, 6}},
                    487:   {OSPFEXTLSDBADVERTISEMENT,  STRING,  RONLY, ospfExtLsdbEntry,
                    488:    3, {12, 1, 7}},
                    489: 
                    490:   /* OSPF area aggregate table. */
                    491:   {OSPFAREAAGGREGATEAREAID,   IPADDRESS, RONLY, ospfAreaAggregateEntry, 
                    492:    3, {14, 1, 1}},
                    493:   {OSPFAREAAGGREGATELSDBTYPE, INTEGER, RONLY, ospfAreaAggregateEntry, 
                    494:    3, {14, 1, 2}},
                    495:   {OSPFAREAAGGREGATENET,      IPADDRESS, RONLY, ospfAreaAggregateEntry, 
                    496:    3, {14, 1, 3}},
                    497:   {OSPFAREAAGGREGATEMASK,     IPADDRESS, RONLY, ospfAreaAggregateEntry, 
                    498:    3, {14, 1, 4}},
                    499:   {OSPFAREAAGGREGATESTATUS,   INTEGER, RWRITE, ospfAreaAggregateEntry,
                    500:    3, {14, 1, 5}},
                    501:   {OSPFAREAAGGREGATEEFFECT,   INTEGER, RWRITE, ospfAreaAggregateEntry,
                    502:    3, {14, 1, 6}}
                    503: };
                    504: 
                    505: /* The administrative status of OSPF.  When OSPF is enbled on at least
                    506:    one interface return 1. */
                    507: static int
                    508: ospf_admin_stat (struct ospf *ospf)
                    509: {
                    510:   struct listnode *node;
                    511:   struct ospf_interface *oi;
                    512: 
                    513:   if (ospf == NULL)
                    514:     return 0;
                    515: 
                    516:   for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
                    517:     if (oi && oi->address)
                    518:       return 1;
                    519: 
                    520:   return 0;
                    521: }
                    522: 
                    523: static u_char *
                    524: ospfGeneralGroup (struct variable *v, oid *name, size_t *length,
                    525:                  int exact, size_t *var_len, WriteMethod **write_method)
                    526: {
                    527:   struct ospf *ospf;
                    528: 
                    529:   ospf = ospf_lookup ();
                    530: 
                    531:   /* Check whether the instance identifier is valid */
                    532:   if (smux_header_generic (v, name, length, exact, var_len, write_method)
                    533:       == MATCH_FAILED)
                    534:     return NULL;
                    535: 
                    536:   /* Return the current value of the variable */
                    537:   switch (v->magic) 
                    538:     {
                    539:     case OSPFROUTERID:         /* 1 */
                    540:       /* Router-ID of this OSPF instance. */
                    541:       if (ospf)
                    542:        return SNMP_IPADDRESS (ospf->router_id);
                    543:       else
                    544:        return SNMP_IPADDRESS (ospf_empty_addr);
                    545:       break;
                    546:     case OSPFADMINSTAT:                /* 2 */
                    547:       /* The administrative status of OSPF in the router. */
                    548:       if (ospf_admin_stat (ospf))
                    549:        return SNMP_INTEGER (OSPF_STATUS_ENABLED);
                    550:       else
                    551:        return SNMP_INTEGER (OSPF_STATUS_DISABLED);
                    552:       break;
                    553:     case OSPFVERSIONNUMBER:    /* 3 */
                    554:       /* OSPF version 2. */
                    555:       return SNMP_INTEGER (OSPF_VERSION);
                    556:       break;
                    557:     case OSPFAREABDRRTRSTATUS: /* 4 */
                    558:       /* Area Border router status. */
                    559:       if (ospf && CHECK_FLAG (ospf->flags, OSPF_FLAG_ABR))
                    560:        return SNMP_INTEGER (SNMP_TRUE);
                    561:       else
                    562:        return SNMP_INTEGER (SNMP_FALSE);
                    563:       break;
                    564:     case OSPFASBDRRTRSTATUS:   /* 5 */
                    565:       /* AS Border router status. */
                    566:       if (ospf && CHECK_FLAG (ospf->flags, OSPF_FLAG_ASBR))
                    567:        return SNMP_INTEGER (SNMP_TRUE);
                    568:       else
                    569:        return SNMP_INTEGER (SNMP_FALSE);
                    570:       break;
                    571:     case OSPFEXTERNLSACOUNT:   /* 6 */
                    572:       /* External LSA counts. */
                    573:       if (ospf)
                    574:        return SNMP_INTEGER (ospf_lsdb_count_all (ospf->lsdb));
                    575:       else
                    576:        return SNMP_INTEGER (0);
                    577:       break;
                    578:     case OSPFEXTERNLSACKSUMSUM:        /* 7 */
                    579:       /* External LSA checksum. */
                    580:       return SNMP_INTEGER (0);
                    581:       break;
                    582:     case OSPFTOSSUPPORT:       /* 8 */
                    583:       /* TOS is not supported. */
                    584:       return SNMP_INTEGER (SNMP_FALSE);
                    585:       break;
                    586:     case OSPFORIGINATENEWLSAS: /* 9 */
                    587:       /* The number of new link-state advertisements. */
                    588:       if (ospf)
                    589:        return SNMP_INTEGER (ospf->lsa_originate_count);
                    590:       else
                    591:        return SNMP_INTEGER (0);
                    592:       break;
                    593:     case OSPFRXNEWLSAS:                /* 10 */
                    594:       /* The number of link-state advertisements received determined
                    595:          to be new instantiations. */
                    596:       if (ospf)
                    597:        return SNMP_INTEGER (ospf->rx_lsa_count);
                    598:       else
                    599:        return SNMP_INTEGER (0);
                    600:       break;
                    601:     case OSPFEXTLSDBLIMIT:     /* 11 */
                    602:       /* There is no limit for the number of non-default
                    603:          AS-external-LSAs. */
                    604:       return SNMP_INTEGER (-1);
                    605:       break;
                    606:     case OSPFMULTICASTEXTENSIONS: /* 12 */
                    607:       /* Multicast Extensions to OSPF is not supported. */
                    608:       return SNMP_INTEGER (0);
                    609:       break;
                    610:     case OSPFEXITOVERFLOWINTERVAL: /* 13 */
                    611:       /* Overflow is not supported. */
                    612:       return SNMP_INTEGER (0);
                    613:       break;
                    614:     case OSPFDEMANDEXTENSIONS: /* 14 */
                    615:       /* Demand routing is not supported. */
                    616:       return SNMP_INTEGER (SNMP_FALSE);
                    617:       break;
                    618:     default:
                    619:       return NULL;
                    620:     }
                    621:   return NULL;
                    622: }
                    623: 
                    624: static struct ospf_area *
                    625: ospf_area_lookup_next (struct ospf *ospf, struct in_addr *area_id, int first)
                    626: {
                    627:   struct ospf_area *area;
                    628:   struct listnode *node;
                    629: 
                    630:   if (ospf == NULL)
                    631:     return NULL;
                    632: 
                    633:   if (first)
                    634:     {
                    635:       node = listhead (ospf->areas);
                    636:       if (node)
                    637:        {
                    638:          area = listgetdata (node);
                    639:          *area_id = area->area_id;
                    640:          return area;
                    641:        }
                    642:       return NULL;
                    643:     }
                    644:   for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
                    645:     {
                    646:       if (ntohl (area->area_id.s_addr) > ntohl (area_id->s_addr))
                    647:        {
                    648:          *area_id = area->area_id;
                    649:          return area;
                    650:        }
                    651:     }
                    652:   return NULL;
                    653: }
                    654: 
                    655: static struct ospf_area *
                    656: ospfAreaLookup (struct variable *v, oid name[], size_t *length,
                    657:                struct in_addr *addr, int exact)
                    658: {
                    659:   struct ospf *ospf;
                    660:   struct ospf_area *area;
                    661:   int len;
                    662: 
                    663:   ospf = ospf_lookup ();
                    664:   if (ospf == NULL)
                    665:     return NULL;
                    666: 
                    667:   if (exact)
                    668:     {
                    669:       /* Length is insufficient to lookup OSPF area. */
                    670:       if (*length - v->namelen != sizeof (struct in_addr))
                    671:        return NULL;
                    672: 
                    673:       oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr);
                    674: 
                    675:       area = ospf_area_lookup_by_area_id (ospf, *addr);
                    676: 
                    677:       return area;
                    678:     }
                    679:   else
                    680:     {
                    681:       len = *length - v->namelen;
                    682:       if (len > 4)
                    683:        len = 4;
                    684:       
                    685:       oid2in_addr (name + v->namelen, len, addr);
                    686: 
                    687:       area = ospf_area_lookup_next (ospf, addr, len == 0 ? 1 : 0);
                    688: 
                    689:       if (area == NULL)
                    690:        return NULL;
                    691: 
                    692:       oid_copy_addr (name + v->namelen, addr, sizeof (struct in_addr));
                    693:       *length = sizeof (struct in_addr) + v->namelen;
                    694: 
                    695:       return area;
                    696:     }
                    697:   return NULL;
                    698: }
                    699: 
                    700: static u_char *
                    701: ospfAreaEntry (struct variable *v, oid *name, size_t *length, int exact,
                    702:               size_t *var_len, WriteMethod **write_method)
                    703: {
                    704:   struct ospf_area *area;
                    705:   struct in_addr addr;
                    706: 
1.1.1.3 ! misho     707:   if (smux_header_table(v, name, length, exact, var_len, write_method)
        !           708:       == MATCH_FAILED)
        !           709:     return NULL;
        !           710: 
1.1       misho     711:   memset (&addr, 0, sizeof (struct in_addr));
                    712: 
                    713:   area = ospfAreaLookup (v, name, length, &addr, exact);
                    714:   if (! area)
                    715:     return NULL;
                    716:   
                    717:   /* Return the current value of the variable */
                    718:   switch (v->magic) 
                    719:     {
                    720:     case OSPFAREAID:           /* 1 */
                    721:       return SNMP_IPADDRESS (area->area_id);
                    722:       break;
                    723:     case OSPFAUTHTYPE:         /* 2 */
                    724:       return SNMP_INTEGER (area->auth_type);
                    725:       break;
                    726:     case OSPFIMPORTASEXTERN:   /* 3 */
                    727:       return SNMP_INTEGER (area->external_routing + 1);
                    728:       break;
                    729:     case OSPFSPFRUNS:          /* 4 */
                    730:       return SNMP_INTEGER (area->spf_calculation);
                    731:       break;
                    732:     case OSPFAREABDRRTRCOUNT:  /* 5 */
                    733:       return SNMP_INTEGER (area->abr_count);
                    734:       break;
                    735:     case OSPFASBDRRTRCOUNT:    /* 6 */
                    736:       return SNMP_INTEGER (area->asbr_count);
                    737:       break;
                    738:     case OSPFAREALSACOUNT:     /* 7 */
                    739:       return SNMP_INTEGER (area->lsdb->total);
                    740:       break;
                    741:     case OSPFAREALSACKSUMSUM:  /* 8 */
                    742:       return SNMP_INTEGER (0);
                    743:       break;
                    744:     case OSPFAREASUMMARY:      /* 9 */
                    745: #define OSPF_noAreaSummary   1
                    746: #define OSPF_sendAreaSummary 2
                    747:       if (area->no_summary)
                    748:        return SNMP_INTEGER (OSPF_noAreaSummary);
                    749:       else
                    750:        return SNMP_INTEGER (OSPF_sendAreaSummary);
                    751:       break;
                    752:     case OSPFAREASTATUS:       /* 10 */
                    753:       return SNMP_INTEGER (SNMP_VALID);
                    754:       break;
                    755:     default:
                    756:       return NULL;
                    757:       break;
                    758:     }
                    759:   return NULL;
                    760: }
                    761: 
                    762: static struct ospf_area *
                    763: ospf_stub_area_lookup_next (struct in_addr *area_id, int first)
                    764: {
                    765:   struct ospf_area *area;
                    766:   struct listnode *node;
                    767:   struct ospf *ospf;
                    768: 
                    769:   ospf = ospf_lookup ();
                    770:   if (ospf == NULL)
                    771:     return NULL;
                    772: 
                    773:   for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
                    774:     {
                    775:       if (area->external_routing == OSPF_AREA_STUB)
                    776:        {
                    777:          if (first)
                    778:            {
                    779:              *area_id = area->area_id;
                    780:              return area;
                    781:            }
                    782:          else if (ntohl (area->area_id.s_addr) > ntohl (area_id->s_addr))
                    783:            {
                    784:              *area_id = area->area_id;
                    785:              return area;
                    786:            }
                    787:        }
                    788:     }
                    789:   return NULL;
                    790: }
                    791: 
                    792: static struct ospf_area *
                    793: ospfStubAreaLookup (struct variable *v, oid name[], size_t *length,
                    794:                    struct in_addr *addr, int exact)
                    795: {
                    796:   struct ospf *ospf;
                    797:   struct ospf_area *area;
                    798:   int len;
                    799: 
                    800:   ospf = ospf_lookup ();
                    801:   if (ospf == NULL)
                    802:     return NULL;
                    803: 
                    804:   /* Exact lookup. */
                    805:   if (exact)
                    806:     {
                    807:       /* ospfStubAreaID + ospfStubTOS. */
                    808:       if (*length != v->namelen + sizeof (struct in_addr) + 1)
                    809:        return NULL;
                    810: 
                    811:       /* Check ospfStubTOS is zero. */
                    812:       if (name[*length - 1] != 0)
                    813:        return NULL;
                    814: 
                    815:       oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr);
                    816: 
                    817:       area = ospf_area_lookup_by_area_id (ospf, *addr);
                    818: 
                    819:       if (area->external_routing == OSPF_AREA_STUB)
                    820:        return area;
                    821:       else
                    822:        return NULL;
                    823:     }
                    824:   else
                    825:     {
                    826:       len = *length - v->namelen;
                    827:       if (len > 4)
                    828:        len = 4;
                    829:       
                    830:       oid2in_addr (name + v->namelen, len, addr);
                    831: 
                    832:       area = ospf_stub_area_lookup_next (addr, len == 0 ? 1 : 0);
                    833: 
                    834:       if (area == NULL)
                    835:        return NULL;
                    836: 
                    837:       oid_copy_addr (name + v->namelen, addr, sizeof (struct in_addr));
                    838:       /* Set TOS 0. */
                    839:       name[v->namelen + sizeof (struct in_addr)] = 0;
                    840:       *length = v->namelen + sizeof (struct in_addr) + 1;
                    841: 
                    842:       return area;
                    843:     }
                    844:   return NULL;
                    845: }
                    846: 
                    847: static u_char *
                    848: ospfStubAreaEntry (struct variable *v, oid *name, size_t *length,
                    849:                   int exact, size_t *var_len, WriteMethod **write_method)
                    850: {
                    851:   struct ospf_area *area;
                    852:   struct in_addr addr;
                    853: 
1.1.1.3 ! misho     854:   if (smux_header_table(v, name, length, exact, var_len, write_method)
        !           855:       == MATCH_FAILED)
        !           856:     return NULL;
        !           857: 
1.1       misho     858:   memset (&addr, 0, sizeof (struct in_addr));
                    859: 
                    860:   area = ospfStubAreaLookup (v, name, length, &addr, exact);
                    861:   if (! area)
                    862:     return NULL;
                    863: 
                    864:   /* Return the current value of the variable */
                    865:   switch (v->magic) 
                    866:     {
                    867:     case OSPFSTUBAREAID:       /* 1 */
                    868:       /* OSPF stub area id. */
                    869:       return SNMP_IPADDRESS (area->area_id);
                    870:       break;
                    871:     case OSPFSTUBTOS:          /* 2 */
                    872:       /* TOS value is not supported. */
                    873:       return SNMP_INTEGER (0);
                    874:       break;
                    875:     case OSPFSTUBMETRIC:       /* 3 */
                    876:       /* Default cost to stub area. */
                    877:       return SNMP_INTEGER (area->default_cost);
                    878:       break;
                    879:     case OSPFSTUBSTATUS:       /* 4 */
                    880:       /* Status of the stub area. */
                    881:       return SNMP_INTEGER (SNMP_VALID);
                    882:       break;
                    883:     case OSPFSTUBMETRICTYPE:   /* 5 */
                    884:       /* OSPF Metric type. */
                    885: #define OSPF_ospfMetric     1
                    886: #define OSPF_comparableCost 2
                    887: #define OSPF_nonComparable  3
                    888:       return SNMP_INTEGER (OSPF_ospfMetric);
                    889:       break;
                    890:     default:
                    891:       return NULL;
                    892:       break;
                    893:     }
                    894:   return NULL;
                    895: }
                    896: 
                    897: static struct ospf_lsa *
                    898: lsdb_lookup_next (struct ospf_area *area, u_char *type, int type_next,
                    899:                  struct in_addr *ls_id, int ls_id_next,
                    900:                  struct in_addr *router_id, int router_id_next)
                    901: {
                    902:   struct ospf_lsa *lsa;
                    903:   int i;
                    904: 
                    905:   if (type_next)
                    906:     i = OSPF_MIN_LSA;
                    907:   else
                    908:     i = *type;
                    909: 
                    910:   /* Sanity check, if LSA type unknwon
                    911:      merley skip any LSA */
                    912:   if ((i < OSPF_MIN_LSA) || (i >= OSPF_MAX_LSA))
                    913:     {
                    914:       zlog_debug("Strange request with LSA type %d\n", i);
                    915:       return NULL;
                    916:     }
                    917: 
                    918:   for (; i < OSPF_MAX_LSA; i++)
                    919:     {
                    920:       *type = i;
                    921: 
                    922:       lsa = ospf_lsdb_lookup_by_id_next (area->lsdb, *type, *ls_id, *router_id,
                    923:                                        ls_id_next);
                    924:       if (lsa)
                    925:        return lsa;
                    926: 
                    927:       ls_id_next = 1;
                    928:     }
                    929:   return NULL;
                    930: }
                    931: 
                    932: static struct ospf_lsa *
                    933: ospfLsdbLookup (struct variable *v, oid *name, size_t *length,
                    934:                struct in_addr *area_id, u_char *type,
                    935:                struct in_addr *ls_id, struct in_addr *router_id, int exact)
                    936: {
                    937:   struct ospf *ospf;
                    938:   struct ospf_area *area;
                    939:   struct ospf_lsa *lsa;
1.1.1.2   misho     940:   int len;
1.1       misho     941:   int type_next;
                    942:   int ls_id_next;
                    943:   int router_id_next;
                    944:   oid *offset;
                    945:   int offsetlen;
                    946: 
                    947:   ospf = ospf_lookup ();
                    948: 
                    949: #define OSPF_LSDB_ENTRY_OFFSET \
                    950:           (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
                    951: 
                    952:   if (exact)
                    953:     {
                    954:       /* Area ID + Type + LS ID + Router ID. */
                    955:       if (*length - v->namelen != OSPF_LSDB_ENTRY_OFFSET)
                    956:        return NULL;
                    957:       
                    958:       /* Set OID offset for Area ID. */
                    959:       offset = name + v->namelen;
                    960: 
                    961:       /* Lookup area first. */
                    962:       oid2in_addr (offset, IN_ADDR_SIZE, area_id);
                    963:       area = ospf_area_lookup_by_area_id (ospf, *area_id);
                    964:       if (! area)
                    965:        return NULL;
                    966:       offset += IN_ADDR_SIZE;
                    967: 
                    968:       /* Type. */
                    969:       *type = *offset;
                    970:       offset++;
                    971: 
                    972:       /* LS ID. */
                    973:       oid2in_addr (offset, IN_ADDR_SIZE, ls_id);
                    974:       offset += IN_ADDR_SIZE;
                    975: 
                    976:       /* Router ID. */
                    977:       oid2in_addr (offset, IN_ADDR_SIZE, router_id);
                    978: 
                    979:       /* Lookup LSDB. */
                    980:       return ospf_lsdb_lookup_by_id (area->lsdb, *type, *ls_id, *router_id);
                    981:     }
                    982:   else
                    983:     {
                    984:       /* Get variable length. */
                    985:       offset = name + v->namelen;
                    986:       offsetlen = *length - v->namelen;
                    987:       len = offsetlen;
                    988: 
                    989:       if (len > IN_ADDR_SIZE)
                    990:        len = IN_ADDR_SIZE;
                    991: 
                    992:       oid2in_addr (offset, len, area_id);
                    993: 
                    994:       /* First we search area. */
                    995:       if (len == IN_ADDR_SIZE)
                    996:        area = ospf_area_lookup_by_area_id (ospf, *area_id);
                    997:       else
1.1.1.2   misho     998:        area = ospf_area_lookup_next (ospf, area_id, 1);
1.1       misho     999: 
                   1000:       if (area == NULL)
                   1001:        return NULL;
                   1002: 
                   1003:       do 
                   1004:        {
                   1005:          /* Next we lookup type. */
1.1.1.2   misho    1006:          offset += len;
                   1007:          offsetlen -= len;
1.1       misho    1008:          len = offsetlen;
                   1009: 
                   1010:          if (len <= 0)
                   1011:            type_next = 1;
                   1012:          else
                   1013:            {
                   1014:              len = 1;
                   1015:              type_next = 0;
                   1016:              *type = *offset;
                   1017:            }
                   1018:        
                   1019:          /* LS ID. */
                   1020:          offset++;
                   1021:          offsetlen--;
                   1022:          len = offsetlen;
                   1023: 
                   1024:          if (len <= 0)
                   1025:            ls_id_next = 1;
                   1026:          else
                   1027:            {
                   1028:              ls_id_next = 0;
                   1029:              if (len > IN_ADDR_SIZE)
                   1030:                len = IN_ADDR_SIZE;
                   1031: 
                   1032:              oid2in_addr (offset, len, ls_id);
                   1033:            }
                   1034: 
                   1035:          /* Router ID. */
                   1036:          offset += IN_ADDR_SIZE;
                   1037:          offsetlen -= IN_ADDR_SIZE;
                   1038:          len = offsetlen;
                   1039: 
                   1040:          if (len <= 0)
                   1041:            router_id_next = 1;
                   1042:          else
                   1043:            {
                   1044:              router_id_next = 0;
                   1045:              if (len > IN_ADDR_SIZE)
                   1046:                len = IN_ADDR_SIZE;
                   1047: 
                   1048:              oid2in_addr (offset, len, router_id);
                   1049:            }
                   1050: 
                   1051:          lsa = lsdb_lookup_next (area, type, type_next, ls_id, ls_id_next,
                   1052:                                  router_id, router_id_next);
                   1053: 
                   1054:          if (lsa)
                   1055:            {
                   1056:              /* Fill in length. */
                   1057:              *length = v->namelen + OSPF_LSDB_ENTRY_OFFSET;
                   1058: 
                   1059:              /* Fill in value. */
                   1060:              offset = name + v->namelen;
                   1061:              oid_copy_addr (offset, area_id, IN_ADDR_SIZE);
                   1062:              offset += IN_ADDR_SIZE;
                   1063:              *offset = lsa->data->type;
                   1064:              offset++;
                   1065:              oid_copy_addr (offset, &lsa->data->id, IN_ADDR_SIZE);
                   1066:              offset += IN_ADDR_SIZE;
                   1067:              oid_copy_addr (offset, &lsa->data->adv_router, IN_ADDR_SIZE);
                   1068:            
                   1069:              return lsa;
                   1070:            }
                   1071:        }
                   1072:       while ((area = ospf_area_lookup_next (ospf, area_id, 0)) != NULL);
                   1073:     }
                   1074:   return NULL;
                   1075: }
                   1076: 
                   1077: static u_char *
                   1078: ospfLsdbEntry (struct variable *v, oid *name, size_t *length, int exact,
                   1079:               size_t *var_len, WriteMethod **write_method)
                   1080: {
                   1081:   struct ospf_lsa *lsa;
                   1082:   struct lsa_header *lsah;
                   1083:   struct in_addr area_id;
                   1084:   u_char type;
                   1085:   struct in_addr ls_id;
                   1086:   struct in_addr router_id;
                   1087:   struct ospf *ospf;
                   1088: 
1.1.1.3 ! misho    1089:   if (smux_header_table(v, name, length, exact, var_len, write_method)
        !          1090:       == MATCH_FAILED)
        !          1091:     return NULL;
        !          1092: 
1.1       misho    1093:   /* INDEX { ospfLsdbAreaId, ospfLsdbType,
                   1094:      ospfLsdbLsid, ospfLsdbRouterId } */
                   1095: 
                   1096:   memset (&area_id, 0, sizeof (struct in_addr));
                   1097:   type = 0;
                   1098:   memset (&ls_id, 0, sizeof (struct in_addr));
                   1099:   memset (&router_id, 0, sizeof (struct in_addr));
                   1100: 
                   1101:   /* Check OSPF instance. */
                   1102:   ospf = ospf_lookup ();
                   1103:   if (ospf == NULL)
                   1104:     return NULL;
                   1105: 
                   1106:   lsa = ospfLsdbLookup (v, name, length, &area_id, &type, &ls_id, &router_id,
                   1107:                        exact);
                   1108:   if (! lsa)
                   1109:     return NULL;
                   1110: 
                   1111:   lsah = lsa->data;
                   1112: 
                   1113:   /* Return the current value of the variable */
                   1114:   switch (v->magic) 
                   1115:     {
                   1116:     case OSPFLSDBAREAID:       /* 1 */
                   1117:       return SNMP_IPADDRESS (lsa->area->area_id);
                   1118:       break;
                   1119:     case OSPFLSDBTYPE:         /* 2 */
                   1120:       return SNMP_INTEGER (lsah->type);
                   1121:       break;
                   1122:     case OSPFLSDBLSID:         /* 3 */
                   1123:       return SNMP_IPADDRESS (lsah->id);
                   1124:       break;
                   1125:     case OSPFLSDBROUTERID:     /* 4 */
                   1126:       return SNMP_IPADDRESS (lsah->adv_router);
                   1127:       break;
                   1128:     case OSPFLSDBSEQUENCE:     /* 5 */
                   1129:       return SNMP_INTEGER (lsah->ls_seqnum);
                   1130:       break;
                   1131:     case OSPFLSDBAGE:          /* 6 */
                   1132:       return SNMP_INTEGER (lsah->ls_age);
                   1133:       break;
                   1134:     case OSPFLSDBCHECKSUM:     /* 7 */
                   1135:       return SNMP_INTEGER (lsah->checksum);
                   1136:       break;
                   1137:     case OSPFLSDBADVERTISEMENT:        /* 8 */
                   1138:       *var_len = ntohs (lsah->length);
                   1139:       return (u_char *) lsah;
                   1140:       break;
                   1141:     default:
                   1142:       return NULL;
                   1143:       break;
                   1144:     }
                   1145:   return NULL;
                   1146: }
                   1147: 
                   1148: static struct ospf_area_range *
                   1149: ospfAreaRangeLookup (struct variable *v, oid *name, size_t *length,
                   1150:                     struct in_addr *area_id, struct in_addr *range_net,
                   1151:                     int exact)
                   1152: {
                   1153:   oid *offset;
                   1154:   int offsetlen;
                   1155:   unsigned int len;
                   1156:   struct ospf *ospf;
                   1157:   struct ospf_area *area;
                   1158:   struct ospf_area_range *range;
                   1159:   struct prefix_ipv4 p;
                   1160:   p.family = AF_INET;
                   1161:   p.prefixlen = IPV4_MAX_BITLEN;
                   1162: 
                   1163:   ospf = ospf_lookup ();
                   1164: 
                   1165:   if (exact) 
                   1166:     {
                   1167:       /* Area ID + Range Network. */
                   1168:       if (v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE != *length)
                   1169:        return NULL;
                   1170: 
                   1171:       /* Set OID offset for Area ID. */
                   1172:       offset = name + v->namelen;
                   1173: 
                   1174:       /* Lookup area first. */
                   1175:       oid2in_addr (offset, IN_ADDR_SIZE, area_id);
                   1176: 
                   1177:       area = ospf_area_lookup_by_area_id (ospf, *area_id);
                   1178:       if (! area)
                   1179:        return NULL;
                   1180: 
                   1181:       offset += IN_ADDR_SIZE;
                   1182: 
                   1183:       /* Lookup area range. */
                   1184:       oid2in_addr (offset, IN_ADDR_SIZE, range_net);
                   1185:       p.prefix = *range_net;
                   1186: 
                   1187:       return ospf_area_range_lookup (area, &p);
                   1188:     }
                   1189:   else
                   1190:     {
                   1191:       /* Set OID offset for Area ID. */
                   1192:       offset = name + v->namelen;
                   1193:       offsetlen = *length - v->namelen;
                   1194: 
                   1195:       len = offsetlen;
                   1196:       if (len > IN_ADDR_SIZE)
                   1197:        len = IN_ADDR_SIZE;
                   1198: 
                   1199:       oid2in_addr (offset, len, area_id);
                   1200: 
                   1201:       /* First we search area. */
                   1202:       if (len == IN_ADDR_SIZE)
                   1203:        area = ospf_area_lookup_by_area_id (ospf,*area_id);
                   1204:       else
                   1205:        area = ospf_area_lookup_next (ospf, area_id, len == 0 ? 1 : 0);
                   1206: 
                   1207:       if (area == NULL)
                   1208:        return NULL;
                   1209: 
                   1210:       do 
                   1211:        {
                   1212:          offset += IN_ADDR_SIZE;
                   1213:          offsetlen -= IN_ADDR_SIZE;
                   1214:          len = offsetlen;
                   1215: 
                   1216:          if (len < 0)
                   1217:            len = 0;
                   1218:          if (len > IN_ADDR_SIZE)
                   1219:            len = IN_ADDR_SIZE;
                   1220: 
                   1221:          oid2in_addr (offset, len, range_net);
                   1222: 
                   1223:          range = ospf_area_range_lookup_next (area, range_net,
                   1224:                                               len == 0 ? 1 : 0);
                   1225: 
                   1226:          if (range)
                   1227:            {
                   1228:              /* Fill in length. */
                   1229:              *length = v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE;
                   1230: 
                   1231:              /* Fill in value. */
                   1232:              offset = name + v->namelen;
                   1233:              oid_copy_addr (offset, area_id, IN_ADDR_SIZE);
                   1234:              offset += IN_ADDR_SIZE;
                   1235:              oid_copy_addr (offset, range_net, IN_ADDR_SIZE);
                   1236: 
                   1237:              return range;
                   1238:            }
                   1239:        }
                   1240:       while ((area = ospf_area_lookup_next (ospf, area_id, 0)) != NULL);
                   1241:     }
                   1242:   return NULL;
                   1243: }
                   1244: 
                   1245: static u_char *
                   1246: ospfAreaRangeEntry (struct variable *v, oid *name, size_t *length, int exact,
                   1247:                    size_t *var_len, WriteMethod **write_method)
                   1248: {
                   1249:   struct ospf_area_range *range;
                   1250:   struct in_addr area_id;
                   1251:   struct in_addr range_net;
                   1252:   struct in_addr mask;
                   1253:   struct ospf *ospf;
                   1254:   
1.1.1.3 ! misho    1255:   if (smux_header_table(v, name, length, exact, var_len, write_method)
        !          1256:       == MATCH_FAILED)
        !          1257:     return NULL;
        !          1258: 
1.1       misho    1259:   /* Check OSPF instance. */
                   1260:   ospf = ospf_lookup ();
                   1261:   if (ospf == NULL)
                   1262:     return NULL;
                   1263: 
                   1264:   memset (&area_id, 0, IN_ADDR_SIZE);
                   1265:   memset (&range_net, 0, IN_ADDR_SIZE);
                   1266: 
                   1267:   range = ospfAreaRangeLookup (v, name, length, &area_id, &range_net, exact);
                   1268:   if (! range)
                   1269:     return NULL;
                   1270: 
                   1271:   /* Convert prefixlen to network mask format. */
                   1272:   masklen2ip (range->subst_masklen, &mask);
                   1273: 
                   1274:   /* Return the current value of the variable */
                   1275:   switch (v->magic) 
                   1276:     {
                   1277:     case OSPFAREARANGEAREAID:  /* 1 */
                   1278:       return SNMP_IPADDRESS (area_id);
                   1279:       break;
                   1280:     case OSPFAREARANGENET:     /* 2 */
                   1281:       return SNMP_IPADDRESS (range_net);
                   1282:       break;
                   1283:     case OSPFAREARANGEMASK:    /* 3 */
                   1284:       return SNMP_IPADDRESS (mask);
                   1285:       break;
                   1286:     case OSPFAREARANGESTATUS:  /* 4 */
                   1287:       return SNMP_INTEGER (SNMP_VALID);
                   1288:       break;
                   1289:     case OSPFAREARANGEEFFECT:  /* 5 */
                   1290: #define OSPF_advertiseMatching      1
                   1291: #define OSPF_doNotAdvertiseMatching 2
                   1292:       return SNMP_INTEGER (OSPF_advertiseMatching);
                   1293:       break;
                   1294:     default:
                   1295:       return NULL;
                   1296:       break;
                   1297:     }
                   1298:   return NULL;
                   1299: }
                   1300: 
                   1301: static struct ospf_nbr_nbma *
                   1302: ospfHostLookup (struct variable *v, oid *name, size_t *length,
                   1303:                struct in_addr *addr, int exact)
                   1304: {
                   1305:   int len;
                   1306:   struct ospf_nbr_nbma *nbr_nbma;
                   1307:   struct ospf *ospf;
                   1308: 
                   1309:   ospf = ospf_lookup ();
                   1310:   if (ospf == NULL)
                   1311:     return NULL;
                   1312: 
                   1313:   if (exact)
                   1314:     {
                   1315:       /* INDEX { ospfHostIpAddress, ospfHostTOS } */
                   1316:       if (*length != v->namelen + IN_ADDR_SIZE + 1)
                   1317:        return NULL;
                   1318: 
                   1319:       /* Check ospfHostTOS. */
                   1320:       if (name[*length - 1] != 0)
                   1321:        return NULL;
                   1322: 
                   1323:       oid2in_addr (name + v->namelen, IN_ADDR_SIZE, addr);
                   1324: 
                   1325:       nbr_nbma = ospf_nbr_nbma_lookup (ospf, *addr);
                   1326: 
                   1327:       return nbr_nbma;
                   1328:     }
                   1329:   else
                   1330:     {
                   1331:       len = *length - v->namelen;
                   1332:       if (len > 4)
                   1333:        len = 4;
                   1334:       
                   1335:       oid2in_addr (name + v->namelen, len, addr);
                   1336: 
                   1337:       nbr_nbma = ospf_nbr_nbma_lookup_next (ospf, addr, len == 0 ? 1 : 0);
                   1338: 
                   1339:       if (nbr_nbma == NULL)
                   1340:        return NULL;
                   1341: 
                   1342:       oid_copy_addr (name + v->namelen, addr, IN_ADDR_SIZE);
                   1343: 
                   1344:       /* Set TOS 0. */
                   1345:       name[v->namelen + IN_ADDR_SIZE] = 0;
                   1346: 
                   1347:       *length = v->namelen + IN_ADDR_SIZE + 1;
                   1348: 
                   1349:       return nbr_nbma;
                   1350:     }
                   1351:   return NULL;
                   1352: }
                   1353: 
                   1354: static u_char *
                   1355: ospfHostEntry (struct variable *v, oid *name, size_t *length, int exact,
                   1356:               size_t *var_len, WriteMethod **write_method)
                   1357: {
                   1358:   struct ospf_nbr_nbma *nbr_nbma;
                   1359:   struct ospf_interface *oi;
                   1360:   struct in_addr addr;
                   1361:   struct ospf *ospf;
                   1362: 
1.1.1.3 ! misho    1363:   if (smux_header_table(v, name, length, exact, var_len, write_method)
        !          1364:       == MATCH_FAILED)
        !          1365:     return NULL;
        !          1366: 
1.1       misho    1367:   /* Check OSPF instance. */
                   1368:   ospf = ospf_lookup ();
                   1369:   if (ospf == NULL)
                   1370:     return NULL;
                   1371: 
                   1372:   memset (&addr, 0, sizeof (struct in_addr));
                   1373: 
                   1374:   nbr_nbma = ospfHostLookup (v, name, length, &addr, exact);
                   1375:   if (nbr_nbma == NULL)
                   1376:     return NULL;
                   1377: 
                   1378:   oi = nbr_nbma->oi;
                   1379: 
                   1380:   /* Return the current value of the variable */
                   1381:   switch (v->magic) 
                   1382:     {
                   1383:     case OSPFHOSTIPADDRESS:    /* 1 */
                   1384:       return SNMP_IPADDRESS (nbr_nbma->addr);
                   1385:       break;
                   1386:     case OSPFHOSTTOS:          /* 2 */
                   1387:       return SNMP_INTEGER (0);
                   1388:       break;
                   1389:     case OSPFHOSTMETRIC:       /* 3 */
                   1390:       if (oi)
                   1391:        return SNMP_INTEGER (oi->output_cost);
                   1392:       else
                   1393:        return SNMP_INTEGER (1);
                   1394:       break;
                   1395:     case OSPFHOSTSTATUS:       /* 4 */
                   1396:       return SNMP_INTEGER (SNMP_VALID);
                   1397:       break;
                   1398:     case OSPFHOSTAREAID:       /* 5 */
                   1399:       if (oi && oi->area)
                   1400:        return SNMP_IPADDRESS (oi->area->area_id);
                   1401:       else
                   1402:        return SNMP_IPADDRESS (ospf_empty_addr);
                   1403:       break;
                   1404:     default:
                   1405:       return NULL;
                   1406:       break;
                   1407:     }
                   1408:   return NULL;
                   1409: }
                   1410: 
                   1411: struct list *ospf_snmp_iflist;
                   1412: 
                   1413: struct ospf_snmp_if
                   1414: {
                   1415:   struct in_addr addr;
                   1416:   unsigned int ifindex;
                   1417:   struct interface *ifp;
                   1418: };
                   1419: 
                   1420: static struct ospf_snmp_if *
                   1421: ospf_snmp_if_new (void)
                   1422: {
                   1423:   return XCALLOC (0, sizeof (struct ospf_snmp_if));
                   1424: }
                   1425: 
                   1426: static void
                   1427: ospf_snmp_if_free (struct ospf_snmp_if *osif)
                   1428: {
                   1429:   XFREE (0, osif);
                   1430: }
                   1431: 
                   1432: void
                   1433: ospf_snmp_if_delete (struct interface *ifp)
                   1434: {
                   1435:   struct listnode *node, *nnode;
                   1436:   struct ospf_snmp_if *osif;
                   1437: 
                   1438:   for (ALL_LIST_ELEMENTS (ospf_snmp_iflist, node, nnode, osif))
                   1439:     {
                   1440:       if (osif->ifp == ifp)
                   1441:        {
                   1442:          list_delete_node (ospf_snmp_iflist, node);
                   1443:          ospf_snmp_if_free (osif);
                   1444:          return;
                   1445:        }
                   1446:     }
                   1447: }
                   1448: 
                   1449: void
                   1450: ospf_snmp_if_update (struct interface *ifp)
                   1451: {
                   1452:   struct listnode *node;
                   1453:   struct listnode *pn;
                   1454:   struct connected *ifc;
                   1455:   struct prefix *p;
                   1456:   struct ospf_snmp_if *osif;
                   1457:   struct in_addr *addr;
                   1458:   unsigned int ifindex;
                   1459: 
                   1460:   ospf_snmp_if_delete (ifp);
                   1461: 
                   1462:   p = NULL;
                   1463:   addr = NULL;
                   1464:   ifindex = 0;
                   1465: 
                   1466:   /* Lookup first IPv4 address entry. */
                   1467:   for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc))
                   1468:     {
                   1469:       p = CONNECTED_ID(ifc);
                   1470: 
                   1471:       if (p->family == AF_INET)
                   1472:        {
                   1473:          addr = &p->u.prefix4;
                   1474:          break;
                   1475:        }
                   1476:     }
                   1477:   if (! addr)
                   1478:     ifindex = ifp->ifindex;
                   1479: 
                   1480:   /* Add interface to the list. */
                   1481:   pn = NULL;
                   1482:   for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, node, osif))
                   1483:     {
                   1484:       if (addr)
                   1485:        {
                   1486:          /* Usual interfaces --> Sort them based on interface IPv4 addresses */
                   1487:          if (ntohl (osif->addr.s_addr) > ntohl (addr->s_addr))
                   1488:            break;
                   1489:        }
                   1490:       else
                   1491:        {
                   1492:          /* Unnumbered interfaces --> Sort them based on interface indexes */
                   1493:          if (osif->addr.s_addr != 0 || osif->ifindex > ifindex)
                   1494:            break;
                   1495:        }
                   1496:       pn = node;
                   1497:     }
                   1498: 
                   1499:   osif = ospf_snmp_if_new ();
                   1500:   if (addr) /* Usual interface */
                   1501:   {
                   1502:     osif->addr = *addr;
                   1503:     
                   1504:     /* This field is used for storing ospfAddressLessIf OID value,
                   1505:      * conform to RFC1850 OSPF-MIB specification, it must be 0 for
                   1506:      * usual interface */
                   1507:     osif->ifindex = 0;
                   1508:   }
                   1509:   else  /* Unnumbered interface */
                   1510:     osif->ifindex = ifindex;
                   1511:   osif->ifp = ifp;
                   1512: 
                   1513:   listnode_add_after (ospf_snmp_iflist, pn, osif);
                   1514: }
                   1515: 
                   1516: static int
                   1517: ospf_snmp_is_if_have_addr (struct interface *ifp)
                   1518: {
                   1519:   struct listnode *nn;
                   1520:   struct connected *ifc;
                   1521: 
                   1522:   /* Is this interface having any connected IPv4 address ? */
                   1523:   for (ALL_LIST_ELEMENTS_RO (ifp->connected, nn, ifc))
                   1524:   {
                   1525:     if (CONNECTED_PREFIX(ifc)->family == AF_INET)
                   1526:       return 1;
                   1527:   }
                   1528:   
                   1529:   return 0;
                   1530: }
                   1531: 
                   1532: static struct ospf_interface *
                   1533: ospf_snmp_if_lookup (struct in_addr *ifaddr, unsigned int *ifindex)
                   1534: {
                   1535:   struct listnode *node;
                   1536:   struct ospf_snmp_if *osif;
                   1537:   struct ospf_interface *oi = NULL;
                   1538:   struct ospf *ospf = ospf_lookup ();
                   1539: 
                   1540:   for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, node, osif))
                   1541:     {  
                   1542:       if (ifaddr->s_addr)
                   1543:         {
                   1544:              if (IPV4_ADDR_SAME (&osif->addr, ifaddr))
                   1545:             oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
                   1546:         }
                   1547:       else
                   1548:         {
                   1549:              if (osif->ifindex == *ifindex)
                   1550:             oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
                   1551:         }
                   1552:     }
                   1553:   return oi;
                   1554: }
                   1555: 
                   1556: static struct ospf_interface *
                   1557: ospf_snmp_if_lookup_next (struct in_addr *ifaddr, unsigned int *ifindex,
                   1558:                          int ifaddr_next, int ifindex_next)
                   1559: {
                   1560:   struct ospf_snmp_if *osif;
                   1561:   struct listnode *nn;
                   1562:   struct ospf *ospf = ospf_lookup ();
                   1563:   struct ospf_interface *oi = NULL;
                   1564: 
                   1565:   if (ospf == NULL)
                   1566:     return NULL;
                   1567: 
                   1568:   /* No instance is specified --> Return the first OSPF interface */
                   1569:   if (ifaddr_next)
                   1570:     {
                   1571:       for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, nn, osif))
                   1572:        {
                   1573:          osif = listgetdata (nn);
                   1574:          *ifaddr = osif->addr;
                   1575:          *ifindex = osif->ifindex;
                   1576:           /* Because no instance is specified, we don't care about the kind of 
                   1577:            * interface (usual or unnumbered), just returning the first valid 
                   1578:            * OSPF interface */
                   1579:           oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
                   1580:           if (oi)
                   1581:             return (oi);
                   1582:        }
                   1583:       return NULL;
                   1584:     }
                   1585: 
                   1586:   /* An instance is specified --> Return the next OSPF interface */
                   1587:   for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, nn, osif))
                   1588:     {
                   1589:       /* Usual interface */
                   1590:       if (ifaddr->s_addr) 
                   1591:        {
                   1592:          /* The interface must have valid AF_INET connected address */
                   1593:          /* it must have lager IPv4 address value than the lookup entry */
                   1594:          if ((ospf_snmp_is_if_have_addr(osif->ifp)) &&
                   1595:              (ntohl (osif->addr.s_addr) > ntohl (ifaddr->s_addr)))
                   1596:            {
                   1597:              *ifaddr = osif->addr;
                   1598:              *ifindex = osif->ifindex;
                   1599:         
                   1600:              /* and it must be an OSPF interface */
                   1601:              oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
                   1602:              if (oi)
                   1603:                return oi;
                   1604:            }
                   1605:        }
                   1606:       /* Unnumbered interface */
                   1607:       else  
                   1608:         /* The interface must NOT have valid AF_INET connected address */
                   1609:         /* it must have lager interface index than the lookup entry */
                   1610:         if ((!ospf_snmp_is_if_have_addr(osif->ifp)) &&
                   1611:             (osif->ifindex > *ifindex))
                   1612:           {
                   1613:             *ifaddr = osif->addr;
                   1614:             *ifindex = osif->ifindex;
                   1615:         
                   1616:             /* and it must be an OSPF interface */
                   1617:             oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
                   1618:             if (oi)
                   1619:               return oi;
                   1620:           }
                   1621:     }
                   1622:   return NULL;
                   1623: }
                   1624: 
                   1625: static int
                   1626: ospf_snmp_iftype (struct interface *ifp)
                   1627: {
                   1628: #define ospf_snmp_iftype_broadcast         1
                   1629: #define ospf_snmp_iftype_nbma              2
                   1630: #define ospf_snmp_iftype_pointToPoint      3
                   1631: #define ospf_snmp_iftype_pointToMultipoint 5
                   1632:   if (if_is_broadcast (ifp))
                   1633:     return ospf_snmp_iftype_broadcast;
                   1634:   if (if_is_pointopoint (ifp))
                   1635:     return ospf_snmp_iftype_pointToPoint;
                   1636:   return ospf_snmp_iftype_broadcast;
                   1637: }
                   1638: 
                   1639: static struct ospf_interface *
                   1640: ospfIfLookup (struct variable *v, oid *name, size_t *length,
                   1641:              struct in_addr *ifaddr, unsigned int *ifindex, int exact)
                   1642: {
                   1643:   unsigned int len;
                   1644:   int ifaddr_next = 0;
                   1645:   int ifindex_next = 0;
                   1646:   struct ospf_interface *oi;
                   1647:   oid *offset;
                   1648: 
                   1649:   if (exact)
                   1650:     {
                   1651:       if (*length != v->namelen + IN_ADDR_SIZE + 1)
                   1652:        return NULL;
                   1653: 
                   1654:       oid2in_addr (name + v->namelen, IN_ADDR_SIZE, ifaddr);
                   1655:       *ifindex = name[v->namelen + IN_ADDR_SIZE];
                   1656: 
                   1657:       return ospf_snmp_if_lookup (ifaddr, ifindex);
                   1658:     }
                   1659:   else
                   1660:     {
                   1661:       len = *length - v->namelen;
                   1662:       if (len >= IN_ADDR_SIZE)
                   1663:        len = IN_ADDR_SIZE;
                   1664:       if (len <= 0)
                   1665:        ifaddr_next = 1;
                   1666: 
                   1667:       oid2in_addr (name + v->namelen, len, ifaddr);
                   1668: 
                   1669:       len = *length - v->namelen - IN_ADDR_SIZE;
                   1670:       if (len >= 1)
                   1671:        len = 1;
                   1672:       else
                   1673:        ifindex_next = 1;
                   1674: 
                   1675:       if (len == 1)
                   1676:        *ifindex = name[v->namelen + IN_ADDR_SIZE];
                   1677: 
                   1678:       oi = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next,
                   1679:                                      ifindex_next);
                   1680:       if (oi)
                   1681:        {
                   1682:          *length = v->namelen + IN_ADDR_SIZE + 1;
                   1683:          offset = name + v->namelen;
                   1684:          oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE);
                   1685:          offset += IN_ADDR_SIZE;
                   1686:          *offset = *ifindex;
                   1687:          return oi;
                   1688:        }
                   1689:     }
                   1690:   return NULL;
                   1691: }
                   1692: 
                   1693: static u_char *
                   1694: ospfIfEntry (struct variable *v, oid *name, size_t *length, int exact,
                   1695:             size_t *var_len, WriteMethod **write_method)
                   1696: {
                   1697:   unsigned int ifindex;
                   1698:   struct in_addr ifaddr;
                   1699:   struct ospf_interface *oi;
                   1700:   struct ospf *ospf;
                   1701: 
1.1.1.3 ! misho    1702:   if (smux_header_table(v, name, length, exact, var_len, write_method)
        !          1703:       == MATCH_FAILED)
        !          1704:     return NULL;
        !          1705: 
1.1       misho    1706:   ifindex = 0;
                   1707:   memset (&ifaddr, 0, sizeof (struct in_addr));
                   1708: 
                   1709:   /* Check OSPF instance. */
                   1710:   ospf = ospf_lookup ();
                   1711:   if (ospf == NULL)
                   1712:     return NULL;
                   1713: 
                   1714:   oi = ospfIfLookup (v, name, length, &ifaddr, &ifindex, exact);
                   1715:   if (oi == NULL)
                   1716:     return NULL;
                   1717: 
                   1718:   /* Return the current value of the variable */
                   1719:   switch (v->magic) 
                   1720:     {
                   1721:     case OSPFIFIPADDRESS:      /* 1 */
                   1722:       return SNMP_IPADDRESS (ifaddr);
                   1723:       break;
                   1724:     case OSPFADDRESSLESSIF:    /* 2 */
                   1725:       return SNMP_INTEGER (ifindex);
                   1726:       break;
                   1727:     case OSPFIFAREAID:         /* 3 */
                   1728:       if (oi->area)
                   1729:        return SNMP_IPADDRESS (oi->area->area_id);
                   1730:       else
                   1731:        return SNMP_IPADDRESS (ospf_empty_addr);
                   1732:       break;
                   1733:     case OSPFIFTYPE:           /* 4 */
                   1734:       return SNMP_INTEGER (ospf_snmp_iftype (oi->ifp));
                   1735:       break;
                   1736:     case OSPFIFADMINSTAT:      /* 5 */
                   1737:       if (oi)
                   1738:        return SNMP_INTEGER (OSPF_STATUS_ENABLED);
                   1739:       else
                   1740:        return SNMP_INTEGER (OSPF_STATUS_DISABLED);
                   1741:       break;
                   1742:     case OSPFIFRTRPRIORITY:    /* 6 */
                   1743:       return SNMP_INTEGER (PRIORITY (oi));
                   1744:       break;
                   1745:     case OSPFIFTRANSITDELAY:   /* 7 */
                   1746:       return SNMP_INTEGER (OSPF_IF_PARAM (oi, transmit_delay));
                   1747:       break;
                   1748:     case OSPFIFRETRANSINTERVAL:        /* 8 */
                   1749:       return SNMP_INTEGER (OSPF_IF_PARAM (oi, retransmit_interval));
                   1750:       break;
                   1751:     case OSPFIFHELLOINTERVAL:  /* 9 */
                   1752:       return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_hello));
                   1753:       break;
                   1754:     case OSPFIFRTRDEADINTERVAL:        /* 10 */
                   1755:       return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_wait));
                   1756:       break;
                   1757:     case OSPFIFPOLLINTERVAL:   /* 11 */
                   1758:       return SNMP_INTEGER (OSPF_POLL_INTERVAL_DEFAULT);
                   1759:       break;
                   1760:     case OSPFIFSTATE:          /* 12 */
                   1761:       return SNMP_INTEGER (ISM_SNMP(oi->state));
                   1762:       break;
                   1763:     case OSPFIFDESIGNATEDROUTER: /* 13 */
                   1764:       return SNMP_IPADDRESS (DR (oi));
                   1765:       break;
                   1766:     case OSPFIFBACKUPDESIGNATEDROUTER: /* 14 */
                   1767:       return SNMP_IPADDRESS (BDR (oi));
                   1768:       break;
                   1769:     case OSPFIFEVENTS:         /* 15 */
                   1770:       return SNMP_INTEGER (oi->state_change);
                   1771:       break;
                   1772:     case OSPFIFAUTHKEY:                /* 16 */
                   1773:       *var_len = 0;
                   1774:       return (u_char *) OSPF_IF_PARAM (oi, auth_simple);
                   1775:       break;
                   1776:     case OSPFIFSTATUS:         /* 17 */
                   1777:       return SNMP_INTEGER (SNMP_VALID);
                   1778:       break;
                   1779:     case OSPFIFMULTICASTFORWARDING: /* 18 */
                   1780: #define ospf_snmp_multiforward_blocked    1
                   1781: #define ospf_snmp_multiforward_multicast  2
                   1782: #define ospf_snmp_multiforward_unicast    3
                   1783:       return SNMP_INTEGER (ospf_snmp_multiforward_blocked);
                   1784:       break;
                   1785:     case OSPFIFDEMAND:         /* 19 */
                   1786:       return SNMP_INTEGER (SNMP_FALSE);
                   1787:       break;
                   1788:     case OSPFIFAUTHTYPE:       /* 20 */
                   1789:       if (oi->area)
                   1790:        return SNMP_INTEGER (oi->area->auth_type);
                   1791:       else
                   1792:        return SNMP_INTEGER (0);
                   1793:       break;
                   1794:     default:
                   1795:       return NULL;
                   1796:       break;
                   1797:     }
                   1798:   return NULL;
                   1799: }
                   1800: 
                   1801: #define OSPF_SNMP_METRIC_VALUE 1
                   1802: 
                   1803: static struct ospf_interface *
                   1804: ospfIfMetricLookup (struct variable *v, oid *name, size_t *length,
                   1805:                    struct in_addr *ifaddr, unsigned int *ifindex, int exact)
                   1806: {
                   1807:   unsigned int len;
                   1808:   int ifaddr_next = 0;
                   1809:   int ifindex_next = 0;
                   1810:   struct ospf_interface *oi;
                   1811:   oid *offset;
                   1812:   int metric;
                   1813: 
                   1814:   if (exact)
                   1815:     {
                   1816:       if (*length != v->namelen + IN_ADDR_SIZE + 1 + 1)
                   1817:        return NULL;
                   1818: 
                   1819:       oid2in_addr (name + v->namelen, IN_ADDR_SIZE, ifaddr);
                   1820:       *ifindex = name[v->namelen + IN_ADDR_SIZE];
                   1821:       metric = name[v->namelen + IN_ADDR_SIZE + 1];
                   1822: 
                   1823:       if (metric != OSPF_SNMP_METRIC_VALUE)
                   1824:        return NULL;
                   1825: 
                   1826:       return ospf_snmp_if_lookup (ifaddr, ifindex);
                   1827:     }
                   1828:   else
                   1829:     {
                   1830:       len = *length - v->namelen;
                   1831:       if (len >= IN_ADDR_SIZE)
                   1832:        len = IN_ADDR_SIZE;
                   1833:       else
                   1834:        ifaddr_next = 1;
                   1835: 
                   1836:       oid2in_addr (name + v->namelen, len, ifaddr);
                   1837: 
                   1838:       len = *length - v->namelen - IN_ADDR_SIZE;
                   1839:       if (len >= 1)
                   1840:        len = 1;
                   1841:       else
                   1842:        ifindex_next = 1;
                   1843: 
                   1844:       if (len == 1)
                   1845:        *ifindex = name[v->namelen + IN_ADDR_SIZE];
                   1846: 
                   1847:       oi = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next,
                   1848:                                      ifindex_next);
                   1849:       if (oi)
                   1850:        {
                   1851:          *length = v->namelen + IN_ADDR_SIZE + 1 + 1;
                   1852:          offset = name + v->namelen;
                   1853:          oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE);
                   1854:          offset += IN_ADDR_SIZE;
                   1855:          *offset = *ifindex;
                   1856:          offset++;
                   1857:          *offset = OSPF_SNMP_METRIC_VALUE;
                   1858:          return oi;
                   1859:        }
                   1860:     }
                   1861:   return NULL;
                   1862: }
                   1863: 
                   1864: static u_char *
                   1865: ospfIfMetricEntry (struct variable *v, oid *name, size_t *length, int exact,
                   1866:                   size_t *var_len, WriteMethod **write_method)
                   1867: {
                   1868:   /* Currently we support metric 1 only. */
                   1869:   unsigned int ifindex;
                   1870:   struct in_addr ifaddr;
                   1871:   struct ospf_interface *oi;
                   1872:   struct ospf *ospf;
                   1873: 
1.1.1.3 ! misho    1874:   if (smux_header_table(v, name, length, exact, var_len, write_method)
        !          1875:       == MATCH_FAILED)
        !          1876:     return NULL;
        !          1877: 
1.1       misho    1878:   ifindex = 0;
                   1879:   memset (&ifaddr, 0, sizeof (struct in_addr));
                   1880: 
                   1881:   /* Check OSPF instance. */
                   1882:   ospf = ospf_lookup ();
                   1883:   if (ospf == NULL)
                   1884:     return NULL;
                   1885: 
                   1886:   oi = ospfIfMetricLookup (v, name, length, &ifaddr, &ifindex, exact);
                   1887:   if (oi == NULL)
                   1888:     return NULL;
                   1889: 
                   1890:   /* Return the current value of the variable */
                   1891:   switch (v->magic) 
                   1892:     {
                   1893:     case OSPFIFMETRICIPADDRESS:
                   1894:       return SNMP_IPADDRESS (ifaddr);
                   1895:       break;
                   1896:     case OSPFIFMETRICADDRESSLESSIF:
                   1897:       return SNMP_INTEGER (ifindex);
                   1898:       break;
                   1899:     case OSPFIFMETRICTOS:
                   1900:       return SNMP_INTEGER (0);
                   1901:       break;
                   1902:     case OSPFIFMETRICVALUE:
                   1903:       return SNMP_INTEGER (OSPF_SNMP_METRIC_VALUE);
                   1904:       break;
                   1905:     case OSPFIFMETRICSTATUS:
                   1906:       return SNMP_INTEGER (1);
                   1907:       break;
                   1908:     default:
                   1909:       return NULL;
                   1910:       break;
                   1911:     }
                   1912:   return NULL;
                   1913: }
                   1914: 
                   1915: struct route_table *ospf_snmp_vl_table;
                   1916: 
                   1917: void
                   1918: ospf_snmp_vl_add (struct ospf_vl_data *vl_data)
                   1919: {
                   1920:   struct prefix_ls lp;
                   1921:   struct route_node *rn;
                   1922: 
                   1923:   memset (&lp, 0, sizeof (struct prefix_ls));
                   1924:   lp.family = 0;
                   1925:   lp.prefixlen = 64;
                   1926:   lp.id = vl_data->vl_area_id;
                   1927:   lp.adv_router = vl_data->vl_peer;
                   1928: 
                   1929:   rn = route_node_get (ospf_snmp_vl_table, (struct prefix *) &lp);
                   1930:   rn->info = vl_data;
                   1931: }
                   1932: 
                   1933: void
                   1934: ospf_snmp_vl_delete (struct ospf_vl_data *vl_data)
                   1935: {
                   1936:   struct prefix_ls lp;
                   1937:   struct route_node *rn;
                   1938: 
                   1939:   memset (&lp, 0, sizeof (struct prefix_ls));
                   1940:   lp.family = 0;
                   1941:   lp.prefixlen = 64;
                   1942:   lp.id = vl_data->vl_area_id;
                   1943:   lp.adv_router = vl_data->vl_peer;
                   1944: 
                   1945:   rn = route_node_lookup (ospf_snmp_vl_table, (struct prefix *) &lp);
                   1946:   if (! rn)
                   1947:     return;
                   1948:   rn->info = NULL;
                   1949:   route_unlock_node (rn);
                   1950:   route_unlock_node (rn);
                   1951: }
                   1952: 
                   1953: static struct ospf_vl_data *
                   1954: ospf_snmp_vl_lookup (struct in_addr *area_id, struct in_addr *neighbor)
                   1955: {
                   1956:   struct prefix_ls lp;
                   1957:   struct route_node *rn;
                   1958:   struct ospf_vl_data *vl_data;
                   1959: 
                   1960:   memset (&lp, 0, sizeof (struct prefix_ls));
                   1961:   lp.family = 0;
                   1962:   lp.prefixlen = 64;
                   1963:   lp.id = *area_id;
                   1964:   lp.adv_router = *neighbor;
                   1965: 
                   1966:   rn = route_node_lookup (ospf_snmp_vl_table, (struct prefix *) &lp);
                   1967:   if (rn)
                   1968:     {
                   1969:       vl_data = rn->info;
                   1970:       route_unlock_node (rn);
                   1971:       return vl_data;
                   1972:     }
                   1973:   return NULL;
                   1974: }
                   1975: 
                   1976: static struct ospf_vl_data *
                   1977: ospf_snmp_vl_lookup_next (struct in_addr *area_id, struct in_addr *neighbor,
                   1978:                          int first)
                   1979: {
                   1980:   struct prefix_ls lp;
                   1981:   struct route_node *rn;
                   1982:   struct ospf_vl_data *vl_data;
                   1983: 
                   1984:   memset (&lp, 0, sizeof (struct prefix_ls));
                   1985:   lp.family = 0;
                   1986:   lp.prefixlen = 64;
                   1987:   lp.id = *area_id;
                   1988:   lp.adv_router = *neighbor;
                   1989: 
                   1990:   if (first)
                   1991:     rn = route_top (ospf_snmp_vl_table);
                   1992:   else
                   1993:     {
                   1994:       rn = route_node_get (ospf_snmp_vl_table, (struct prefix *) &lp);
                   1995:       rn = route_next (rn);
                   1996:     }
                   1997: 
                   1998:   for (; rn; rn = route_next (rn))
                   1999:     if (rn->info)
                   2000:       break;
                   2001: 
                   2002:   if (rn && rn->info)
                   2003:     {
                   2004:       vl_data = rn->info;
                   2005:       *area_id = vl_data->vl_area_id;
                   2006:       *neighbor = vl_data->vl_peer;
                   2007:       route_unlock_node (rn);
                   2008:       return vl_data;
                   2009:     }
                   2010:   return NULL;
                   2011: }
                   2012: 
                   2013: static struct ospf_vl_data *
                   2014: ospfVirtIfLookup (struct variable *v, oid *name, size_t *length,
                   2015:                  struct in_addr *area_id, struct in_addr *neighbor, int exact)
                   2016: {
                   2017:   int first;
                   2018:   unsigned int len;
                   2019:   struct ospf_vl_data *vl_data;
                   2020: 
                   2021:   if (exact)
                   2022:     {
                   2023:       if (*length != v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE)
                   2024:        return NULL;
                   2025: 
                   2026:       oid2in_addr (name + v->namelen, IN_ADDR_SIZE, area_id);
                   2027:       oid2in_addr (name + v->namelen + IN_ADDR_SIZE, IN_ADDR_SIZE, neighbor);
                   2028: 
                   2029:       return ospf_snmp_vl_lookup (area_id, neighbor);
                   2030:     }
                   2031:   else
                   2032:     {
                   2033:       first = 0;
                   2034: 
                   2035:       len = *length - v->namelen;
                   2036:       if (len <= 0)
                   2037:        first = 1;
                   2038:       if (len > IN_ADDR_SIZE)
                   2039:        len = IN_ADDR_SIZE;
                   2040:       oid2in_addr (name + v->namelen, len, area_id);
                   2041: 
                   2042:       len = *length - v->namelen - IN_ADDR_SIZE;
                   2043:       if (len > IN_ADDR_SIZE)
                   2044:        len = IN_ADDR_SIZE;
                   2045:       oid2in_addr (name + v->namelen + IN_ADDR_SIZE, len, neighbor);
                   2046: 
                   2047:       vl_data = ospf_snmp_vl_lookup_next (area_id, neighbor, first);
                   2048: 
                   2049:       if (vl_data)
                   2050:        {
                   2051:          *length = v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE;
                   2052:          oid_copy_addr (name + v->namelen, area_id, IN_ADDR_SIZE);
                   2053:          oid_copy_addr (name + v->namelen + IN_ADDR_SIZE, neighbor,
                   2054:                         IN_ADDR_SIZE);
                   2055:          return vl_data;
                   2056:        }
                   2057:     }
                   2058:   return NULL;
                   2059: }
                   2060: 
                   2061: static u_char *
                   2062: ospfVirtIfEntry (struct variable *v, oid *name, size_t *length, int exact,
                   2063:                 size_t *var_len, WriteMethod **write_method)
                   2064: {
                   2065:   struct ospf_vl_data *vl_data;
                   2066:   struct ospf_interface *oi;
                   2067:   struct in_addr area_id;
                   2068:   struct in_addr neighbor;
                   2069: 
1.1.1.3 ! misho    2070:   if (smux_header_table(v, name, length, exact, var_len, write_method)
        !          2071:       == MATCH_FAILED)
        !          2072:     return NULL;
        !          2073: 
1.1       misho    2074:   memset (&area_id, 0, sizeof (struct in_addr));
                   2075:   memset (&neighbor, 0, sizeof (struct in_addr));
                   2076: 
                   2077:   vl_data = ospfVirtIfLookup (v, name, length, &area_id, &neighbor, exact);
                   2078:   if (! vl_data)
                   2079:     return NULL;
                   2080:   oi = vl_data->vl_oi;
                   2081:   if (! oi)
                   2082:     return NULL;
                   2083:   
                   2084:   /* Return the current value of the variable */
                   2085:   switch (v->magic) 
                   2086:     {
                   2087:     case OSPFVIRTIFAREAID:
                   2088:       return SNMP_IPADDRESS (area_id);
                   2089:       break;
                   2090:     case OSPFVIRTIFNEIGHBOR:
                   2091:       return SNMP_IPADDRESS (neighbor);
                   2092:       break;
                   2093:     case OSPFVIRTIFTRANSITDELAY:
                   2094:       return SNMP_INTEGER (OSPF_IF_PARAM (oi, transmit_delay));
                   2095:       break;
                   2096:     case OSPFVIRTIFRETRANSINTERVAL:
                   2097:       return SNMP_INTEGER (OSPF_IF_PARAM (oi, retransmit_interval));
                   2098:       break;
                   2099:     case OSPFVIRTIFHELLOINTERVAL:
                   2100:       return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_hello));
                   2101:       break;
                   2102:     case OSPFVIRTIFRTRDEADINTERVAL:
                   2103:       return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_wait));
                   2104:       break;
                   2105:     case OSPFVIRTIFSTATE:
                   2106:       return SNMP_INTEGER (oi->state);
                   2107:       break;
                   2108:     case OSPFVIRTIFEVENTS:
                   2109:       return SNMP_INTEGER (oi->state_change);
                   2110:       break;
                   2111:     case OSPFVIRTIFAUTHKEY:
                   2112:       *var_len = 0;
                   2113:       return (u_char *) OSPF_IF_PARAM (oi, auth_simple);
                   2114:       break;
                   2115:     case OSPFVIRTIFSTATUS:
                   2116:       return SNMP_INTEGER (SNMP_VALID);
                   2117:       break;
                   2118:     case OSPFVIRTIFAUTHTYPE:
                   2119:       if (oi->area)
                   2120:        return SNMP_INTEGER (oi->area->auth_type);
                   2121:       else
                   2122:        return SNMP_INTEGER (0);
                   2123:       break;
                   2124:     default:
                   2125:       return NULL;
                   2126:       break;
                   2127:     }
                   2128:   return NULL;
                   2129: }
                   2130: 
                   2131: static struct ospf_neighbor *
                   2132: ospf_snmp_nbr_lookup (struct ospf *ospf, struct in_addr *nbr_addr,
                   2133:                      unsigned int *ifindex)
                   2134: {
                   2135:   struct listnode *node, *nnode;
                   2136:   struct ospf_interface *oi;
                   2137:   struct ospf_neighbor *nbr;
                   2138:   struct route_node *rn;
                   2139: 
                   2140:   for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
                   2141:     {
                   2142:       for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
                   2143:        if ((nbr = rn->info) != NULL
                   2144:            && nbr != oi->nbr_self
                   2145: /* If EXACT match is needed, provide ALL entry found
                   2146:            && nbr->state != NSM_Down
                   2147:  */
                   2148:            && nbr->src.s_addr != 0)
                   2149:          {
                   2150:            if (IPV4_ADDR_SAME (&nbr->src, nbr_addr))
                   2151:              {
                   2152:                route_unlock_node (rn);
                   2153:                return nbr;
                   2154:              }
                   2155:          }
                   2156:     }
                   2157:   return NULL;
                   2158: }
                   2159: 
                   2160: static struct ospf_neighbor *
                   2161: ospf_snmp_nbr_lookup_next (struct in_addr *nbr_addr, unsigned int *ifindex,
                   2162:                           int first)
                   2163: {
                   2164:   struct listnode *nn;
                   2165:   struct ospf_interface *oi;
                   2166:   struct ospf_neighbor *nbr;
                   2167:   struct route_node *rn;
                   2168:   struct ospf_neighbor *min = NULL;
                   2169:   struct ospf *ospf = ospf;
                   2170: 
                   2171:   ospf = ospf_lookup ();
                   2172: 
                   2173:   for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, nn, oi))
                   2174:     {
                   2175:       for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
                   2176:        if ((nbr = rn->info) != NULL
                   2177:            && nbr != oi->nbr_self
                   2178:            && nbr->state != NSM_Down
                   2179:            && nbr->src.s_addr != 0)
                   2180:          {
                   2181:            if (first)
                   2182:              {
                   2183:                if (! min)
                   2184:                  min = nbr;
                   2185:                else if (ntohl (nbr->src.s_addr) < ntohl (min->src.s_addr))
                   2186:                  min = nbr;
                   2187:              }
                   2188:            else if (ntohl (nbr->src.s_addr) > ntohl (nbr_addr->s_addr))
                   2189:              {
                   2190:                if (! min)
                   2191:                  min = nbr;
                   2192:                else if (ntohl (nbr->src.s_addr) < ntohl (min->src.s_addr))
                   2193:                  min = nbr;
                   2194:              }
                   2195:          }
                   2196:     }
                   2197:   if (min)
                   2198:     {
                   2199:       *nbr_addr = min->src;
                   2200:       *ifindex = 0;
                   2201:       return min;
                   2202:     }
                   2203:   return NULL;
                   2204: }
                   2205: 
                   2206: static struct ospf_neighbor *
                   2207: ospfNbrLookup (struct variable *v, oid *name, size_t *length,
                   2208:               struct in_addr *nbr_addr, unsigned int *ifindex, int exact)
                   2209: {
                   2210:   unsigned int len;
                   2211:   int first;
                   2212:   struct ospf_neighbor *nbr;
                   2213:   struct ospf *ospf;
                   2214: 
                   2215:   ospf = ospf_lookup ();
                   2216: 
                   2217:   if (! ospf)
                   2218:     return NULL;
                   2219: 
                   2220:   if (exact)
                   2221:     {
                   2222:       if (*length != v->namelen + IN_ADDR_SIZE + 1)
                   2223:        return NULL;
                   2224: 
                   2225:       oid2in_addr (name + v->namelen, IN_ADDR_SIZE, nbr_addr);
                   2226:       *ifindex = name[v->namelen + IN_ADDR_SIZE];
                   2227: 
                   2228:       return ospf_snmp_nbr_lookup (ospf, nbr_addr, ifindex);
                   2229:     }
                   2230:   else
                   2231:     {
                   2232:       first = 0;
                   2233:       len = *length - v->namelen;
                   2234: 
                   2235:       if (len <= 0)
                   2236:        first = 1;
                   2237: 
                   2238:       if (len > IN_ADDR_SIZE)
                   2239:        len = IN_ADDR_SIZE;
                   2240: 
                   2241:       oid2in_addr (name + v->namelen, len, nbr_addr);
                   2242: 
                   2243:       len = *length - v->namelen - IN_ADDR_SIZE;
                   2244:       if (len >= 1)
                   2245:        *ifindex = name[v->namelen + IN_ADDR_SIZE];
                   2246:       
                   2247:       nbr = ospf_snmp_nbr_lookup_next (nbr_addr, ifindex, first);
                   2248: 
                   2249:       if (nbr)
                   2250:        {
                   2251:          *length = v->namelen + IN_ADDR_SIZE + 1;
                   2252:          oid_copy_addr (name + v->namelen, nbr_addr, IN_ADDR_SIZE);
                   2253:          name[v->namelen + IN_ADDR_SIZE] = *ifindex;
                   2254:          return nbr;
                   2255:        }
                   2256:     }
                   2257:   return NULL;
                   2258: }
                   2259: 
                   2260: /* map internal quagga neighbor states to official MIB values:
                   2261: 
                   2262: ospfNbrState OBJECT-TYPE
                   2263:         SYNTAX   INTEGER    {
                   2264:                     down (1),
                   2265:                     attempt (2),
                   2266:                     init (3),
                   2267:                     twoWay (4),
                   2268:                     exchangeStart (5),
                   2269:                     exchange (6),
                   2270:                     loading (7),
                   2271:                     full (8)
                   2272:                   }
                   2273: */
                   2274: static int32_t
                   2275: ospf_snmp_neighbor_state(u_char nst)
                   2276: {
                   2277:   switch (nst)
                   2278:     {
                   2279:     case NSM_Attempt:
                   2280:       return 2;
                   2281:     case NSM_Init:
                   2282:       return 3;
                   2283:     case NSM_TwoWay:
                   2284:       return 4;
                   2285:     case NSM_ExStart:
                   2286:       return 5;
                   2287:     case NSM_Exchange:
                   2288:       return 6;
                   2289:     case NSM_Loading:
                   2290:       return 7;
                   2291:     case NSM_Full:
                   2292:       return 8;
                   2293:     default:
                   2294:       return 1; /* down */
                   2295:     }
                   2296: }
                   2297: 
                   2298: static u_char *
                   2299: ospfNbrEntry (struct variable *v, oid *name, size_t *length, int exact,
                   2300:              size_t *var_len, WriteMethod **write_method)
                   2301: {
                   2302:   struct in_addr nbr_addr;
                   2303:   unsigned int ifindex;
                   2304:   struct ospf_neighbor *nbr;
                   2305:   struct ospf_interface *oi;
                   2306: 
1.1.1.3 ! misho    2307:   if (smux_header_table(v, name, length, exact, var_len, write_method)
        !          2308:       == MATCH_FAILED)
        !          2309:     return NULL;
        !          2310: 
1.1       misho    2311:   memset (&nbr_addr, 0, sizeof (struct in_addr));
                   2312:   ifindex = 0;
                   2313:   
                   2314:   nbr = ospfNbrLookup (v, name, length, &nbr_addr, &ifindex, exact);
                   2315:   if (! nbr)
                   2316:     return NULL;
                   2317:   oi = nbr->oi;
                   2318:   if (! oi)
                   2319:     return NULL;
                   2320: 
                   2321:   /* Return the current value of the variable */
                   2322:   switch (v->magic) 
                   2323:     {
                   2324:     case OSPFNBRIPADDR:
                   2325:       return SNMP_IPADDRESS (nbr_addr);
                   2326:       break;
                   2327:     case OSPFNBRADDRESSLESSINDEX:
                   2328:       return SNMP_INTEGER (ifindex);
                   2329:       break;
                   2330:     case OSPFNBRRTRID:
                   2331:       return SNMP_IPADDRESS (nbr->router_id);
                   2332:       break;
                   2333:     case OSPFNBROPTIONS:
                   2334:       return SNMP_INTEGER (oi->nbr_self->options);
                   2335:       break;
                   2336:     case OSPFNBRPRIORITY:
                   2337:       return SNMP_INTEGER (nbr->priority);
                   2338:       break;
                   2339:     case OSPFNBRSTATE:
                   2340:       return SNMP_INTEGER (ospf_snmp_neighbor_state(nbr->state));
                   2341:       break;
                   2342:     case OSPFNBREVENTS:
                   2343:       return SNMP_INTEGER (nbr->state_change);
                   2344:       break;
                   2345:     case OSPFNBRLSRETRANSQLEN:
                   2346:       return SNMP_INTEGER (ospf_ls_retransmit_count (nbr));
                   2347:       break;
                   2348:     case OSPFNBMANBRSTATUS:
                   2349:       return SNMP_INTEGER (SNMP_VALID);
                   2350:       break;
                   2351:     case OSPFNBMANBRPERMANENCE:
                   2352:       return SNMP_INTEGER (2);
                   2353:       break;
                   2354:     case OSPFNBRHELLOSUPPRESSED:
                   2355:       return SNMP_INTEGER (SNMP_FALSE);
                   2356:       break;
                   2357:     default:
                   2358:       return NULL;
                   2359:       break;
                   2360:     }
                   2361:   return NULL;
                   2362: }
                   2363: 
                   2364: static u_char *
                   2365: ospfVirtNbrEntry (struct variable *v, oid *name, size_t *length, int exact,
                   2366:                  size_t *var_len, WriteMethod **write_method)
                   2367: {
                   2368:   struct ospf_vl_data *vl_data;
                   2369:   struct in_addr area_id;
                   2370:   struct in_addr neighbor;
                   2371:   struct ospf *ospf;
                   2372: 
1.1.1.3 ! misho    2373:   if (smux_header_table(v, name, length, exact, var_len, write_method)
        !          2374:       == MATCH_FAILED)
        !          2375:     return NULL;
        !          2376: 
1.1       misho    2377:   memset (&area_id, 0, sizeof (struct in_addr));
                   2378:   memset (&neighbor, 0, sizeof (struct in_addr));
                   2379: 
                   2380:   /* Check OSPF instance. */
                   2381:   ospf = ospf_lookup ();
                   2382:   if (ospf == NULL)
                   2383:     return NULL;
                   2384: 
                   2385:   vl_data = ospfVirtIfLookup (v, name, length, &area_id, &neighbor, exact);
                   2386:   if (! vl_data)
                   2387:     return NULL;
                   2388: 
                   2389:   /* Return the current value of the variable */
                   2390:   switch (v->magic) 
                   2391:     {
                   2392:     case OSPFVIRTNBRAREA:
                   2393:       return (u_char *) NULL;
                   2394:       break;
                   2395:     case OSPFVIRTNBRRTRID:
                   2396:       return (u_char *) NULL;
                   2397:       break;
                   2398:     case OSPFVIRTNBRIPADDR:
                   2399:       return (u_char *) NULL;
                   2400:       break;
                   2401:     case OSPFVIRTNBROPTIONS:
                   2402:       return (u_char *) NULL;
                   2403:       break;
                   2404:     case OSPFVIRTNBRSTATE:
                   2405:       return (u_char *) NULL;
                   2406:       break;
                   2407:     case OSPFVIRTNBREVENTS:
                   2408:       return (u_char *) NULL;
                   2409:       break;
                   2410:     case OSPFVIRTNBRLSRETRANSQLEN:
                   2411:       return (u_char *) NULL;
                   2412:       break;
                   2413:     case OSPFVIRTNBRHELLOSUPPRESSED:
                   2414:       return (u_char *) NULL;
                   2415:       break;
                   2416:     default:
                   2417:       return NULL;
                   2418:       break;
                   2419:     }
                   2420:   return NULL;
                   2421: }
                   2422: 
                   2423: static struct ospf_lsa *
                   2424: ospfExtLsdbLookup (struct variable *v, oid *name, size_t *length, u_char *type,
                   2425:                   struct in_addr *ls_id, struct in_addr *router_id, int exact)
                   2426: {
                   2427:   int first;
                   2428:   oid *offset;
                   2429:   int offsetlen;
                   2430:   u_char lsa_type;
                   2431:   unsigned int len;
                   2432:   struct ospf_lsa *lsa;
                   2433:   struct ospf *ospf;
                   2434: 
                   2435:   ospf = ospf_lookup ();
                   2436:   if (exact)
                   2437:     {
                   2438:       if (*length != v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
                   2439:        return NULL;
                   2440:       
                   2441:       offset = name + v->namelen;
                   2442: 
                   2443:       /* Make it sure given value match to type. */
                   2444:       lsa_type = *offset;
                   2445:       offset++;
                   2446: 
                   2447:       if (lsa_type != *type)
                   2448:        return NULL;
                   2449:       
                   2450:       /* LS ID. */
                   2451:       oid2in_addr (offset, IN_ADDR_SIZE, ls_id);
                   2452:       offset += IN_ADDR_SIZE;
                   2453: 
                   2454:       /* Router ID. */
                   2455:       oid2in_addr (offset, IN_ADDR_SIZE, router_id);
                   2456: 
                   2457:       return ospf_lsdb_lookup_by_id (ospf->lsdb, *type, *ls_id, *router_id);
                   2458:     }
                   2459:   else
                   2460:     {
                   2461:       /* Get variable length. */
                   2462:       first = 0;
                   2463:       offset = name + v->namelen;
                   2464:       offsetlen = *length - v->namelen;
                   2465: 
                   2466:       /* LSA type value. */
                   2467:       lsa_type = *offset;
                   2468:       offset++;
                   2469:       offsetlen--;
                   2470: 
                   2471:       if (offsetlen <= 0 || lsa_type < OSPF_AS_EXTERNAL_LSA)
                   2472:        first = 1;
                   2473: 
                   2474:       /* LS ID. */
                   2475:       len = offsetlen;
                   2476:       if (len > IN_ADDR_SIZE)
                   2477:        len = IN_ADDR_SIZE;
                   2478: 
                   2479:       oid2in_addr (offset, len, ls_id);
                   2480: 
                   2481:       offset += IN_ADDR_SIZE;
                   2482:       offsetlen -= IN_ADDR_SIZE;
                   2483: 
                   2484:       /* Router ID. */
                   2485:       len = offsetlen;
                   2486:       if (len > IN_ADDR_SIZE)
                   2487:        len = IN_ADDR_SIZE;
                   2488: 
                   2489:       oid2in_addr (offset, len, router_id);
                   2490: 
                   2491:       lsa = ospf_lsdb_lookup_by_id_next (ospf->lsdb, *type, *ls_id,
                   2492:                                        *router_id, first);
                   2493: 
                   2494:       if (lsa)
                   2495:        {
                   2496:          /* Fill in length. */
                   2497:          *length = v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE;
                   2498: 
                   2499:          /* Fill in value. */
                   2500:          offset = name + v->namelen;
                   2501: 
                   2502:          *offset = OSPF_AS_EXTERNAL_LSA;
                   2503:          offset++;
                   2504:          oid_copy_addr (offset, &lsa->data->id, IN_ADDR_SIZE);
                   2505:          offset += IN_ADDR_SIZE;
                   2506:          oid_copy_addr (offset, &lsa->data->adv_router, IN_ADDR_SIZE);
                   2507:            
                   2508:          return lsa;
                   2509:        }
                   2510:     }
                   2511:   return NULL;
                   2512: }
                   2513: 
                   2514: static u_char *
                   2515: ospfExtLsdbEntry (struct variable *v, oid *name, size_t *length, int exact,
                   2516:                  size_t *var_len, WriteMethod **write_method)
                   2517: {
                   2518:   struct ospf_lsa *lsa;
                   2519:   struct lsa_header *lsah;
                   2520:   u_char type;
                   2521:   struct in_addr ls_id;
                   2522:   struct in_addr router_id;
                   2523:   struct ospf *ospf;
                   2524: 
1.1.1.3 ! misho    2525:   if (smux_header_table(v, name, length, exact, var_len, write_method)
        !          2526:       == MATCH_FAILED)
        !          2527:     return NULL;
        !          2528: 
1.1       misho    2529:   type = OSPF_AS_EXTERNAL_LSA;
                   2530:   memset (&ls_id, 0, sizeof (struct in_addr));
                   2531:   memset (&router_id, 0, sizeof (struct in_addr));
                   2532: 
                   2533:   /* Check OSPF instance. */
                   2534:   ospf = ospf_lookup ();
                   2535:   if (ospf == NULL)
                   2536:     return NULL;
                   2537: 
                   2538:   lsa = ospfExtLsdbLookup (v, name, length, &type, &ls_id, &router_id, exact);
                   2539:   if (! lsa)
                   2540:     return NULL;
                   2541: 
                   2542:   lsah = lsa->data;
                   2543: 
                   2544:   /* Return the current value of the variable */
                   2545:   switch (v->magic) 
                   2546:     {
                   2547:     case OSPFEXTLSDBTYPE:
                   2548:       return SNMP_INTEGER (OSPF_AS_EXTERNAL_LSA);
                   2549:       break;
                   2550:     case OSPFEXTLSDBLSID:
                   2551:       return SNMP_IPADDRESS (lsah->id);
                   2552:       break;
                   2553:     case OSPFEXTLSDBROUTERID:
                   2554:       return SNMP_IPADDRESS (lsah->adv_router);
                   2555:       break;
                   2556:     case OSPFEXTLSDBSEQUENCE:
                   2557:       return SNMP_INTEGER (lsah->ls_seqnum);
                   2558:       break;
                   2559:     case OSPFEXTLSDBAGE:
                   2560:       return SNMP_INTEGER (lsah->ls_age);
                   2561:       break;
                   2562:     case OSPFEXTLSDBCHECKSUM:
                   2563:       return SNMP_INTEGER (lsah->checksum);
                   2564:       break;
                   2565:     case OSPFEXTLSDBADVERTISEMENT:
                   2566:       *var_len = ntohs (lsah->length);
                   2567:       return (u_char *) lsah;
                   2568:       break;
                   2569:     default:
                   2570:       return NULL;
                   2571:       break;
                   2572:     }
                   2573:   return NULL;
                   2574: }
                   2575: 
                   2576: static u_char *
                   2577: ospfAreaAggregateEntry (struct variable *v, oid *name, size_t *length,
                   2578:                        int exact, size_t *var_len, WriteMethod **write_method)
                   2579: {
1.1.1.3 ! misho    2580:   if (smux_header_table(v, name, length, exact, var_len, write_method)
        !          2581:       == MATCH_FAILED)
        !          2582:     return NULL;
        !          2583: 
1.1       misho    2584:   /* Return the current value of the variable */
                   2585:   switch (v->magic) 
                   2586:     {
                   2587:     case OSPFAREAAGGREGATEAREAID:
                   2588:       return (u_char *) NULL;
                   2589:       break;
                   2590:     case OSPFAREAAGGREGATELSDBTYPE:
                   2591:       return (u_char *) NULL;
                   2592:       break;
                   2593:     case OSPFAREAAGGREGATENET:
                   2594:       return (u_char *) NULL;
                   2595:       break;
                   2596:     case OSPFAREAAGGREGATEMASK:
                   2597:       return (u_char *) NULL;
                   2598:       break;
                   2599:     case OSPFAREAAGGREGATESTATUS:
                   2600:       return (u_char *) NULL;
                   2601:       break;
                   2602:     case OSPFAREAAGGREGATEEFFECT:
                   2603:       return (u_char *) NULL;
                   2604:       break;
                   2605:     default:
                   2606:       return NULL;
                   2607:       break;
                   2608:     }
                   2609:   return NULL;
                   2610: }
                   2611: 
                   2612: /* OSPF Traps. */
                   2613: #define IFSTATECHANGE      16
                   2614: #define VIRTIFSTATECHANGE   1
                   2615: #define NBRSTATECHANGE      2
                   2616: #define VIRTNBRSTATECHANGE  3
                   2617: 
                   2618: struct trap_object ospfNbrTrapList[] =
                   2619: {
1.1.1.3 ! misho    2620:   {-2, {1, OSPFROUTERID}},
        !          2621:   {3, {10, 1, OSPFNBRIPADDR}},
        !          2622:   {3, {10, 1, OSPFNBRRTRID}},
        !          2623:   {3, {10, 1, OSPFNBRSTATE}}
1.1       misho    2624: };
                   2625: 
                   2626: 
                   2627: struct trap_object ospfVirtNbrTrapList[] =
                   2628: {
1.1.1.3 ! misho    2629:   {-2, {1, 1}},
        !          2630:   {3, {11, 1, OSPFVIRTNBRAREA}},
        !          2631:   {3, {11, 1, OSPFVIRTNBRRTRID}},
        !          2632:   {3, {11, 1, OSPFVIRTNBRSTATE}}
1.1       misho    2633: };
                   2634: 
                   2635: struct trap_object ospfIfTrapList[] =
                   2636: {
1.1.1.3 ! misho    2637:   {-2, {1, OSPFROUTERID}},
        !          2638:   {3, {7, 1, OSPFIFIPADDRESS}},
        !          2639:   {3, {7, 1, OSPFADDRESSLESSIF}},
        !          2640:   {3, {7, 1, OSPFIFSTATE}}
1.1       misho    2641: };
                   2642: 
                   2643: struct trap_object ospfVirtIfTrapList[] =
                   2644: {
1.1.1.3 ! misho    2645:   {-2, {1, OSPFROUTERID}},
        !          2646:   {3, {9, 1, OSPFVIRTIFAREAID}},
        !          2647:   {3, {9, 1, OSPFVIRTIFNEIGHBOR}},
        !          2648:   {3, {9, 1, OSPFVIRTIFSTATE}}
1.1       misho    2649: };
                   2650: 
                   2651: void
                   2652: ospfTrapNbrStateChange (struct ospf_neighbor *on)
                   2653: {
                   2654:   oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
                   2655:   char msgbuf[16];
                   2656:   
                   2657:   ospf_nbr_state_message(on, msgbuf, sizeof(msgbuf));
                   2658:   zlog (NULL, LOG_INFO, "ospfTrapNbrStateChange trap sent: %s now %s",
                   2659:        inet_ntoa(on->address.u.prefix4), msgbuf);
                   2660: 
                   2661:   oid_copy_addr (index, &(on->address.u.prefix4), IN_ADDR_SIZE);
                   2662:   index[IN_ADDR_SIZE] = 0;
                   2663: 
1.1.1.3 ! misho    2664:   smux_trap (ospf_variables, sizeof ospf_variables / sizeof (struct variable),
        !          2665:             ospf_trap_oid, sizeof ospf_trap_oid / sizeof (oid),
        !          2666:             ospf_oid, sizeof ospf_oid / sizeof (oid),
1.1       misho    2667:              index,  IN_ADDR_SIZE + 1,
                   2668:              ospfNbrTrapList, 
                   2669:              sizeof ospfNbrTrapList / sizeof (struct trap_object),
1.1.1.3 ! misho    2670:              NBRSTATECHANGE);
1.1       misho    2671: }
                   2672: 
                   2673: void
                   2674: ospfTrapVirtNbrStateChange (struct ospf_neighbor *on)
                   2675: {
                   2676:   oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
                   2677:   
                   2678:   zlog (NULL, LOG_INFO, "ospfTrapVirtNbrStateChange trap sent");
                   2679: 
                   2680:   oid_copy_addr (index, &(on->address.u.prefix4), IN_ADDR_SIZE);
                   2681:   index[IN_ADDR_SIZE] = 0;
                   2682: 
1.1.1.3 ! misho    2683:   smux_trap (ospf_variables, sizeof ospf_variables / sizeof (struct variable),
        !          2684:             ospf_trap_oid, sizeof ospf_trap_oid / sizeof (oid),
        !          2685:             ospf_oid, sizeof ospf_oid / sizeof (oid),
1.1       misho    2686:              index,  IN_ADDR_SIZE + 1,
                   2687:              ospfVirtNbrTrapList, 
                   2688:              sizeof ospfVirtNbrTrapList / sizeof (struct trap_object),
1.1.1.3 ! misho    2689:              VIRTNBRSTATECHANGE);
1.1       misho    2690: }
                   2691: 
                   2692: void
                   2693: ospfTrapIfStateChange (struct ospf_interface *oi)
                   2694: {
                   2695:   oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
                   2696: 
                   2697:   zlog (NULL, LOG_INFO, "ospfTrapIfStateChange trap sent: %s now %s",
                   2698:        inet_ntoa(oi->address->u.prefix4),
                   2699:        LOOKUP(ospf_ism_state_msg, oi->state));
                   2700:   
                   2701:   oid_copy_addr (index, &(oi->address->u.prefix4), IN_ADDR_SIZE);
                   2702:   index[IN_ADDR_SIZE] = 0;
                   2703: 
1.1.1.3 ! misho    2704:   smux_trap (ospf_variables, sizeof ospf_variables / sizeof (struct variable),
        !          2705:             ospf_trap_oid, sizeof ospf_trap_oid / sizeof (oid),
        !          2706:             ospf_oid, sizeof ospf_oid / sizeof (oid),
1.1       misho    2707:              index, IN_ADDR_SIZE + 1,
                   2708:              ospfIfTrapList, 
                   2709:              sizeof ospfIfTrapList / sizeof (struct trap_object),
1.1.1.3 ! misho    2710:              IFSTATECHANGE);
1.1       misho    2711: }
                   2712: 
                   2713: void
                   2714: ospfTrapVirtIfStateChange (struct ospf_interface *oi)
                   2715: {
                   2716:   oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
                   2717: 
                   2718:   zlog (NULL, LOG_INFO, "ospfTrapVirtIfStateChange trap sent");
                   2719:   
                   2720:   oid_copy_addr (index, &(oi->address->u.prefix4), IN_ADDR_SIZE);
                   2721:   index[IN_ADDR_SIZE] = 0;
                   2722: 
1.1.1.3 ! misho    2723:   smux_trap (ospf_variables, sizeof ospf_variables / sizeof (struct variable),
        !          2724:             ospf_trap_oid, sizeof ospf_trap_oid / sizeof (oid),
        !          2725:             ospf_oid, sizeof ospf_oid / sizeof (oid),
1.1       misho    2726:              index, IN_ADDR_SIZE + 1,
                   2727:              ospfVirtIfTrapList,
                   2728:              sizeof ospfVirtIfTrapList / sizeof (struct trap_object),
1.1.1.3 ! misho    2729:              VIRTIFSTATECHANGE);
1.1       misho    2730: }
                   2731: /* Register OSPF2-MIB. */
                   2732: void
                   2733: ospf_snmp_init ()
                   2734: {
                   2735:   ospf_snmp_iflist = list_new ();
                   2736:   ospf_snmp_vl_table = route_table_init ();
                   2737:   smux_init (om->master);
                   2738:   REGISTER_MIB("mibII/ospf", ospf_variables, variable, ospf_oid);
                   2739: }
                   2740: #endif /* HAVE_SNMP */

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