Annotation of embedaddon/quagga/ospfd/ospf_snmp.c, revision 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>