1/* OSPFv3 SNMP support
2 * Copyright (C) 2004 Yasuhiro Ohara
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING.  If not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#ifdef HAVE_SNMP
25
26#include <net-snmp/net-snmp-config.h>
27#include <net-snmp/net-snmp-includes.h>
28
29#include "log.h"
30#include "vty.h"
31#include "linklist.h"
32#include "smux.h"
33
34#include "ospf6_proto.h"
35#include "ospf6_lsa.h"
36#include "ospf6_lsdb.h"
37#include "ospf6_route.h"
38#include "ospf6_top.h"
39#include "ospf6_area.h"
40#include "ospf6_interface.h"
41#include "ospf6_message.h"
42#include "ospf6_neighbor.h"
43#include "ospf6d.h"
44#include "ospf6_snmp.h"
45
46/* OSPFv3-MIB */
47#define OSPFv3MIB 1,3,6,1,2,1,191
48
49/* OSPFv3 MIB General Group values. */
50#define OSPFv3ROUTERID                   1
51#define OSPFv3ADMINSTAT                  2
52#define OSPFv3VERSIONNUMBER              3
53#define OSPFv3AREABDRRTRSTATUS           4
54#define OSPFv3ASBDRRTRSTATUS             5
55#define OSPFv3ASSCOPELSACOUNT            6
56#define OSPFv3ASSCOPELSACHECKSUMSUM      7
57#define OSPFv3ORIGINATENEWLSAS           8
58#define OSPFv3RXNEWLSAS                  9
59#define OSPFv3EXTLSACOUNT               10
60#define OSPFv3EXTAREALSDBLIMIT          11
61#define OSPFv3EXITOVERFLOWINTERVAL      12
62#define OSPFv3DEMANDEXTENSIONS          13
63#define OSPFv3REFERENCEBANDWIDTH        14
64#define OSPFv3RESTARTSUPPORT            15
65#define OSPFv3RESTARTINTERVAL           16
66#define OSPFv3RESTARTSTRICTLSACHECKING  17
67#define OSPFv3RESTARTSTATUS             18
68#define OSPFv3RESTARTAGE                19
69#define OSPFv3RESTARTEXITREASON         20
70#define OSPFv3NOTIFICATIONENABLE        21
71#define OSPFv3STUBROUTERSUPPORT         22
72#define OSPFv3STUBROUTERADVERTISEMENT   23
73#define OSPFv3DISCONTINUITYTIME         24
74#define OSPFv3RESTARTTIME               25
75
76/* OSPFv3 MIB Area Table values: ospfv3AreaTable */
77#define OSPFv3IMPORTASEXTERN             2
78#define OSPFv3AREASPFRUNS                3
79#define OSPFv3AREABDRRTRCOUNT            4
80#define OSPFv3AREAASBDRRTRCOUNT          5
81#define OSPFv3AREASCOPELSACOUNT          6
82#define OSPFv3AREASCOPELSACKSUMSUM       7
83#define OSPFv3AREASUMMARY                8
84#define OSPFv3AREAROWSTATUS              9
85#define OSPFv3AREASTUBMETRIC            10
86#define OSPFv3AREANSSATRANSLATORROLE    11
87#define OSPFv3AREANSSATRANSLATORSTATE   12
88#define OSPFv3AREANSSATRANSLATORSTABINTERVAL    13
89#define OSPFv3AREANSSATRANSLATOREVENTS  14
90#define OSPFv3AREASTUBMETRICTYPE        15
91#define OSPFv3AREATEENABLED             16
92
93/* OSPFv3 MIB * Lsdb Table values: ospfv3*LsdbTable */
94#define OSPFv3WWLSDBSEQUENCE             1
95#define OSPFv3WWLSDBAGE                  2
96#define OSPFv3WWLSDBCHECKSUM             3
97#define OSPFv3WWLSDBADVERTISEMENT        4
98#define OSPFv3WWLSDBTYPEKNOWN            5
99
100/* Three first bits are to identify column */
101#define OSPFv3WWCOLUMN 0x7
102/* Then we use other bits to identify table */
103#define OSPFv3WWASTABLE   (1 << 3)
104#define OSPFv3WWAREATABLE (1 << 4)
105#define OSPFv3WWLINKTABLE (1 << 5)
106#define OSPFv3WWVIRTLINKTABLE (1 << 6)
107
108/* OSPFv3 MIB Host Table values: ospfv3HostTable */
109#define OSPFv3HOSTMETRIC                 3
110#define OSPFv3HOSTROWSTATUS              4
111#define OSPFv3HOSTAREAID                 5
112
113/* OSPFv3 MIB Interface Table values: ospfv3IfTable */
114#define OSPFv3IFAREAID                   3
115#define OSPFv3IFTYPE                     4
116#define OSPFv3IFADMINSTATUS              5
117#define OSPFv3IFRTRPRIORITY              6
118#define OSPFv3IFTRANSITDELAY             7
119#define OSPFv3IFRETRANSINTERVAL          8
120#define OSPFv3IFHELLOINTERVAL            9
121#define OSPFv3IFRTRDEADINTERVAL         10
122#define OSPFv3IFPOLLINTERVAL            11
123#define OSPFv3IFSTATE                   12
124#define OSPFv3IFDESIGNATEDROUTER        13
125#define OSPFv3IFBACKUPDESIGNATEDROUTER  14
126#define OSPFv3IFEVENTS                  15
127#define OSPFv3IFROWSTATUS               16
128#define OSPFv3IFDEMAND                  17
129#define OSPFv3IFMETRICVALUE             18
130#define OSPFv3IFLINKSCOPELSACOUNT       19
131#define OSPFv3IFLINKLSACKSUMSUM         20
132#define OSPFv3IFDEMANDNBRPROBE          21
133#define OSPFv3IFDEMANDNBRPROBERETRANSLIMIT 22
134#define OSPFv3IFDEMANDNBRPROBEINTERVAL  23
135#define OSPFv3IFTEDISABLED              24
136#define OSPFv3IFLINKLSASUPPRESSION      25
137
138/* OSPFv3 MIB Virtual Interface Table values: ospfv3VirtIfTable */
139#define OSPFv3VIRTIFINDEX           3
140#define OSPFv3VIRTIFINSTID          4
141#define OSPFv3VIRTIFTRANSITDELAY    5
142#define OSPFv3VIRTIFRETRANSINTERVAL 6
143#define OSPFv3VIRTIFHELLOINTERVAL   7
144#define OSPFv3VIRTIFRTRDEADINTERVAL 8
145#define OSPFv3VIRTIFSTATE           9
146#define OSPFv3VIRTIFEVENTS         10
147#define OSPFv3VIRTIFROWSTATUS      11
148#define OSPFv3VIRTIFLINKSCOPELSACOUNT 12
149#define OSPFv3VIRTIFLINKLSACKSUMSUM   13
150
151/* OSPFv3 MIB Neighbors Table values: ospfv3NbrTable */
152#define OSPFv3NBRADDRESSTYPE      4
153#define OSPFv3NBRADDRESS          5
154#define OSPFv3NBROPTIONS          6
155#define OSPFv3NBRPRIORITY         7
156#define OSPFv3NBRSTATE            8
157#define OSPFv3NBREVENTS           9
158#define OSPFv3NBRLSRETRANSQLEN   10
159#define OSPFv3NBRHELLOSUPPRESSED 11
160#define OSPFv3NBRIFID            12
161#define OSPFv3NBRRESTARTHELPERSTATUS     13
162#define OSPFv3NBRRESTARTHELPERAGE        14
163#define OSPFv3NBRRESTARTHELPEREXITREASON 15
164
165/* OSPFv3 MIB Configured Neighbors Table values: ospfv3CfgNbrTable */
166#define OSPFv3CFGNBRPRIORITY  5
167#define OSPFv3CFGNBRROWSTATUS 6
168
169/* OSPFv3 MIB Virtual Neighbors Table values: ospfv3VirtNbrTable */
170#define OSPFv3VIRTNBRIFINDEX          3
171#define OSPFv3VIRTNBRIFINSTID         4
172#define OSPFv3VIRTNBRADDRESSTYPE      5
173#define OSPFv3VIRTNBRADDRESS          6
174#define OSPFv3VIRTNBROPTIONS          7
175#define OSPFv3VIRTNBRSTATE            8
176#define OSPFv3VIRTNBREVENTS           9
177#define OSPFv3VIRTNBRLSRETRANSQLEN   10
178#define OSPFv3VIRTNBRHELLOSUPPRESSED 11
179#define OSPFv3VIRTNBRIFID            12
180#define OSPFv3VIRTNBRRESTARTHELPERSTATUS     13
181#define OSPFv3VIRTNBRRESTARTHELPERAGE        14
182#define OSPFv3VIRTNBRRESTARTHELPEREXITREASON 15
183
184/* OSPFv3 MIB Area Aggregate Table values: ospfv3AreaAggregateTable */
185#define OSPFv3AREAAGGREGATEROWSTATUS  6
186#define OSPFv3AREAAGGREGATEEFFECT     7
187#define OSPFv3AREAAGGREGATEROUTETAG   8
188
189/* SYNTAX Status from OSPF-MIB. */
190#define OSPF_STATUS_ENABLED  1
191#define OSPF_STATUS_DISABLED 2
192
193/* SNMP value hack. */
194#define COUNTER     ASN_COUNTER
195#define INTEGER     ASN_INTEGER
196#define GAUGE       ASN_GAUGE
197#define UNSIGNED    ASN_UNSIGNED
198#define TIMETICKS   ASN_TIMETICKS
199#define IPADDRESS   ASN_IPADDRESS
200#define STRING      ASN_OCTET_STR
201
202/* For return values e.g. SNMP_INTEGER macro */
203SNMP_LOCAL_VARIABLES
204
205/* OSPFv3-MIB instances. */
206oid ospfv3_oid [] = { OSPFv3MIB };
207oid ospfv3_trap_oid [] = { OSPFv3MIB, 0 };
208
209/* Hook functions. */
210static u_char *ospfv3GeneralGroup (struct variable *, oid *, size_t *,
211				   int, size_t *, WriteMethod **);
212static u_char *ospfv3AreaEntry (struct variable *, oid *, size_t *,
213				int, size_t *, WriteMethod **);
214static u_char *ospfv3WwLsdbEntry (struct variable *, oid *, size_t *,
215				  int, size_t *, WriteMethod **);
216static u_char *ospfv3NbrEntry (struct variable *, oid *, size_t *,
217			       int, size_t *, WriteMethod **);
218static u_char *ospfv3IfEntry (struct variable *, oid *, size_t *,
219			      int, size_t *, WriteMethod **);
220
221struct variable ospfv3_variables[] =
222{
223  /* OSPF general variables */
224  {OSPFv3ROUTERID,             UNSIGNED,   RWRITE, ospfv3GeneralGroup,
225   3, {1, 1, 1}},
226  {OSPFv3ADMINSTAT,             INTEGER,   RWRITE, ospfv3GeneralGroup,
227   3, {1, 1, 2}},
228  {OSPFv3VERSIONNUMBER,         INTEGER,   RONLY,  ospfv3GeneralGroup,
229   3, {1, 1, 3}},
230  {OSPFv3AREABDRRTRSTATUS,      INTEGER,   RONLY,  ospfv3GeneralGroup,
231   3, {1, 1, 4}},
232  {OSPFv3ASBDRRTRSTATUS,        INTEGER,   RWRITE, ospfv3GeneralGroup,
233   3, {1, 1, 5}},
234  {OSPFv3ASSCOPELSACOUNT,       GAUGE,     RONLY,  ospfv3GeneralGroup,
235   3, {1, 1, 6}},
236  {OSPFv3ASSCOPELSACHECKSUMSUM,UNSIGNED,   RONLY,  ospfv3GeneralGroup,
237   3, {1, 1, 7}},
238  {OSPFv3ORIGINATENEWLSAS,      COUNTER,   RONLY,  ospfv3GeneralGroup,
239   3, {1, 1, 8}},
240  {OSPFv3RXNEWLSAS,             COUNTER,   RONLY,  ospfv3GeneralGroup,
241   3, {1, 1, 9}},
242  {OSPFv3EXTLSACOUNT,           GAUGE,     RONLY,  ospfv3GeneralGroup,
243   3, {1, 1, 10}},
244  {OSPFv3EXTAREALSDBLIMIT,      INTEGER,   RWRITE, ospfv3GeneralGroup,
245   3, {1, 1, 11}},
246  {OSPFv3EXITOVERFLOWINTERVAL, UNSIGNED,   RWRITE, ospfv3GeneralGroup,
247   3, {1, 1, 12}},
248  {OSPFv3DEMANDEXTENSIONS,      INTEGER,   RWRITE, ospfv3GeneralGroup,
249   3, {1, 1, 13}},
250  {OSPFv3REFERENCEBANDWIDTH,   UNSIGNED, RWRITE, ospfv3GeneralGroup,
251   3, {1, 1, 14}},
252  {OSPFv3RESTARTSUPPORT,        INTEGER, RWRITE, ospfv3GeneralGroup,
253   3, {1, 1, 15}},
254  {OSPFv3RESTARTINTERVAL,      UNSIGNED, RWRITE, ospfv3GeneralGroup,
255   3, {1, 1, 16}},
256  {OSPFv3RESTARTSTRICTLSACHECKING, INTEGER, RWRITE, ospfv3GeneralGroup,
257   3, {1, 1, 17}},
258  {OSPFv3RESTARTSTATUS,         INTEGER, RONLY,  ospfv3GeneralGroup,
259   3, {1, 1, 18}},
260  {OSPFv3RESTARTAGE,           UNSIGNED, RONLY,  ospfv3GeneralGroup,
261   3, {1, 1, 19}},
262  {OSPFv3RESTARTEXITREASON,     INTEGER, RONLY,  ospfv3GeneralGroup,
263   3, {1, 1, 20}},
264  {OSPFv3NOTIFICATIONENABLE,    INTEGER, RWRITE, ospfv3GeneralGroup,
265   3, {1, 1, 21}},
266  {OSPFv3STUBROUTERSUPPORT,     INTEGER, RONLY,  ospfv3GeneralGroup,
267   3, {1, 1, 22}},
268  {OSPFv3STUBROUTERADVERTISEMENT, INTEGER, RWRITE, ospfv3GeneralGroup,
269   3, {1, 1, 23}},
270  {OSPFv3DISCONTINUITYTIME,     TIMETICKS, RONLY,  ospfv3GeneralGroup,
271   3, {1, 1, 24}},
272  {OSPFv3RESTARTTIME,           TIMETICKS, RONLY,  ospfv3GeneralGroup,
273   3, {1, 1, 25}},
274
275  /* OSPFv3 Area Data Structure */
276  {OSPFv3IMPORTASEXTERN,        INTEGER,   RWRITE, ospfv3AreaEntry,
277   4, {1, 2, 1, 2}},
278  {OSPFv3AREASPFRUNS,           COUNTER,   RONLY,  ospfv3AreaEntry,
279   4, {1, 2, 1, 3}},
280  {OSPFv3AREABDRRTRCOUNT,       GAUGE,     RONLY,  ospfv3AreaEntry,
281   4, {1, 2, 1, 4}},
282  {OSPFv3AREAASBDRRTRCOUNT,     GAUGE,     RONLY,  ospfv3AreaEntry,
283   4, {1, 2, 1, 5}},
284  {OSPFv3AREASCOPELSACOUNT,     GAUGE,     RONLY,  ospfv3AreaEntry,
285   4, {1, 2, 1, 6}},
286  {OSPFv3AREASCOPELSACKSUMSUM, UNSIGNED,   RONLY,  ospfv3AreaEntry,
287   4, {1, 2, 1, 7}},
288  {OSPFv3AREASUMMARY,           INTEGER,   RWRITE, ospfv3AreaEntry,
289   4, {1, 2, 1, 8}},
290  {OSPFv3AREAROWSTATUS,         INTEGER,   RWRITE, ospfv3AreaEntry,
291   4, {1, 2, 1, 9}},
292  {OSPFv3AREASTUBMETRIC,        INTEGER,   RWRITE, ospfv3AreaEntry,
293   4, {1, 2, 1, 10}},
294  {OSPFv3AREANSSATRANSLATORROLE, INTEGER,  RWRITE, ospfv3AreaEntry,
295   4, {1, 2, 1, 11}},
296  {OSPFv3AREANSSATRANSLATORSTATE, INTEGER, RONLY,  ospfv3AreaEntry,
297   4, {1, 2, 1, 12}},
298  {OSPFv3AREANSSATRANSLATORSTABINTERVAL, UNSIGNED, RWRITE, ospfv3AreaEntry,
299   4, {1, 2, 1, 13}},
300  {OSPFv3AREANSSATRANSLATOREVENTS, COUNTER, RONLY, ospfv3AreaEntry,
301   4, {1, 2, 1, 14}},
302  {OSPFv3AREASTUBMETRICTYPE,    INTEGER, RWRITE, ospfv3AreaEntry,
303   4, {1, 2, 1, 15}},
304  {OSPFv3AREATEENABLED,         INTEGER, RWRITE, ospfv3AreaEntry,
305   4, {1, 2, 1, 16}},
306
307  /* OSPFv3 AS LSDB */
308  {OSPFv3WWLSDBSEQUENCE | OSPFv3WWASTABLE,      INTEGER,   RONLY,  ospfv3WwLsdbEntry,
309   4, {1, 3, 1, 4}},
310  {OSPFv3WWLSDBAGE | OSPFv3WWASTABLE,           UNSIGNED,  RONLY,  ospfv3WwLsdbEntry,
311   4, {1, 3, 1, 5}},
312  {OSPFv3WWLSDBCHECKSUM | OSPFv3WWASTABLE,      INTEGER,   RONLY,  ospfv3WwLsdbEntry,
313   4, {1, 3, 1, 6}},
314  {OSPFv3WWLSDBADVERTISEMENT | OSPFv3WWASTABLE, STRING,    RONLY,  ospfv3WwLsdbEntry,
315   4, {1, 3, 1, 7}},
316  {OSPFv3WWLSDBTYPEKNOWN | OSPFv3WWASTABLE,     INTEGER,   RONLY,  ospfv3WwLsdbEntry,
317   4, {1, 3, 1, 8}},
318
319  /* OSPFv3 Area LSDB */
320  {OSPFv3WWLSDBSEQUENCE | OSPFv3WWAREATABLE,      INTEGER,   RONLY,  ospfv3WwLsdbEntry,
321   4, {1, 4, 1, 5}},
322  {OSPFv3WWLSDBAGE | OSPFv3WWAREATABLE,           UNSIGNED,  RONLY,  ospfv3WwLsdbEntry,
323   4, {1, 4, 1, 6}},
324  {OSPFv3WWLSDBCHECKSUM | OSPFv3WWAREATABLE,      INTEGER,   RONLY,  ospfv3WwLsdbEntry,
325   4, {1, 4, 1, 7}},
326  {OSPFv3WWLSDBADVERTISEMENT | OSPFv3WWAREATABLE, STRING,    RONLY,  ospfv3WwLsdbEntry,
327   4, {1, 4, 1, 8}},
328  {OSPFv3WWLSDBTYPEKNOWN | OSPFv3WWAREATABLE,     INTEGER,   RONLY,  ospfv3WwLsdbEntry,
329   4, {1, 4, 1, 9}},
330
331  /* OSPFv3 Link LSDB */
332  {OSPFv3WWLSDBSEQUENCE | OSPFv3WWLINKTABLE,      INTEGER,   RONLY,  ospfv3WwLsdbEntry,
333   4, {1, 5, 1, 6}},
334  {OSPFv3WWLSDBAGE | OSPFv3WWLINKTABLE,           UNSIGNED,  RONLY,  ospfv3WwLsdbEntry,
335   4, {1, 5, 1, 7}},
336  {OSPFv3WWLSDBCHECKSUM | OSPFv3WWLINKTABLE,      INTEGER,   RONLY,  ospfv3WwLsdbEntry,
337   4, {1, 5, 1, 8}},
338  {OSPFv3WWLSDBADVERTISEMENT | OSPFv3WWLINKTABLE, STRING,    RONLY,  ospfv3WwLsdbEntry,
339   4, {1, 5, 1, 9}},
340  {OSPFv3WWLSDBTYPEKNOWN | OSPFv3WWLINKTABLE,     INTEGER,   RONLY,  ospfv3WwLsdbEntry,
341   4, {1, 5, 1, 10}},
342
343  /* OSPFv3 interfaces */
344  {OSPFv3IFAREAID,             UNSIGNED, RONLY, ospfv3IfEntry,
345   4, {1, 7, 1, 3}},
346  {OSPFv3IFTYPE,               INTEGER,  RONLY, ospfv3IfEntry,
347   4, {1, 7, 1, 4}},
348  {OSPFv3IFADMINSTATUS,        INTEGER,  RONLY, ospfv3IfEntry,
349   4, {1, 7, 1, 5}},
350  {OSPFv3IFRTRPRIORITY,        INTEGER,  RONLY, ospfv3IfEntry,
351   4, {1, 7, 1, 6}},
352  {OSPFv3IFTRANSITDELAY,       UNSIGNED, RONLY, ospfv3IfEntry,
353   4, {1, 7, 1, 7}},
354  {OSPFv3IFRETRANSINTERVAL,    UNSIGNED, RONLY, ospfv3IfEntry,
355   4, {1, 7, 1, 8}},
356  {OSPFv3IFHELLOINTERVAL,      INTEGER,  RONLY, ospfv3IfEntry,
357   4, {1, 7, 1, 9}},
358  {OSPFv3IFRTRDEADINTERVAL,    UNSIGNED, RONLY, ospfv3IfEntry,
359   4, {1, 7, 1, 10}},
360  {OSPFv3IFPOLLINTERVAL,       UNSIGNED, RONLY, ospfv3IfEntry,
361   4, {1, 7, 1, 11}},
362  {OSPFv3IFSTATE,              INTEGER,  RONLY, ospfv3IfEntry,
363   4, {1, 7, 1, 12}},
364  {OSPFv3IFDESIGNATEDROUTER,   UNSIGNED, RONLY, ospfv3IfEntry,
365   4, {1, 7, 1, 13}},
366  {OSPFv3IFBACKUPDESIGNATEDROUTER, UNSIGNED, RONLY, ospfv3IfEntry,
367   4, {1, 7, 1, 14}},
368  {OSPFv3IFEVENTS,             COUNTER,  RONLY, ospfv3IfEntry,
369   4, {1, 7, 1, 15}},
370  {OSPFv3IFROWSTATUS,          INTEGER,  RONLY, ospfv3IfEntry,
371   4, {1, 7, 1, 16}},
372  {OSPFv3IFDEMAND,             INTEGER,  RONLY, ospfv3IfEntry,
373   4, {1, 7, 1, 17}},
374  {OSPFv3IFMETRICVALUE,        INTEGER,  RONLY, ospfv3IfEntry,
375   4, {1, 7, 1, 18}},
376  {OSPFv3IFLINKSCOPELSACOUNT,  GAUGE,    RONLY, ospfv3IfEntry,
377   4, {1, 7, 1, 19}},
378  {OSPFv3IFLINKLSACKSUMSUM,    UNSIGNED, RONLY, ospfv3IfEntry,
379   4, {1, 7, 1, 20}},
380  {OSPFv3IFDEMANDNBRPROBE,     INTEGER,  RONLY, ospfv3IfEntry,
381   4, {1, 7, 1, 21}},
382  {OSPFv3IFDEMANDNBRPROBERETRANSLIMIT, UNSIGNED, RONLY, ospfv3IfEntry,
383   4, {1, 7, 1, 22}},
384  {OSPFv3IFDEMANDNBRPROBEINTERVAL, UNSIGNED, RONLY, ospfv3IfEntry,
385   4, {1, 7, 1, 23}},
386  {OSPFv3IFTEDISABLED,         INTEGER,  RONLY, ospfv3IfEntry,
387   4, {1, 7, 1, 24}},
388  {OSPFv3IFLINKLSASUPPRESSION, INTEGER,  RONLY, ospfv3IfEntry,
389   4, {1, 7, 1, 25}},
390
391  /* OSPFv3 neighbors */
392  {OSPFv3NBRADDRESSTYPE,        INTEGER,   RONLY,  ospfv3NbrEntry,
393   4, {1, 9, 1, 4}},
394  {OSPFv3NBRADDRESS,            STRING,    RONLY,  ospfv3NbrEntry,
395   4, {1, 9, 1, 5}},
396  {OSPFv3NBROPTIONS,            INTEGER,   RONLY,  ospfv3NbrEntry,
397   4, {1, 9, 1, 6}},
398  {OSPFv3NBRPRIORITY,           INTEGER,   RONLY,  ospfv3NbrEntry,
399   4, {1, 9, 1, 7}},
400  {OSPFv3NBRSTATE,              INTEGER,   RONLY,  ospfv3NbrEntry,
401   4, {1, 9, 1, 8}},
402  {OSPFv3NBREVENTS,             COUNTER,   RONLY,  ospfv3NbrEntry,
403   4, {1, 9, 1, 9}},
404  {OSPFv3NBRLSRETRANSQLEN,        GAUGE,   RONLY,  ospfv3NbrEntry,
405   4, {1, 9, 1, 10}},
406  {OSPFv3NBRHELLOSUPPRESSED,    INTEGER,   RONLY,  ospfv3NbrEntry,
407   4, {1, 9, 1, 11}},
408  {OSPFv3NBRIFID,               INTEGER,   RONLY,  ospfv3NbrEntry,
409   4, {1, 9, 1, 12}},
410  {OSPFv3NBRRESTARTHELPERSTATUS, INTEGER,  RONLY,  ospfv3NbrEntry,
411   4, {1, 9, 1, 13}},
412  {OSPFv3NBRRESTARTHELPERAGE,  UNSIGNED,   RONLY,  ospfv3NbrEntry,
413   4, {1, 9, 1, 14}},
414  {OSPFv3NBRRESTARTHELPEREXITREASON, INTEGER, RONLY, ospfv3NbrEntry,
415   4, {1, 9, 1, 15}},
416};
417
418static u_char *
419ospfv3GeneralGroup (struct variable *v, oid *name, size_t *length,
420                    int exact, size_t *var_len, WriteMethod **write_method)
421{
422  u_int16_t sum;
423  u_int32_t count;
424  struct ospf6_lsa *lsa = NULL;
425
426  /* Check whether the instance identifier is valid */
427  if (smux_header_generic (v, name, length, exact, var_len, write_method)
428      == MATCH_FAILED)
429    return NULL;
430
431  /* Return the current value of the variable */
432  switch (v->magic)
433    {
434    case OSPFv3ROUTERID:
435      /* Router-ID of this OSPF instance. */
436      if (ospf6)
437	return SNMP_INTEGER (ntohl (ospf6->router_id));
438      return SNMP_INTEGER (0);
439    case OSPFv3ADMINSTAT:
440      if (ospf6)
441	return SNMP_INTEGER (CHECK_FLAG (ospf6->flag, OSPF6_DISABLED)?
442			     OSPF_STATUS_DISABLED:OSPF_STATUS_ENABLED);
443      return SNMP_INTEGER (OSPF_STATUS_DISABLED);
444    case OSPFv3VERSIONNUMBER:
445      return SNMP_INTEGER (3);
446    case OSPFv3AREABDRRTRSTATUS:
447      if (ospf6)
448	return SNMP_INTEGER (ospf6_is_router_abr (ospf6)?SNMP_TRUE:SNMP_FALSE);
449      return SNMP_INTEGER (SNMP_FALSE);
450    case OSPFv3ASBDRRTRSTATUS:
451      if (ospf6)
452	return SNMP_INTEGER (ospf6_asbr_is_asbr (ospf6)?SNMP_TRUE:SNMP_FALSE);
453      return SNMP_INTEGER (SNMP_FALSE);
454    case OSPFv3ASSCOPELSACOUNT:
455      if (ospf6)
456	return SNMP_INTEGER (ospf6->lsdb->count);
457      return SNMP_INTEGER (0);
458    case OSPFv3ASSCOPELSACHECKSUMSUM:
459      if (ospf6)
460        {
461          for (sum = 0, lsa = ospf6_lsdb_head (ospf6->lsdb);
462               lsa;
463               lsa = ospf6_lsdb_next (lsa))
464            sum += ntohs (lsa->header->checksum);
465          return SNMP_INTEGER (sum);
466        }
467      return SNMP_INTEGER (0);
468    case OSPFv3ORIGINATENEWLSAS:
469      return SNMP_INTEGER (0);	/* Don't know where to get this value... */
470    case OSPFv3RXNEWLSAS:
471      return SNMP_INTEGER (0);	/* Don't know where to get this value... */
472    case OSPFv3EXTLSACOUNT:
473      if (ospf6)
474        {
475          for (count = 0, lsa = ospf6_lsdb_type_head (htons (OSPF6_LSTYPE_AS_EXTERNAL),
476                                                      ospf6->lsdb);
477               lsa;
478               lsa = ospf6_lsdb_type_next (htons (OSPF6_LSTYPE_AS_EXTERNAL),
479                                           lsa))
480            count += 1;
481          return SNMP_INTEGER (count);
482        }
483      return SNMP_INTEGER (0);
484    case OSPFv3EXTAREALSDBLIMIT:
485      return SNMP_INTEGER (-1);
486    case OSPFv3EXITOVERFLOWINTERVAL:
487      return SNMP_INTEGER (0);	/* Not supported */
488    case OSPFv3DEMANDEXTENSIONS:
489      return SNMP_INTEGER (0);	/* Not supported */
490    case OSPFv3REFERENCEBANDWIDTH:
491      if (ospf6)
492        return SNMP_INTEGER (ospf6->ref_bandwidth);
493      /* Otherwise, like for "not implemented". */
494    case OSPFv3RESTARTSUPPORT:
495    case OSPFv3RESTARTINTERVAL:
496    case OSPFv3RESTARTSTRICTLSACHECKING:
497    case OSPFv3RESTARTSTATUS:
498    case OSPFv3RESTARTAGE:
499    case OSPFv3RESTARTEXITREASON:
500    case OSPFv3NOTIFICATIONENABLE:
501    case OSPFv3STUBROUTERSUPPORT:
502    case OSPFv3STUBROUTERADVERTISEMENT:
503    case OSPFv3DISCONTINUITYTIME:
504    case OSPFv3RESTARTTIME:
505      /* TODO: Not implemented */
506      return NULL;
507    }
508  return NULL;
509}
510
511static u_char *
512ospfv3AreaEntry (struct variable *v, oid *name, size_t *length,
513                 int exact, size_t *var_len, WriteMethod **write_method)
514{
515  struct ospf6_area *oa, *area = NULL;
516  struct ospf6_lsa *lsa = NULL;
517  u_int32_t area_id = 0;
518  u_int32_t count;
519  u_int16_t sum;
520  struct listnode *node;
521  unsigned int len;
522  char a[16];
523  struct ospf6_route *ro;
524
525  if (ospf6 == NULL)
526    return NULL;
527
528  if (smux_header_table(v, name, length, exact, var_len, write_method)
529      == MATCH_FAILED)
530    return NULL;
531
532  len = *length - v->namelen;
533  len = (len >= 1 ? 1 : 0);
534  if (exact && len != 1)
535    return NULL;
536  if (len)
537    area_id  = htonl (name[v->namelen]);
538
539  inet_ntop (AF_INET, &area_id, a, sizeof (a));
540  zlog_debug ("SNMP access by area: %s, exact=%d len=%d length=%lu",
541	      a, exact, len, (u_long)*length);
542
543  for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
544    {
545      if (area == NULL)
546        {
547          if (len == 0) /* return first area entry */
548            area = oa;
549          else if (exact && ntohl (oa->area_id) == ntohl (area_id))
550            area = oa;
551          else if (ntohl (oa->area_id) > ntohl (area_id))
552            area = oa;
553        }
554    }
555
556  if (area == NULL)
557    return NULL;
558
559  *length = v->namelen + 1;
560  name[v->namelen] = ntohl (area->area_id);
561
562  inet_ntop (AF_INET, &area->area_id, a, sizeof (a));
563  zlog_debug ("SNMP found area: %s, exact=%d len=%d length=%lu",
564	      a, exact, len, (u_long)*length);
565
566  switch (v->magic)
567    {
568    case OSPFv3IMPORTASEXTERN:
569      /* No NSSA support */
570      return SNMP_INTEGER (IS_AREA_STUB(area)?2:1);
571    case OSPFv3AREASPFRUNS:
572      return SNMP_INTEGER (area->spf_calculation);
573    case OSPFv3AREABDRRTRCOUNT:
574    case OSPFv3AREAASBDRRTRCOUNT:
575      count = 0;
576      for (ro = ospf6_route_head (ospf6->brouter_table); ro;
577	   ro = ospf6_route_next (ro))
578        {
579          if (ntohl (ro->path.area_id) != ntohl (area->area_id)) continue;
580          if (v->magic == OSPFv3AREABDRRTRCOUNT &&
581              CHECK_FLAG (ro->path.router_bits, OSPF6_ROUTER_BIT_B))
582            count++;
583          if (v->magic == OSPFv3AREAASBDRRTRCOUNT &&
584              CHECK_FLAG (ro->path.router_bits, OSPF6_ROUTER_BIT_E))
585            count++;
586        }
587      return SNMP_INTEGER (count);
588    case OSPFv3AREASCOPELSACOUNT:
589      return SNMP_INTEGER (area->lsdb->count);
590    case OSPFv3AREASCOPELSACKSUMSUM:
591      for (sum = 0, lsa = ospf6_lsdb_head (area->lsdb);
592	   lsa;
593	   lsa = ospf6_lsdb_next (lsa))
594	sum += ntohs (lsa->header->checksum);
595      return SNMP_INTEGER (sum);
596    case OSPFv3AREASUMMARY:
597      return SNMP_INTEGER (2); /* sendAreaSummary */
598    case OSPFv3AREAROWSTATUS:
599      return SNMP_INTEGER (1); /* Active */
600    case OSPFv3AREASTUBMETRIC:
601    case OSPFv3AREANSSATRANSLATORROLE:
602    case OSPFv3AREANSSATRANSLATORSTATE:
603    case OSPFv3AREANSSATRANSLATORSTABINTERVAL:
604    case OSPFv3AREANSSATRANSLATOREVENTS:
605    case OSPFv3AREASTUBMETRICTYPE:
606    case OSPFv3AREATEENABLED:
607      /* Not implemented. */
608      return NULL;
609    }
610  return NULL;
611}
612
613static int
614if_icmp_func (struct interface *ifp1, struct interface *ifp2)
615{
616  return (ifp1->ifindex - ifp2->ifindex);
617}
618
619static u_char *
620ospfv3WwLsdbEntry (struct variable *v, oid *name, size_t *length,
621                     int exact, size_t *var_len, WriteMethod **write_method)
622{
623  struct ospf6_lsa *lsa = NULL;
624  u_int32_t ifindex, area_id, id, instid, adv_router;
625  u_int16_t type;
626  int len;
627  oid *offset;
628  int offsetlen;
629  char a[16], b[16], c[16];
630  struct ospf6_area *oa;
631  struct listnode *node;
632  struct interface *iif;
633  struct ospf6_interface *oi = NULL;
634  struct list *ifslist;
635
636  if (smux_header_table(v, name, length, exact, var_len, write_method)
637      == MATCH_FAILED)
638    return NULL;
639
640  instid = ifindex = area_id = type = id = adv_router = 0;
641
642  /* Check OSPFv3 instance. */
643  if (ospf6 == NULL)
644    return NULL;
645
646  /* Get variable length. */
647  offset = name + v->namelen;
648  offsetlen = *length - v->namelen;
649
650  if (exact && (v->magic & OSPFv3WWASTABLE) && offsetlen != 3)
651    return NULL;
652  if (exact && (v->magic & OSPFv3WWAREATABLE) && offsetlen != 4)
653    return NULL;
654  if (exact && (v->magic & OSPFv3WWLINKTABLE) && offsetlen != 5)
655    return NULL;
656
657  if (v->magic & OSPFv3WWLINKTABLE)
658    {
659      /* Parse ifindex */
660      len = (offsetlen < 1 ? 0 : 1);
661      if (len)
662        ifindex = *offset;
663      offset += len;
664      offsetlen -= len;
665
666      /* Parse instance ID */
667      len = (offsetlen < 1 ? 0 : 1);
668      if (len)
669        instid = *offset;
670      offset += len;
671      offsetlen -= len;
672    }
673  else if (v->magic & OSPFv3WWAREATABLE)
674    {
675      /* Parse area-id */
676      len = (offsetlen < 1 ? 0 : 1);
677      if (len)
678        area_id = htonl (*offset);
679      offset += len;
680      offsetlen -= len;
681    }
682
683  /* Parse type */
684  len = (offsetlen < 1 ? 0 : 1);
685  if (len)
686    type = htons (*offset);
687  offset += len;
688  offsetlen -= len;
689
690  /* Parse Router-ID */
691  len = (offsetlen < 1 ? 0 : 1);
692  if (len)
693    adv_router = htonl (*offset);
694  offset += len;
695  offsetlen -= len;
696
697  /* Parse LS-ID */
698  len = (offsetlen < 1 ? 0 : 1);
699  if (len)
700    id = htonl (*offset);
701  offset += len;
702  offsetlen -= len;
703
704  if (exact)
705    {
706      if (v->magic & OSPFv3WWASTABLE)
707        {
708          lsa = ospf6_lsdb_lookup (type, id, adv_router, ospf6->lsdb);
709        }
710      else if (v->magic & OSPFv3WWAREATABLE)
711        {
712          oa = ospf6_area_lookup (area_id, ospf6);
713          if (!oa) return NULL;
714          lsa = ospf6_lsdb_lookup (type, id, adv_router, oa->lsdb);
715        }
716      else if (v->magic & OSPFv3WWLINKTABLE)
717        {
718          oi = ospf6_interface_lookup_by_ifindex (ifindex);
719          if (!oi || oi->instance_id != instid) return NULL;
720          lsa = ospf6_lsdb_lookup (type, id, adv_router, oi->lsdb);
721        }
722    }
723  else
724    {
725      if (v->magic & OSPFv3WWASTABLE)
726	{
727	  if (ospf6->lsdb->count)
728	    lsa = ospf6_lsdb_lookup_next (type, id, adv_router,
729					  ospf6->lsdb);
730	}
731      else if (v->magic & OSPFv3WWAREATABLE)
732	for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
733          {
734            if (oa->area_id < area_id)
735              continue;
736
737            if (oa->lsdb->count)
738              lsa = ospf6_lsdb_lookup_next (type, id, adv_router,
739                                            oa->lsdb);
740            if (lsa) break;
741            type = 0;
742            id = 0;
743            adv_router = 0;
744          }
745      else if (v->magic & OSPFv3WWLINKTABLE)
746        {
747          /* We build a sorted list of interfaces */
748          ifslist = list_new ();
749          if (!ifslist) return NULL;
750          ifslist->cmp = (int (*)(void *, void *))if_icmp_func;
751          for (ALL_LIST_ELEMENTS_RO (iflist, node, iif))
752            listnode_add_sort (ifslist, iif);
753
754          for (ALL_LIST_ELEMENTS_RO (ifslist, node, iif))
755            {
756              if (!iif->ifindex) continue;
757              oi = ospf6_interface_lookup_by_ifindex (iif->ifindex);
758              if (!oi) continue;
759              if (iif->ifindex < ifindex) continue;
760              if (oi->instance_id < instid) continue;
761
762              if (oi->lsdb->count)
763                lsa = ospf6_lsdb_lookup_next (type, id, adv_router,
764                                            oi->lsdb);
765              if (lsa) break;
766              type = 0;
767              id = 0;
768              adv_router = 0;
769              oi = NULL;
770            }
771
772          list_delete_all_node (ifslist);
773        }
774    }
775
776  if (! lsa)
777      return NULL;
778
779  /* Add indexes */
780  if (v->magic & OSPFv3WWASTABLE)
781    {
782      *length = v->namelen + 3;
783      offset = name + v->namelen;
784    }
785  else if (v->magic & OSPFv3WWAREATABLE)
786    {
787      *length = v->namelen + 4;
788      offset = name + v->namelen;
789      *offset = ntohl (oa->area_id);
790      offset++;
791    }
792  else if (v->magic & OSPFv3WWLINKTABLE)
793    {
794      *length = v->namelen + 5;
795      offset = name + v->namelen;
796      *offset = oi->interface->ifindex;
797      offset++;
798      *offset = oi->instance_id;
799      offset++;
800    }
801  *offset = ntohs (lsa->header->type);
802  offset++;
803  *offset = ntohl (lsa->header->adv_router);
804  offset++;
805  *offset = ntohl (lsa->header->id);
806  offset++;
807
808  /* Return the current value of the variable */
809  switch (v->magic & OSPFv3WWCOLUMN)
810    {
811    case OSPFv3WWLSDBSEQUENCE:
812      return SNMP_INTEGER (ntohl (lsa->header->seqnum));
813      break;
814    case OSPFv3WWLSDBAGE:
815      ospf6_lsa_age_current (lsa);
816      return SNMP_INTEGER (ntohs (lsa->header->age));
817      break;
818    case OSPFv3WWLSDBCHECKSUM:
819      return SNMP_INTEGER (ntohs (lsa->header->checksum));
820      break;
821    case OSPFv3WWLSDBADVERTISEMENT:
822      *var_len = ntohs (lsa->header->length);
823      return (u_char *) lsa->header;
824      break;
825    case OSPFv3WWLSDBTYPEKNOWN:
826      return SNMP_INTEGER (OSPF6_LSA_IS_KNOWN (lsa->header->type) ?
827                           SNMP_TRUE : SNMP_FALSE);
828      break;
829    }
830  return NULL;
831}
832
833static u_char *
834ospfv3IfEntry (struct variable *v, oid *name, size_t *length,
835		int exact, size_t *var_len, WriteMethod **write_method)
836{
837  unsigned int ifindex, instid;
838  struct ospf6_interface *oi = NULL;
839  struct ospf6_lsa *lsa = NULL;
840  struct interface      *iif;
841  struct listnode *i;
842  struct list *ifslist;
843  oid *offset;
844  int offsetlen, len;
845  u_int32_t sum;
846
847  if (smux_header_table (v, name, length, exact, var_len, write_method)
848      == MATCH_FAILED)
849    return NULL;
850
851  ifindex = instid = 0;
852
853  /* Check OSPFv3 instance. */
854  if (ospf6 == NULL)
855    return NULL;
856
857  /* Get variable length. */
858  offset = name + v->namelen;
859  offsetlen = *length - v->namelen;
860
861  if (exact && offsetlen != 2)
862    return NULL;
863
864  /* Parse if index */
865  len = (offsetlen < 1 ? 0 : 1);
866  if (len)
867    ifindex = *offset;
868  offset += len;
869  offsetlen -= len;
870
871  /* Parse instance ID */
872  len = (offsetlen < 1 ? 0 : 1);
873  if (len)
874    instid = *offset;
875  offset += len;
876  offsetlen -= len;
877
878  if (exact)
879    {
880      oi = ospf6_interface_lookup_by_ifindex (ifindex);
881      if (!oi || oi->instance_id != instid) return NULL;
882    }
883  else
884    {
885      /* We build a sorted list of interfaces */
886      ifslist = list_new ();
887      if (!ifslist) return NULL;
888      ifslist->cmp = (int (*)(void *, void *))if_icmp_func;
889      for (ALL_LIST_ELEMENTS_RO (iflist, i, iif))
890	listnode_add_sort (ifslist, iif);
891
892      for (ALL_LIST_ELEMENTS_RO (ifslist, i, iif))
893        {
894          if (!iif->ifindex) continue;
895          oi = ospf6_interface_lookup_by_ifindex (iif->ifindex);
896          if (!oi) continue;
897          if (iif->ifindex > ifindex ||
898              (iif->ifindex == ifindex &&
899               (oi->instance_id > instid)))
900            break;
901          oi = NULL;
902        }
903
904      list_delete_all_node (ifslist);
905    }
906
907  if (!oi) return NULL;
908
909  /* Add Index (IfIndex, IfInstId) */
910  *length = v->namelen + 2;
911  offset = name + v->namelen;
912  *offset = oi->interface->ifindex;
913  offset++;
914  *offset = oi->instance_id;
915  offset++;
916
917  /* Return the current value of the variable */
918  switch (v->magic)
919    {
920    case OSPFv3IFAREAID:
921      if (oi->area)
922	return SNMP_INTEGER (ntohl (oi->area->area_id));
923      break;
924    case OSPFv3IFTYPE:
925      if (if_is_broadcast (oi->interface))
926	return SNMP_INTEGER (1);
927      else if (if_is_pointopoint (oi->interface))
928	return SNMP_INTEGER (3);
929      else break;		/* Unknown, don't put anything */
930    case OSPFv3IFADMINSTATUS:
931      if (oi->area)
932	return SNMP_INTEGER (OSPF_STATUS_ENABLED);
933      return SNMP_INTEGER (OSPF_STATUS_DISABLED);
934    case OSPFv3IFRTRPRIORITY:
935      return SNMP_INTEGER (oi->priority);
936    case OSPFv3IFTRANSITDELAY:
937      return SNMP_INTEGER (oi->transdelay);
938    case OSPFv3IFRETRANSINTERVAL:
939      return SNMP_INTEGER (oi->rxmt_interval);
940    case OSPFv3IFHELLOINTERVAL:
941      return SNMP_INTEGER (oi->hello_interval);
942    case OSPFv3IFRTRDEADINTERVAL:
943      return SNMP_INTEGER (oi->dead_interval);
944    case OSPFv3IFPOLLINTERVAL:
945      /* No support for NBMA */
946      break;
947    case OSPFv3IFSTATE:
948      return SNMP_INTEGER (oi->state);
949    case OSPFv3IFDESIGNATEDROUTER:
950      return SNMP_INTEGER (ntohl (oi->drouter));
951    case OSPFv3IFBACKUPDESIGNATEDROUTER:
952      return SNMP_INTEGER (ntohl (oi->bdrouter));
953    case OSPFv3IFEVENTS:
954      return SNMP_INTEGER (oi->state_change);
955    case OSPFv3IFROWSTATUS:
956      return SNMP_INTEGER (1);
957    case OSPFv3IFDEMAND:
958      return SNMP_INTEGER (SNMP_FALSE);
959    case OSPFv3IFMETRICVALUE:
960      return SNMP_INTEGER (oi->cost);
961    case OSPFv3IFLINKSCOPELSACOUNT:
962      return SNMP_INTEGER (oi->lsdb->count);
963    case OSPFv3IFLINKLSACKSUMSUM:
964      for (sum = 0, lsa = ospf6_lsdb_head (oi->lsdb);
965	   lsa;
966	   lsa = ospf6_lsdb_next (lsa))
967	sum += ntohs (lsa->header->checksum);
968      return SNMP_INTEGER (sum);
969    case OSPFv3IFDEMANDNBRPROBE:
970    case OSPFv3IFDEMANDNBRPROBERETRANSLIMIT:
971    case OSPFv3IFDEMANDNBRPROBEINTERVAL:
972    case OSPFv3IFTEDISABLED:
973    case OSPFv3IFLINKLSASUPPRESSION:
974      /* Not implemented. Only works if all the last ones are not
975	 implemented! */
976      return NULL;
977    }
978
979  /* Try an internal getnext. Some columns are missing in this table. */
980  if (!exact && (name[*length-1] < MAX_SUBID))
981    return ospfv3IfEntry(v, name, length,
982			 exact, var_len, write_method);
983  return NULL;
984}
985
986static u_char *
987ospfv3NbrEntry (struct variable *v, oid *name, size_t *length,
988		int exact, size_t *var_len, WriteMethod **write_method)
989{
990  unsigned int ifindex, instid, rtrid;
991  struct ospf6_interface *oi = NULL;
992  struct ospf6_neighbor  *on = NULL;
993  struct interface      *iif;
994  struct listnode *i, *j;
995  struct list *ifslist;
996  oid *offset;
997  int offsetlen, len;
998
999  if (smux_header_table (v, name, length, exact, var_len, write_method)
1000      == MATCH_FAILED)
1001    return NULL;
1002
1003  ifindex = instid = rtrid = 0;
1004
1005  /* Check OSPFv3 instance. */
1006  if (ospf6 == NULL)
1007    return NULL;
1008
1009  /* Get variable length. */
1010  offset = name + v->namelen;
1011  offsetlen = *length - v->namelen;
1012
1013  if (exact && offsetlen != 3)
1014    return NULL;
1015
1016  /* Parse if index */
1017  len = (offsetlen < 1 ? 0 : 1);
1018  if (len)
1019    ifindex = *offset;
1020  offset += len;
1021  offsetlen -= len;
1022
1023  /* Parse instance ID */
1024  len = (offsetlen < 1 ? 0 : 1);
1025  if (len)
1026    instid = *offset;
1027  offset += len;
1028  offsetlen -= len;
1029
1030  /* Parse router ID */
1031  len = (offsetlen < 1 ? 0 : 1);
1032  if (len)
1033    rtrid = htonl (*offset);
1034  offset += len;
1035  offsetlen -= len;
1036
1037  if (exact)
1038    {
1039      oi = ospf6_interface_lookup_by_ifindex (ifindex);
1040      if (!oi || oi->instance_id != instid) return NULL;
1041      on = ospf6_neighbor_lookup (rtrid, oi);
1042    }
1043  else
1044    {
1045      /* We build a sorted list of interfaces */
1046      ifslist = list_new ();
1047      if (!ifslist) return NULL;
1048      ifslist->cmp = (int (*)(void *, void *))if_icmp_func;
1049      for (ALL_LIST_ELEMENTS_RO (iflist, i, iif))
1050	listnode_add_sort (ifslist, iif);
1051
1052      for (ALL_LIST_ELEMENTS_RO (ifslist, i, iif))
1053        {
1054          if (!iif->ifindex) continue;
1055          oi = ospf6_interface_lookup_by_ifindex (iif->ifindex);
1056          if (!oi) continue;
1057          for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on)) {
1058            if (iif->ifindex > ifindex ||
1059                (iif->ifindex == ifindex &&
1060                 (oi->instance_id > instid ||
1061                  (oi->instance_id == instid &&
1062                   ntohl (on->router_id) > ntohl (rtrid)))))
1063              break;
1064          }
1065          if (on) break;
1066          oi = NULL;
1067          on = NULL;
1068        }
1069
1070      list_delete_all_node (ifslist);
1071    }
1072
1073  if (!oi || !on) return NULL;
1074
1075  /* Add Index (IfIndex, IfInstId, RtrId) */
1076  *length = v->namelen + 3;
1077  offset = name + v->namelen;
1078  *offset = oi->interface->ifindex;
1079  offset++;
1080  *offset = oi->instance_id;
1081  offset++;
1082  *offset = ntohl (on->router_id);
1083  offset++;
1084
1085  /* Return the current value of the variable */
1086  switch (v->magic)
1087    {
1088    case OSPFv3NBRADDRESSTYPE:
1089      return SNMP_INTEGER (2);	/* IPv6 only */
1090    case OSPFv3NBRADDRESS:
1091      *var_len = sizeof (struct in6_addr);
1092      return (u_char *) &on->linklocal_addr;
1093    case OSPFv3NBROPTIONS:
1094      return SNMP_INTEGER (on->options[2]);
1095    case OSPFv3NBRPRIORITY:
1096      return SNMP_INTEGER (on->priority);
1097    case OSPFv3NBRSTATE:
1098      return SNMP_INTEGER (on->state);
1099    case OSPFv3NBREVENTS:
1100      return SNMP_INTEGER (on->state_change);
1101    case OSPFv3NBRLSRETRANSQLEN:
1102      return SNMP_INTEGER (on->retrans_list->count);
1103    case OSPFv3NBRHELLOSUPPRESSED:
1104      return SNMP_INTEGER (SNMP_FALSE);
1105    case OSPFv3NBRIFID:
1106      return SNMP_INTEGER (on->ifindex);
1107    case OSPFv3NBRRESTARTHELPERSTATUS:
1108    case OSPFv3NBRRESTARTHELPERAGE:
1109    case OSPFv3NBRRESTARTHELPEREXITREASON:
1110      /* Not implemented. Only works if all the last ones are not
1111	 implemented! */
1112      return NULL;
1113    }
1114
1115  return NULL;
1116}
1117
1118/* OSPF Traps. */
1119#define NBRSTATECHANGE      2
1120#define IFSTATECHANGE      10
1121
1122static struct trap_object ospf6NbrTrapList[] =
1123{
1124  {-3, {1, 1, OSPFv3ROUTERID}},
1125  {4, {1, 9, 1, OSPFv3NBRADDRESSTYPE}},
1126  {4, {1, 9, 1, OSPFv3NBRADDRESS}},
1127  {4, {1, 9, 1, OSPFv3NBRSTATE}}
1128};
1129
1130static struct trap_object ospf6IfTrapList[] =
1131{
1132  {-3, {1, 1, OSPFv3ROUTERID}},
1133  {4, {1, 7, 1, OSPFv3IFSTATE}},
1134  {4, {1, 7, 1, OSPFv3IFADMINSTATUS}},
1135  {4, {1, 7, 1, OSPFv3IFAREAID}}
1136};
1137
1138void
1139ospf6TrapNbrStateChange (struct ospf6_neighbor *on)
1140{
1141  oid index[3];
1142
1143  index[0] = on->ospf6_if->interface->ifindex;
1144  index[1] = on->ospf6_if->instance_id;
1145  index[2] = ntohl (on->router_id);
1146
1147  smux_trap (ospfv3_variables, sizeof ospfv3_variables / sizeof (struct variable),
1148	     ospfv3_trap_oid, sizeof ospfv3_trap_oid / sizeof (oid),
1149	     ospfv3_oid, sizeof ospfv3_oid / sizeof (oid),
1150             index,  3,
1151             ospf6NbrTrapList,
1152             sizeof ospf6NbrTrapList / sizeof (struct trap_object),
1153             NBRSTATECHANGE);
1154}
1155
1156void
1157ospf6TrapIfStateChange (struct ospf6_interface *oi)
1158{
1159  oid index[2];
1160
1161  index[0] = oi->interface->ifindex;
1162  index[1] = oi->instance_id;
1163
1164  smux_trap (ospfv3_variables, sizeof ospfv3_variables / sizeof (struct variable),
1165	     ospfv3_trap_oid, sizeof ospfv3_trap_oid / sizeof (oid),
1166	     ospfv3_oid, sizeof ospfv3_oid / sizeof (oid),
1167             index,  2,
1168             ospf6IfTrapList,
1169             sizeof ospf6IfTrapList / sizeof (struct trap_object),
1170             IFSTATECHANGE);
1171}
1172
1173/* Register OSPFv3-MIB. */
1174void
1175ospf6_snmp_init (struct thread_master *master)
1176{
1177  smux_init (master);
1178  REGISTER_MIB ("OSPFv3MIB", ospfv3_variables, variable, ospfv3_oid);
1179}
1180
1181#endif /* HAVE_SNMP */
1182
1183