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