mirror of
				https://git.proxmox.com/git/mirror_frr
				synced 2025-11-04 01:43:38 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			2744 lines
		
	
	
		
			71 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			2744 lines
		
	
	
		
			71 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* OSPFv2 SNMP support
 | 
						|
 * Copyright (C) 2005 6WIND <alain.ritoux@6wind.com>
 | 
						|
 * Copyright (C) 2000 IP Infusion Inc.
 | 
						|
 *
 | 
						|
 * Written by Kunihiro Ishiguro <kunihiro@zebra.org>
 | 
						|
 *
 | 
						|
 * This file is part of GNU Zebra.
 | 
						|
 *
 | 
						|
 * GNU Zebra is free software; you can redistribute it and/or modify it
 | 
						|
 * under the terms of the GNU General Public License as published by the
 | 
						|
 * Free Software Foundation; either version 2, or (at your option) any
 | 
						|
 * later version.
 | 
						|
 *
 | 
						|
 * GNU Zebra is distributed in the hope that it will be useful, but
 | 
						|
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
						|
 * General Public License for more details.
 | 
						|
 *
 | 
						|
 * You should have received a copy of the GNU General Public License
 | 
						|
 * along with GNU Zebra; see the file COPYING.  If not, write to the Free
 | 
						|
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 | 
						|
 * 02111-1307, USA.  
 | 
						|
 */
 | 
						|
 | 
						|
#include <zebra.h>
 | 
						|
 | 
						|
#ifdef HAVE_SNMP
 | 
						|
#include <net-snmp/net-snmp-config.h>
 | 
						|
#include <net-snmp/net-snmp-includes.h>
 | 
						|
 | 
						|
#include "if.h"
 | 
						|
#include "log.h"
 | 
						|
#include "prefix.h"
 | 
						|
#include "table.h"
 | 
						|
#include "command.h"
 | 
						|
#include "memory.h"
 | 
						|
#include "smux.h"
 | 
						|
 | 
						|
#include "ospfd/ospfd.h"
 | 
						|
#include "ospfd/ospf_interface.h"
 | 
						|
#include "ospfd/ospf_asbr.h"
 | 
						|
#include "ospfd/ospf_lsa.h"
 | 
						|
#include "ospfd/ospf_lsdb.h"
 | 
						|
#include "ospfd/ospf_abr.h"
 | 
						|
#include "ospfd/ospf_neighbor.h"
 | 
						|
#include "ospfd/ospf_nsm.h"
 | 
						|
#include "ospfd/ospf_flood.h"
 | 
						|
#include "ospfd/ospf_ism.h"
 | 
						|
#include "ospfd/ospf_dump.h"
 | 
						|
#include "ospfd/ospf_snmp.h"
 | 
						|
 | 
						|
/* OSPF2-MIB. */
 | 
						|
#define OSPF2MIB 1,3,6,1,2,1,14
 | 
						|
 | 
						|
/* OSPF MIB General Group values. */
 | 
						|
#define OSPFROUTERID                     1
 | 
						|
#define OSPFADMINSTAT                    2
 | 
						|
#define OSPFVERSIONNUMBER                3
 | 
						|
#define OSPFAREABDRRTRSTATUS             4
 | 
						|
#define OSPFASBDRRTRSTATUS               5
 | 
						|
#define OSPFEXTERNLSACOUNT               6
 | 
						|
#define OSPFEXTERNLSACKSUMSUM            7
 | 
						|
#define OSPFTOSSUPPORT                   8
 | 
						|
#define OSPFORIGINATENEWLSAS             9
 | 
						|
#define OSPFRXNEWLSAS                    10
 | 
						|
#define OSPFEXTLSDBLIMIT                 11
 | 
						|
#define OSPFMULTICASTEXTENSIONS          12
 | 
						|
#define OSPFEXITOVERFLOWINTERVAL         13
 | 
						|
#define OSPFDEMANDEXTENSIONS             14
 | 
						|
 | 
						|
/* OSPF MIB ospfAreaTable. */
 | 
						|
#define OSPFAREAID                       1
 | 
						|
#define OSPFAUTHTYPE                     2
 | 
						|
#define OSPFIMPORTASEXTERN               3
 | 
						|
#define OSPFSPFRUNS                      4
 | 
						|
#define OSPFAREABDRRTRCOUNT              5
 | 
						|
#define OSPFASBDRRTRCOUNT                6
 | 
						|
#define OSPFAREALSACOUNT                 7
 | 
						|
#define OSPFAREALSACKSUMSUM              8
 | 
						|
#define OSPFAREASUMMARY                  9
 | 
						|
#define OSPFAREASTATUS                   10
 | 
						|
 | 
						|
/* OSPF MIB ospfStubAreaTable. */
 | 
						|
#define OSPFSTUBAREAID                   1
 | 
						|
#define OSPFSTUBTOS                      2
 | 
						|
#define OSPFSTUBMETRIC                   3
 | 
						|
#define OSPFSTUBSTATUS                   4
 | 
						|
#define OSPFSTUBMETRICTYPE               5
 | 
						|
 | 
						|
/* OSPF MIB ospfLsdbTable. */
 | 
						|
#define OSPFLSDBAREAID                   1
 | 
						|
#define OSPFLSDBTYPE                     2
 | 
						|
#define OSPFLSDBLSID                     3
 | 
						|
#define OSPFLSDBROUTERID                 4
 | 
						|
#define OSPFLSDBSEQUENCE                 5
 | 
						|
#define OSPFLSDBAGE                      6
 | 
						|
#define OSPFLSDBCHECKSUM                 7
 | 
						|
#define OSPFLSDBADVERTISEMENT            8
 | 
						|
 | 
						|
/* OSPF MIB ospfAreaRangeTable. */
 | 
						|
#define OSPFAREARANGEAREAID              1
 | 
						|
#define OSPFAREARANGENET                 2
 | 
						|
#define OSPFAREARANGEMASK                3
 | 
						|
#define OSPFAREARANGESTATUS              4
 | 
						|
#define OSPFAREARANGEEFFECT              5
 | 
						|
 | 
						|
/* OSPF MIB ospfHostTable. */
 | 
						|
#define OSPFHOSTIPADDRESS                1
 | 
						|
#define OSPFHOSTTOS                      2
 | 
						|
#define OSPFHOSTMETRIC                   3
 | 
						|
#define OSPFHOSTSTATUS                   4
 | 
						|
#define OSPFHOSTAREAID                   5
 | 
						|
 | 
						|
/* OSPF MIB ospfIfTable. */
 | 
						|
#define OSPFIFIPADDRESS                  1
 | 
						|
#define OSPFADDRESSLESSIF                2
 | 
						|
#define OSPFIFAREAID                     3
 | 
						|
#define OSPFIFTYPE                       4
 | 
						|
#define OSPFIFADMINSTAT                  5
 | 
						|
#define OSPFIFRTRPRIORITY                6
 | 
						|
#define OSPFIFTRANSITDELAY               7
 | 
						|
#define OSPFIFRETRANSINTERVAL            8
 | 
						|
#define OSPFIFHELLOINTERVAL              9
 | 
						|
#define OSPFIFRTRDEADINTERVAL            10
 | 
						|
#define OSPFIFPOLLINTERVAL               11
 | 
						|
#define OSPFIFSTATE                      12
 | 
						|
#define OSPFIFDESIGNATEDROUTER           13
 | 
						|
#define OSPFIFBACKUPDESIGNATEDROUTER     14
 | 
						|
#define OSPFIFEVENTS                     15
 | 
						|
#define OSPFIFAUTHKEY                    16
 | 
						|
#define OSPFIFSTATUS                     17
 | 
						|
#define OSPFIFMULTICASTFORWARDING        18
 | 
						|
#define OSPFIFDEMAND                     19
 | 
						|
#define OSPFIFAUTHTYPE                   20
 | 
						|
 | 
						|
/* OSPF MIB ospfIfMetricTable. */
 | 
						|
#define OSPFIFMETRICIPADDRESS            1
 | 
						|
#define OSPFIFMETRICADDRESSLESSIF        2
 | 
						|
#define OSPFIFMETRICTOS                  3
 | 
						|
#define OSPFIFMETRICVALUE                4
 | 
						|
#define OSPFIFMETRICSTATUS               5
 | 
						|
 | 
						|
/* OSPF MIB ospfVirtIfTable. */
 | 
						|
#define OSPFVIRTIFAREAID                 1
 | 
						|
#define OSPFVIRTIFNEIGHBOR               2
 | 
						|
#define OSPFVIRTIFTRANSITDELAY           3
 | 
						|
#define OSPFVIRTIFRETRANSINTERVAL        4
 | 
						|
#define OSPFVIRTIFHELLOINTERVAL          5
 | 
						|
#define OSPFVIRTIFRTRDEADINTERVAL        6
 | 
						|
#define OSPFVIRTIFSTATE                  7
 | 
						|
#define OSPFVIRTIFEVENTS                 8
 | 
						|
#define OSPFVIRTIFAUTHKEY                9
 | 
						|
#define OSPFVIRTIFSTATUS                 10
 | 
						|
#define OSPFVIRTIFAUTHTYPE               11
 | 
						|
 | 
						|
/* OSPF MIB ospfNbrTable. */
 | 
						|
#define OSPFNBRIPADDR                    1
 | 
						|
#define OSPFNBRADDRESSLESSINDEX          2
 | 
						|
#define OSPFNBRRTRID                     3
 | 
						|
#define OSPFNBROPTIONS                   4
 | 
						|
#define OSPFNBRPRIORITY                  5
 | 
						|
#define OSPFNBRSTATE                     6
 | 
						|
#define OSPFNBREVENTS                    7
 | 
						|
#define OSPFNBRLSRETRANSQLEN             8
 | 
						|
#define OSPFNBMANBRSTATUS                9
 | 
						|
#define OSPFNBMANBRPERMANENCE            10
 | 
						|
#define OSPFNBRHELLOSUPPRESSED           11
 | 
						|
 | 
						|
/* OSPF MIB ospfVirtNbrTable. */
 | 
						|
#define OSPFVIRTNBRAREA                  1
 | 
						|
#define OSPFVIRTNBRRTRID                 2
 | 
						|
#define OSPFVIRTNBRIPADDR                3
 | 
						|
#define OSPFVIRTNBROPTIONS               4
 | 
						|
#define OSPFVIRTNBRSTATE                 5
 | 
						|
#define OSPFVIRTNBREVENTS                6
 | 
						|
#define OSPFVIRTNBRLSRETRANSQLEN         7
 | 
						|
#define OSPFVIRTNBRHELLOSUPPRESSED       8
 | 
						|
 | 
						|
/* OSPF MIB ospfExtLsdbTable. */
 | 
						|
#define OSPFEXTLSDBTYPE                  1
 | 
						|
#define OSPFEXTLSDBLSID                  2
 | 
						|
#define OSPFEXTLSDBROUTERID              3
 | 
						|
#define OSPFEXTLSDBSEQUENCE              4
 | 
						|
#define OSPFEXTLSDBAGE                   5
 | 
						|
#define OSPFEXTLSDBCHECKSUM              6
 | 
						|
#define OSPFEXTLSDBADVERTISEMENT         7
 | 
						|
 | 
						|
/* OSPF MIB ospfAreaAggregateTable. */
 | 
						|
#define OSPFAREAAGGREGATEAREAID          1
 | 
						|
#define OSPFAREAAGGREGATELSDBTYPE        2
 | 
						|
#define OSPFAREAAGGREGATENET             3
 | 
						|
#define OSPFAREAAGGREGATEMASK            4
 | 
						|
#define OSPFAREAAGGREGATESTATUS          5
 | 
						|
#define OSPFAREAAGGREGATEEFFECT          6
 | 
						|
 | 
						|
/* SYNTAX Status from OSPF-MIB. */
 | 
						|
#define OSPF_STATUS_ENABLED  1
 | 
						|
#define OSPF_STATUS_DISABLED 2
 | 
						|
 | 
						|
/* SNMP value hack. */
 | 
						|
#define COUNTER     ASN_COUNTER
 | 
						|
#define INTEGER     ASN_INTEGER
 | 
						|
#define GAUGE       ASN_GAUGE
 | 
						|
#define TIMETICKS   ASN_TIMETICKS
 | 
						|
#define IPADDRESS   ASN_IPADDRESS
 | 
						|
#define STRING      ASN_OCTET_STR
 | 
						|
 | 
						|
/* Declare static local variables for convenience. */
 | 
						|
SNMP_LOCAL_VARIABLES
 | 
						|
 | 
						|
/* OSPF-MIB instances. */
 | 
						|
static oid ospf_oid [] = { OSPF2MIB };
 | 
						|
static oid ospf_trap_oid [] = { OSPF2MIB, 16, 2 }; /* Not reverse mappable! */
 | 
						|
 | 
						|
/* IP address 0.0.0.0. */
 | 
						|
static struct in_addr ospf_empty_addr = { .s_addr = 0 };
 | 
						|
 | 
						|
/* Hook functions. */
 | 
						|
static u_char *ospfGeneralGroup (struct variable *, oid *, size_t *,
 | 
						|
				 int, size_t *, WriteMethod **);
 | 
						|
static u_char *ospfAreaEntry (struct variable *, oid *, size_t *, int,
 | 
						|
			      size_t *, WriteMethod **);
 | 
						|
static u_char *ospfStubAreaEntry (struct variable *, oid *, size_t *,
 | 
						|
				  int, size_t *, WriteMethod **);
 | 
						|
static u_char *ospfLsdbEntry (struct variable *, oid *, size_t *, int,
 | 
						|
			      size_t *, WriteMethod **);
 | 
						|
static u_char *ospfAreaRangeEntry (struct variable *, oid *, size_t *, int,
 | 
						|
				   size_t *, WriteMethod **);
 | 
						|
static u_char *ospfHostEntry (struct variable *, oid *, size_t *, int,
 | 
						|
			      size_t *, WriteMethod **);
 | 
						|
static u_char *ospfIfEntry (struct variable *, oid *, size_t *, int,
 | 
						|
			    size_t *, WriteMethod **);
 | 
						|
static u_char *ospfIfMetricEntry (struct variable *, oid *, size_t *, int,
 | 
						|
				  size_t *, WriteMethod **);
 | 
						|
static u_char *ospfVirtIfEntry (struct variable *, oid *, size_t *, int,
 | 
						|
				size_t *, WriteMethod **);
 | 
						|
static u_char *ospfNbrEntry (struct variable *, oid *, size_t *, int,
 | 
						|
			     size_t *, WriteMethod **);
 | 
						|
static u_char *ospfVirtNbrEntry (struct variable *, oid *, size_t *, int,
 | 
						|
				 size_t *, WriteMethod **);
 | 
						|
static u_char *ospfExtLsdbEntry (struct variable *, oid *, size_t *, int,
 | 
						|
				 size_t *, WriteMethod **);
 | 
						|
static u_char *ospfAreaAggregateEntry (struct variable *, oid *, size_t *,
 | 
						|
				       int, size_t *, WriteMethod **);
 | 
						|
 | 
						|
static struct variable ospf_variables[] =
 | 
						|
{
 | 
						|
  /* OSPF general variables */
 | 
						|
  {OSPFROUTERID,              IPADDRESS, RWRITE, ospfGeneralGroup,
 | 
						|
   2, {1, 1}},
 | 
						|
  {OSPFADMINSTAT,             INTEGER, RWRITE, ospfGeneralGroup,
 | 
						|
   2, {1, 2}},
 | 
						|
  {OSPFVERSIONNUMBER,         INTEGER, RONLY, ospfGeneralGroup,
 | 
						|
   2, {1, 3}},
 | 
						|
  {OSPFAREABDRRTRSTATUS,      INTEGER, RONLY, ospfGeneralGroup,
 | 
						|
   2, {1, 4}},
 | 
						|
  {OSPFASBDRRTRSTATUS,        INTEGER, RWRITE, ospfGeneralGroup,
 | 
						|
   2, {1, 5}},
 | 
						|
  {OSPFEXTERNLSACOUNT,        GAUGE, RONLY, ospfGeneralGroup,
 | 
						|
   2, {1, 6}},
 | 
						|
  {OSPFEXTERNLSACKSUMSUM,     INTEGER, RONLY, ospfGeneralGroup,
 | 
						|
   2, {1, 7}},
 | 
						|
  {OSPFTOSSUPPORT,            INTEGER, RWRITE, ospfGeneralGroup,
 | 
						|
   2, {1, 8}},
 | 
						|
  {OSPFORIGINATENEWLSAS,      COUNTER, RONLY, ospfGeneralGroup,
 | 
						|
   2, {1, 9}},
 | 
						|
  {OSPFRXNEWLSAS,             COUNTER, RONLY, ospfGeneralGroup,
 | 
						|
   2, {1, 10}},
 | 
						|
  {OSPFEXTLSDBLIMIT,          INTEGER, RWRITE, ospfGeneralGroup,
 | 
						|
   2, {1, 11}},
 | 
						|
  {OSPFMULTICASTEXTENSIONS,   INTEGER, RWRITE, ospfGeneralGroup,
 | 
						|
   2, {1, 12}},
 | 
						|
  {OSPFEXITOVERFLOWINTERVAL,  INTEGER, RWRITE, ospfGeneralGroup,
 | 
						|
   2, {1, 13}},
 | 
						|
  {OSPFDEMANDEXTENSIONS,      INTEGER, RWRITE, ospfGeneralGroup,
 | 
						|
   2, {1, 14}},
 | 
						|
 | 
						|
  /* OSPF area data structure. */
 | 
						|
  {OSPFAREAID,                IPADDRESS, RONLY, ospfAreaEntry,
 | 
						|
   3, {2, 1, 1}},
 | 
						|
  {OSPFAUTHTYPE,              INTEGER, RWRITE, ospfAreaEntry,
 | 
						|
   3, {2, 1, 2}},
 | 
						|
  {OSPFIMPORTASEXTERN,        INTEGER, RWRITE, ospfAreaEntry,
 | 
						|
   3, {2, 1, 3}},
 | 
						|
  {OSPFSPFRUNS,               COUNTER, RONLY, ospfAreaEntry,
 | 
						|
   3, {2, 1, 4}},
 | 
						|
  {OSPFAREABDRRTRCOUNT,       GAUGE, RONLY, ospfAreaEntry,
 | 
						|
   3, {2, 1, 5}},
 | 
						|
  {OSPFASBDRRTRCOUNT,         GAUGE, RONLY, ospfAreaEntry,
 | 
						|
   3, {2, 1, 6}},
 | 
						|
  {OSPFAREALSACOUNT,          GAUGE, RONLY, ospfAreaEntry,
 | 
						|
   3, {2, 1, 7}},
 | 
						|
  {OSPFAREALSACKSUMSUM,       INTEGER, RONLY, ospfAreaEntry,
 | 
						|
   3, {2, 1, 8}},
 | 
						|
  {OSPFAREASUMMARY,           INTEGER, RWRITE, ospfAreaEntry,
 | 
						|
   3, {2, 1, 9}},
 | 
						|
  {OSPFAREASTATUS,            INTEGER, RWRITE, ospfAreaEntry,
 | 
						|
   3, {2, 1, 10}},
 | 
						|
 | 
						|
  /* OSPF stub area information. */
 | 
						|
  {OSPFSTUBAREAID,            IPADDRESS, RONLY, ospfStubAreaEntry,
 | 
						|
   3, {3, 1, 1}},
 | 
						|
  {OSPFSTUBTOS,               INTEGER, RONLY, ospfStubAreaEntry,
 | 
						|
   3, {3, 1, 2}},
 | 
						|
  {OSPFSTUBMETRIC,            INTEGER, RWRITE, ospfStubAreaEntry,
 | 
						|
   3, {3, 1, 3}},
 | 
						|
  {OSPFSTUBSTATUS,            INTEGER, RWRITE, ospfStubAreaEntry,
 | 
						|
   3, {3, 1, 4}},
 | 
						|
  {OSPFSTUBMETRICTYPE,        INTEGER, RWRITE, ospfStubAreaEntry,
 | 
						|
   3, {3, 1, 5}},
 | 
						|
 | 
						|
  /* OSPF link state database. */
 | 
						|
  {OSPFLSDBAREAID,            IPADDRESS, RONLY, ospfLsdbEntry,
 | 
						|
   3, {4, 1, 1}},
 | 
						|
  {OSPFLSDBTYPE,              INTEGER, RONLY, ospfLsdbEntry,
 | 
						|
   3, {4, 1, 2}},
 | 
						|
  {OSPFLSDBLSID,              IPADDRESS, RONLY, ospfLsdbEntry,
 | 
						|
   3, {4, 1, 3}},
 | 
						|
  {OSPFLSDBROUTERID,          IPADDRESS, RONLY, ospfLsdbEntry,
 | 
						|
   3, {4, 1, 4}},
 | 
						|
  {OSPFLSDBSEQUENCE,          INTEGER, RONLY, ospfLsdbEntry,
 | 
						|
   3, {4, 1, 5}},
 | 
						|
  {OSPFLSDBAGE,               INTEGER, RONLY, ospfLsdbEntry,
 | 
						|
   3, {4, 1, 6}},
 | 
						|
  {OSPFLSDBCHECKSUM,          INTEGER, RONLY, ospfLsdbEntry,
 | 
						|
   3, {4, 1, 7}},
 | 
						|
  {OSPFLSDBADVERTISEMENT,     STRING, RONLY, ospfLsdbEntry,
 | 
						|
   3, {4, 1, 8}},
 | 
						|
 | 
						|
  /* Area range table. */
 | 
						|
  {OSPFAREARANGEAREAID,       IPADDRESS, RONLY, ospfAreaRangeEntry,
 | 
						|
   3, {5, 1, 1}},
 | 
						|
  {OSPFAREARANGENET,          IPADDRESS, RONLY, ospfAreaRangeEntry,
 | 
						|
   3, {5, 1, 2}},
 | 
						|
  {OSPFAREARANGEMASK,         IPADDRESS, RWRITE, ospfAreaRangeEntry,
 | 
						|
   3, {5, 1, 3}},
 | 
						|
  {OSPFAREARANGESTATUS,       INTEGER, RWRITE, ospfAreaRangeEntry,
 | 
						|
   3, {5, 1, 4}},
 | 
						|
  {OSPFAREARANGEEFFECT,       INTEGER, RWRITE, ospfAreaRangeEntry,
 | 
						|
   3, {5, 1, 5}},
 | 
						|
 | 
						|
  /* OSPF host table. */
 | 
						|
  {OSPFHOSTIPADDRESS,         IPADDRESS, RONLY, ospfHostEntry,
 | 
						|
   3, {6, 1, 1}},
 | 
						|
  {OSPFHOSTTOS,               INTEGER, RONLY, ospfHostEntry,
 | 
						|
   3, {6, 1, 2}},
 | 
						|
  {OSPFHOSTMETRIC,            INTEGER, RWRITE, ospfHostEntry,
 | 
						|
   3, {6, 1, 3}},
 | 
						|
  {OSPFHOSTSTATUS,            INTEGER, RWRITE, ospfHostEntry,
 | 
						|
   3, {6, 1, 4}},
 | 
						|
  {OSPFHOSTAREAID,            IPADDRESS, RONLY, ospfHostEntry,
 | 
						|
   3, {6, 1, 5}},
 | 
						|
 | 
						|
  /* OSPF interface table. */
 | 
						|
  {OSPFIFIPADDRESS,           IPADDRESS, RONLY, ospfIfEntry,
 | 
						|
   3, {7, 1, 1}},
 | 
						|
  {OSPFADDRESSLESSIF,         INTEGER, RONLY, ospfIfEntry,
 | 
						|
   3, {7, 1, 2}},
 | 
						|
  {OSPFIFAREAID,              IPADDRESS, RWRITE, ospfIfEntry,
 | 
						|
   3, {7, 1, 3}},
 | 
						|
  {OSPFIFTYPE,                INTEGER, RWRITE, ospfIfEntry,
 | 
						|
   3, {7, 1, 4}},
 | 
						|
  {OSPFIFADMINSTAT,           INTEGER, RWRITE, ospfIfEntry,
 | 
						|
   3, {7, 1, 5}},
 | 
						|
  {OSPFIFRTRPRIORITY,         INTEGER, RWRITE, ospfIfEntry,
 | 
						|
   3, {7, 1, 6}},
 | 
						|
  {OSPFIFTRANSITDELAY,        INTEGER, RWRITE, ospfIfEntry,
 | 
						|
   3, {7, 1, 7}},
 | 
						|
  {OSPFIFRETRANSINTERVAL,     INTEGER, RWRITE, ospfIfEntry,
 | 
						|
   3, {7, 1, 8}},
 | 
						|
  {OSPFIFHELLOINTERVAL,       INTEGER, RWRITE, ospfIfEntry,
 | 
						|
   3, {7, 1, 9}},
 | 
						|
  {OSPFIFRTRDEADINTERVAL,     INTEGER, RWRITE, ospfIfEntry,
 | 
						|
   3, {7, 1, 10}},
 | 
						|
  {OSPFIFPOLLINTERVAL,        INTEGER, RWRITE, ospfIfEntry,
 | 
						|
   3, {7, 1, 11}},
 | 
						|
  {OSPFIFSTATE,               INTEGER, RONLY, ospfIfEntry,
 | 
						|
   3, {7, 1, 12}},
 | 
						|
  {OSPFIFDESIGNATEDROUTER,    IPADDRESS, RONLY, ospfIfEntry,
 | 
						|
   3, {7, 1, 13}},
 | 
						|
  {OSPFIFBACKUPDESIGNATEDROUTER, IPADDRESS, RONLY, ospfIfEntry,
 | 
						|
   3, {7, 1, 14}},
 | 
						|
  {OSPFIFEVENTS,              COUNTER, RONLY, ospfIfEntry,
 | 
						|
   3, {7, 1, 15}},
 | 
						|
  {OSPFIFAUTHKEY,             STRING,  RWRITE, ospfIfEntry,
 | 
						|
   3, {7, 1, 16}},
 | 
						|
  {OSPFIFSTATUS,              INTEGER, RWRITE, ospfIfEntry,
 | 
						|
   3, {7, 1, 17}},
 | 
						|
  {OSPFIFMULTICASTFORWARDING, INTEGER, RWRITE, ospfIfEntry,
 | 
						|
   3, {7, 1, 18}},
 | 
						|
  {OSPFIFDEMAND,              INTEGER, RWRITE, ospfIfEntry,
 | 
						|
   3, {7, 1, 19}},
 | 
						|
  {OSPFIFAUTHTYPE,            INTEGER, RWRITE, ospfIfEntry,
 | 
						|
   3, {7, 1, 20}},
 | 
						|
 | 
						|
  /* OSPF interface metric table. */
 | 
						|
  {OSPFIFMETRICIPADDRESS,     IPADDRESS, RONLY, ospfIfMetricEntry,
 | 
						|
   3, {8, 1, 1}},
 | 
						|
  {OSPFIFMETRICADDRESSLESSIF, INTEGER, RONLY, ospfIfMetricEntry,
 | 
						|
   3, {8, 1, 2}},
 | 
						|
  {OSPFIFMETRICTOS,           INTEGER, RONLY, ospfIfMetricEntry,
 | 
						|
   3, {8, 1, 3}},
 | 
						|
  {OSPFIFMETRICVALUE,         INTEGER, RWRITE, ospfIfMetricEntry,
 | 
						|
   3, {8, 1, 4}},
 | 
						|
  {OSPFIFMETRICSTATUS,        INTEGER, RWRITE, ospfIfMetricEntry,
 | 
						|
   3, {8, 1, 5}},
 | 
						|
 | 
						|
  /* OSPF virtual interface table. */
 | 
						|
  {OSPFVIRTIFAREAID,          IPADDRESS, RONLY, ospfVirtIfEntry,
 | 
						|
   3, {9, 1, 1}},
 | 
						|
  {OSPFVIRTIFNEIGHBOR,        IPADDRESS, RONLY, ospfVirtIfEntry,
 | 
						|
   3, {9, 1, 2}},
 | 
						|
  {OSPFVIRTIFTRANSITDELAY,    INTEGER, RWRITE, ospfVirtIfEntry,
 | 
						|
   3, {9, 1, 3}},
 | 
						|
  {OSPFVIRTIFRETRANSINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry,
 | 
						|
   3, {9, 1, 4}},
 | 
						|
  {OSPFVIRTIFHELLOINTERVAL,   INTEGER, RWRITE, ospfVirtIfEntry,
 | 
						|
   3, {9, 1, 5}},
 | 
						|
  {OSPFVIRTIFRTRDEADINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry,
 | 
						|
   3, {9, 1, 6}},
 | 
						|
  {OSPFVIRTIFSTATE,           INTEGER, RONLY, ospfVirtIfEntry,
 | 
						|
   3, {9, 1, 7}},
 | 
						|
  {OSPFVIRTIFEVENTS,          COUNTER, RONLY, ospfVirtIfEntry,
 | 
						|
   3, {9, 1, 8}},
 | 
						|
  {OSPFVIRTIFAUTHKEY,         STRING,  RWRITE, ospfVirtIfEntry,
 | 
						|
   3, {9, 1, 9}},
 | 
						|
  {OSPFVIRTIFSTATUS,          INTEGER, RWRITE, ospfVirtIfEntry,
 | 
						|
   3, {9, 1, 10}},
 | 
						|
  {OSPFVIRTIFAUTHTYPE,        INTEGER, RWRITE, ospfVirtIfEntry,
 | 
						|
   3, {9, 1, 11}},
 | 
						|
 | 
						|
  /* OSPF neighbor table. */
 | 
						|
  {OSPFNBRIPADDR,             IPADDRESS, RONLY, ospfNbrEntry,
 | 
						|
   3, {10, 1, 1}},
 | 
						|
  {OSPFNBRADDRESSLESSINDEX,   INTEGER, RONLY, ospfNbrEntry,
 | 
						|
   3, {10, 1, 2}},
 | 
						|
  {OSPFNBRRTRID,              IPADDRESS, RONLY, ospfNbrEntry,
 | 
						|
   3, {10, 1, 3}},
 | 
						|
  {OSPFNBROPTIONS,            INTEGER, RONLY, ospfNbrEntry,
 | 
						|
   3, {10, 1, 4}},
 | 
						|
  {OSPFNBRPRIORITY,           INTEGER, RWRITE, ospfNbrEntry,
 | 
						|
   3, {10, 1, 5}},
 | 
						|
  {OSPFNBRSTATE,              INTEGER, RONLY, ospfNbrEntry,
 | 
						|
   3, {10, 1, 6}},
 | 
						|
  {OSPFNBREVENTS,             COUNTER, RONLY, ospfNbrEntry,
 | 
						|
   3, {10, 1, 7}},
 | 
						|
  {OSPFNBRLSRETRANSQLEN,      GAUGE, RONLY, ospfNbrEntry,
 | 
						|
   3, {10, 1, 8}},
 | 
						|
  {OSPFNBMANBRSTATUS,         INTEGER, RWRITE, ospfNbrEntry,
 | 
						|
   3, {10, 1, 9}},
 | 
						|
  {OSPFNBMANBRPERMANENCE,     INTEGER, RONLY, ospfNbrEntry,
 | 
						|
   3, {10, 1, 10}},
 | 
						|
  {OSPFNBRHELLOSUPPRESSED,    INTEGER, RONLY, ospfNbrEntry,
 | 
						|
   3, {10, 1, 11}},
 | 
						|
 | 
						|
  /* OSPF virtual neighbor table. */
 | 
						|
  {OSPFVIRTNBRAREA,           IPADDRESS, RONLY, ospfVirtNbrEntry,
 | 
						|
   3, {11, 1, 1}},
 | 
						|
  {OSPFVIRTNBRRTRID,          IPADDRESS, RONLY, ospfVirtNbrEntry,
 | 
						|
   3, {11, 1, 2}},
 | 
						|
  {OSPFVIRTNBRIPADDR,         IPADDRESS, RONLY, ospfVirtNbrEntry,
 | 
						|
   3, {11, 1, 3}},
 | 
						|
  {OSPFVIRTNBROPTIONS,        INTEGER, RONLY, ospfVirtNbrEntry,
 | 
						|
   3, {11, 1, 4}},
 | 
						|
  {OSPFVIRTNBRSTATE,          INTEGER, RONLY, ospfVirtNbrEntry,
 | 
						|
   3, {11, 1, 5}},
 | 
						|
  {OSPFVIRTNBREVENTS,         COUNTER, RONLY, ospfVirtNbrEntry,
 | 
						|
   3, {11, 1, 6}},
 | 
						|
  {OSPFVIRTNBRLSRETRANSQLEN,  INTEGER, RONLY, ospfVirtNbrEntry,
 | 
						|
   3, {11, 1, 7}},
 | 
						|
  {OSPFVIRTNBRHELLOSUPPRESSED, INTEGER, RONLY, ospfVirtNbrEntry,
 | 
						|
   3, {11, 1, 8}},
 | 
						|
 | 
						|
  /* OSPF link state database, external. */
 | 
						|
  {OSPFEXTLSDBTYPE,           INTEGER, RONLY, ospfExtLsdbEntry,
 | 
						|
   3, {12, 1, 1}},
 | 
						|
  {OSPFEXTLSDBLSID,           IPADDRESS, RONLY, ospfExtLsdbEntry,
 | 
						|
   3, {12, 1, 2}},
 | 
						|
  {OSPFEXTLSDBROUTERID,       IPADDRESS, RONLY, ospfExtLsdbEntry,
 | 
						|
   3, {12, 1, 3}},
 | 
						|
  {OSPFEXTLSDBSEQUENCE,       INTEGER, RONLY, ospfExtLsdbEntry,
 | 
						|
   3, {12, 1, 4}},
 | 
						|
  {OSPFEXTLSDBAGE,            INTEGER, RONLY, ospfExtLsdbEntry,
 | 
						|
   3, {12, 1, 5}},
 | 
						|
  {OSPFEXTLSDBCHECKSUM,       INTEGER, RONLY, ospfExtLsdbEntry,
 | 
						|
   3, {12, 1, 6}},
 | 
						|
  {OSPFEXTLSDBADVERTISEMENT,  STRING,  RONLY, ospfExtLsdbEntry,
 | 
						|
   3, {12, 1, 7}},
 | 
						|
 | 
						|
  /* OSPF area aggregate table. */
 | 
						|
  {OSPFAREAAGGREGATEAREAID,   IPADDRESS, RONLY, ospfAreaAggregateEntry, 
 | 
						|
   3, {14, 1, 1}},
 | 
						|
  {OSPFAREAAGGREGATELSDBTYPE, INTEGER, RONLY, ospfAreaAggregateEntry, 
 | 
						|
   3, {14, 1, 2}},
 | 
						|
  {OSPFAREAAGGREGATENET,      IPADDRESS, RONLY, ospfAreaAggregateEntry, 
 | 
						|
   3, {14, 1, 3}},
 | 
						|
  {OSPFAREAAGGREGATEMASK,     IPADDRESS, RONLY, ospfAreaAggregateEntry, 
 | 
						|
   3, {14, 1, 4}},
 | 
						|
  {OSPFAREAAGGREGATESTATUS,   INTEGER, RWRITE, ospfAreaAggregateEntry,
 | 
						|
   3, {14, 1, 5}},
 | 
						|
  {OSPFAREAAGGREGATEEFFECT,   INTEGER, RWRITE, ospfAreaAggregateEntry,
 | 
						|
   3, {14, 1, 6}}
 | 
						|
};
 | 
						|
 | 
						|
/* The administrative status of OSPF.  When OSPF is enbled on at least
 | 
						|
   one interface return 1. */
 | 
						|
static int
 | 
						|
ospf_admin_stat (struct ospf *ospf)
 | 
						|
{
 | 
						|
  struct listnode *node;
 | 
						|
  struct ospf_interface *oi;
 | 
						|
 | 
						|
  if (ospf == NULL)
 | 
						|
    return 0;
 | 
						|
 | 
						|
  for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
 | 
						|
    if (oi && oi->address)
 | 
						|
      return 1;
 | 
						|
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
static u_char *
 | 
						|
ospfGeneralGroup (struct variable *v, oid *name, size_t *length,
 | 
						|
		  int exact, size_t *var_len, WriteMethod **write_method)
 | 
						|
{
 | 
						|
  struct ospf *ospf;
 | 
						|
 | 
						|
  ospf = ospf_lookup ();
 | 
						|
 | 
						|
  /* Check whether the instance identifier is valid */
 | 
						|
  if (smux_header_generic (v, name, length, exact, var_len, write_method)
 | 
						|
      == MATCH_FAILED)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  /* Return the current value of the variable */
 | 
						|
  switch (v->magic) 
 | 
						|
    {
 | 
						|
    case OSPFROUTERID:		/* 1 */
 | 
						|
      /* Router-ID of this OSPF instance. */
 | 
						|
      if (ospf)
 | 
						|
	return SNMP_IPADDRESS (ospf->router_id);
 | 
						|
      else
 | 
						|
	return SNMP_IPADDRESS (ospf_empty_addr);
 | 
						|
      break;
 | 
						|
    case OSPFADMINSTAT:		/* 2 */
 | 
						|
      /* The administrative status of OSPF in the router. */
 | 
						|
      if (ospf_admin_stat (ospf))
 | 
						|
	return SNMP_INTEGER (OSPF_STATUS_ENABLED);
 | 
						|
      else
 | 
						|
	return SNMP_INTEGER (OSPF_STATUS_DISABLED);
 | 
						|
      break;
 | 
						|
    case OSPFVERSIONNUMBER:	/* 3 */
 | 
						|
      /* OSPF version 2. */
 | 
						|
      return SNMP_INTEGER (OSPF_VERSION);
 | 
						|
      break;
 | 
						|
    case OSPFAREABDRRTRSTATUS:	/* 4 */
 | 
						|
      /* Area Border router status. */
 | 
						|
      if (ospf && CHECK_FLAG (ospf->flags, OSPF_FLAG_ABR))
 | 
						|
	return SNMP_INTEGER (SNMP_TRUE);
 | 
						|
      else
 | 
						|
	return SNMP_INTEGER (SNMP_FALSE);
 | 
						|
      break;
 | 
						|
    case OSPFASBDRRTRSTATUS:	/* 5 */
 | 
						|
      /* AS Border router status. */
 | 
						|
      if (ospf && CHECK_FLAG (ospf->flags, OSPF_FLAG_ASBR))
 | 
						|
	return SNMP_INTEGER (SNMP_TRUE);
 | 
						|
      else
 | 
						|
	return SNMP_INTEGER (SNMP_FALSE);
 | 
						|
      break;
 | 
						|
    case OSPFEXTERNLSACOUNT:	/* 6 */
 | 
						|
      /* External LSA counts. */
 | 
						|
      if (ospf)
 | 
						|
	return SNMP_INTEGER (ospf_lsdb_count_all (ospf->lsdb));
 | 
						|
      else
 | 
						|
	return SNMP_INTEGER (0);
 | 
						|
      break;
 | 
						|
    case OSPFEXTERNLSACKSUMSUM:	/* 7 */
 | 
						|
      /* External LSA checksum. */
 | 
						|
      return SNMP_INTEGER (0);
 | 
						|
      break;
 | 
						|
    case OSPFTOSSUPPORT:	/* 8 */
 | 
						|
      /* TOS is not supported. */
 | 
						|
      return SNMP_INTEGER (SNMP_FALSE);
 | 
						|
      break;
 | 
						|
    case OSPFORIGINATENEWLSAS:	/* 9 */
 | 
						|
      /* The number of new link-state advertisements. */
 | 
						|
      if (ospf)
 | 
						|
	return SNMP_INTEGER (ospf->lsa_originate_count);
 | 
						|
      else
 | 
						|
	return SNMP_INTEGER (0);
 | 
						|
      break;
 | 
						|
    case OSPFRXNEWLSAS:		/* 10 */
 | 
						|
      /* The number of link-state advertisements received determined
 | 
						|
         to be new instantiations. */
 | 
						|
      if (ospf)
 | 
						|
	return SNMP_INTEGER (ospf->rx_lsa_count);
 | 
						|
      else
 | 
						|
	return SNMP_INTEGER (0);
 | 
						|
      break;
 | 
						|
    case OSPFEXTLSDBLIMIT:	/* 11 */
 | 
						|
      /* There is no limit for the number of non-default
 | 
						|
         AS-external-LSAs. */
 | 
						|
      return SNMP_INTEGER (-1);
 | 
						|
      break;
 | 
						|
    case OSPFMULTICASTEXTENSIONS: /* 12 */
 | 
						|
      /* Multicast Extensions to OSPF is not supported. */
 | 
						|
      return SNMP_INTEGER (0);
 | 
						|
      break;
 | 
						|
    case OSPFEXITOVERFLOWINTERVAL: /* 13 */
 | 
						|
      /* Overflow is not supported. */
 | 
						|
      return SNMP_INTEGER (0);
 | 
						|
      break;
 | 
						|
    case OSPFDEMANDEXTENSIONS:	/* 14 */
 | 
						|
      /* Demand routing is not supported. */
 | 
						|
      return SNMP_INTEGER (SNMP_FALSE);
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      return NULL;
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static struct ospf_area *
 | 
						|
ospf_area_lookup_next (struct ospf *ospf, struct in_addr *area_id, int first)
 | 
						|
{
 | 
						|
  struct ospf_area *area;
 | 
						|
  struct listnode *node;
 | 
						|
 | 
						|
  if (ospf == NULL)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  if (first)
 | 
						|
    {
 | 
						|
      node = listhead (ospf->areas);
 | 
						|
      if (node)
 | 
						|
	{
 | 
						|
	  area = listgetdata (node);
 | 
						|
	  *area_id = area->area_id;
 | 
						|
	  return area;
 | 
						|
	}
 | 
						|
      return NULL;
 | 
						|
    }
 | 
						|
  for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
 | 
						|
    {
 | 
						|
      if (ntohl (area->area_id.s_addr) > ntohl (area_id->s_addr))
 | 
						|
	{
 | 
						|
	  *area_id = area->area_id;
 | 
						|
	  return area;
 | 
						|
	}
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static struct ospf_area *
 | 
						|
ospfAreaLookup (struct variable *v, oid name[], size_t *length,
 | 
						|
		struct in_addr *addr, int exact)
 | 
						|
{
 | 
						|
  struct ospf *ospf;
 | 
						|
  struct ospf_area *area;
 | 
						|
  int len;
 | 
						|
 | 
						|
  ospf = ospf_lookup ();
 | 
						|
  if (ospf == NULL)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  if (exact)
 | 
						|
    {
 | 
						|
      /* Length is insufficient to lookup OSPF area. */
 | 
						|
      if (*length - v->namelen != sizeof (struct in_addr))
 | 
						|
	return NULL;
 | 
						|
 | 
						|
      oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr);
 | 
						|
 | 
						|
      area = ospf_area_lookup_by_area_id (ospf, *addr);
 | 
						|
 | 
						|
      return area;
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      len = *length - v->namelen;
 | 
						|
      if (len > 4)
 | 
						|
	len = 4;
 | 
						|
      
 | 
						|
      oid2in_addr (name + v->namelen, len, addr);
 | 
						|
 | 
						|
      area = ospf_area_lookup_next (ospf, addr, len == 0 ? 1 : 0);
 | 
						|
 | 
						|
      if (area == NULL)
 | 
						|
	return NULL;
 | 
						|
 | 
						|
      oid_copy_addr (name + v->namelen, addr, sizeof (struct in_addr));
 | 
						|
      *length = sizeof (struct in_addr) + v->namelen;
 | 
						|
 | 
						|
      return area;
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static u_char *
 | 
						|
ospfAreaEntry (struct variable *v, oid *name, size_t *length, int exact,
 | 
						|
	       size_t *var_len, WriteMethod **write_method)
 | 
						|
{
 | 
						|
  struct ospf_area *area;
 | 
						|
  struct in_addr addr;
 | 
						|
 | 
						|
  if (smux_header_table(v, name, length, exact, var_len, write_method)
 | 
						|
      == MATCH_FAILED)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  memset (&addr, 0, sizeof (struct in_addr));
 | 
						|
 | 
						|
  area = ospfAreaLookup (v, name, length, &addr, exact);
 | 
						|
  if (! area)
 | 
						|
    return NULL;
 | 
						|
  
 | 
						|
  /* Return the current value of the variable */
 | 
						|
  switch (v->magic) 
 | 
						|
    {
 | 
						|
    case OSPFAREAID:		/* 1 */
 | 
						|
      return SNMP_IPADDRESS (area->area_id);
 | 
						|
      break;
 | 
						|
    case OSPFAUTHTYPE:		/* 2 */
 | 
						|
      return SNMP_INTEGER (area->auth_type);
 | 
						|
      break;
 | 
						|
    case OSPFIMPORTASEXTERN:	/* 3 */
 | 
						|
      return SNMP_INTEGER (area->external_routing + 1);
 | 
						|
      break;
 | 
						|
    case OSPFSPFRUNS:		/* 4 */
 | 
						|
      return SNMP_INTEGER (area->spf_calculation);
 | 
						|
      break;
 | 
						|
    case OSPFAREABDRRTRCOUNT:	/* 5 */
 | 
						|
      return SNMP_INTEGER (area->abr_count);
 | 
						|
      break;
 | 
						|
    case OSPFASBDRRTRCOUNT:	/* 6 */
 | 
						|
      return SNMP_INTEGER (area->asbr_count);
 | 
						|
      break;
 | 
						|
    case OSPFAREALSACOUNT:	/* 7 */
 | 
						|
      return SNMP_INTEGER (area->lsdb->total);
 | 
						|
      break;
 | 
						|
    case OSPFAREALSACKSUMSUM:	/* 8 */
 | 
						|
      return SNMP_INTEGER (0);
 | 
						|
      break;
 | 
						|
    case OSPFAREASUMMARY:	/* 9 */
 | 
						|
#define OSPF_noAreaSummary   1
 | 
						|
#define OSPF_sendAreaSummary 2
 | 
						|
      if (area->no_summary)
 | 
						|
	return SNMP_INTEGER (OSPF_noAreaSummary);
 | 
						|
      else
 | 
						|
	return SNMP_INTEGER (OSPF_sendAreaSummary);
 | 
						|
      break;
 | 
						|
    case OSPFAREASTATUS:	/* 10 */
 | 
						|
      return SNMP_INTEGER (SNMP_VALID);
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      return NULL;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static struct ospf_area *
 | 
						|
ospf_stub_area_lookup_next (struct in_addr *area_id, int first)
 | 
						|
{
 | 
						|
  struct ospf_area *area;
 | 
						|
  struct listnode *node;
 | 
						|
  struct ospf *ospf;
 | 
						|
 | 
						|
  ospf = ospf_lookup ();
 | 
						|
  if (ospf == NULL)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
 | 
						|
    {
 | 
						|
      if (area->external_routing == OSPF_AREA_STUB)
 | 
						|
	{
 | 
						|
	  if (first)
 | 
						|
	    {
 | 
						|
	      *area_id = area->area_id;
 | 
						|
	      return area;
 | 
						|
	    }
 | 
						|
	  else if (ntohl (area->area_id.s_addr) > ntohl (area_id->s_addr))
 | 
						|
	    {
 | 
						|
	      *area_id = area->area_id;
 | 
						|
	      return area;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static struct ospf_area *
 | 
						|
ospfStubAreaLookup (struct variable *v, oid name[], size_t *length,
 | 
						|
		    struct in_addr *addr, int exact)
 | 
						|
{
 | 
						|
  struct ospf *ospf;
 | 
						|
  struct ospf_area *area;
 | 
						|
  int len;
 | 
						|
 | 
						|
  ospf = ospf_lookup ();
 | 
						|
  if (ospf == NULL)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  /* Exact lookup. */
 | 
						|
  if (exact)
 | 
						|
    {
 | 
						|
      /* ospfStubAreaID + ospfStubTOS. */
 | 
						|
      if (*length != v->namelen + sizeof (struct in_addr) + 1)
 | 
						|
	return NULL;
 | 
						|
 | 
						|
      /* Check ospfStubTOS is zero. */
 | 
						|
      if (name[*length - 1] != 0)
 | 
						|
	return NULL;
 | 
						|
 | 
						|
      oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr);
 | 
						|
 | 
						|
      area = ospf_area_lookup_by_area_id (ospf, *addr);
 | 
						|
 | 
						|
      if (area->external_routing == OSPF_AREA_STUB)
 | 
						|
	return area;
 | 
						|
      else
 | 
						|
	return NULL;
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      len = *length - v->namelen;
 | 
						|
      if (len > 4)
 | 
						|
	len = 4;
 | 
						|
      
 | 
						|
      oid2in_addr (name + v->namelen, len, addr);
 | 
						|
 | 
						|
      area = ospf_stub_area_lookup_next (addr, len == 0 ? 1 : 0);
 | 
						|
 | 
						|
      if (area == NULL)
 | 
						|
	return NULL;
 | 
						|
 | 
						|
      oid_copy_addr (name + v->namelen, addr, sizeof (struct in_addr));
 | 
						|
      /* Set TOS 0. */
 | 
						|
      name[v->namelen + sizeof (struct in_addr)] = 0;
 | 
						|
      *length = v->namelen + sizeof (struct in_addr) + 1;
 | 
						|
 | 
						|
      return area;
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static u_char *
 | 
						|
ospfStubAreaEntry (struct variable *v, oid *name, size_t *length,
 | 
						|
		   int exact, size_t *var_len, WriteMethod **write_method)
 | 
						|
{
 | 
						|
  struct ospf_area *area;
 | 
						|
  struct in_addr addr;
 | 
						|
 | 
						|
  if (smux_header_table(v, name, length, exact, var_len, write_method)
 | 
						|
      == MATCH_FAILED)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  memset (&addr, 0, sizeof (struct in_addr));
 | 
						|
 | 
						|
  area = ospfStubAreaLookup (v, name, length, &addr, exact);
 | 
						|
  if (! area)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  /* Return the current value of the variable */
 | 
						|
  switch (v->magic) 
 | 
						|
    {
 | 
						|
    case OSPFSTUBAREAID:	/* 1 */
 | 
						|
      /* OSPF stub area id. */
 | 
						|
      return SNMP_IPADDRESS (area->area_id);
 | 
						|
      break;
 | 
						|
    case OSPFSTUBTOS:		/* 2 */
 | 
						|
      /* TOS value is not supported. */
 | 
						|
      return SNMP_INTEGER (0);
 | 
						|
      break;
 | 
						|
    case OSPFSTUBMETRIC:	/* 3 */
 | 
						|
      /* Default cost to stub area. */
 | 
						|
      return SNMP_INTEGER (area->default_cost);
 | 
						|
      break;
 | 
						|
    case OSPFSTUBSTATUS:	/* 4 */
 | 
						|
      /* Status of the stub area. */
 | 
						|
      return SNMP_INTEGER (SNMP_VALID);
 | 
						|
      break;
 | 
						|
    case OSPFSTUBMETRICTYPE:	/* 5 */
 | 
						|
      /* OSPF Metric type. */
 | 
						|
#define OSPF_ospfMetric     1
 | 
						|
#define OSPF_comparableCost 2
 | 
						|
#define OSPF_nonComparable  3
 | 
						|
      return SNMP_INTEGER (OSPF_ospfMetric);
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      return NULL;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static struct ospf_lsa *
 | 
						|
lsdb_lookup_next (struct ospf_area *area, u_char *type, int type_next,
 | 
						|
		  struct in_addr *ls_id, int ls_id_next,
 | 
						|
		  struct in_addr *router_id, int router_id_next)
 | 
						|
{
 | 
						|
  struct ospf_lsa *lsa;
 | 
						|
  int i;
 | 
						|
 | 
						|
  if (type_next)
 | 
						|
    i = OSPF_MIN_LSA;
 | 
						|
  else
 | 
						|
    i = *type;
 | 
						|
 | 
						|
  /* Sanity check, if LSA type unknwon
 | 
						|
     merley skip any LSA */
 | 
						|
  if ((i < OSPF_MIN_LSA) || (i >= OSPF_MAX_LSA))
 | 
						|
    {
 | 
						|
      zlog_debug("Strange request with LSA type %d\n", i);
 | 
						|
      return NULL;
 | 
						|
    }
 | 
						|
 | 
						|
  for (; i < OSPF_MAX_LSA; i++)
 | 
						|
    {
 | 
						|
      *type = i;
 | 
						|
 | 
						|
      lsa = ospf_lsdb_lookup_by_id_next (area->lsdb, *type, *ls_id, *router_id,
 | 
						|
					ls_id_next);
 | 
						|
      if (lsa)
 | 
						|
	return lsa;
 | 
						|
 | 
						|
      ls_id_next = 1;
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static struct ospf_lsa *
 | 
						|
ospfLsdbLookup (struct variable *v, oid *name, size_t *length,
 | 
						|
		struct in_addr *area_id, u_char *type,
 | 
						|
		struct in_addr *ls_id, struct in_addr *router_id, int exact)
 | 
						|
{
 | 
						|
  struct ospf *ospf;
 | 
						|
  struct ospf_area *area;
 | 
						|
  struct ospf_lsa *lsa;
 | 
						|
  int len;
 | 
						|
  int type_next;
 | 
						|
  int ls_id_next;
 | 
						|
  int router_id_next;
 | 
						|
  oid *offset;
 | 
						|
  int offsetlen;
 | 
						|
 | 
						|
  ospf = ospf_lookup ();
 | 
						|
 | 
						|
#define OSPF_LSDB_ENTRY_OFFSET \
 | 
						|
          (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
 | 
						|
 | 
						|
  if (exact)
 | 
						|
    {
 | 
						|
      /* Area ID + Type + LS ID + Router ID. */
 | 
						|
      if (*length - v->namelen != OSPF_LSDB_ENTRY_OFFSET)
 | 
						|
	return NULL;
 | 
						|
      
 | 
						|
      /* Set OID offset for Area ID. */
 | 
						|
      offset = name + v->namelen;
 | 
						|
 | 
						|
      /* Lookup area first. */
 | 
						|
      oid2in_addr (offset, IN_ADDR_SIZE, area_id);
 | 
						|
      area = ospf_area_lookup_by_area_id (ospf, *area_id);
 | 
						|
      if (! area)
 | 
						|
	return NULL;
 | 
						|
      offset += IN_ADDR_SIZE;
 | 
						|
 | 
						|
      /* Type. */
 | 
						|
      *type = *offset;
 | 
						|
      offset++;
 | 
						|
 | 
						|
      /* LS ID. */
 | 
						|
      oid2in_addr (offset, IN_ADDR_SIZE, ls_id);
 | 
						|
      offset += IN_ADDR_SIZE;
 | 
						|
 | 
						|
      /* Router ID. */
 | 
						|
      oid2in_addr (offset, IN_ADDR_SIZE, router_id);
 | 
						|
 | 
						|
      /* Lookup LSDB. */
 | 
						|
      return ospf_lsdb_lookup_by_id (area->lsdb, *type, *ls_id, *router_id);
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      /* Get variable length. */
 | 
						|
      offset = name + v->namelen;
 | 
						|
      offsetlen = *length - v->namelen;
 | 
						|
      len = offsetlen;
 | 
						|
 | 
						|
      if (len > (int)IN_ADDR_SIZE)
 | 
						|
	len = IN_ADDR_SIZE;
 | 
						|
 | 
						|
      oid2in_addr (offset, len, area_id);
 | 
						|
 | 
						|
      /* First we search area. */
 | 
						|
      if (len == IN_ADDR_SIZE)
 | 
						|
	area = ospf_area_lookup_by_area_id (ospf, *area_id);
 | 
						|
      else
 | 
						|
	area = ospf_area_lookup_next (ospf, area_id, 1);
 | 
						|
 | 
						|
      if (area == NULL)
 | 
						|
	return NULL;
 | 
						|
 | 
						|
      do 
 | 
						|
	{
 | 
						|
	  /* Next we lookup type. */
 | 
						|
	  offset += len;
 | 
						|
	  offsetlen -= len;
 | 
						|
	  len = offsetlen;
 | 
						|
 | 
						|
	  if (len <= 0)
 | 
						|
	    type_next = 1;
 | 
						|
	  else
 | 
						|
	    {
 | 
						|
	      len = 1;
 | 
						|
	      type_next = 0;
 | 
						|
	      *type = *offset;
 | 
						|
	    }
 | 
						|
	
 | 
						|
	  /* LS ID. */
 | 
						|
	  offset++;
 | 
						|
	  offsetlen--;
 | 
						|
	  len = offsetlen;
 | 
						|
 | 
						|
	  if (len <= 0)
 | 
						|
	    ls_id_next = 1;
 | 
						|
	  else
 | 
						|
	    {
 | 
						|
	      ls_id_next = 0;
 | 
						|
	      if (len > (int)IN_ADDR_SIZE)
 | 
						|
		len = IN_ADDR_SIZE;
 | 
						|
 | 
						|
	      oid2in_addr (offset, len, ls_id);
 | 
						|
	    }
 | 
						|
 | 
						|
	  /* Router ID. */
 | 
						|
	  offset += IN_ADDR_SIZE;
 | 
						|
	  offsetlen -= IN_ADDR_SIZE;
 | 
						|
	  len = offsetlen;
 | 
						|
 | 
						|
	  if (len <= 0)
 | 
						|
	    router_id_next = 1;
 | 
						|
	  else
 | 
						|
	    {
 | 
						|
	      router_id_next = 0;
 | 
						|
	      if (len > (int)IN_ADDR_SIZE)
 | 
						|
		len = IN_ADDR_SIZE;
 | 
						|
 | 
						|
	      oid2in_addr (offset, len, router_id);
 | 
						|
	    }
 | 
						|
 | 
						|
	  lsa = lsdb_lookup_next (area, type, type_next, ls_id, ls_id_next,
 | 
						|
				  router_id, router_id_next);
 | 
						|
 | 
						|
	  if (lsa)
 | 
						|
	    {
 | 
						|
	      /* Fill in length. */
 | 
						|
	      *length = v->namelen + OSPF_LSDB_ENTRY_OFFSET;
 | 
						|
 | 
						|
	      /* Fill in value. */
 | 
						|
	      offset = name + v->namelen;
 | 
						|
	      oid_copy_addr (offset, area_id, IN_ADDR_SIZE);
 | 
						|
	      offset += IN_ADDR_SIZE;
 | 
						|
	      *offset = lsa->data->type;
 | 
						|
	      offset++;
 | 
						|
	      oid_copy_addr (offset, &lsa->data->id, IN_ADDR_SIZE);
 | 
						|
	      offset += IN_ADDR_SIZE;
 | 
						|
	      oid_copy_addr (offset, &lsa->data->adv_router, IN_ADDR_SIZE);
 | 
						|
	    
 | 
						|
	      return lsa;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
      while ((area = ospf_area_lookup_next (ospf, area_id, 0)) != NULL);
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static u_char *
 | 
						|
ospfLsdbEntry (struct variable *v, oid *name, size_t *length, int exact,
 | 
						|
	       size_t *var_len, WriteMethod **write_method)
 | 
						|
{
 | 
						|
  struct ospf_lsa *lsa;
 | 
						|
  struct lsa_header *lsah;
 | 
						|
  struct in_addr area_id;
 | 
						|
  u_char type;
 | 
						|
  struct in_addr ls_id;
 | 
						|
  struct in_addr router_id;
 | 
						|
  struct ospf *ospf;
 | 
						|
 | 
						|
  if (smux_header_table(v, name, length, exact, var_len, write_method)
 | 
						|
      == MATCH_FAILED)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  /* INDEX { ospfLsdbAreaId, ospfLsdbType,
 | 
						|
     ospfLsdbLsid, ospfLsdbRouterId } */
 | 
						|
 | 
						|
  memset (&area_id, 0, sizeof (struct in_addr));
 | 
						|
  type = 0;
 | 
						|
  memset (&ls_id, 0, sizeof (struct in_addr));
 | 
						|
  memset (&router_id, 0, sizeof (struct in_addr));
 | 
						|
 | 
						|
  /* Check OSPF instance. */
 | 
						|
  ospf = ospf_lookup ();
 | 
						|
  if (ospf == NULL)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  lsa = ospfLsdbLookup (v, name, length, &area_id, &type, &ls_id, &router_id,
 | 
						|
			exact);
 | 
						|
  if (! lsa)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  lsah = lsa->data;
 | 
						|
 | 
						|
  /* Return the current value of the variable */
 | 
						|
  switch (v->magic) 
 | 
						|
    {
 | 
						|
    case OSPFLSDBAREAID:	/* 1 */
 | 
						|
      return SNMP_IPADDRESS (lsa->area->area_id);
 | 
						|
      break;
 | 
						|
    case OSPFLSDBTYPE:		/* 2 */
 | 
						|
      return SNMP_INTEGER (lsah->type);
 | 
						|
      break;
 | 
						|
    case OSPFLSDBLSID:		/* 3 */
 | 
						|
      return SNMP_IPADDRESS (lsah->id);
 | 
						|
      break;
 | 
						|
    case OSPFLSDBROUTERID:	/* 4 */
 | 
						|
      return SNMP_IPADDRESS (lsah->adv_router);
 | 
						|
      break;
 | 
						|
    case OSPFLSDBSEQUENCE:	/* 5 */
 | 
						|
      return SNMP_INTEGER (lsah->ls_seqnum);
 | 
						|
      break;
 | 
						|
    case OSPFLSDBAGE:		/* 6 */
 | 
						|
      return SNMP_INTEGER (lsah->ls_age);
 | 
						|
      break;
 | 
						|
    case OSPFLSDBCHECKSUM:	/* 7 */
 | 
						|
      return SNMP_INTEGER (lsah->checksum);
 | 
						|
      break;
 | 
						|
    case OSPFLSDBADVERTISEMENT:	/* 8 */
 | 
						|
      *var_len = ntohs (lsah->length);
 | 
						|
      return (u_char *) lsah;
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      return NULL;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static struct ospf_area_range *
 | 
						|
ospfAreaRangeLookup (struct variable *v, oid *name, size_t *length,
 | 
						|
		     struct in_addr *area_id, struct in_addr *range_net,
 | 
						|
		     int exact)
 | 
						|
{
 | 
						|
  oid *offset;
 | 
						|
  int offsetlen;
 | 
						|
  int len;
 | 
						|
  struct ospf *ospf;
 | 
						|
  struct ospf_area *area;
 | 
						|
  struct ospf_area_range *range;
 | 
						|
  struct prefix_ipv4 p;
 | 
						|
  p.family = AF_INET;
 | 
						|
  p.prefixlen = IPV4_MAX_BITLEN;
 | 
						|
 | 
						|
  ospf = ospf_lookup ();
 | 
						|
 | 
						|
  if (exact) 
 | 
						|
    {
 | 
						|
      /* Area ID + Range Network. */
 | 
						|
      if (v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE != *length)
 | 
						|
	return NULL;
 | 
						|
 | 
						|
      /* Set OID offset for Area ID. */
 | 
						|
      offset = name + v->namelen;
 | 
						|
 | 
						|
      /* Lookup area first. */
 | 
						|
      oid2in_addr (offset, IN_ADDR_SIZE, area_id);
 | 
						|
 | 
						|
      area = ospf_area_lookup_by_area_id (ospf, *area_id);
 | 
						|
      if (! area)
 | 
						|
	return NULL;
 | 
						|
 | 
						|
      offset += IN_ADDR_SIZE;
 | 
						|
 | 
						|
      /* Lookup area range. */
 | 
						|
      oid2in_addr (offset, IN_ADDR_SIZE, range_net);
 | 
						|
      p.prefix = *range_net;
 | 
						|
 | 
						|
      return ospf_area_range_lookup (area, &p);
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      /* Set OID offset for Area ID. */
 | 
						|
      offset = name + v->namelen;
 | 
						|
      offsetlen = *length - v->namelen;
 | 
						|
 | 
						|
      len = offsetlen;
 | 
						|
      if (len > (int)IN_ADDR_SIZE)
 | 
						|
	len = IN_ADDR_SIZE;
 | 
						|
 | 
						|
      oid2in_addr (offset, len, area_id);
 | 
						|
 | 
						|
      /* First we search area. */
 | 
						|
      if (len == IN_ADDR_SIZE)
 | 
						|
	area = ospf_area_lookup_by_area_id (ospf,*area_id);
 | 
						|
      else
 | 
						|
	area = ospf_area_lookup_next (ospf, area_id, len == 0 ? 1 : 0);
 | 
						|
 | 
						|
      if (area == NULL)
 | 
						|
	return NULL;
 | 
						|
 | 
						|
      do 
 | 
						|
	{
 | 
						|
	  offset += IN_ADDR_SIZE;
 | 
						|
	  offsetlen -= IN_ADDR_SIZE;
 | 
						|
	  len = offsetlen;
 | 
						|
 | 
						|
	  if (len < 0)
 | 
						|
	    len = 0;
 | 
						|
	  if (len > (int)IN_ADDR_SIZE)
 | 
						|
	    len = IN_ADDR_SIZE;
 | 
						|
 | 
						|
	  oid2in_addr (offset, len, range_net);
 | 
						|
 | 
						|
	  range = ospf_area_range_lookup_next (area, range_net,
 | 
						|
					       len == 0 ? 1 : 0);
 | 
						|
 | 
						|
	  if (range)
 | 
						|
	    {
 | 
						|
	      /* Fill in length. */
 | 
						|
	      *length = v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE;
 | 
						|
 | 
						|
	      /* Fill in value. */
 | 
						|
	      offset = name + v->namelen;
 | 
						|
	      oid_copy_addr (offset, area_id, IN_ADDR_SIZE);
 | 
						|
	      offset += IN_ADDR_SIZE;
 | 
						|
	      oid_copy_addr (offset, range_net, IN_ADDR_SIZE);
 | 
						|
 | 
						|
	      return range;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
      while ((area = ospf_area_lookup_next (ospf, area_id, 0)) != NULL);
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static u_char *
 | 
						|
ospfAreaRangeEntry (struct variable *v, oid *name, size_t *length, int exact,
 | 
						|
		    size_t *var_len, WriteMethod **write_method)
 | 
						|
{
 | 
						|
  struct ospf_area_range *range;
 | 
						|
  struct in_addr area_id;
 | 
						|
  struct in_addr range_net;
 | 
						|
  struct in_addr mask;
 | 
						|
  struct ospf *ospf;
 | 
						|
  
 | 
						|
  if (smux_header_table(v, name, length, exact, var_len, write_method)
 | 
						|
      == MATCH_FAILED)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  /* Check OSPF instance. */
 | 
						|
  ospf = ospf_lookup ();
 | 
						|
  if (ospf == NULL)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  memset (&area_id, 0, IN_ADDR_SIZE);
 | 
						|
  memset (&range_net, 0, IN_ADDR_SIZE);
 | 
						|
 | 
						|
  range = ospfAreaRangeLookup (v, name, length, &area_id, &range_net, exact);
 | 
						|
  if (! range)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  /* Convert prefixlen to network mask format. */
 | 
						|
  masklen2ip (range->subst_masklen, &mask);
 | 
						|
 | 
						|
  /* Return the current value of the variable */
 | 
						|
  switch (v->magic) 
 | 
						|
    {
 | 
						|
    case OSPFAREARANGEAREAID:	/* 1 */
 | 
						|
      return SNMP_IPADDRESS (area_id);
 | 
						|
      break;
 | 
						|
    case OSPFAREARANGENET:	/* 2 */
 | 
						|
      return SNMP_IPADDRESS (range_net);
 | 
						|
      break;
 | 
						|
    case OSPFAREARANGEMASK:	/* 3 */
 | 
						|
      return SNMP_IPADDRESS (mask);
 | 
						|
      break;
 | 
						|
    case OSPFAREARANGESTATUS:	/* 4 */
 | 
						|
      return SNMP_INTEGER (SNMP_VALID);
 | 
						|
      break;
 | 
						|
    case OSPFAREARANGEEFFECT:	/* 5 */
 | 
						|
#define OSPF_advertiseMatching      1
 | 
						|
#define OSPF_doNotAdvertiseMatching 2
 | 
						|
      return SNMP_INTEGER (OSPF_advertiseMatching);
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      return NULL;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static struct ospf_nbr_nbma *
 | 
						|
ospfHostLookup (struct variable *v, oid *name, size_t *length,
 | 
						|
		struct in_addr *addr, int exact)
 | 
						|
{
 | 
						|
  int len;
 | 
						|
  struct ospf_nbr_nbma *nbr_nbma;
 | 
						|
  struct ospf *ospf;
 | 
						|
 | 
						|
  ospf = ospf_lookup ();
 | 
						|
  if (ospf == NULL)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  if (exact)
 | 
						|
    {
 | 
						|
      /* INDEX { ospfHostIpAddress, ospfHostTOS } */
 | 
						|
      if (*length != v->namelen + IN_ADDR_SIZE + 1)
 | 
						|
	return NULL;
 | 
						|
 | 
						|
      /* Check ospfHostTOS. */
 | 
						|
      if (name[*length - 1] != 0)
 | 
						|
	return NULL;
 | 
						|
 | 
						|
      oid2in_addr (name + v->namelen, IN_ADDR_SIZE, addr);
 | 
						|
 | 
						|
      nbr_nbma = ospf_nbr_nbma_lookup (ospf, *addr);
 | 
						|
 | 
						|
      return nbr_nbma;
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      len = *length - v->namelen;
 | 
						|
      if (len > 4)
 | 
						|
	len = 4;
 | 
						|
      
 | 
						|
      oid2in_addr (name + v->namelen, len, addr);
 | 
						|
 | 
						|
      nbr_nbma = ospf_nbr_nbma_lookup_next (ospf, addr, len == 0 ? 1 : 0);
 | 
						|
 | 
						|
      if (nbr_nbma == NULL)
 | 
						|
	return NULL;
 | 
						|
 | 
						|
      oid_copy_addr (name + v->namelen, addr, IN_ADDR_SIZE);
 | 
						|
 | 
						|
      /* Set TOS 0. */
 | 
						|
      name[v->namelen + IN_ADDR_SIZE] = 0;
 | 
						|
 | 
						|
      *length = v->namelen + IN_ADDR_SIZE + 1;
 | 
						|
 | 
						|
      return nbr_nbma;
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static u_char *
 | 
						|
ospfHostEntry (struct variable *v, oid *name, size_t *length, int exact,
 | 
						|
	       size_t *var_len, WriteMethod **write_method)
 | 
						|
{
 | 
						|
  struct ospf_nbr_nbma *nbr_nbma;
 | 
						|
  struct ospf_interface *oi;
 | 
						|
  struct in_addr addr;
 | 
						|
  struct ospf *ospf;
 | 
						|
 | 
						|
  if (smux_header_table(v, name, length, exact, var_len, write_method)
 | 
						|
      == MATCH_FAILED)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  /* Check OSPF instance. */
 | 
						|
  ospf = ospf_lookup ();
 | 
						|
  if (ospf == NULL)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  memset (&addr, 0, sizeof (struct in_addr));
 | 
						|
 | 
						|
  nbr_nbma = ospfHostLookup (v, name, length, &addr, exact);
 | 
						|
  if (nbr_nbma == NULL)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  oi = nbr_nbma->oi;
 | 
						|
 | 
						|
  /* Return the current value of the variable */
 | 
						|
  switch (v->magic) 
 | 
						|
    {
 | 
						|
    case OSPFHOSTIPADDRESS:	/* 1 */
 | 
						|
      return SNMP_IPADDRESS (nbr_nbma->addr);
 | 
						|
      break;
 | 
						|
    case OSPFHOSTTOS:		/* 2 */
 | 
						|
      return SNMP_INTEGER (0);
 | 
						|
      break;
 | 
						|
    case OSPFHOSTMETRIC:	/* 3 */
 | 
						|
      if (oi)
 | 
						|
	return SNMP_INTEGER (oi->output_cost);
 | 
						|
      else
 | 
						|
	return SNMP_INTEGER (1);
 | 
						|
      break;
 | 
						|
    case OSPFHOSTSTATUS:	/* 4 */
 | 
						|
      return SNMP_INTEGER (SNMP_VALID);
 | 
						|
      break;
 | 
						|
    case OSPFHOSTAREAID:	/* 5 */
 | 
						|
      if (oi && oi->area)
 | 
						|
	return SNMP_IPADDRESS (oi->area->area_id);
 | 
						|
      else
 | 
						|
	return SNMP_IPADDRESS (ospf_empty_addr);
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      return NULL;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static struct list *ospf_snmp_iflist;
 | 
						|
 | 
						|
struct ospf_snmp_if
 | 
						|
{
 | 
						|
  struct in_addr addr;
 | 
						|
  ifindex_t ifindex;
 | 
						|
  struct interface *ifp;
 | 
						|
};
 | 
						|
 | 
						|
static struct ospf_snmp_if *
 | 
						|
ospf_snmp_if_new (void)
 | 
						|
{
 | 
						|
  return XCALLOC (MTYPE_TMP, sizeof (struct ospf_snmp_if));
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
ospf_snmp_if_free (struct ospf_snmp_if *osif)
 | 
						|
{
 | 
						|
  XFREE (MTYPE_TMP, osif);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
ospf_snmp_if_delete (struct interface *ifp)
 | 
						|
{
 | 
						|
  struct listnode *node, *nnode;
 | 
						|
  struct ospf_snmp_if *osif;
 | 
						|
 | 
						|
  for (ALL_LIST_ELEMENTS (ospf_snmp_iflist, node, nnode, osif))
 | 
						|
    {
 | 
						|
      if (osif->ifp == ifp)
 | 
						|
	{
 | 
						|
	  list_delete_node (ospf_snmp_iflist, node);
 | 
						|
	  ospf_snmp_if_free (osif);
 | 
						|
	  return;
 | 
						|
	}
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
ospf_snmp_if_update (struct interface *ifp)
 | 
						|
{
 | 
						|
  struct listnode *node;
 | 
						|
  struct listnode *pn;
 | 
						|
  struct connected *ifc;
 | 
						|
  struct prefix *p;
 | 
						|
  struct ospf_snmp_if *osif;
 | 
						|
  struct in_addr *addr;
 | 
						|
  ifindex_t ifindex;
 | 
						|
 | 
						|
  ospf_snmp_if_delete (ifp);
 | 
						|
 | 
						|
  p = NULL;
 | 
						|
  addr = NULL;
 | 
						|
  ifindex = 0;
 | 
						|
 | 
						|
  /* Lookup first IPv4 address entry. */
 | 
						|
  for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc))
 | 
						|
    {
 | 
						|
      p = CONNECTED_ID(ifc);
 | 
						|
 | 
						|
      if (p->family == AF_INET)
 | 
						|
	{
 | 
						|
	  addr = &p->u.prefix4;
 | 
						|
	  break;
 | 
						|
	}
 | 
						|
    }
 | 
						|
  if (! addr)
 | 
						|
    ifindex = ifp->ifindex;
 | 
						|
 | 
						|
  /* Add interface to the list. */
 | 
						|
  pn = NULL;
 | 
						|
  for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, node, osif))
 | 
						|
    {
 | 
						|
      if (addr)
 | 
						|
	{
 | 
						|
	  /* Usual interfaces --> Sort them based on interface IPv4 addresses */
 | 
						|
	  if (ntohl (osif->addr.s_addr) > ntohl (addr->s_addr))
 | 
						|
	    break;
 | 
						|
	}
 | 
						|
      else
 | 
						|
	{
 | 
						|
	  /* Unnumbered interfaces --> Sort them based on interface indexes */
 | 
						|
	  if (osif->addr.s_addr != 0 || osif->ifindex > ifindex)
 | 
						|
	    break;
 | 
						|
	}
 | 
						|
      pn = node;
 | 
						|
    }
 | 
						|
 | 
						|
  osif = ospf_snmp_if_new ();
 | 
						|
  if (addr) /* Usual interface */
 | 
						|
  {
 | 
						|
    osif->addr = *addr;
 | 
						|
    
 | 
						|
    /* This field is used for storing ospfAddressLessIf OID value,
 | 
						|
     * conform to RFC1850 OSPF-MIB specification, it must be 0 for
 | 
						|
     * usual interface */
 | 
						|
    osif->ifindex = 0;
 | 
						|
  }
 | 
						|
  else  /* Unnumbered interface */
 | 
						|
    osif->ifindex = ifindex;
 | 
						|
  osif->ifp = ifp;
 | 
						|
 | 
						|
  listnode_add_after (ospf_snmp_iflist, pn, osif);
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ospf_snmp_is_if_have_addr (struct interface *ifp)
 | 
						|
{
 | 
						|
  struct listnode *nn;
 | 
						|
  struct connected *ifc;
 | 
						|
 | 
						|
  /* Is this interface having any connected IPv4 address ? */
 | 
						|
  for (ALL_LIST_ELEMENTS_RO (ifp->connected, nn, ifc))
 | 
						|
  {
 | 
						|
    if (CONNECTED_PREFIX(ifc)->family == AF_INET)
 | 
						|
      return 1;
 | 
						|
  }
 | 
						|
  
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
static struct ospf_interface *
 | 
						|
ospf_snmp_if_lookup (struct in_addr *ifaddr, ifindex_t *ifindex)
 | 
						|
{
 | 
						|
  struct listnode *node;
 | 
						|
  struct ospf_snmp_if *osif;
 | 
						|
  struct ospf_interface *oi = NULL;
 | 
						|
  struct ospf *ospf = ospf_lookup ();
 | 
						|
 | 
						|
  for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, node, osif))
 | 
						|
    {  
 | 
						|
      if (ifaddr->s_addr)
 | 
						|
        {
 | 
						|
	      if (IPV4_ADDR_SAME (&osif->addr, ifaddr))
 | 
						|
            oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
 | 
						|
        }
 | 
						|
      else
 | 
						|
        {
 | 
						|
	      if (osif->ifindex == *ifindex)
 | 
						|
            oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
 | 
						|
        }
 | 
						|
    }
 | 
						|
  return oi;
 | 
						|
}
 | 
						|
 | 
						|
static struct ospf_interface *
 | 
						|
ospf_snmp_if_lookup_next (struct in_addr *ifaddr, ifindex_t *ifindex,
 | 
						|
			  int ifaddr_next, ifindex_t ifindex_next)
 | 
						|
{
 | 
						|
  struct ospf_snmp_if *osif;
 | 
						|
  struct listnode *nn;
 | 
						|
  struct ospf *ospf = ospf_lookup ();
 | 
						|
  struct ospf_interface *oi = NULL;
 | 
						|
 | 
						|
  if (ospf == NULL)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  /* No instance is specified --> Return the first OSPF interface */
 | 
						|
  if (ifaddr_next)
 | 
						|
    {
 | 
						|
      for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, nn, osif))
 | 
						|
	{
 | 
						|
	  osif = listgetdata (nn);
 | 
						|
	  *ifaddr = osif->addr;
 | 
						|
	  *ifindex = osif->ifindex;
 | 
						|
          /* Because no instance is specified, we don't care about the kind of 
 | 
						|
           * interface (usual or unnumbered), just returning the first valid 
 | 
						|
           * OSPF interface */
 | 
						|
          oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
 | 
						|
          if (oi)
 | 
						|
            return (oi);
 | 
						|
	}
 | 
						|
      return NULL;
 | 
						|
    }
 | 
						|
 | 
						|
  /* An instance is specified --> Return the next OSPF interface */
 | 
						|
  for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, nn, osif))
 | 
						|
    {
 | 
						|
      /* Usual interface */
 | 
						|
      if (ifaddr->s_addr) 
 | 
						|
	{
 | 
						|
	  /* The interface must have valid AF_INET connected address */
 | 
						|
	  /* it must have lager IPv4 address value than the lookup entry */
 | 
						|
	  if ((ospf_snmp_is_if_have_addr(osif->ifp)) &&
 | 
						|
	      (ntohl (osif->addr.s_addr) > ntohl (ifaddr->s_addr)))
 | 
						|
	    {
 | 
						|
	      *ifaddr = osif->addr;
 | 
						|
	      *ifindex = osif->ifindex;
 | 
						|
        
 | 
						|
	      /* and it must be an OSPF interface */
 | 
						|
	      oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
 | 
						|
	      if (oi)
 | 
						|
		return oi;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
      /* Unnumbered interface */
 | 
						|
      else  
 | 
						|
        /* The interface must NOT have valid AF_INET connected address */
 | 
						|
        /* it must have lager interface index than the lookup entry */
 | 
						|
        if ((!ospf_snmp_is_if_have_addr(osif->ifp)) &&
 | 
						|
            (osif->ifindex > *ifindex))
 | 
						|
          {
 | 
						|
            *ifaddr = osif->addr;
 | 
						|
            *ifindex = osif->ifindex;
 | 
						|
        
 | 
						|
            /* and it must be an OSPF interface */
 | 
						|
            oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
 | 
						|
            if (oi)
 | 
						|
              return oi;
 | 
						|
          }
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
ospf_snmp_iftype (struct interface *ifp)
 | 
						|
{
 | 
						|
#define ospf_snmp_iftype_broadcast         1
 | 
						|
#define ospf_snmp_iftype_nbma              2
 | 
						|
#define ospf_snmp_iftype_pointToPoint      3
 | 
						|
#define ospf_snmp_iftype_pointToMultipoint 5
 | 
						|
  if (if_is_broadcast (ifp))
 | 
						|
    return ospf_snmp_iftype_broadcast;
 | 
						|
  if (if_is_pointopoint (ifp))
 | 
						|
    return ospf_snmp_iftype_pointToPoint;
 | 
						|
  return ospf_snmp_iftype_broadcast;
 | 
						|
}
 | 
						|
 | 
						|
static struct ospf_interface *
 | 
						|
ospfIfLookup (struct variable *v, oid *name, size_t *length,
 | 
						|
	      struct in_addr *ifaddr, ifindex_t *ifindex, int exact)
 | 
						|
{
 | 
						|
  unsigned int len;
 | 
						|
  int ifaddr_next = 0;
 | 
						|
  ifindex_t ifindex_next = 0;
 | 
						|
  struct ospf_interface *oi;
 | 
						|
  oid *offset;
 | 
						|
 | 
						|
  if (exact)
 | 
						|
    {
 | 
						|
      if (*length != v->namelen + IN_ADDR_SIZE + 1)
 | 
						|
	return NULL;
 | 
						|
 | 
						|
      oid2in_addr (name + v->namelen, IN_ADDR_SIZE, ifaddr);
 | 
						|
      *ifindex = name[v->namelen + IN_ADDR_SIZE];
 | 
						|
 | 
						|
      return ospf_snmp_if_lookup (ifaddr, ifindex);
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      len = *length - v->namelen;
 | 
						|
      if (len >= IN_ADDR_SIZE)
 | 
						|
	len = IN_ADDR_SIZE;
 | 
						|
      if (len <= 0)
 | 
						|
	ifaddr_next = 1;
 | 
						|
 | 
						|
      oid2in_addr (name + v->namelen, len, ifaddr);
 | 
						|
 | 
						|
      len = *length - v->namelen - IN_ADDR_SIZE;
 | 
						|
      if (len >= 1)
 | 
						|
	len = 1;
 | 
						|
      else
 | 
						|
	ifindex_next = 1;
 | 
						|
 | 
						|
      if (len == 1)
 | 
						|
	*ifindex = name[v->namelen + IN_ADDR_SIZE];
 | 
						|
 | 
						|
      oi = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next,
 | 
						|
				      ifindex_next);
 | 
						|
      if (oi)
 | 
						|
	{
 | 
						|
	  *length = v->namelen + IN_ADDR_SIZE + 1;
 | 
						|
	  offset = name + v->namelen;
 | 
						|
	  oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE);
 | 
						|
	  offset += IN_ADDR_SIZE;
 | 
						|
	  *offset = *ifindex;
 | 
						|
	  return oi;
 | 
						|
	}
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static u_char *
 | 
						|
ospfIfEntry (struct variable *v, oid *name, size_t *length, int exact,
 | 
						|
	     size_t *var_len, WriteMethod **write_method)
 | 
						|
{
 | 
						|
  ifindex_t ifindex;
 | 
						|
  struct in_addr ifaddr;
 | 
						|
  struct ospf_interface *oi;
 | 
						|
  struct ospf *ospf;
 | 
						|
 | 
						|
  if (smux_header_table(v, name, length, exact, var_len, write_method)
 | 
						|
      == MATCH_FAILED)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  ifindex = 0;
 | 
						|
  memset (&ifaddr, 0, sizeof (struct in_addr));
 | 
						|
 | 
						|
  /* Check OSPF instance. */
 | 
						|
  ospf = ospf_lookup ();
 | 
						|
  if (ospf == NULL)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  oi = ospfIfLookup (v, name, length, &ifaddr, &ifindex, exact);
 | 
						|
  if (oi == NULL)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  /* Return the current value of the variable */
 | 
						|
  switch (v->magic) 
 | 
						|
    {
 | 
						|
    case OSPFIFIPADDRESS:	/* 1 */
 | 
						|
      return SNMP_IPADDRESS (ifaddr);
 | 
						|
      break;
 | 
						|
    case OSPFADDRESSLESSIF:	/* 2 */
 | 
						|
      return SNMP_INTEGER (ifindex);
 | 
						|
      break;
 | 
						|
    case OSPFIFAREAID:		/* 3 */
 | 
						|
      if (oi->area)
 | 
						|
	return SNMP_IPADDRESS (oi->area->area_id);
 | 
						|
      else
 | 
						|
	return SNMP_IPADDRESS (ospf_empty_addr);
 | 
						|
      break;
 | 
						|
    case OSPFIFTYPE:		/* 4 */
 | 
						|
      return SNMP_INTEGER (ospf_snmp_iftype (oi->ifp));
 | 
						|
      break;
 | 
						|
    case OSPFIFADMINSTAT:	/* 5 */
 | 
						|
      if (oi)
 | 
						|
	return SNMP_INTEGER (OSPF_STATUS_ENABLED);
 | 
						|
      else
 | 
						|
	return SNMP_INTEGER (OSPF_STATUS_DISABLED);
 | 
						|
      break;
 | 
						|
    case OSPFIFRTRPRIORITY:	/* 6 */
 | 
						|
      return SNMP_INTEGER (PRIORITY (oi));
 | 
						|
      break;
 | 
						|
    case OSPFIFTRANSITDELAY:	/* 7 */
 | 
						|
      return SNMP_INTEGER (OSPF_IF_PARAM (oi, transmit_delay));
 | 
						|
      break;
 | 
						|
    case OSPFIFRETRANSINTERVAL:	/* 8 */
 | 
						|
      return SNMP_INTEGER (OSPF_IF_PARAM (oi, retransmit_interval));
 | 
						|
      break;
 | 
						|
    case OSPFIFHELLOINTERVAL:	/* 9 */
 | 
						|
      return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_hello));
 | 
						|
      break;
 | 
						|
    case OSPFIFRTRDEADINTERVAL:	/* 10 */
 | 
						|
      return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_wait));
 | 
						|
      break;
 | 
						|
    case OSPFIFPOLLINTERVAL:	/* 11 */
 | 
						|
      return SNMP_INTEGER (OSPF_POLL_INTERVAL_DEFAULT);
 | 
						|
      break;
 | 
						|
    case OSPFIFSTATE:		/* 12 */
 | 
						|
      return SNMP_INTEGER (ISM_SNMP(oi->state));
 | 
						|
      break;
 | 
						|
    case OSPFIFDESIGNATEDROUTER: /* 13 */
 | 
						|
      return SNMP_IPADDRESS (DR (oi));
 | 
						|
      break;
 | 
						|
    case OSPFIFBACKUPDESIGNATEDROUTER: /* 14 */
 | 
						|
      return SNMP_IPADDRESS (BDR (oi));
 | 
						|
      break;
 | 
						|
    case OSPFIFEVENTS:		/* 15 */
 | 
						|
      return SNMP_INTEGER (oi->state_change);
 | 
						|
      break;
 | 
						|
    case OSPFIFAUTHKEY:		/* 16 */
 | 
						|
      *var_len = 0;
 | 
						|
      return (u_char *) OSPF_IF_PARAM (oi, auth_simple);
 | 
						|
      break;
 | 
						|
    case OSPFIFSTATUS:		/* 17 */
 | 
						|
      return SNMP_INTEGER (SNMP_VALID);
 | 
						|
      break;
 | 
						|
    case OSPFIFMULTICASTFORWARDING: /* 18 */
 | 
						|
#define ospf_snmp_multiforward_blocked    1
 | 
						|
#define ospf_snmp_multiforward_multicast  2
 | 
						|
#define ospf_snmp_multiforward_unicast    3
 | 
						|
      return SNMP_INTEGER (ospf_snmp_multiforward_blocked);
 | 
						|
      break;
 | 
						|
    case OSPFIFDEMAND:		/* 19 */
 | 
						|
      return SNMP_INTEGER (SNMP_FALSE);
 | 
						|
      break;
 | 
						|
    case OSPFIFAUTHTYPE:	/* 20 */
 | 
						|
      if (oi->area)
 | 
						|
	return SNMP_INTEGER (oi->area->auth_type);
 | 
						|
      else
 | 
						|
	return SNMP_INTEGER (0);
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      return NULL;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
#define OSPF_SNMP_METRIC_VALUE 1
 | 
						|
 | 
						|
static struct ospf_interface *
 | 
						|
ospfIfMetricLookup (struct variable *v, oid *name, size_t *length,
 | 
						|
		    struct in_addr *ifaddr, ifindex_t *ifindex, int exact)
 | 
						|
{
 | 
						|
  unsigned int len;
 | 
						|
  int ifaddr_next = 0;
 | 
						|
  ifindex_t ifindex_next = 0;
 | 
						|
  struct ospf_interface *oi;
 | 
						|
  oid *offset;
 | 
						|
  int metric;
 | 
						|
 | 
						|
  if (exact)
 | 
						|
    {
 | 
						|
      if (*length != v->namelen + IN_ADDR_SIZE + 1 + 1)
 | 
						|
	return NULL;
 | 
						|
 | 
						|
      oid2in_addr (name + v->namelen, IN_ADDR_SIZE, ifaddr);
 | 
						|
      *ifindex = name[v->namelen + IN_ADDR_SIZE];
 | 
						|
      metric = name[v->namelen + IN_ADDR_SIZE + 1];
 | 
						|
 | 
						|
      if (metric != OSPF_SNMP_METRIC_VALUE)
 | 
						|
	return NULL;
 | 
						|
 | 
						|
      return ospf_snmp_if_lookup (ifaddr, ifindex);
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      len = *length - v->namelen;
 | 
						|
      if (len >= IN_ADDR_SIZE)
 | 
						|
	len = IN_ADDR_SIZE;
 | 
						|
      else
 | 
						|
	ifaddr_next = 1;
 | 
						|
 | 
						|
      oid2in_addr (name + v->namelen, len, ifaddr);
 | 
						|
 | 
						|
      len = *length - v->namelen - IN_ADDR_SIZE;
 | 
						|
      if (len >= 1)
 | 
						|
	len = 1;
 | 
						|
      else
 | 
						|
	ifindex_next = 1;
 | 
						|
 | 
						|
      if (len == 1)
 | 
						|
	*ifindex = name[v->namelen + IN_ADDR_SIZE];
 | 
						|
 | 
						|
      oi = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next,
 | 
						|
				      ifindex_next);
 | 
						|
      if (oi)
 | 
						|
	{
 | 
						|
	  *length = v->namelen + IN_ADDR_SIZE + 1 + 1;
 | 
						|
	  offset = name + v->namelen;
 | 
						|
	  oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE);
 | 
						|
	  offset += IN_ADDR_SIZE;
 | 
						|
	  *offset = *ifindex;
 | 
						|
	  offset++;
 | 
						|
	  *offset = OSPF_SNMP_METRIC_VALUE;
 | 
						|
	  return oi;
 | 
						|
	}
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static u_char *
 | 
						|
ospfIfMetricEntry (struct variable *v, oid *name, size_t *length, int exact,
 | 
						|
		   size_t *var_len, WriteMethod **write_method)
 | 
						|
{
 | 
						|
  /* Currently we support metric 1 only. */
 | 
						|
  ifindex_t ifindex;
 | 
						|
  struct in_addr ifaddr;
 | 
						|
  struct ospf_interface *oi;
 | 
						|
  struct ospf *ospf;
 | 
						|
 | 
						|
  if (smux_header_table(v, name, length, exact, var_len, write_method)
 | 
						|
      == MATCH_FAILED)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  ifindex = 0;
 | 
						|
  memset (&ifaddr, 0, sizeof (struct in_addr));
 | 
						|
 | 
						|
  /* Check OSPF instance. */
 | 
						|
  ospf = ospf_lookup ();
 | 
						|
  if (ospf == NULL)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  oi = ospfIfMetricLookup (v, name, length, &ifaddr, &ifindex, exact);
 | 
						|
  if (oi == NULL)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  /* Return the current value of the variable */
 | 
						|
  switch (v->magic) 
 | 
						|
    {
 | 
						|
    case OSPFIFMETRICIPADDRESS:
 | 
						|
      return SNMP_IPADDRESS (ifaddr);
 | 
						|
      break;
 | 
						|
    case OSPFIFMETRICADDRESSLESSIF:
 | 
						|
      return SNMP_INTEGER (ifindex);
 | 
						|
      break;
 | 
						|
    case OSPFIFMETRICTOS:
 | 
						|
      return SNMP_INTEGER (0);
 | 
						|
      break;
 | 
						|
    case OSPFIFMETRICVALUE:
 | 
						|
      return SNMP_INTEGER (OSPF_SNMP_METRIC_VALUE);
 | 
						|
      break;
 | 
						|
    case OSPFIFMETRICSTATUS:
 | 
						|
      return SNMP_INTEGER (1);
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      return NULL;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static struct route_table *ospf_snmp_vl_table;
 | 
						|
 | 
						|
void
 | 
						|
ospf_snmp_vl_add (struct ospf_vl_data *vl_data)
 | 
						|
{
 | 
						|
  struct prefix_ls lp;
 | 
						|
  struct route_node *rn;
 | 
						|
 | 
						|
  memset (&lp, 0, sizeof (struct prefix_ls));
 | 
						|
  lp.family = 0;
 | 
						|
  lp.prefixlen = 64;
 | 
						|
  lp.id = vl_data->vl_area_id;
 | 
						|
  lp.adv_router = vl_data->vl_peer;
 | 
						|
 | 
						|
  rn = route_node_get (ospf_snmp_vl_table, (struct prefix *) &lp);
 | 
						|
  if (rn->info)
 | 
						|
    route_unlock_node (rn);
 | 
						|
 | 
						|
  rn->info = vl_data;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
ospf_snmp_vl_delete (struct ospf_vl_data *vl_data)
 | 
						|
{
 | 
						|
  struct prefix_ls lp;
 | 
						|
  struct route_node *rn;
 | 
						|
 | 
						|
  memset (&lp, 0, sizeof (struct prefix_ls));
 | 
						|
  lp.family = 0;
 | 
						|
  lp.prefixlen = 64;
 | 
						|
  lp.id = vl_data->vl_area_id;
 | 
						|
  lp.adv_router = vl_data->vl_peer;
 | 
						|
 | 
						|
  rn = route_node_lookup (ospf_snmp_vl_table, (struct prefix *) &lp);
 | 
						|
  if (! rn)
 | 
						|
    return;
 | 
						|
  rn->info = NULL;
 | 
						|
  route_unlock_node (rn);
 | 
						|
  route_unlock_node (rn);
 | 
						|
}
 | 
						|
 | 
						|
static struct ospf_vl_data *
 | 
						|
ospf_snmp_vl_lookup (struct in_addr *area_id, struct in_addr *neighbor)
 | 
						|
{
 | 
						|
  struct prefix_ls lp;
 | 
						|
  struct route_node *rn;
 | 
						|
  struct ospf_vl_data *vl_data;
 | 
						|
 | 
						|
  memset (&lp, 0, sizeof (struct prefix_ls));
 | 
						|
  lp.family = 0;
 | 
						|
  lp.prefixlen = 64;
 | 
						|
  lp.id = *area_id;
 | 
						|
  lp.adv_router = *neighbor;
 | 
						|
 | 
						|
  rn = route_node_lookup (ospf_snmp_vl_table, (struct prefix *) &lp);
 | 
						|
  if (rn)
 | 
						|
    {
 | 
						|
      vl_data = rn->info;
 | 
						|
      route_unlock_node (rn);
 | 
						|
      return vl_data;
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static struct ospf_vl_data *
 | 
						|
ospf_snmp_vl_lookup_next (struct in_addr *area_id, struct in_addr *neighbor,
 | 
						|
			  int first)
 | 
						|
{
 | 
						|
  struct prefix_ls lp;
 | 
						|
  struct route_node *rn;
 | 
						|
  struct ospf_vl_data *vl_data;
 | 
						|
 | 
						|
  memset (&lp, 0, sizeof (struct prefix_ls));
 | 
						|
  lp.family = 0;
 | 
						|
  lp.prefixlen = 64;
 | 
						|
  lp.id = *area_id;
 | 
						|
  lp.adv_router = *neighbor;
 | 
						|
 | 
						|
  if (first)
 | 
						|
    rn = route_top (ospf_snmp_vl_table);
 | 
						|
  else
 | 
						|
    {
 | 
						|
      rn = route_node_get (ospf_snmp_vl_table, (struct prefix *) &lp);
 | 
						|
      rn = route_next (rn);
 | 
						|
    }
 | 
						|
 | 
						|
  for (; rn; rn = route_next (rn))
 | 
						|
    if (rn->info)
 | 
						|
      break;
 | 
						|
 | 
						|
  if (rn && rn->info)
 | 
						|
    {
 | 
						|
      vl_data = rn->info;
 | 
						|
      *area_id = vl_data->vl_area_id;
 | 
						|
      *neighbor = vl_data->vl_peer;
 | 
						|
      route_unlock_node (rn);
 | 
						|
      return vl_data;
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static struct ospf_vl_data *
 | 
						|
ospfVirtIfLookup (struct variable *v, oid *name, size_t *length,
 | 
						|
		  struct in_addr *area_id, struct in_addr *neighbor, int exact)
 | 
						|
{
 | 
						|
  int first;
 | 
						|
  unsigned int len;
 | 
						|
  struct ospf_vl_data *vl_data;
 | 
						|
 | 
						|
  if (exact)
 | 
						|
    {
 | 
						|
      if (*length != v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE)
 | 
						|
	return NULL;
 | 
						|
 | 
						|
      oid2in_addr (name + v->namelen, IN_ADDR_SIZE, area_id);
 | 
						|
      oid2in_addr (name + v->namelen + IN_ADDR_SIZE, IN_ADDR_SIZE, neighbor);
 | 
						|
 | 
						|
      return ospf_snmp_vl_lookup (area_id, neighbor);
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      first = 0;
 | 
						|
 | 
						|
      len = *length - v->namelen;
 | 
						|
      if (len <= 0)
 | 
						|
	first = 1;
 | 
						|
      if (len > IN_ADDR_SIZE)
 | 
						|
	len = IN_ADDR_SIZE;
 | 
						|
      oid2in_addr (name + v->namelen, len, area_id);
 | 
						|
 | 
						|
      len = *length - v->namelen - IN_ADDR_SIZE;
 | 
						|
      if (len > IN_ADDR_SIZE)
 | 
						|
	len = IN_ADDR_SIZE;
 | 
						|
      oid2in_addr (name + v->namelen + IN_ADDR_SIZE, len, neighbor);
 | 
						|
 | 
						|
      vl_data = ospf_snmp_vl_lookup_next (area_id, neighbor, first);
 | 
						|
 | 
						|
      if (vl_data)
 | 
						|
	{
 | 
						|
	  *length = v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE;
 | 
						|
	  oid_copy_addr (name + v->namelen, area_id, IN_ADDR_SIZE);
 | 
						|
	  oid_copy_addr (name + v->namelen + IN_ADDR_SIZE, neighbor,
 | 
						|
			 IN_ADDR_SIZE);
 | 
						|
	  return vl_data;
 | 
						|
	}
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static u_char *
 | 
						|
ospfVirtIfEntry (struct variable *v, oid *name, size_t *length, int exact,
 | 
						|
		 size_t *var_len, WriteMethod **write_method)
 | 
						|
{
 | 
						|
  struct ospf_vl_data *vl_data;
 | 
						|
  struct ospf_interface *oi;
 | 
						|
  struct in_addr area_id;
 | 
						|
  struct in_addr neighbor;
 | 
						|
 | 
						|
  if (smux_header_table(v, name, length, exact, var_len, write_method)
 | 
						|
      == MATCH_FAILED)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  memset (&area_id, 0, sizeof (struct in_addr));
 | 
						|
  memset (&neighbor, 0, sizeof (struct in_addr));
 | 
						|
 | 
						|
  vl_data = ospfVirtIfLookup (v, name, length, &area_id, &neighbor, exact);
 | 
						|
  if (! vl_data)
 | 
						|
    return NULL;
 | 
						|
  oi = vl_data->vl_oi;
 | 
						|
  if (! oi)
 | 
						|
    return NULL;
 | 
						|
  
 | 
						|
  /* Return the current value of the variable */
 | 
						|
  switch (v->magic) 
 | 
						|
    {
 | 
						|
    case OSPFVIRTIFAREAID:
 | 
						|
      return SNMP_IPADDRESS (area_id);
 | 
						|
      break;
 | 
						|
    case OSPFVIRTIFNEIGHBOR:
 | 
						|
      return SNMP_IPADDRESS (neighbor);
 | 
						|
      break;
 | 
						|
    case OSPFVIRTIFTRANSITDELAY:
 | 
						|
      return SNMP_INTEGER (OSPF_IF_PARAM (oi, transmit_delay));
 | 
						|
      break;
 | 
						|
    case OSPFVIRTIFRETRANSINTERVAL:
 | 
						|
      return SNMP_INTEGER (OSPF_IF_PARAM (oi, retransmit_interval));
 | 
						|
      break;
 | 
						|
    case OSPFVIRTIFHELLOINTERVAL:
 | 
						|
      return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_hello));
 | 
						|
      break;
 | 
						|
    case OSPFVIRTIFRTRDEADINTERVAL:
 | 
						|
      return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_wait));
 | 
						|
      break;
 | 
						|
    case OSPFVIRTIFSTATE:
 | 
						|
      return SNMP_INTEGER (oi->state);
 | 
						|
      break;
 | 
						|
    case OSPFVIRTIFEVENTS:
 | 
						|
      return SNMP_INTEGER (oi->state_change);
 | 
						|
      break;
 | 
						|
    case OSPFVIRTIFAUTHKEY:
 | 
						|
      *var_len = 0;
 | 
						|
      return (u_char *) OSPF_IF_PARAM (oi, auth_simple);
 | 
						|
      break;
 | 
						|
    case OSPFVIRTIFSTATUS:
 | 
						|
      return SNMP_INTEGER (SNMP_VALID);
 | 
						|
      break;
 | 
						|
    case OSPFVIRTIFAUTHTYPE:
 | 
						|
      if (oi->area)
 | 
						|
	return SNMP_INTEGER (oi->area->auth_type);
 | 
						|
      else
 | 
						|
	return SNMP_INTEGER (0);
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      return NULL;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static struct ospf_neighbor *
 | 
						|
ospf_snmp_nbr_lookup (struct ospf *ospf, struct in_addr *nbr_addr,
 | 
						|
		      ifindex_t *ifindex)
 | 
						|
{
 | 
						|
  struct listnode *node, *nnode;
 | 
						|
  struct ospf_interface *oi;
 | 
						|
  struct ospf_neighbor *nbr;
 | 
						|
  struct route_node *rn;
 | 
						|
 | 
						|
  for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
 | 
						|
    {
 | 
						|
      for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
 | 
						|
	if ((nbr = rn->info) != NULL
 | 
						|
	    && nbr != oi->nbr_self
 | 
						|
/* If EXACT match is needed, provide ALL entry found
 | 
						|
	    && nbr->state != NSM_Down
 | 
						|
 */
 | 
						|
	    && nbr->src.s_addr != 0)
 | 
						|
	  {
 | 
						|
	    if (IPV4_ADDR_SAME (&nbr->src, nbr_addr))
 | 
						|
	      {
 | 
						|
		route_unlock_node (rn);
 | 
						|
		return nbr;
 | 
						|
	      }
 | 
						|
	  }
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static struct ospf_neighbor *
 | 
						|
ospf_snmp_nbr_lookup_next (struct in_addr *nbr_addr, ifindex_t *ifindex,
 | 
						|
			   int first)
 | 
						|
{
 | 
						|
  struct listnode *nn;
 | 
						|
  struct ospf_interface *oi;
 | 
						|
  struct ospf_neighbor *nbr;
 | 
						|
  struct route_node *rn;
 | 
						|
  struct ospf_neighbor *min = NULL;
 | 
						|
  struct ospf *ospf = ospf;
 | 
						|
 | 
						|
  ospf = ospf_lookup ();
 | 
						|
 | 
						|
  for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, nn, oi))
 | 
						|
    {
 | 
						|
      for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
 | 
						|
	if ((nbr = rn->info) != NULL
 | 
						|
	    && nbr != oi->nbr_self
 | 
						|
	    && nbr->state != NSM_Down
 | 
						|
	    && nbr->src.s_addr != 0)
 | 
						|
	  {
 | 
						|
	    if (first)
 | 
						|
	      {
 | 
						|
		if (! min)
 | 
						|
		  min = nbr;
 | 
						|
		else if (ntohl (nbr->src.s_addr) < ntohl (min->src.s_addr))
 | 
						|
		  min = nbr;
 | 
						|
	      }
 | 
						|
	    else if (ntohl (nbr->src.s_addr) > ntohl (nbr_addr->s_addr))
 | 
						|
	      {
 | 
						|
		if (! min)
 | 
						|
		  min = nbr;
 | 
						|
		else if (ntohl (nbr->src.s_addr) < ntohl (min->src.s_addr))
 | 
						|
		  min = nbr;
 | 
						|
	      }
 | 
						|
	  }
 | 
						|
    }
 | 
						|
  if (min)
 | 
						|
    {
 | 
						|
      *nbr_addr = min->src;
 | 
						|
      *ifindex = 0;
 | 
						|
      return min;
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static struct ospf_neighbor *
 | 
						|
ospfNbrLookup (struct variable *v, oid *name, size_t *length,
 | 
						|
	       struct in_addr *nbr_addr, ifindex_t *ifindex, int exact)
 | 
						|
{
 | 
						|
  unsigned int len;
 | 
						|
  int first;
 | 
						|
  struct ospf_neighbor *nbr;
 | 
						|
  struct ospf *ospf;
 | 
						|
 | 
						|
  ospf = ospf_lookup ();
 | 
						|
 | 
						|
  if (! ospf)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  if (exact)
 | 
						|
    {
 | 
						|
      if (*length != v->namelen + IN_ADDR_SIZE + 1)
 | 
						|
	return NULL;
 | 
						|
 | 
						|
      oid2in_addr (name + v->namelen, IN_ADDR_SIZE, nbr_addr);
 | 
						|
      *ifindex = name[v->namelen + IN_ADDR_SIZE];
 | 
						|
 | 
						|
      return ospf_snmp_nbr_lookup (ospf, nbr_addr, ifindex);
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      first = 0;
 | 
						|
      len = *length - v->namelen;
 | 
						|
 | 
						|
      if (len <= 0)
 | 
						|
	first = 1;
 | 
						|
 | 
						|
      if (len > IN_ADDR_SIZE)
 | 
						|
	len = IN_ADDR_SIZE;
 | 
						|
 | 
						|
      oid2in_addr (name + v->namelen, len, nbr_addr);
 | 
						|
 | 
						|
      len = *length - v->namelen - IN_ADDR_SIZE;
 | 
						|
      if (len >= 1)
 | 
						|
	*ifindex = name[v->namelen + IN_ADDR_SIZE];
 | 
						|
      
 | 
						|
      nbr = ospf_snmp_nbr_lookup_next (nbr_addr, ifindex, first);
 | 
						|
 | 
						|
      if (nbr)
 | 
						|
	{
 | 
						|
	  *length = v->namelen + IN_ADDR_SIZE + 1;
 | 
						|
	  oid_copy_addr (name + v->namelen, nbr_addr, IN_ADDR_SIZE);
 | 
						|
	  name[v->namelen + IN_ADDR_SIZE] = *ifindex;
 | 
						|
	  return nbr;
 | 
						|
	}
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
/* map internal quagga neighbor states to official MIB values:
 | 
						|
 | 
						|
ospfNbrState OBJECT-TYPE
 | 
						|
        SYNTAX   INTEGER    {
 | 
						|
                    down (1),
 | 
						|
                    attempt (2),
 | 
						|
                    init (3),
 | 
						|
                    twoWay (4),
 | 
						|
                    exchangeStart (5),
 | 
						|
                    exchange (6),
 | 
						|
                    loading (7),
 | 
						|
                    full (8)
 | 
						|
                  }
 | 
						|
*/
 | 
						|
static int32_t
 | 
						|
ospf_snmp_neighbor_state(u_char nst)
 | 
						|
{
 | 
						|
  switch (nst)
 | 
						|
    {
 | 
						|
    case NSM_Attempt:
 | 
						|
      return 2;
 | 
						|
    case NSM_Init:
 | 
						|
      return 3;
 | 
						|
    case NSM_TwoWay:
 | 
						|
      return 4;
 | 
						|
    case NSM_ExStart:
 | 
						|
      return 5;
 | 
						|
    case NSM_Exchange:
 | 
						|
      return 6;
 | 
						|
    case NSM_Loading:
 | 
						|
      return 7;
 | 
						|
    case NSM_Full:
 | 
						|
      return 8;
 | 
						|
    default:
 | 
						|
      return 1; /* down */
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static u_char *
 | 
						|
ospfNbrEntry (struct variable *v, oid *name, size_t *length, int exact,
 | 
						|
	      size_t *var_len, WriteMethod **write_method)
 | 
						|
{
 | 
						|
  struct in_addr nbr_addr;
 | 
						|
  ifindex_t ifindex;
 | 
						|
  struct ospf_neighbor *nbr;
 | 
						|
  struct ospf_interface *oi;
 | 
						|
 | 
						|
  if (smux_header_table(v, name, length, exact, var_len, write_method)
 | 
						|
      == MATCH_FAILED)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  memset (&nbr_addr, 0, sizeof (struct in_addr));
 | 
						|
  ifindex = 0;
 | 
						|
  
 | 
						|
  nbr = ospfNbrLookup (v, name, length, &nbr_addr, &ifindex, exact);
 | 
						|
  if (! nbr)
 | 
						|
    return NULL;
 | 
						|
  oi = nbr->oi;
 | 
						|
  if (! oi)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  /* Return the current value of the variable */
 | 
						|
  switch (v->magic) 
 | 
						|
    {
 | 
						|
    case OSPFNBRIPADDR:
 | 
						|
      return SNMP_IPADDRESS (nbr_addr);
 | 
						|
      break;
 | 
						|
    case OSPFNBRADDRESSLESSINDEX:
 | 
						|
      return SNMP_INTEGER (ifindex);
 | 
						|
      break;
 | 
						|
    case OSPFNBRRTRID:
 | 
						|
      return SNMP_IPADDRESS (nbr->router_id);
 | 
						|
      break;
 | 
						|
    case OSPFNBROPTIONS:
 | 
						|
      return SNMP_INTEGER (oi->nbr_self->options);
 | 
						|
      break;
 | 
						|
    case OSPFNBRPRIORITY:
 | 
						|
      return SNMP_INTEGER (nbr->priority);
 | 
						|
      break;
 | 
						|
    case OSPFNBRSTATE:
 | 
						|
      return SNMP_INTEGER (ospf_snmp_neighbor_state(nbr->state));
 | 
						|
      break;
 | 
						|
    case OSPFNBREVENTS:
 | 
						|
      return SNMP_INTEGER (nbr->state_change);
 | 
						|
      break;
 | 
						|
    case OSPFNBRLSRETRANSQLEN:
 | 
						|
      return SNMP_INTEGER (ospf_ls_retransmit_count (nbr));
 | 
						|
      break;
 | 
						|
    case OSPFNBMANBRSTATUS:
 | 
						|
      return SNMP_INTEGER (SNMP_VALID);
 | 
						|
      break;
 | 
						|
    case OSPFNBMANBRPERMANENCE:
 | 
						|
      return SNMP_INTEGER (2);
 | 
						|
      break;
 | 
						|
    case OSPFNBRHELLOSUPPRESSED:
 | 
						|
      return SNMP_INTEGER (SNMP_FALSE);
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      return NULL;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static u_char *
 | 
						|
ospfVirtNbrEntry (struct variable *v, oid *name, size_t *length, int exact,
 | 
						|
		  size_t *var_len, WriteMethod **write_method)
 | 
						|
{
 | 
						|
  struct ospf_vl_data *vl_data;
 | 
						|
  struct in_addr area_id;
 | 
						|
  struct in_addr neighbor;
 | 
						|
  struct ospf *ospf;
 | 
						|
 | 
						|
  if (smux_header_table(v, name, length, exact, var_len, write_method)
 | 
						|
      == MATCH_FAILED)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  memset (&area_id, 0, sizeof (struct in_addr));
 | 
						|
  memset (&neighbor, 0, sizeof (struct in_addr));
 | 
						|
 | 
						|
  /* Check OSPF instance. */
 | 
						|
  ospf = ospf_lookup ();
 | 
						|
  if (ospf == NULL)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  vl_data = ospfVirtIfLookup (v, name, length, &area_id, &neighbor, exact);
 | 
						|
  if (! vl_data)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  /* Return the current value of the variable */
 | 
						|
  switch (v->magic) 
 | 
						|
    {
 | 
						|
    case OSPFVIRTNBRAREA:
 | 
						|
      return (u_char *) NULL;
 | 
						|
      break;
 | 
						|
    case OSPFVIRTNBRRTRID:
 | 
						|
      return (u_char *) NULL;
 | 
						|
      break;
 | 
						|
    case OSPFVIRTNBRIPADDR:
 | 
						|
      return (u_char *) NULL;
 | 
						|
      break;
 | 
						|
    case OSPFVIRTNBROPTIONS:
 | 
						|
      return (u_char *) NULL;
 | 
						|
      break;
 | 
						|
    case OSPFVIRTNBRSTATE:
 | 
						|
      return (u_char *) NULL;
 | 
						|
      break;
 | 
						|
    case OSPFVIRTNBREVENTS:
 | 
						|
      return (u_char *) NULL;
 | 
						|
      break;
 | 
						|
    case OSPFVIRTNBRLSRETRANSQLEN:
 | 
						|
      return (u_char *) NULL;
 | 
						|
      break;
 | 
						|
    case OSPFVIRTNBRHELLOSUPPRESSED:
 | 
						|
      return (u_char *) NULL;
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      return NULL;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static struct ospf_lsa *
 | 
						|
ospfExtLsdbLookup (struct variable *v, oid *name, size_t *length, u_char *type,
 | 
						|
		   struct in_addr *ls_id, struct in_addr *router_id, int exact)
 | 
						|
{
 | 
						|
  int first;
 | 
						|
  oid *offset;
 | 
						|
  int offsetlen;
 | 
						|
  u_char lsa_type;
 | 
						|
  unsigned int len;
 | 
						|
  struct ospf_lsa *lsa;
 | 
						|
  struct ospf *ospf;
 | 
						|
 | 
						|
  ospf = ospf_lookup ();
 | 
						|
  if (exact)
 | 
						|
    {
 | 
						|
      if (*length != v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
 | 
						|
	return NULL;
 | 
						|
      
 | 
						|
      offset = name + v->namelen;
 | 
						|
 | 
						|
      /* Make it sure given value match to type. */
 | 
						|
      lsa_type = *offset;
 | 
						|
      offset++;
 | 
						|
 | 
						|
      if (lsa_type != *type)
 | 
						|
	return NULL;
 | 
						|
      
 | 
						|
      /* LS ID. */
 | 
						|
      oid2in_addr (offset, IN_ADDR_SIZE, ls_id);
 | 
						|
      offset += IN_ADDR_SIZE;
 | 
						|
 | 
						|
      /* Router ID. */
 | 
						|
      oid2in_addr (offset, IN_ADDR_SIZE, router_id);
 | 
						|
 | 
						|
      return ospf_lsdb_lookup_by_id (ospf->lsdb, *type, *ls_id, *router_id);
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      /* Get variable length. */
 | 
						|
      first = 0;
 | 
						|
      offset = name + v->namelen;
 | 
						|
      offsetlen = *length - v->namelen;
 | 
						|
 | 
						|
      /* LSA type value. */
 | 
						|
      lsa_type = *offset;
 | 
						|
      offset++;
 | 
						|
      offsetlen--;
 | 
						|
 | 
						|
      if (offsetlen <= 0 || lsa_type < OSPF_AS_EXTERNAL_LSA)
 | 
						|
	first = 1;
 | 
						|
 | 
						|
      /* LS ID. */
 | 
						|
      len = offsetlen;
 | 
						|
      if (len > IN_ADDR_SIZE)
 | 
						|
	len = IN_ADDR_SIZE;
 | 
						|
 | 
						|
      oid2in_addr (offset, len, ls_id);
 | 
						|
 | 
						|
      offset += IN_ADDR_SIZE;
 | 
						|
      offsetlen -= IN_ADDR_SIZE;
 | 
						|
 | 
						|
      /* Router ID. */
 | 
						|
      len = offsetlen;
 | 
						|
      if (len > IN_ADDR_SIZE)
 | 
						|
	len = IN_ADDR_SIZE;
 | 
						|
 | 
						|
      oid2in_addr (offset, len, router_id);
 | 
						|
 | 
						|
      lsa = ospf_lsdb_lookup_by_id_next (ospf->lsdb, *type, *ls_id,
 | 
						|
					*router_id, first);
 | 
						|
 | 
						|
      if (lsa)
 | 
						|
	{
 | 
						|
	  /* Fill in length. */
 | 
						|
	  *length = v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE;
 | 
						|
 | 
						|
	  /* Fill in value. */
 | 
						|
	  offset = name + v->namelen;
 | 
						|
 | 
						|
	  *offset = OSPF_AS_EXTERNAL_LSA;
 | 
						|
	  offset++;
 | 
						|
	  oid_copy_addr (offset, &lsa->data->id, IN_ADDR_SIZE);
 | 
						|
	  offset += IN_ADDR_SIZE;
 | 
						|
	  oid_copy_addr (offset, &lsa->data->adv_router, IN_ADDR_SIZE);
 | 
						|
	    
 | 
						|
	  return lsa;
 | 
						|
	}
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static u_char *
 | 
						|
ospfExtLsdbEntry (struct variable *v, oid *name, size_t *length, int exact,
 | 
						|
		  size_t *var_len, WriteMethod **write_method)
 | 
						|
{
 | 
						|
  struct ospf_lsa *lsa;
 | 
						|
  struct lsa_header *lsah;
 | 
						|
  u_char type;
 | 
						|
  struct in_addr ls_id;
 | 
						|
  struct in_addr router_id;
 | 
						|
  struct ospf *ospf;
 | 
						|
 | 
						|
  if (smux_header_table(v, name, length, exact, var_len, write_method)
 | 
						|
      == MATCH_FAILED)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  type = OSPF_AS_EXTERNAL_LSA;
 | 
						|
  memset (&ls_id, 0, sizeof (struct in_addr));
 | 
						|
  memset (&router_id, 0, sizeof (struct in_addr));
 | 
						|
 | 
						|
  /* Check OSPF instance. */
 | 
						|
  ospf = ospf_lookup ();
 | 
						|
  if (ospf == NULL)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  lsa = ospfExtLsdbLookup (v, name, length, &type, &ls_id, &router_id, exact);
 | 
						|
  if (! lsa)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  lsah = lsa->data;
 | 
						|
 | 
						|
  /* Return the current value of the variable */
 | 
						|
  switch (v->magic) 
 | 
						|
    {
 | 
						|
    case OSPFEXTLSDBTYPE:
 | 
						|
      return SNMP_INTEGER (OSPF_AS_EXTERNAL_LSA);
 | 
						|
      break;
 | 
						|
    case OSPFEXTLSDBLSID:
 | 
						|
      return SNMP_IPADDRESS (lsah->id);
 | 
						|
      break;
 | 
						|
    case OSPFEXTLSDBROUTERID:
 | 
						|
      return SNMP_IPADDRESS (lsah->adv_router);
 | 
						|
      break;
 | 
						|
    case OSPFEXTLSDBSEQUENCE:
 | 
						|
      return SNMP_INTEGER (lsah->ls_seqnum);
 | 
						|
      break;
 | 
						|
    case OSPFEXTLSDBAGE:
 | 
						|
      return SNMP_INTEGER (lsah->ls_age);
 | 
						|
      break;
 | 
						|
    case OSPFEXTLSDBCHECKSUM:
 | 
						|
      return SNMP_INTEGER (lsah->checksum);
 | 
						|
      break;
 | 
						|
    case OSPFEXTLSDBADVERTISEMENT:
 | 
						|
      *var_len = ntohs (lsah->length);
 | 
						|
      return (u_char *) lsah;
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      return NULL;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
static u_char *
 | 
						|
ospfAreaAggregateEntry (struct variable *v, oid *name, size_t *length,
 | 
						|
			int exact, size_t *var_len, WriteMethod **write_method)
 | 
						|
{
 | 
						|
  if (smux_header_table(v, name, length, exact, var_len, write_method)
 | 
						|
      == MATCH_FAILED)
 | 
						|
    return NULL;
 | 
						|
 | 
						|
  /* Return the current value of the variable */
 | 
						|
  switch (v->magic) 
 | 
						|
    {
 | 
						|
    case OSPFAREAAGGREGATEAREAID:
 | 
						|
      return (u_char *) NULL;
 | 
						|
      break;
 | 
						|
    case OSPFAREAAGGREGATELSDBTYPE:
 | 
						|
      return (u_char *) NULL;
 | 
						|
      break;
 | 
						|
    case OSPFAREAAGGREGATENET:
 | 
						|
      return (u_char *) NULL;
 | 
						|
      break;
 | 
						|
    case OSPFAREAAGGREGATEMASK:
 | 
						|
      return (u_char *) NULL;
 | 
						|
      break;
 | 
						|
    case OSPFAREAAGGREGATESTATUS:
 | 
						|
      return (u_char *) NULL;
 | 
						|
      break;
 | 
						|
    case OSPFAREAAGGREGATEEFFECT:
 | 
						|
      return (u_char *) NULL;
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      return NULL;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  return NULL;
 | 
						|
}
 | 
						|
 | 
						|
/* OSPF Traps. */
 | 
						|
#define IFSTATECHANGE      16
 | 
						|
#define VIRTIFSTATECHANGE   1
 | 
						|
#define NBRSTATECHANGE      2
 | 
						|
#define VIRTNBRSTATECHANGE  3
 | 
						|
 | 
						|
static struct trap_object ospfNbrTrapList[] =
 | 
						|
{
 | 
						|
  {-2, {1, OSPFROUTERID}},
 | 
						|
  {3, {10, 1, OSPFNBRIPADDR}},
 | 
						|
  {3, {10, 1, OSPFNBRRTRID}},
 | 
						|
  {3, {10, 1, OSPFNBRSTATE}}
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
static struct trap_object ospfVirtNbrTrapList[] =
 | 
						|
{
 | 
						|
  {-2, {1, 1}},
 | 
						|
  {3, {11, 1, OSPFVIRTNBRAREA}},
 | 
						|
  {3, {11, 1, OSPFVIRTNBRRTRID}},
 | 
						|
  {3, {11, 1, OSPFVIRTNBRSTATE}}
 | 
						|
};
 | 
						|
 | 
						|
static struct trap_object ospfIfTrapList[] =
 | 
						|
{
 | 
						|
  {-2, {1, OSPFROUTERID}},
 | 
						|
  {3, {7, 1, OSPFIFIPADDRESS}},
 | 
						|
  {3, {7, 1, OSPFADDRESSLESSIF}},
 | 
						|
  {3, {7, 1, OSPFIFSTATE}}
 | 
						|
};
 | 
						|
 | 
						|
static struct trap_object ospfVirtIfTrapList[] =
 | 
						|
{
 | 
						|
  {-2, {1, OSPFROUTERID}},
 | 
						|
  {3, {9, 1, OSPFVIRTIFAREAID}},
 | 
						|
  {3, {9, 1, OSPFVIRTIFNEIGHBOR}},
 | 
						|
  {3, {9, 1, OSPFVIRTIFSTATE}}
 | 
						|
};
 | 
						|
 | 
						|
void
 | 
						|
ospfTrapNbrStateChange (struct ospf_neighbor *on)
 | 
						|
{
 | 
						|
  oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
 | 
						|
  char msgbuf[16];
 | 
						|
  
 | 
						|
  ospf_nbr_state_message(on, msgbuf, sizeof(msgbuf));
 | 
						|
  zlog (NULL, LOG_INFO, "ospfTrapNbrStateChange trap sent: %s now %s",
 | 
						|
	inet_ntoa(on->address.u.prefix4), msgbuf);
 | 
						|
 | 
						|
  oid_copy_addr (index, &(on->address.u.prefix4), IN_ADDR_SIZE);
 | 
						|
  index[IN_ADDR_SIZE] = 0;
 | 
						|
 | 
						|
  smux_trap (ospf_variables, sizeof ospf_variables / sizeof (struct variable),
 | 
						|
	     ospf_trap_oid, sizeof ospf_trap_oid / sizeof (oid),
 | 
						|
	     ospf_oid, sizeof ospf_oid / sizeof (oid),
 | 
						|
             index,  IN_ADDR_SIZE + 1,
 | 
						|
             ospfNbrTrapList, 
 | 
						|
             sizeof ospfNbrTrapList / sizeof (struct trap_object),
 | 
						|
             NBRSTATECHANGE);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
ospfTrapVirtNbrStateChange (struct ospf_neighbor *on)
 | 
						|
{
 | 
						|
  oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
 | 
						|
  
 | 
						|
  zlog (NULL, LOG_INFO, "ospfTrapVirtNbrStateChange trap sent");
 | 
						|
 | 
						|
  oid_copy_addr (index, &(on->address.u.prefix4), IN_ADDR_SIZE);
 | 
						|
  index[IN_ADDR_SIZE] = 0;
 | 
						|
 | 
						|
  smux_trap (ospf_variables, sizeof ospf_variables / sizeof (struct variable),
 | 
						|
	     ospf_trap_oid, sizeof ospf_trap_oid / sizeof (oid),
 | 
						|
	     ospf_oid, sizeof ospf_oid / sizeof (oid),
 | 
						|
             index,  IN_ADDR_SIZE + 1,
 | 
						|
             ospfVirtNbrTrapList, 
 | 
						|
             sizeof ospfVirtNbrTrapList / sizeof (struct trap_object),
 | 
						|
             VIRTNBRSTATECHANGE);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
ospfTrapIfStateChange (struct ospf_interface *oi)
 | 
						|
{
 | 
						|
  oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
 | 
						|
 | 
						|
  zlog (NULL, LOG_INFO, "ospfTrapIfStateChange trap sent: %s now %s",
 | 
						|
  	inet_ntoa(oi->address->u.prefix4),
 | 
						|
	LOOKUP(ospf_ism_state_msg, oi->state));
 | 
						|
  
 | 
						|
  oid_copy_addr (index, &(oi->address->u.prefix4), IN_ADDR_SIZE);
 | 
						|
  index[IN_ADDR_SIZE] = 0;
 | 
						|
 | 
						|
  smux_trap (ospf_variables, sizeof ospf_variables / sizeof (struct variable),
 | 
						|
	     ospf_trap_oid, sizeof ospf_trap_oid / sizeof (oid),
 | 
						|
	     ospf_oid, sizeof ospf_oid / sizeof (oid),
 | 
						|
             index, IN_ADDR_SIZE + 1,
 | 
						|
             ospfIfTrapList, 
 | 
						|
             sizeof ospfIfTrapList / sizeof (struct trap_object),
 | 
						|
             IFSTATECHANGE);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
ospfTrapVirtIfStateChange (struct ospf_interface *oi)
 | 
						|
{
 | 
						|
  oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
 | 
						|
 | 
						|
  zlog (NULL, LOG_INFO, "ospfTrapVirtIfStateChange trap sent");
 | 
						|
  
 | 
						|
  oid_copy_addr (index, &(oi->address->u.prefix4), IN_ADDR_SIZE);
 | 
						|
  index[IN_ADDR_SIZE] = 0;
 | 
						|
 | 
						|
  smux_trap (ospf_variables, sizeof ospf_variables / sizeof (struct variable),
 | 
						|
	     ospf_trap_oid, sizeof ospf_trap_oid / sizeof (oid),
 | 
						|
	     ospf_oid, sizeof ospf_oid / sizeof (oid),
 | 
						|
             index, IN_ADDR_SIZE + 1,
 | 
						|
             ospfVirtIfTrapList,
 | 
						|
             sizeof ospfVirtIfTrapList / sizeof (struct trap_object),
 | 
						|
             VIRTIFSTATECHANGE);
 | 
						|
}
 | 
						|
/* Register OSPF2-MIB. */
 | 
						|
void
 | 
						|
ospf_snmp_init ()
 | 
						|
{
 | 
						|
  ospf_snmp_iflist = list_new ();
 | 
						|
  ospf_snmp_vl_table = route_table_init ();
 | 
						|
  smux_init (om->master);
 | 
						|
  REGISTER_MIB("mibII/ospf", ospf_variables, variable, ospf_oid);
 | 
						|
}
 | 
						|
#endif /* HAVE_SNMP */
 |