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

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

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