ospf_snmp.c
上传用户:xiaozhuqw
上传日期:2009-11-15
资源大小:1338k
文件大小:64k
源码类别:

网络

开发平台:

Unix_Linux

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