]> git.proxmox.com Git - mirror_frr.git/blame - ospfd/ospf_snmp.c
*: use hooks for sending SNMP traps
[mirror_frr.git] / ospfd / ospf_snmp.c
CommitLineData
718e3744 1/* OSPFv2 SNMP support
ba682537 2 * Copyright (C) 2005 6WIND <alain.ritoux@6wind.com>
718e3744 3 * Copyright (C) 2000 IP Infusion Inc.
4 *
5 * Written by Kunihiro Ishiguro <kunihiro@zebra.org>
6 *
7 * This file is part of GNU Zebra.
8 *
9 * GNU Zebra is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2, or (at your option) any
12 * later version.
13 *
14 * GNU Zebra is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with GNU Zebra; see the file COPYING. If not, write to the Free
21 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22 * 02111-1307, USA.
23 */
24
25#include <zebra.h>
26
27#ifdef HAVE_SNMP
07661cb5 28#include <net-snmp/net-snmp-config.h>
fb62a3ce 29#include <net-snmp/net-snmp-includes.h>
718e3744 30
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
39#include "ospfd/ospfd.h"
40#include "ospfd/ospf_interface.h"
41#include "ospfd/ospf_asbr.h"
42#include "ospfd/ospf_lsa.h"
43#include "ospfd/ospf_lsdb.h"
44#include "ospfd/ospf_abr.h"
45#include "ospfd/ospf_neighbor.h"
46#include "ospfd/ospf_nsm.h"
47#include "ospfd/ospf_flood.h"
e6217879 48#include "ospfd/ospf_ism.h"
9aecfae2 49#include "ospfd/ospf_dump.h"
3012671f 50#include "ospfd/ospf_zebra.h"
6b0655a2 51
718e3744 52/* OSPF2-MIB. */
53#define OSPF2MIB 1,3,6,1,2,1,14
54
718e3744 55/* OSPF MIB General Group values. */
56#define OSPFROUTERID 1
57#define OSPFADMINSTAT 2
58#define OSPFVERSIONNUMBER 3
59#define OSPFAREABDRRTRSTATUS 4
60#define OSPFASBDRRTRSTATUS 5
61#define OSPFEXTERNLSACOUNT 6
62#define OSPFEXTERNLSACKSUMSUM 7
63#define OSPFTOSSUPPORT 8
64#define OSPFORIGINATENEWLSAS 9
65#define OSPFRXNEWLSAS 10
66#define OSPFEXTLSDBLIMIT 11
67#define OSPFMULTICASTEXTENSIONS 12
68#define OSPFEXITOVERFLOWINTERVAL 13
69#define OSPFDEMANDEXTENSIONS 14
70
71/* OSPF MIB ospfAreaTable. */
72#define OSPFAREAID 1
73#define OSPFAUTHTYPE 2
74#define OSPFIMPORTASEXTERN 3
75#define OSPFSPFRUNS 4
76#define OSPFAREABDRRTRCOUNT 5
77#define OSPFASBDRRTRCOUNT 6
78#define OSPFAREALSACOUNT 7
79#define OSPFAREALSACKSUMSUM 8
80#define OSPFAREASUMMARY 9
81#define OSPFAREASTATUS 10
82
83/* OSPF MIB ospfStubAreaTable. */
84#define OSPFSTUBAREAID 1
85#define OSPFSTUBTOS 2
86#define OSPFSTUBMETRIC 3
87#define OSPFSTUBSTATUS 4
88#define OSPFSTUBMETRICTYPE 5
89
90/* OSPF MIB ospfLsdbTable. */
91#define OSPFLSDBAREAID 1
92#define OSPFLSDBTYPE 2
93#define OSPFLSDBLSID 3
94#define OSPFLSDBROUTERID 4
95#define OSPFLSDBSEQUENCE 5
96#define OSPFLSDBAGE 6
97#define OSPFLSDBCHECKSUM 7
98#define OSPFLSDBADVERTISEMENT 8
99
100/* OSPF MIB ospfAreaRangeTable. */
101#define OSPFAREARANGEAREAID 1
102#define OSPFAREARANGENET 2
103#define OSPFAREARANGEMASK 3
104#define OSPFAREARANGESTATUS 4
105#define OSPFAREARANGEEFFECT 5
106
107/* OSPF MIB ospfHostTable. */
108#define OSPFHOSTIPADDRESS 1
109#define OSPFHOSTTOS 2
110#define OSPFHOSTMETRIC 3
111#define OSPFHOSTSTATUS 4
112#define OSPFHOSTAREAID 5
113
114/* OSPF MIB ospfIfTable. */
115#define OSPFIFIPADDRESS 1
116#define OSPFADDRESSLESSIF 2
117#define OSPFIFAREAID 3
118#define OSPFIFTYPE 4
119#define OSPFIFADMINSTAT 5
120#define OSPFIFRTRPRIORITY 6
121#define OSPFIFTRANSITDELAY 7
122#define OSPFIFRETRANSINTERVAL 8
123#define OSPFIFHELLOINTERVAL 9
124#define OSPFIFRTRDEADINTERVAL 10
125#define OSPFIFPOLLINTERVAL 11
126#define OSPFIFSTATE 12
127#define OSPFIFDESIGNATEDROUTER 13
128#define OSPFIFBACKUPDESIGNATEDROUTER 14
129#define OSPFIFEVENTS 15
130#define OSPFIFAUTHKEY 16
131#define OSPFIFSTATUS 17
132#define OSPFIFMULTICASTFORWARDING 18
133#define OSPFIFDEMAND 19
134#define OSPFIFAUTHTYPE 20
135
136/* OSPF MIB ospfIfMetricTable. */
137#define OSPFIFMETRICIPADDRESS 1
138#define OSPFIFMETRICADDRESSLESSIF 2
139#define OSPFIFMETRICTOS 3
140#define OSPFIFMETRICVALUE 4
141#define OSPFIFMETRICSTATUS 5
142
143/* OSPF MIB ospfVirtIfTable. */
144#define OSPFVIRTIFAREAID 1
145#define OSPFVIRTIFNEIGHBOR 2
146#define OSPFVIRTIFTRANSITDELAY 3
147#define OSPFVIRTIFRETRANSINTERVAL 4
148#define OSPFVIRTIFHELLOINTERVAL 5
149#define OSPFVIRTIFRTRDEADINTERVAL 6
150#define OSPFVIRTIFSTATE 7
151#define OSPFVIRTIFEVENTS 8
152#define OSPFVIRTIFAUTHKEY 9
153#define OSPFVIRTIFSTATUS 10
154#define OSPFVIRTIFAUTHTYPE 11
155
156/* OSPF MIB ospfNbrTable. */
157#define OSPFNBRIPADDR 1
158#define OSPFNBRADDRESSLESSINDEX 2
159#define OSPFNBRRTRID 3
160#define OSPFNBROPTIONS 4
161#define OSPFNBRPRIORITY 5
162#define OSPFNBRSTATE 6
163#define OSPFNBREVENTS 7
164#define OSPFNBRLSRETRANSQLEN 8
165#define OSPFNBMANBRSTATUS 9
166#define OSPFNBMANBRPERMANENCE 10
167#define OSPFNBRHELLOSUPPRESSED 11
168
169/* OSPF MIB ospfVirtNbrTable. */
170#define OSPFVIRTNBRAREA 1
171#define OSPFVIRTNBRRTRID 2
172#define OSPFVIRTNBRIPADDR 3
173#define OSPFVIRTNBROPTIONS 4
174#define OSPFVIRTNBRSTATE 5
175#define OSPFVIRTNBREVENTS 6
176#define OSPFVIRTNBRLSRETRANSQLEN 7
177#define OSPFVIRTNBRHELLOSUPPRESSED 8
178
179/* OSPF MIB ospfExtLsdbTable. */
180#define OSPFEXTLSDBTYPE 1
181#define OSPFEXTLSDBLSID 2
182#define OSPFEXTLSDBROUTERID 3
183#define OSPFEXTLSDBSEQUENCE 4
184#define OSPFEXTLSDBAGE 5
185#define OSPFEXTLSDBCHECKSUM 6
186#define OSPFEXTLSDBADVERTISEMENT 7
187
188/* OSPF MIB ospfAreaAggregateTable. */
189#define OSPFAREAAGGREGATEAREAID 1
190#define OSPFAREAAGGREGATELSDBTYPE 2
191#define OSPFAREAAGGREGATENET 3
192#define OSPFAREAAGGREGATEMASK 4
193#define OSPFAREAAGGREGATESTATUS 5
194#define OSPFAREAAGGREGATEEFFECT 6
195
196/* SYNTAX Status from OSPF-MIB. */
197#define OSPF_STATUS_ENABLED 1
198#define OSPF_STATUS_DISABLED 2
199
200/* SNMP value hack. */
201#define COUNTER ASN_COUNTER
202#define INTEGER ASN_INTEGER
203#define GAUGE ASN_GAUGE
204#define TIMETICKS ASN_TIMETICKS
205#define IPADDRESS ASN_IPADDRESS
206#define STRING ASN_OCTET_STR
6b0655a2 207
3012671f
DL
208/* Because DR/DROther values are exhanged wrt RFC */
209#define ISM_SNMP(x) (((x) == ISM_DROther) ? ISM_DR : \
210 ((x) == ISM_DR) ? ISM_DROther : (x))
211
718e3744 212/* Declare static local variables for convenience. */
213SNMP_LOCAL_VARIABLES
214
215/* OSPF-MIB instances. */
1c6f50bf
DL
216static oid ospf_oid [] = { OSPF2MIB };
217static oid ospf_trap_oid [] = { OSPF2MIB, 16, 2 }; /* Not reverse mappable! */
718e3744 218
219/* IP address 0.0.0.0. */
19c3598b 220static struct in_addr ospf_empty_addr = { .s_addr = 0 };
718e3744 221
222/* Hook functions. */
0be8dfb2
CC
223static u_char *ospfGeneralGroup (struct variable *, oid *, size_t *,
224 int, size_t *, WriteMethod **);
225static u_char *ospfAreaEntry (struct variable *, oid *, size_t *, int,
226 size_t *, WriteMethod **);
227static u_char *ospfStubAreaEntry (struct variable *, oid *, size_t *,
228 int, size_t *, WriteMethod **);
229static u_char *ospfLsdbEntry (struct variable *, oid *, size_t *, int,
230 size_t *, WriteMethod **);
231static u_char *ospfAreaRangeEntry (struct variable *, oid *, size_t *, int,
232 size_t *, WriteMethod **);
233static u_char *ospfHostEntry (struct variable *, oid *, size_t *, int,
234 size_t *, WriteMethod **);
235static u_char *ospfIfEntry (struct variable *, oid *, size_t *, int,
236 size_t *, WriteMethod **);
237static u_char *ospfIfMetricEntry (struct variable *, oid *, size_t *, int,
238 size_t *, WriteMethod **);
239static u_char *ospfVirtIfEntry (struct variable *, oid *, size_t *, int,
240 size_t *, WriteMethod **);
241static u_char *ospfNbrEntry (struct variable *, oid *, size_t *, int,
242 size_t *, WriteMethod **);
243static u_char *ospfVirtNbrEntry (struct variable *, oid *, size_t *, int,
244 size_t *, WriteMethod **);
245static u_char *ospfExtLsdbEntry (struct variable *, oid *, size_t *, int,
246 size_t *, WriteMethod **);
247static u_char *ospfAreaAggregateEntry (struct variable *, oid *, size_t *,
248 int, size_t *, WriteMethod **);
718e3744 249
1c6f50bf 250static struct variable ospf_variables[] =
718e3744 251{
252 /* OSPF general variables */
253 {OSPFROUTERID, IPADDRESS, RWRITE, ospfGeneralGroup,
254 2, {1, 1}},
255 {OSPFADMINSTAT, INTEGER, RWRITE, ospfGeneralGroup,
256 2, {1, 2}},
257 {OSPFVERSIONNUMBER, INTEGER, RONLY, ospfGeneralGroup,
258 2, {1, 3}},
259 {OSPFAREABDRRTRSTATUS, INTEGER, RONLY, ospfGeneralGroup,
260 2, {1, 4}},
261 {OSPFASBDRRTRSTATUS, INTEGER, RWRITE, ospfGeneralGroup,
262 2, {1, 5}},
263 {OSPFEXTERNLSACOUNT, GAUGE, RONLY, ospfGeneralGroup,
264 2, {1, 6}},
265 {OSPFEXTERNLSACKSUMSUM, INTEGER, RONLY, ospfGeneralGroup,
266 2, {1, 7}},
267 {OSPFTOSSUPPORT, INTEGER, RWRITE, ospfGeneralGroup,
268 2, {1, 8}},
269 {OSPFORIGINATENEWLSAS, COUNTER, RONLY, ospfGeneralGroup,
270 2, {1, 9}},
271 {OSPFRXNEWLSAS, COUNTER, RONLY, ospfGeneralGroup,
272 2, {1, 10}},
273 {OSPFEXTLSDBLIMIT, INTEGER, RWRITE, ospfGeneralGroup,
274 2, {1, 11}},
275 {OSPFMULTICASTEXTENSIONS, INTEGER, RWRITE, ospfGeneralGroup,
276 2, {1, 12}},
277 {OSPFEXITOVERFLOWINTERVAL, INTEGER, RWRITE, ospfGeneralGroup,
278 2, {1, 13}},
279 {OSPFDEMANDEXTENSIONS, INTEGER, RWRITE, ospfGeneralGroup,
280 2, {1, 14}},
281
282 /* OSPF area data structure. */
283 {OSPFAREAID, IPADDRESS, RONLY, ospfAreaEntry,
284 3, {2, 1, 1}},
285 {OSPFAUTHTYPE, INTEGER, RWRITE, ospfAreaEntry,
286 3, {2, 1, 2}},
287 {OSPFIMPORTASEXTERN, INTEGER, RWRITE, ospfAreaEntry,
288 3, {2, 1, 3}},
289 {OSPFSPFRUNS, COUNTER, RONLY, ospfAreaEntry,
290 3, {2, 1, 4}},
291 {OSPFAREABDRRTRCOUNT, GAUGE, RONLY, ospfAreaEntry,
292 3, {2, 1, 5}},
293 {OSPFASBDRRTRCOUNT, GAUGE, RONLY, ospfAreaEntry,
294 3, {2, 1, 6}},
295 {OSPFAREALSACOUNT, GAUGE, RONLY, ospfAreaEntry,
296 3, {2, 1, 7}},
297 {OSPFAREALSACKSUMSUM, INTEGER, RONLY, ospfAreaEntry,
298 3, {2, 1, 8}},
299 {OSPFAREASUMMARY, INTEGER, RWRITE, ospfAreaEntry,
300 3, {2, 1, 9}},
301 {OSPFAREASTATUS, INTEGER, RWRITE, ospfAreaEntry,
302 3, {2, 1, 10}},
303
304 /* OSPF stub area information. */
305 {OSPFSTUBAREAID, IPADDRESS, RONLY, ospfStubAreaEntry,
306 3, {3, 1, 1}},
307 {OSPFSTUBTOS, INTEGER, RONLY, ospfStubAreaEntry,
308 3, {3, 1, 2}},
309 {OSPFSTUBMETRIC, INTEGER, RWRITE, ospfStubAreaEntry,
310 3, {3, 1, 3}},
311 {OSPFSTUBSTATUS, INTEGER, RWRITE, ospfStubAreaEntry,
312 3, {3, 1, 4}},
313 {OSPFSTUBMETRICTYPE, INTEGER, RWRITE, ospfStubAreaEntry,
314 3, {3, 1, 5}},
315
316 /* OSPF link state database. */
317 {OSPFLSDBAREAID, IPADDRESS, RONLY, ospfLsdbEntry,
318 3, {4, 1, 1}},
319 {OSPFLSDBTYPE, INTEGER, RONLY, ospfLsdbEntry,
320 3, {4, 1, 2}},
321 {OSPFLSDBLSID, IPADDRESS, RONLY, ospfLsdbEntry,
322 3, {4, 1, 3}},
323 {OSPFLSDBROUTERID, IPADDRESS, RONLY, ospfLsdbEntry,
324 3, {4, 1, 4}},
325 {OSPFLSDBSEQUENCE, INTEGER, RONLY, ospfLsdbEntry,
326 3, {4, 1, 5}},
327 {OSPFLSDBAGE, INTEGER, RONLY, ospfLsdbEntry,
328 3, {4, 1, 6}},
329 {OSPFLSDBCHECKSUM, INTEGER, RONLY, ospfLsdbEntry,
330 3, {4, 1, 7}},
331 {OSPFLSDBADVERTISEMENT, STRING, RONLY, ospfLsdbEntry,
332 3, {4, 1, 8}},
333
334 /* Area range table. */
335 {OSPFAREARANGEAREAID, IPADDRESS, RONLY, ospfAreaRangeEntry,
336 3, {5, 1, 1}},
337 {OSPFAREARANGENET, IPADDRESS, RONLY, ospfAreaRangeEntry,
338 3, {5, 1, 2}},
339 {OSPFAREARANGEMASK, IPADDRESS, RWRITE, ospfAreaRangeEntry,
340 3, {5, 1, 3}},
341 {OSPFAREARANGESTATUS, INTEGER, RWRITE, ospfAreaRangeEntry,
342 3, {5, 1, 4}},
343 {OSPFAREARANGEEFFECT, INTEGER, RWRITE, ospfAreaRangeEntry,
344 3, {5, 1, 5}},
345
346 /* OSPF host table. */
347 {OSPFHOSTIPADDRESS, IPADDRESS, RONLY, ospfHostEntry,
348 3, {6, 1, 1}},
349 {OSPFHOSTTOS, INTEGER, RONLY, ospfHostEntry,
350 3, {6, 1, 2}},
351 {OSPFHOSTMETRIC, INTEGER, RWRITE, ospfHostEntry,
352 3, {6, 1, 3}},
353 {OSPFHOSTSTATUS, INTEGER, RWRITE, ospfHostEntry,
354 3, {6, 1, 4}},
355 {OSPFHOSTAREAID, IPADDRESS, RONLY, ospfHostEntry,
356 3, {6, 1, 5}},
357
358 /* OSPF interface table. */
359 {OSPFIFIPADDRESS, IPADDRESS, RONLY, ospfIfEntry,
360 3, {7, 1, 1}},
361 {OSPFADDRESSLESSIF, INTEGER, RONLY, ospfIfEntry,
362 3, {7, 1, 2}},
363 {OSPFIFAREAID, IPADDRESS, RWRITE, ospfIfEntry,
364 3, {7, 1, 3}},
365 {OSPFIFTYPE, INTEGER, RWRITE, ospfIfEntry,
366 3, {7, 1, 4}},
367 {OSPFIFADMINSTAT, INTEGER, RWRITE, ospfIfEntry,
368 3, {7, 1, 5}},
369 {OSPFIFRTRPRIORITY, INTEGER, RWRITE, ospfIfEntry,
370 3, {7, 1, 6}},
371 {OSPFIFTRANSITDELAY, INTEGER, RWRITE, ospfIfEntry,
372 3, {7, 1, 7}},
373 {OSPFIFRETRANSINTERVAL, INTEGER, RWRITE, ospfIfEntry,
374 3, {7, 1, 8}},
375 {OSPFIFHELLOINTERVAL, INTEGER, RWRITE, ospfIfEntry,
376 3, {7, 1, 9}},
377 {OSPFIFRTRDEADINTERVAL, INTEGER, RWRITE, ospfIfEntry,
378 3, {7, 1, 10}},
379 {OSPFIFPOLLINTERVAL, INTEGER, RWRITE, ospfIfEntry,
380 3, {7, 1, 11}},
381 {OSPFIFSTATE, INTEGER, RONLY, ospfIfEntry,
382 3, {7, 1, 12}},
383 {OSPFIFDESIGNATEDROUTER, IPADDRESS, RONLY, ospfIfEntry,
384 3, {7, 1, 13}},
385 {OSPFIFBACKUPDESIGNATEDROUTER, IPADDRESS, RONLY, ospfIfEntry,
386 3, {7, 1, 14}},
387 {OSPFIFEVENTS, COUNTER, RONLY, ospfIfEntry,
388 3, {7, 1, 15}},
389 {OSPFIFAUTHKEY, STRING, RWRITE, ospfIfEntry,
390 3, {7, 1, 16}},
391 {OSPFIFSTATUS, INTEGER, RWRITE, ospfIfEntry,
392 3, {7, 1, 17}},
393 {OSPFIFMULTICASTFORWARDING, INTEGER, RWRITE, ospfIfEntry,
394 3, {7, 1, 18}},
395 {OSPFIFDEMAND, INTEGER, RWRITE, ospfIfEntry,
396 3, {7, 1, 19}},
397 {OSPFIFAUTHTYPE, INTEGER, RWRITE, ospfIfEntry,
398 3, {7, 1, 20}},
399
400 /* OSPF interface metric table. */
401 {OSPFIFMETRICIPADDRESS, IPADDRESS, RONLY, ospfIfMetricEntry,
402 3, {8, 1, 1}},
403 {OSPFIFMETRICADDRESSLESSIF, INTEGER, RONLY, ospfIfMetricEntry,
404 3, {8, 1, 2}},
405 {OSPFIFMETRICTOS, INTEGER, RONLY, ospfIfMetricEntry,
406 3, {8, 1, 3}},
407 {OSPFIFMETRICVALUE, INTEGER, RWRITE, ospfIfMetricEntry,
408 3, {8, 1, 4}},
409 {OSPFIFMETRICSTATUS, INTEGER, RWRITE, ospfIfMetricEntry,
410 3, {8, 1, 5}},
411
412 /* OSPF virtual interface table. */
413 {OSPFVIRTIFAREAID, IPADDRESS, RONLY, ospfVirtIfEntry,
414 3, {9, 1, 1}},
415 {OSPFVIRTIFNEIGHBOR, IPADDRESS, RONLY, ospfVirtIfEntry,
416 3, {9, 1, 2}},
417 {OSPFVIRTIFTRANSITDELAY, INTEGER, RWRITE, ospfVirtIfEntry,
418 3, {9, 1, 3}},
419 {OSPFVIRTIFRETRANSINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry,
420 3, {9, 1, 4}},
421 {OSPFVIRTIFHELLOINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry,
422 3, {9, 1, 5}},
423 {OSPFVIRTIFRTRDEADINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry,
424 3, {9, 1, 6}},
425 {OSPFVIRTIFSTATE, INTEGER, RONLY, ospfVirtIfEntry,
426 3, {9, 1, 7}},
427 {OSPFVIRTIFEVENTS, COUNTER, RONLY, ospfVirtIfEntry,
428 3, {9, 1, 8}},
429 {OSPFVIRTIFAUTHKEY, STRING, RWRITE, ospfVirtIfEntry,
430 3, {9, 1, 9}},
431 {OSPFVIRTIFSTATUS, INTEGER, RWRITE, ospfVirtIfEntry,
432 3, {9, 1, 10}},
433 {OSPFVIRTIFAUTHTYPE, INTEGER, RWRITE, ospfVirtIfEntry,
434 3, {9, 1, 11}},
435
436 /* OSPF neighbor table. */
437 {OSPFNBRIPADDR, IPADDRESS, RONLY, ospfNbrEntry,
438 3, {10, 1, 1}},
439 {OSPFNBRADDRESSLESSINDEX, INTEGER, RONLY, ospfNbrEntry,
440 3, {10, 1, 2}},
441 {OSPFNBRRTRID, IPADDRESS, RONLY, ospfNbrEntry,
442 3, {10, 1, 3}},
443 {OSPFNBROPTIONS, INTEGER, RONLY, ospfNbrEntry,
444 3, {10, 1, 4}},
445 {OSPFNBRPRIORITY, INTEGER, RWRITE, ospfNbrEntry,
446 3, {10, 1, 5}},
447 {OSPFNBRSTATE, INTEGER, RONLY, ospfNbrEntry,
448 3, {10, 1, 6}},
449 {OSPFNBREVENTS, COUNTER, RONLY, ospfNbrEntry,
450 3, {10, 1, 7}},
451 {OSPFNBRLSRETRANSQLEN, GAUGE, RONLY, ospfNbrEntry,
452 3, {10, 1, 8}},
453 {OSPFNBMANBRSTATUS, INTEGER, RWRITE, ospfNbrEntry,
454 3, {10, 1, 9}},
455 {OSPFNBMANBRPERMANENCE, INTEGER, RONLY, ospfNbrEntry,
456 3, {10, 1, 10}},
457 {OSPFNBRHELLOSUPPRESSED, INTEGER, RONLY, ospfNbrEntry,
458 3, {10, 1, 11}},
459
460 /* OSPF virtual neighbor table. */
461 {OSPFVIRTNBRAREA, IPADDRESS, RONLY, ospfVirtNbrEntry,
462 3, {11, 1, 1}},
463 {OSPFVIRTNBRRTRID, IPADDRESS, RONLY, ospfVirtNbrEntry,
464 3, {11, 1, 2}},
465 {OSPFVIRTNBRIPADDR, IPADDRESS, RONLY, ospfVirtNbrEntry,
466 3, {11, 1, 3}},
467 {OSPFVIRTNBROPTIONS, INTEGER, RONLY, ospfVirtNbrEntry,
468 3, {11, 1, 4}},
469 {OSPFVIRTNBRSTATE, INTEGER, RONLY, ospfVirtNbrEntry,
470 3, {11, 1, 5}},
471 {OSPFVIRTNBREVENTS, COUNTER, RONLY, ospfVirtNbrEntry,
472 3, {11, 1, 6}},
473 {OSPFVIRTNBRLSRETRANSQLEN, INTEGER, RONLY, ospfVirtNbrEntry,
474 3, {11, 1, 7}},
475 {OSPFVIRTNBRHELLOSUPPRESSED, INTEGER, RONLY, ospfVirtNbrEntry,
476 3, {11, 1, 8}},
477
478 /* OSPF link state database, external. */
479 {OSPFEXTLSDBTYPE, INTEGER, RONLY, ospfExtLsdbEntry,
480 3, {12, 1, 1}},
481 {OSPFEXTLSDBLSID, IPADDRESS, RONLY, ospfExtLsdbEntry,
482 3, {12, 1, 2}},
483 {OSPFEXTLSDBROUTERID, IPADDRESS, RONLY, ospfExtLsdbEntry,
484 3, {12, 1, 3}},
485 {OSPFEXTLSDBSEQUENCE, INTEGER, RONLY, ospfExtLsdbEntry,
486 3, {12, 1, 4}},
487 {OSPFEXTLSDBAGE, INTEGER, RONLY, ospfExtLsdbEntry,
488 3, {12, 1, 5}},
489 {OSPFEXTLSDBCHECKSUM, INTEGER, RONLY, ospfExtLsdbEntry,
490 3, {12, 1, 6}},
491 {OSPFEXTLSDBADVERTISEMENT, STRING, RONLY, ospfExtLsdbEntry,
492 3, {12, 1, 7}},
493
494 /* OSPF area aggregate table. */
495 {OSPFAREAAGGREGATEAREAID, IPADDRESS, RONLY, ospfAreaAggregateEntry,
496 3, {14, 1, 1}},
497 {OSPFAREAAGGREGATELSDBTYPE, INTEGER, RONLY, ospfAreaAggregateEntry,
498 3, {14, 1, 2}},
499 {OSPFAREAAGGREGATENET, IPADDRESS, RONLY, ospfAreaAggregateEntry,
500 3, {14, 1, 3}},
501 {OSPFAREAAGGREGATEMASK, IPADDRESS, RONLY, ospfAreaAggregateEntry,
502 3, {14, 1, 4}},
503 {OSPFAREAAGGREGATESTATUS, INTEGER, RWRITE, ospfAreaAggregateEntry,
504 3, {14, 1, 5}},
505 {OSPFAREAAGGREGATEEFFECT, INTEGER, RWRITE, ospfAreaAggregateEntry,
506 3, {14, 1, 6}}
507};
6b0655a2 508
718e3744 509/* The administrative status of OSPF. When OSPF is enbled on at least
510 one interface return 1. */
0be8dfb2 511static int
68980084 512ospf_admin_stat (struct ospf *ospf)
718e3744 513{
aa20c6f1 514 struct listnode *node;
718e3744 515 struct ospf_interface *oi;
516
68980084 517 if (ospf == NULL)
718e3744 518 return 0;
519
1eb8ef25 520 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
521 if (oi && oi->address)
522 return 1;
718e3744 523
718e3744 524 return 0;
525}
526
527static u_char *
528ospfGeneralGroup (struct variable *v, oid *name, size_t *length,
529 int exact, size_t *var_len, WriteMethod **write_method)
530{
020709f9 531 struct ospf *ospf;
532
533 ospf = ospf_lookup ();
68980084 534
718e3744 535 /* Check whether the instance identifier is valid */
536 if (smux_header_generic (v, name, length, exact, var_len, write_method)
537 == MATCH_FAILED)
538 return NULL;
539
540 /* Return the current value of the variable */
541 switch (v->magic)
542 {
543 case OSPFROUTERID: /* 1 */
544 /* Router-ID of this OSPF instance. */
68980084 545 if (ospf)
546 return SNMP_IPADDRESS (ospf->router_id);
718e3744 547 else
548 return SNMP_IPADDRESS (ospf_empty_addr);
549 break;
550 case OSPFADMINSTAT: /* 2 */
551 /* The administrative status of OSPF in the router. */
68980084 552 if (ospf_admin_stat (ospf))
718e3744 553 return SNMP_INTEGER (OSPF_STATUS_ENABLED);
554 else
555 return SNMP_INTEGER (OSPF_STATUS_DISABLED);
556 break;
557 case OSPFVERSIONNUMBER: /* 3 */
558 /* OSPF version 2. */
559 return SNMP_INTEGER (OSPF_VERSION);
560 break;
561 case OSPFAREABDRRTRSTATUS: /* 4 */
562 /* Area Border router status. */
68980084 563 if (ospf && CHECK_FLAG (ospf->flags, OSPF_FLAG_ABR))
718e3744 564 return SNMP_INTEGER (SNMP_TRUE);
565 else
566 return SNMP_INTEGER (SNMP_FALSE);
567 break;
568 case OSPFASBDRRTRSTATUS: /* 5 */
569 /* AS Border router status. */
68980084 570 if (ospf && CHECK_FLAG (ospf->flags, OSPF_FLAG_ASBR))
718e3744 571 return SNMP_INTEGER (SNMP_TRUE);
572 else
573 return SNMP_INTEGER (SNMP_FALSE);
574 break;
575 case OSPFEXTERNLSACOUNT: /* 6 */
576 /* External LSA counts. */
68980084 577 if (ospf)
578 return SNMP_INTEGER (ospf_lsdb_count_all (ospf->lsdb));
718e3744 579 else
580 return SNMP_INTEGER (0);
581 break;
582 case OSPFEXTERNLSACKSUMSUM: /* 7 */
583 /* External LSA checksum. */
584 return SNMP_INTEGER (0);
585 break;
586 case OSPFTOSSUPPORT: /* 8 */
587 /* TOS is not supported. */
588 return SNMP_INTEGER (SNMP_FALSE);
589 break;
590 case OSPFORIGINATENEWLSAS: /* 9 */
591 /* The number of new link-state advertisements. */
68980084 592 if (ospf)
593 return SNMP_INTEGER (ospf->lsa_originate_count);
718e3744 594 else
595 return SNMP_INTEGER (0);
596 break;
597 case OSPFRXNEWLSAS: /* 10 */
598 /* The number of link-state advertisements received determined
599 to be new instantiations. */
68980084 600 if (ospf)
601 return SNMP_INTEGER (ospf->rx_lsa_count);
718e3744 602 else
603 return SNMP_INTEGER (0);
604 break;
605 case OSPFEXTLSDBLIMIT: /* 11 */
606 /* There is no limit for the number of non-default
607 AS-external-LSAs. */
608 return SNMP_INTEGER (-1);
609 break;
610 case OSPFMULTICASTEXTENSIONS: /* 12 */
611 /* Multicast Extensions to OSPF is not supported. */
612 return SNMP_INTEGER (0);
613 break;
614 case OSPFEXITOVERFLOWINTERVAL: /* 13 */
615 /* Overflow is not supported. */
616 return SNMP_INTEGER (0);
617 break;
618 case OSPFDEMANDEXTENSIONS: /* 14 */
619 /* Demand routing is not supported. */
620 return SNMP_INTEGER (SNMP_FALSE);
621 break;
622 default:
623 return NULL;
624 }
625 return NULL;
626}
627
0be8dfb2 628static struct ospf_area *
68980084 629ospf_area_lookup_next (struct ospf *ospf, struct in_addr *area_id, int first)
718e3744 630{
631 struct ospf_area *area;
aa20c6f1 632 struct listnode *node;
718e3744 633
020709f9 634 if (ospf == NULL)
718e3744 635 return NULL;
636
637 if (first)
638 {
68980084 639 node = listhead (ospf->areas);
718e3744 640 if (node)
641 {
1eb8ef25 642 area = listgetdata (node);
718e3744 643 *area_id = area->area_id;
644 return area;
645 }
646 return NULL;
647 }
1eb8ef25 648 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
718e3744 649 {
718e3744 650 if (ntohl (area->area_id.s_addr) > ntohl (area_id->s_addr))
651 {
652 *area_id = area->area_id;
653 return area;
654 }
655 }
656 return NULL;
657}
658
0be8dfb2 659static struct ospf_area *
718e3744 660ospfAreaLookup (struct variable *v, oid name[], size_t *length,
661 struct in_addr *addr, int exact)
662{
020709f9 663 struct ospf *ospf;
718e3744 664 struct ospf_area *area;
68980084 665 int len;
718e3744 666
020709f9 667 ospf = ospf_lookup ();
68980084 668 if (ospf == NULL)
718e3744 669 return NULL;
670
671 if (exact)
672 {
673 /* Length is insufficient to lookup OSPF area. */
674 if (*length - v->namelen != sizeof (struct in_addr))
675 return NULL;
676
677 oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr);
678
68980084 679 area = ospf_area_lookup_by_area_id (ospf, *addr);
718e3744 680
681 return area;
682 }
683 else
684 {
685 len = *length - v->namelen;
686 if (len > 4)
687 len = 4;
688
689 oid2in_addr (name + v->namelen, len, addr);
690
68980084 691 area = ospf_area_lookup_next (ospf, addr, len == 0 ? 1 : 0);
718e3744 692
693 if (area == NULL)
694 return NULL;
695
696 oid_copy_addr (name + v->namelen, addr, sizeof (struct in_addr));
697 *length = sizeof (struct in_addr) + v->namelen;
698
699 return area;
700 }
701 return NULL;
702}
703
704static u_char *
705ospfAreaEntry (struct variable *v, oid *name, size_t *length, int exact,
706 size_t *var_len, WriteMethod **write_method)
707{
708 struct ospf_area *area;
709 struct in_addr addr;
710
8046ba6e
VB
711 if (smux_header_table(v, name, length, exact, var_len, write_method)
712 == MATCH_FAILED)
713 return NULL;
714
718e3744 715 memset (&addr, 0, sizeof (struct in_addr));
716
717 area = ospfAreaLookup (v, name, length, &addr, exact);
718 if (! area)
719 return NULL;
720
721 /* Return the current value of the variable */
722 switch (v->magic)
723 {
724 case OSPFAREAID: /* 1 */
725 return SNMP_IPADDRESS (area->area_id);
726 break;
727 case OSPFAUTHTYPE: /* 2 */
728 return SNMP_INTEGER (area->auth_type);
729 break;
730 case OSPFIMPORTASEXTERN: /* 3 */
731 return SNMP_INTEGER (area->external_routing + 1);
732 break;
733 case OSPFSPFRUNS: /* 4 */
734 return SNMP_INTEGER (area->spf_calculation);
735 break;
736 case OSPFAREABDRRTRCOUNT: /* 5 */
737 return SNMP_INTEGER (area->abr_count);
738 break;
739 case OSPFASBDRRTRCOUNT: /* 6 */
740 return SNMP_INTEGER (area->asbr_count);
741 break;
742 case OSPFAREALSACOUNT: /* 7 */
743 return SNMP_INTEGER (area->lsdb->total);
744 break;
745 case OSPFAREALSACKSUMSUM: /* 8 */
746 return SNMP_INTEGER (0);
747 break;
748 case OSPFAREASUMMARY: /* 9 */
749#define OSPF_noAreaSummary 1
750#define OSPF_sendAreaSummary 2
751 if (area->no_summary)
752 return SNMP_INTEGER (OSPF_noAreaSummary);
753 else
754 return SNMP_INTEGER (OSPF_sendAreaSummary);
755 break;
756 case OSPFAREASTATUS: /* 10 */
757 return SNMP_INTEGER (SNMP_VALID);
758 break;
759 default:
760 return NULL;
761 break;
762 }
763 return NULL;
764}
765
0be8dfb2 766static struct ospf_area *
718e3744 767ospf_stub_area_lookup_next (struct in_addr *area_id, int first)
768{
769 struct ospf_area *area;
aa20c6f1 770 struct listnode *node;
020709f9 771 struct ospf *ospf;
718e3744 772
020709f9 773 ospf = ospf_lookup ();
774 if (ospf == NULL)
718e3744 775 return NULL;
776
1eb8ef25 777 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
718e3744 778 {
718e3744 779 if (area->external_routing == OSPF_AREA_STUB)
780 {
781 if (first)
782 {
783 *area_id = area->area_id;
784 return area;
785 }
786 else if (ntohl (area->area_id.s_addr) > ntohl (area_id->s_addr))
787 {
788 *area_id = area->area_id;
789 return area;
790 }
791 }
792 }
793 return NULL;
794}
795
0be8dfb2 796static struct ospf_area *
718e3744 797ospfStubAreaLookup (struct variable *v, oid name[], size_t *length,
798 struct in_addr *addr, int exact)
799{
020709f9 800 struct ospf *ospf;
718e3744 801 struct ospf_area *area;
68980084 802 int len;
718e3744 803
020709f9 804 ospf = ospf_lookup ();
805 if (ospf == NULL)
718e3744 806 return NULL;
807
808 /* Exact lookup. */
809 if (exact)
810 {
811 /* ospfStubAreaID + ospfStubTOS. */
812 if (*length != v->namelen + sizeof (struct in_addr) + 1)
813 return NULL;
814
815 /* Check ospfStubTOS is zero. */
816 if (name[*length - 1] != 0)
817 return NULL;
818
819 oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr);
820
68980084 821 area = ospf_area_lookup_by_area_id (ospf, *addr);
718e3744 822
823 if (area->external_routing == OSPF_AREA_STUB)
824 return area;
825 else
826 return NULL;
827 }
828 else
829 {
830 len = *length - v->namelen;
831 if (len > 4)
832 len = 4;
833
834 oid2in_addr (name + v->namelen, len, addr);
835
836 area = ospf_stub_area_lookup_next (addr, len == 0 ? 1 : 0);
837
838 if (area == NULL)
839 return NULL;
840
841 oid_copy_addr (name + v->namelen, addr, sizeof (struct in_addr));
842 /* Set TOS 0. */
843 name[v->namelen + sizeof (struct in_addr)] = 0;
844 *length = v->namelen + sizeof (struct in_addr) + 1;
845
846 return area;
847 }
848 return NULL;
849}
850
851static u_char *
852ospfStubAreaEntry (struct variable *v, oid *name, size_t *length,
853 int exact, size_t *var_len, WriteMethod **write_method)
854{
855 struct ospf_area *area;
856 struct in_addr addr;
857
8046ba6e
VB
858 if (smux_header_table(v, name, length, exact, var_len, write_method)
859 == MATCH_FAILED)
860 return NULL;
861
718e3744 862 memset (&addr, 0, sizeof (struct in_addr));
863
864 area = ospfStubAreaLookup (v, name, length, &addr, exact);
865 if (! area)
866 return NULL;
867
868 /* Return the current value of the variable */
869 switch (v->magic)
870 {
871 case OSPFSTUBAREAID: /* 1 */
872 /* OSPF stub area id. */
873 return SNMP_IPADDRESS (area->area_id);
874 break;
875 case OSPFSTUBTOS: /* 2 */
876 /* TOS value is not supported. */
877 return SNMP_INTEGER (0);
878 break;
879 case OSPFSTUBMETRIC: /* 3 */
880 /* Default cost to stub area. */
881 return SNMP_INTEGER (area->default_cost);
882 break;
883 case OSPFSTUBSTATUS: /* 4 */
884 /* Status of the stub area. */
885 return SNMP_INTEGER (SNMP_VALID);
886 break;
887 case OSPFSTUBMETRICTYPE: /* 5 */
888 /* OSPF Metric type. */
889#define OSPF_ospfMetric 1
890#define OSPF_comparableCost 2
891#define OSPF_nonComparable 3
892 return SNMP_INTEGER (OSPF_ospfMetric);
893 break;
894 default:
895 return NULL;
896 break;
897 }
898 return NULL;
899}
900
0be8dfb2 901static struct ospf_lsa *
718e3744 902lsdb_lookup_next (struct ospf_area *area, u_char *type, int type_next,
903 struct in_addr *ls_id, int ls_id_next,
904 struct in_addr *router_id, int router_id_next)
905{
906 struct ospf_lsa *lsa;
907 int i;
908
909 if (type_next)
910 i = OSPF_MIN_LSA;
911 else
912 i = *type;
913
ba682537 914 /* Sanity check, if LSA type unknwon
915 merley skip any LSA */
916 if ((i < OSPF_MIN_LSA) || (i >= OSPF_MAX_LSA))
917 {
918 zlog_debug("Strange request with LSA type %d\n", i);
919 return NULL;
920 }
921
718e3744 922 for (; i < OSPF_MAX_LSA; i++)
923 {
924 *type = i;
925
926 lsa = ospf_lsdb_lookup_by_id_next (area->lsdb, *type, *ls_id, *router_id,
927 ls_id_next);
928 if (lsa)
929 return lsa;
930
931 ls_id_next = 1;
932 }
933 return NULL;
934}
935
0be8dfb2 936static struct ospf_lsa *
718e3744 937ospfLsdbLookup (struct variable *v, oid *name, size_t *length,
938 struct in_addr *area_id, u_char *type,
939 struct in_addr *ls_id, struct in_addr *router_id, int exact)
940{
020709f9 941 struct ospf *ospf;
718e3744 942 struct ospf_area *area;
943 struct ospf_lsa *lsa;
7939e016 944 int len;
718e3744 945 int type_next;
946 int ls_id_next;
947 int router_id_next;
948 oid *offset;
949 int offsetlen;
950
020709f9 951 ospf = ospf_lookup ();
952
718e3744 953#define OSPF_LSDB_ENTRY_OFFSET \
954 (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
955
956 if (exact)
957 {
958 /* Area ID + Type + LS ID + Router ID. */
959 if (*length - v->namelen != OSPF_LSDB_ENTRY_OFFSET)
960 return NULL;
961
962 /* Set OID offset for Area ID. */
963 offset = name + v->namelen;
964
965 /* Lookup area first. */
966 oid2in_addr (offset, IN_ADDR_SIZE, area_id);
68980084 967 area = ospf_area_lookup_by_area_id (ospf, *area_id);
718e3744 968 if (! area)
969 return NULL;
970 offset += IN_ADDR_SIZE;
971
972 /* Type. */
973 *type = *offset;
974 offset++;
975
976 /* LS ID. */
977 oid2in_addr (offset, IN_ADDR_SIZE, ls_id);
978 offset += IN_ADDR_SIZE;
979
980 /* Router ID. */
981 oid2in_addr (offset, IN_ADDR_SIZE, router_id);
982
983 /* Lookup LSDB. */
984 return ospf_lsdb_lookup_by_id (area->lsdb, *type, *ls_id, *router_id);
985 }
986 else
987 {
988 /* Get variable length. */
989 offset = name + v->namelen;
990 offsetlen = *length - v->namelen;
991 len = offsetlen;
992
7e635035 993 if (len > (int)IN_ADDR_SIZE)
718e3744 994 len = IN_ADDR_SIZE;
995
996 oid2in_addr (offset, len, area_id);
997
998 /* First we search area. */
999 if (len == IN_ADDR_SIZE)
68980084 1000 area = ospf_area_lookup_by_area_id (ospf, *area_id);
718e3744 1001 else
7939e016 1002 area = ospf_area_lookup_next (ospf, area_id, 1);
718e3744 1003
1004 if (area == NULL)
1005 return NULL;
1006
1007 do
1008 {
1009 /* Next we lookup type. */
7939e016
JBD
1010 offset += len;
1011 offsetlen -= len;
718e3744 1012 len = offsetlen;
1013
1014 if (len <= 0)
1015 type_next = 1;
1016 else
1017 {
1018 len = 1;
1019 type_next = 0;
1020 *type = *offset;
1021 }
1022
1023 /* LS ID. */
1024 offset++;
1025 offsetlen--;
1026 len = offsetlen;
1027
1028 if (len <= 0)
1029 ls_id_next = 1;
1030 else
1031 {
1032 ls_id_next = 0;
7e635035 1033 if (len > (int)IN_ADDR_SIZE)
718e3744 1034 len = IN_ADDR_SIZE;
1035
1036 oid2in_addr (offset, len, ls_id);
1037 }
1038
1039 /* Router ID. */
1040 offset += IN_ADDR_SIZE;
1041 offsetlen -= IN_ADDR_SIZE;
1042 len = offsetlen;
1043
1044 if (len <= 0)
1045 router_id_next = 1;
1046 else
1047 {
1048 router_id_next = 0;
7e635035 1049 if (len > (int)IN_ADDR_SIZE)
718e3744 1050 len = IN_ADDR_SIZE;
1051
1052 oid2in_addr (offset, len, router_id);
1053 }
1054
1055 lsa = lsdb_lookup_next (area, type, type_next, ls_id, ls_id_next,
1056 router_id, router_id_next);
1057
1058 if (lsa)
1059 {
1060 /* Fill in length. */
1061 *length = v->namelen + OSPF_LSDB_ENTRY_OFFSET;
1062
1063 /* Fill in value. */
1064 offset = name + v->namelen;
1065 oid_copy_addr (offset, area_id, IN_ADDR_SIZE);
1066 offset += IN_ADDR_SIZE;
1067 *offset = lsa->data->type;
1068 offset++;
1069 oid_copy_addr (offset, &lsa->data->id, IN_ADDR_SIZE);
1070 offset += IN_ADDR_SIZE;
1071 oid_copy_addr (offset, &lsa->data->adv_router, IN_ADDR_SIZE);
1072
1073 return lsa;
1074 }
1075 }
68980084 1076 while ((area = ospf_area_lookup_next (ospf, area_id, 0)) != NULL);
718e3744 1077 }
1078 return NULL;
1079}
1080
1081static u_char *
1082ospfLsdbEntry (struct variable *v, oid *name, size_t *length, int exact,
1083 size_t *var_len, WriteMethod **write_method)
1084{
1085 struct ospf_lsa *lsa;
1086 struct lsa_header *lsah;
1087 struct in_addr area_id;
1088 u_char type;
1089 struct in_addr ls_id;
1090 struct in_addr router_id;
020709f9 1091 struct ospf *ospf;
718e3744 1092
8046ba6e
VB
1093 if (smux_header_table(v, name, length, exact, var_len, write_method)
1094 == MATCH_FAILED)
1095 return NULL;
1096
718e3744 1097 /* INDEX { ospfLsdbAreaId, ospfLsdbType,
1098 ospfLsdbLsid, ospfLsdbRouterId } */
1099
1100 memset (&area_id, 0, sizeof (struct in_addr));
1101 type = 0;
1102 memset (&ls_id, 0, sizeof (struct in_addr));
1103 memset (&router_id, 0, sizeof (struct in_addr));
1104
1105 /* Check OSPF instance. */
020709f9 1106 ospf = ospf_lookup ();
1107 if (ospf == NULL)
718e3744 1108 return NULL;
1109
1110 lsa = ospfLsdbLookup (v, name, length, &area_id, &type, &ls_id, &router_id,
1111 exact);
1112 if (! lsa)
1113 return NULL;
1114
1115 lsah = lsa->data;
1116
1117 /* Return the current value of the variable */
1118 switch (v->magic)
1119 {
1120 case OSPFLSDBAREAID: /* 1 */
1121 return SNMP_IPADDRESS (lsa->area->area_id);
1122 break;
1123 case OSPFLSDBTYPE: /* 2 */
1124 return SNMP_INTEGER (lsah->type);
1125 break;
1126 case OSPFLSDBLSID: /* 3 */
1127 return SNMP_IPADDRESS (lsah->id);
1128 break;
1129 case OSPFLSDBROUTERID: /* 4 */
1130 return SNMP_IPADDRESS (lsah->adv_router);
1131 break;
1132 case OSPFLSDBSEQUENCE: /* 5 */
1133 return SNMP_INTEGER (lsah->ls_seqnum);
1134 break;
1135 case OSPFLSDBAGE: /* 6 */
1136 return SNMP_INTEGER (lsah->ls_age);
1137 break;
1138 case OSPFLSDBCHECKSUM: /* 7 */
1139 return SNMP_INTEGER (lsah->checksum);
1140 break;
1141 case OSPFLSDBADVERTISEMENT: /* 8 */
1142 *var_len = ntohs (lsah->length);
1143 return (u_char *) lsah;
1144 break;
1145 default:
1146 return NULL;
1147 break;
1148 }
1149 return NULL;
1150}
1151
0be8dfb2 1152static struct ospf_area_range *
718e3744 1153ospfAreaRangeLookup (struct variable *v, oid *name, size_t *length,
1154 struct in_addr *area_id, struct in_addr *range_net,
1155 int exact)
1156{
1157 oid *offset;
1158 int offsetlen;
7e635035 1159 int len;
020709f9 1160 struct ospf *ospf;
718e3744 1161 struct ospf_area *area;
1162 struct ospf_area_range *range;
1163 struct prefix_ipv4 p;
1164 p.family = AF_INET;
1165 p.prefixlen = IPV4_MAX_BITLEN;
1166
020709f9 1167 ospf = ospf_lookup ();
1168
718e3744 1169 if (exact)
1170 {
1171 /* Area ID + Range Network. */
1172 if (v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE != *length)
1173 return NULL;
1174
1175 /* Set OID offset for Area ID. */
1176 offset = name + v->namelen;
1177
1178 /* Lookup area first. */
1179 oid2in_addr (offset, IN_ADDR_SIZE, area_id);
1180
68980084 1181 area = ospf_area_lookup_by_area_id (ospf, *area_id);
718e3744 1182 if (! area)
1183 return NULL;
1184
1185 offset += IN_ADDR_SIZE;
1186
1187 /* Lookup area range. */
1188 oid2in_addr (offset, IN_ADDR_SIZE, range_net);
1189 p.prefix = *range_net;
1190
1191 return ospf_area_range_lookup (area, &p);
1192 }
1193 else
1194 {
1195 /* Set OID offset for Area ID. */
1196 offset = name + v->namelen;
1197 offsetlen = *length - v->namelen;
1198
1199 len = offsetlen;
7e635035 1200 if (len > (int)IN_ADDR_SIZE)
718e3744 1201 len = IN_ADDR_SIZE;
1202
1203 oid2in_addr (offset, len, area_id);
1204
1205 /* First we search area. */
1206 if (len == IN_ADDR_SIZE)
68980084 1207 area = ospf_area_lookup_by_area_id (ospf,*area_id);
718e3744 1208 else
68980084 1209 area = ospf_area_lookup_next (ospf, area_id, len == 0 ? 1 : 0);
718e3744 1210
1211 if (area == NULL)
1212 return NULL;
1213
1214 do
1215 {
1216 offset += IN_ADDR_SIZE;
1217 offsetlen -= IN_ADDR_SIZE;
1218 len = offsetlen;
1219
1220 if (len < 0)
1221 len = 0;
7e635035 1222 if (len > (int)IN_ADDR_SIZE)
718e3744 1223 len = IN_ADDR_SIZE;
1224
1225 oid2in_addr (offset, len, range_net);
1226
1227 range = ospf_area_range_lookup_next (area, range_net,
1228 len == 0 ? 1 : 0);
1229
1230 if (range)
1231 {
1232 /* Fill in length. */
1233 *length = v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE;
1234
1235 /* Fill in value. */
1236 offset = name + v->namelen;
1237 oid_copy_addr (offset, area_id, IN_ADDR_SIZE);
1238 offset += IN_ADDR_SIZE;
1239 oid_copy_addr (offset, range_net, IN_ADDR_SIZE);
1240
1241 return range;
1242 }
1243 }
68980084 1244 while ((area = ospf_area_lookup_next (ospf, area_id, 0)) != NULL);
718e3744 1245 }
1246 return NULL;
1247}
1248
1249static u_char *
1250ospfAreaRangeEntry (struct variable *v, oid *name, size_t *length, int exact,
1251 size_t *var_len, WriteMethod **write_method)
1252{
1253 struct ospf_area_range *range;
1254 struct in_addr area_id;
1255 struct in_addr range_net;
1256 struct in_addr mask;
020709f9 1257 struct ospf *ospf;
718e3744 1258
8046ba6e
VB
1259 if (smux_header_table(v, name, length, exact, var_len, write_method)
1260 == MATCH_FAILED)
1261 return NULL;
1262
718e3744 1263 /* Check OSPF instance. */
020709f9 1264 ospf = ospf_lookup ();
68980084 1265 if (ospf == NULL)
718e3744 1266 return NULL;
1267
1268 memset (&area_id, 0, IN_ADDR_SIZE);
1269 memset (&range_net, 0, IN_ADDR_SIZE);
1270
1271 range = ospfAreaRangeLookup (v, name, length, &area_id, &range_net, exact);
1272 if (! range)
1273 return NULL;
1274
1275 /* Convert prefixlen to network mask format. */
1276 masklen2ip (range->subst_masklen, &mask);
1277
1278 /* Return the current value of the variable */
1279 switch (v->magic)
1280 {
1281 case OSPFAREARANGEAREAID: /* 1 */
1282 return SNMP_IPADDRESS (area_id);
1283 break;
1284 case OSPFAREARANGENET: /* 2 */
1285 return SNMP_IPADDRESS (range_net);
1286 break;
1287 case OSPFAREARANGEMASK: /* 3 */
1288 return SNMP_IPADDRESS (mask);
1289 break;
1290 case OSPFAREARANGESTATUS: /* 4 */
1291 return SNMP_INTEGER (SNMP_VALID);
1292 break;
1293 case OSPFAREARANGEEFFECT: /* 5 */
1294#define OSPF_advertiseMatching 1
1295#define OSPF_doNotAdvertiseMatching 2
1296 return SNMP_INTEGER (OSPF_advertiseMatching);
1297 break;
1298 default:
1299 return NULL;
1300 break;
1301 }
1302 return NULL;
1303}
1304
0be8dfb2 1305static struct ospf_nbr_nbma *
718e3744 1306ospfHostLookup (struct variable *v, oid *name, size_t *length,
1307 struct in_addr *addr, int exact)
1308{
1309 int len;
1310 struct ospf_nbr_nbma *nbr_nbma;
020709f9 1311 struct ospf *ospf;
718e3744 1312
020709f9 1313 ospf = ospf_lookup ();
68980084 1314 if (ospf == NULL)
718e3744 1315 return NULL;
1316
1317 if (exact)
1318 {
1319 /* INDEX { ospfHostIpAddress, ospfHostTOS } */
1320 if (*length != v->namelen + IN_ADDR_SIZE + 1)
1321 return NULL;
1322
1323 /* Check ospfHostTOS. */
1324 if (name[*length - 1] != 0)
1325 return NULL;
1326
1327 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, addr);
1328
68980084 1329 nbr_nbma = ospf_nbr_nbma_lookup (ospf, *addr);
718e3744 1330
1331 return nbr_nbma;
1332 }
1333 else
1334 {
1335 len = *length - v->namelen;
1336 if (len > 4)
1337 len = 4;
1338
1339 oid2in_addr (name + v->namelen, len, addr);
1340
68980084 1341 nbr_nbma = ospf_nbr_nbma_lookup_next (ospf, addr, len == 0 ? 1 : 0);
718e3744 1342
1343 if (nbr_nbma == NULL)
1344 return NULL;
1345
1346 oid_copy_addr (name + v->namelen, addr, IN_ADDR_SIZE);
1347
1348 /* Set TOS 0. */
1349 name[v->namelen + IN_ADDR_SIZE] = 0;
1350
1351 *length = v->namelen + IN_ADDR_SIZE + 1;
1352
1353 return nbr_nbma;
1354 }
1355 return NULL;
1356}
1357
1358static u_char *
1359ospfHostEntry (struct variable *v, oid *name, size_t *length, int exact,
1360 size_t *var_len, WriteMethod **write_method)
1361{
1362 struct ospf_nbr_nbma *nbr_nbma;
1363 struct ospf_interface *oi;
1364 struct in_addr addr;
020709f9 1365 struct ospf *ospf;
718e3744 1366
8046ba6e
VB
1367 if (smux_header_table(v, name, length, exact, var_len, write_method)
1368 == MATCH_FAILED)
1369 return NULL;
1370
718e3744 1371 /* Check OSPF instance. */
020709f9 1372 ospf = ospf_lookup ();
68980084 1373 if (ospf == NULL)
718e3744 1374 return NULL;
1375
1376 memset (&addr, 0, sizeof (struct in_addr));
1377
1378 nbr_nbma = ospfHostLookup (v, name, length, &addr, exact);
1379 if (nbr_nbma == NULL)
1380 return NULL;
1381
1382 oi = nbr_nbma->oi;
1383
1384 /* Return the current value of the variable */
1385 switch (v->magic)
1386 {
1387 case OSPFHOSTIPADDRESS: /* 1 */
1388 return SNMP_IPADDRESS (nbr_nbma->addr);
1389 break;
1390 case OSPFHOSTTOS: /* 2 */
1391 return SNMP_INTEGER (0);
1392 break;
1393 case OSPFHOSTMETRIC: /* 3 */
1394 if (oi)
1395 return SNMP_INTEGER (oi->output_cost);
1396 else
1397 return SNMP_INTEGER (1);
1398 break;
1399 case OSPFHOSTSTATUS: /* 4 */
1400 return SNMP_INTEGER (SNMP_VALID);
1401 break;
1402 case OSPFHOSTAREAID: /* 5 */
1403 if (oi && oi->area)
1404 return SNMP_IPADDRESS (oi->area->area_id);
1405 else
1406 return SNMP_IPADDRESS (ospf_empty_addr);
1407 break;
1408 default:
1409 return NULL;
1410 break;
1411 }
1412 return NULL;
1413}
6b0655a2 1414
1c6f50bf 1415static struct list *ospf_snmp_iflist;
718e3744 1416
1417struct ospf_snmp_if
1418{
1419 struct in_addr addr;
b892f1dd 1420 ifindex_t ifindex;
718e3744 1421 struct interface *ifp;
1422};
1423
0be8dfb2 1424static struct ospf_snmp_if *
66e5cd87 1425ospf_snmp_if_new (void)
718e3744 1426{
c66f9c61 1427 return XCALLOC (MTYPE_TMP, sizeof (struct ospf_snmp_if));
718e3744 1428}
1429
0be8dfb2 1430static void
718e3744 1431ospf_snmp_if_free (struct ospf_snmp_if *osif)
1432{
c66f9c61 1433 XFREE (MTYPE_TMP, osif);
718e3744 1434}
1435
3012671f 1436static int
718e3744 1437ospf_snmp_if_delete (struct interface *ifp)
1438{
1eb8ef25 1439 struct listnode *node, *nnode;
718e3744 1440 struct ospf_snmp_if *osif;
1441
1eb8ef25 1442 for (ALL_LIST_ELEMENTS (ospf_snmp_iflist, node, nnode, osif))
718e3744 1443 {
1444 if (osif->ifp == ifp)
1445 {
1eb8ef25 1446 list_delete_node (ospf_snmp_iflist, node);
718e3744 1447 ospf_snmp_if_free (osif);
3012671f 1448 break;
718e3744 1449 }
1450 }
3012671f 1451 return 0;
718e3744 1452}
1453
3012671f 1454static int
718e3744 1455ospf_snmp_if_update (struct interface *ifp)
1456{
1eb8ef25 1457 struct listnode *node;
718e3744 1458 struct listnode *pn;
1459 struct connected *ifc;
1460 struct prefix *p;
1461 struct ospf_snmp_if *osif;
1462 struct in_addr *addr;
b892f1dd 1463 ifindex_t ifindex;
718e3744 1464
1465 ospf_snmp_if_delete (ifp);
1466
1467 p = NULL;
1468 addr = NULL;
1469 ifindex = 0;
1470
1471 /* Lookup first IPv4 address entry. */
1eb8ef25 1472 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc))
718e3744 1473 {
e4529636 1474 p = CONNECTED_ID(ifc);
718e3744 1475
1476 if (p->family == AF_INET)
1477 {
1478 addr = &p->u.prefix4;
1479 break;
1480 }
1481 }
1482 if (! addr)
1483 ifindex = ifp->ifindex;
1484
1485 /* Add interface to the list. */
1486 pn = NULL;
1eb8ef25 1487 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, node, osif))
718e3744 1488 {
1489 if (addr)
1490 {
77df1f78 1491 /* Usual interfaces --> Sort them based on interface IPv4 addresses */
718e3744 1492 if (ntohl (osif->addr.s_addr) > ntohl (addr->s_addr))
1493 break;
1494 }
1495 else
1496 {
77df1f78 1497 /* Unnumbered interfaces --> Sort them based on interface indexes */
718e3744 1498 if (osif->addr.s_addr != 0 || osif->ifindex > ifindex)
1499 break;
1500 }
1eb8ef25 1501 pn = node;
718e3744 1502 }
1503
1504 osif = ospf_snmp_if_new ();
77df1f78 1505 if (addr) /* Usual interface */
1506 {
718e3744 1507 osif->addr = *addr;
77df1f78 1508
1509 /* This field is used for storing ospfAddressLessIf OID value,
1510 * conform to RFC1850 OSPF-MIB specification, it must be 0 for
1511 * usual interface */
1512 osif->ifindex = 0;
1513 }
1514 else /* Unnumbered interface */
718e3744 1515 osif->ifindex = ifindex;
1516 osif->ifp = ifp;
1517
1518 listnode_add_after (ospf_snmp_iflist, pn, osif);
3012671f 1519 return 0;
718e3744 1520}
1521
0be8dfb2 1522static int
77df1f78 1523ospf_snmp_is_if_have_addr (struct interface *ifp)
1524{
77df1f78 1525 struct listnode *nn;
1526 struct connected *ifc;
1527
1528 /* Is this interface having any connected IPv4 address ? */
1529 for (ALL_LIST_ELEMENTS_RO (ifp->connected, nn, ifc))
1530 {
e4529636 1531 if (CONNECTED_PREFIX(ifc)->family == AF_INET)
77df1f78 1532 return 1;
1533 }
1534
1535 return 0;
1536}
1537
0be8dfb2 1538static struct ospf_interface *
b892f1dd 1539ospf_snmp_if_lookup (struct in_addr *ifaddr, ifindex_t *ifindex)
718e3744 1540{
1eb8ef25 1541 struct listnode *node;
718e3744 1542 struct ospf_snmp_if *osif;
77df1f78 1543 struct ospf_interface *oi = NULL;
1544 struct ospf *ospf = ospf_lookup ();
718e3744 1545
1eb8ef25 1546 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, node, osif))
718e3744 1547 {
1548 if (ifaddr->s_addr)
77df1f78 1549 {
1550 if (IPV4_ADDR_SAME (&osif->addr, ifaddr))
1551 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1552 }
718e3744 1553 else
77df1f78 1554 {
1555 if (osif->ifindex == *ifindex)
1556 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1557 }
718e3744 1558 }
77df1f78 1559 return oi;
718e3744 1560}
1561
0be8dfb2 1562static struct ospf_interface *
b892f1dd
PJ
1563ospf_snmp_if_lookup_next (struct in_addr *ifaddr, ifindex_t *ifindex,
1564 int ifaddr_next, ifindex_t ifindex_next)
718e3744 1565{
1566 struct ospf_snmp_if *osif;
1567 struct listnode *nn;
77df1f78 1568 struct ospf *ospf = ospf_lookup ();
1569 struct ospf_interface *oi = NULL;
718e3744 1570
77df1f78 1571 if (ospf == NULL)
1572 return NULL;
1573
1574 /* No instance is specified --> Return the first OSPF interface */
718e3744 1575 if (ifaddr_next)
1576 {
77df1f78 1577 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, nn, osif))
718e3744 1578 {
1eb8ef25 1579 osif = listgetdata (nn);
718e3744 1580 *ifaddr = osif->addr;
1581 *ifindex = osif->ifindex;
77df1f78 1582 /* Because no instance is specified, we don't care about the kind of
1583 * interface (usual or unnumbered), just returning the first valid
1584 * OSPF interface */
1585 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1586 if (oi)
1587 return (oi);
718e3744 1588 }
1589 return NULL;
1590 }
1591
77df1f78 1592 /* An instance is specified --> Return the next OSPF interface */
1eb8ef25 1593 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, nn, osif))
718e3744 1594 {
77df1f78 1595 /* Usual interface */
1596 if (ifaddr->s_addr)
0be8dfb2
CC
1597 {
1598 /* The interface must have valid AF_INET connected address */
1599 /* it must have lager IPv4 address value than the lookup entry */
1600 if ((ospf_snmp_is_if_have_addr(osif->ifp)) &&
1601 (ntohl (osif->addr.s_addr) > ntohl (ifaddr->s_addr)))
1602 {
1603 *ifaddr = osif->addr;
1604 *ifindex = osif->ifindex;
77df1f78 1605
0be8dfb2
CC
1606 /* and it must be an OSPF interface */
1607 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1608 if (oi)
1609 return oi;
1610 }
1611 }
77df1f78 1612 /* Unnumbered interface */
1613 else
1614 /* The interface must NOT have valid AF_INET connected address */
1615 /* it must have lager interface index than the lookup entry */
1616 if ((!ospf_snmp_is_if_have_addr(osif->ifp)) &&
1617 (osif->ifindex > *ifindex))
1618 {
1619 *ifaddr = osif->addr;
1620 *ifindex = osif->ifindex;
1621
1622 /* and it must be an OSPF interface */
1623 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1624 if (oi)
1625 return oi;
1626 }
718e3744 1627 }
1628 return NULL;
1629}
1630
0be8dfb2 1631static int
718e3744 1632ospf_snmp_iftype (struct interface *ifp)
1633{
1634#define ospf_snmp_iftype_broadcast 1
1635#define ospf_snmp_iftype_nbma 2
1636#define ospf_snmp_iftype_pointToPoint 3
1637#define ospf_snmp_iftype_pointToMultipoint 5
1638 if (if_is_broadcast (ifp))
1639 return ospf_snmp_iftype_broadcast;
1640 if (if_is_pointopoint (ifp))
1641 return ospf_snmp_iftype_pointToPoint;
1642 return ospf_snmp_iftype_broadcast;
1643}
1644
0be8dfb2 1645static struct ospf_interface *
718e3744 1646ospfIfLookup (struct variable *v, oid *name, size_t *length,
b892f1dd 1647 struct in_addr *ifaddr, ifindex_t *ifindex, int exact)
718e3744 1648{
6c835671 1649 unsigned int len;
718e3744 1650 int ifaddr_next = 0;
b892f1dd 1651 ifindex_t ifindex_next = 0;
77df1f78 1652 struct ospf_interface *oi;
718e3744 1653 oid *offset;
1654
1655 if (exact)
1656 {
1657 if (*length != v->namelen + IN_ADDR_SIZE + 1)
1658 return NULL;
1659
1660 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, ifaddr);
1661 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1662
1663 return ospf_snmp_if_lookup (ifaddr, ifindex);
1664 }
1665 else
1666 {
1667 len = *length - v->namelen;
1668 if (len >= IN_ADDR_SIZE)
1669 len = IN_ADDR_SIZE;
1670 if (len <= 0)
1671 ifaddr_next = 1;
1672
1673 oid2in_addr (name + v->namelen, len, ifaddr);
1674
1675 len = *length - v->namelen - IN_ADDR_SIZE;
1676 if (len >= 1)
1677 len = 1;
1678 else
1679 ifindex_next = 1;
1680
1681 if (len == 1)
1682 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1683
77df1f78 1684 oi = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next,
718e3744 1685 ifindex_next);
77df1f78 1686 if (oi)
718e3744 1687 {
1688 *length = v->namelen + IN_ADDR_SIZE + 1;
1689 offset = name + v->namelen;
1690 oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE);
1691 offset += IN_ADDR_SIZE;
1692 *offset = *ifindex;
77df1f78 1693 return oi;
718e3744 1694 }
1695 }
1696 return NULL;
1697}
1698
1699static u_char *
1700ospfIfEntry (struct variable *v, oid *name, size_t *length, int exact,
0be8dfb2 1701 size_t *var_len, WriteMethod **write_method)
718e3744 1702{
b892f1dd 1703 ifindex_t ifindex;
718e3744 1704 struct in_addr ifaddr;
1705 struct ospf_interface *oi;
020709f9 1706 struct ospf *ospf;
718e3744 1707
8046ba6e
VB
1708 if (smux_header_table(v, name, length, exact, var_len, write_method)
1709 == MATCH_FAILED)
1710 return NULL;
1711
718e3744 1712 ifindex = 0;
1713 memset (&ifaddr, 0, sizeof (struct in_addr));
1714
1715 /* Check OSPF instance. */
020709f9 1716 ospf = ospf_lookup ();
68980084 1717 if (ospf == NULL)
718e3744 1718 return NULL;
1719
77df1f78 1720 oi = ospfIfLookup (v, name, length, &ifaddr, &ifindex, exact);
718e3744 1721 if (oi == NULL)
1722 return NULL;
1723
1724 /* Return the current value of the variable */
1725 switch (v->magic)
1726 {
1727 case OSPFIFIPADDRESS: /* 1 */
1728 return SNMP_IPADDRESS (ifaddr);
1729 break;
1730 case OSPFADDRESSLESSIF: /* 2 */
1731 return SNMP_INTEGER (ifindex);
1732 break;
1733 case OSPFIFAREAID: /* 3 */
1734 if (oi->area)
1735 return SNMP_IPADDRESS (oi->area->area_id);
1736 else
1737 return SNMP_IPADDRESS (ospf_empty_addr);
1738 break;
1739 case OSPFIFTYPE: /* 4 */
77df1f78 1740 return SNMP_INTEGER (ospf_snmp_iftype (oi->ifp));
718e3744 1741 break;
1742 case OSPFIFADMINSTAT: /* 5 */
1743 if (oi)
1744 return SNMP_INTEGER (OSPF_STATUS_ENABLED);
1745 else
1746 return SNMP_INTEGER (OSPF_STATUS_DISABLED);
1747 break;
1748 case OSPFIFRTRPRIORITY: /* 6 */
1749 return SNMP_INTEGER (PRIORITY (oi));
1750 break;
1751 case OSPFIFTRANSITDELAY: /* 7 */
1752 return SNMP_INTEGER (OSPF_IF_PARAM (oi, transmit_delay));
1753 break;
1754 case OSPFIFRETRANSINTERVAL: /* 8 */
1755 return SNMP_INTEGER (OSPF_IF_PARAM (oi, retransmit_interval));
1756 break;
1757 case OSPFIFHELLOINTERVAL: /* 9 */
1758 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_hello));
1759 break;
1760 case OSPFIFRTRDEADINTERVAL: /* 10 */
1761 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_wait));
1762 break;
1763 case OSPFIFPOLLINTERVAL: /* 11 */
1764 return SNMP_INTEGER (OSPF_POLL_INTERVAL_DEFAULT);
1765 break;
1766 case OSPFIFSTATE: /* 12 */
ba682537 1767 return SNMP_INTEGER (ISM_SNMP(oi->state));
718e3744 1768 break;
1769 case OSPFIFDESIGNATEDROUTER: /* 13 */
1770 return SNMP_IPADDRESS (DR (oi));
1771 break;
1772 case OSPFIFBACKUPDESIGNATEDROUTER: /* 14 */
1773 return SNMP_IPADDRESS (BDR (oi));
1774 break;
1775 case OSPFIFEVENTS: /* 15 */
1776 return SNMP_INTEGER (oi->state_change);
1777 break;
1778 case OSPFIFAUTHKEY: /* 16 */
1779 *var_len = 0;
1780 return (u_char *) OSPF_IF_PARAM (oi, auth_simple);
1781 break;
1782 case OSPFIFSTATUS: /* 17 */
1783 return SNMP_INTEGER (SNMP_VALID);
1784 break;
1785 case OSPFIFMULTICASTFORWARDING: /* 18 */
1786#define ospf_snmp_multiforward_blocked 1
1787#define ospf_snmp_multiforward_multicast 2
1788#define ospf_snmp_multiforward_unicast 3
1789 return SNMP_INTEGER (ospf_snmp_multiforward_blocked);
1790 break;
1791 case OSPFIFDEMAND: /* 19 */
1792 return SNMP_INTEGER (SNMP_FALSE);
1793 break;
1794 case OSPFIFAUTHTYPE: /* 20 */
1795 if (oi->area)
1796 return SNMP_INTEGER (oi->area->auth_type);
1797 else
1798 return SNMP_INTEGER (0);
1799 break;
1800 default:
1801 return NULL;
1802 break;
1803 }
1804 return NULL;
1805}
1806
1807#define OSPF_SNMP_METRIC_VALUE 1
1808
0be8dfb2 1809static struct ospf_interface *
718e3744 1810ospfIfMetricLookup (struct variable *v, oid *name, size_t *length,
b892f1dd 1811 struct in_addr *ifaddr, ifindex_t *ifindex, int exact)
718e3744 1812{
6c835671 1813 unsigned int len;
718e3744 1814 int ifaddr_next = 0;
b892f1dd 1815 ifindex_t ifindex_next = 0;
77df1f78 1816 struct ospf_interface *oi;
718e3744 1817 oid *offset;
1818 int metric;
1819
1820 if (exact)
1821 {
1822 if (*length != v->namelen + IN_ADDR_SIZE + 1 + 1)
1823 return NULL;
1824
1825 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, ifaddr);
1826 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1827 metric = name[v->namelen + IN_ADDR_SIZE + 1];
1828
1829 if (metric != OSPF_SNMP_METRIC_VALUE)
1830 return NULL;
1831
1832 return ospf_snmp_if_lookup (ifaddr, ifindex);
1833 }
1834 else
1835 {
1836 len = *length - v->namelen;
1837 if (len >= IN_ADDR_SIZE)
1838 len = IN_ADDR_SIZE;
1839 else
1840 ifaddr_next = 1;
1841
1842 oid2in_addr (name + v->namelen, len, ifaddr);
1843
1844 len = *length - v->namelen - IN_ADDR_SIZE;
1845 if (len >= 1)
1846 len = 1;
1847 else
1848 ifindex_next = 1;
1849
1850 if (len == 1)
1851 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1852
77df1f78 1853 oi = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next,
718e3744 1854 ifindex_next);
77df1f78 1855 if (oi)
718e3744 1856 {
1857 *length = v->namelen + IN_ADDR_SIZE + 1 + 1;
1858 offset = name + v->namelen;
1859 oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE);
1860 offset += IN_ADDR_SIZE;
1861 *offset = *ifindex;
1862 offset++;
1863 *offset = OSPF_SNMP_METRIC_VALUE;
77df1f78 1864 return oi;
718e3744 1865 }
1866 }
1867 return NULL;
1868}
1869
1870static u_char *
1871ospfIfMetricEntry (struct variable *v, oid *name, size_t *length, int exact,
1872 size_t *var_len, WriteMethod **write_method)
1873{
1874 /* Currently we support metric 1 only. */
b892f1dd 1875 ifindex_t ifindex;
718e3744 1876 struct in_addr ifaddr;
1877 struct ospf_interface *oi;
020709f9 1878 struct ospf *ospf;
718e3744 1879
8046ba6e
VB
1880 if (smux_header_table(v, name, length, exact, var_len, write_method)
1881 == MATCH_FAILED)
1882 return NULL;
1883
718e3744 1884 ifindex = 0;
1885 memset (&ifaddr, 0, sizeof (struct in_addr));
1886
1887 /* Check OSPF instance. */
020709f9 1888 ospf = ospf_lookup ();
68980084 1889 if (ospf == NULL)
718e3744 1890 return NULL;
1891
77df1f78 1892 oi = ospfIfMetricLookup (v, name, length, &ifaddr, &ifindex, exact);
718e3744 1893 if (oi == NULL)
1894 return NULL;
1895
1896 /* Return the current value of the variable */
1897 switch (v->magic)
1898 {
1899 case OSPFIFMETRICIPADDRESS:
1900 return SNMP_IPADDRESS (ifaddr);
1901 break;
1902 case OSPFIFMETRICADDRESSLESSIF:
1903 return SNMP_INTEGER (ifindex);
1904 break;
1905 case OSPFIFMETRICTOS:
1906 return SNMP_INTEGER (0);
1907 break;
1908 case OSPFIFMETRICVALUE:
1909 return SNMP_INTEGER (OSPF_SNMP_METRIC_VALUE);
1910 break;
1911 case OSPFIFMETRICSTATUS:
1912 return SNMP_INTEGER (1);
1913 break;
1914 default:
1915 return NULL;
1916 break;
1917 }
1918 return NULL;
1919}
6b0655a2 1920
1c6f50bf 1921static struct route_table *ospf_snmp_vl_table;
718e3744 1922
3012671f 1923static int
718e3744 1924ospf_snmp_vl_add (struct ospf_vl_data *vl_data)
1925{
1926 struct prefix_ls lp;
1927 struct route_node *rn;
1928
1929 memset (&lp, 0, sizeof (struct prefix_ls));
1930 lp.family = 0;
1931 lp.prefixlen = 64;
1932 lp.id = vl_data->vl_area_id;
1933 lp.adv_router = vl_data->vl_peer;
1934
1935 rn = route_node_get (ospf_snmp_vl_table, (struct prefix *) &lp);
14fcc0e6
JT
1936 if (rn->info)
1937 route_unlock_node (rn);
1938
718e3744 1939 rn->info = vl_data;
3012671f 1940 return 0;
718e3744 1941}
1942
3012671f 1943static int
718e3744 1944ospf_snmp_vl_delete (struct ospf_vl_data *vl_data)
1945{
1946 struct prefix_ls lp;
1947 struct route_node *rn;
1948
1949 memset (&lp, 0, sizeof (struct prefix_ls));
1950 lp.family = 0;
1951 lp.prefixlen = 64;
1952 lp.id = vl_data->vl_area_id;
1953 lp.adv_router = vl_data->vl_peer;
1954
1955 rn = route_node_lookup (ospf_snmp_vl_table, (struct prefix *) &lp);
1956 if (! rn)
3012671f 1957 return 0;
718e3744 1958 rn->info = NULL;
1959 route_unlock_node (rn);
1960 route_unlock_node (rn);
3012671f 1961 return 0;
718e3744 1962}
1963
0be8dfb2 1964static struct ospf_vl_data *
718e3744 1965ospf_snmp_vl_lookup (struct in_addr *area_id, struct in_addr *neighbor)
1966{
1967 struct prefix_ls lp;
1968 struct route_node *rn;
1969 struct ospf_vl_data *vl_data;
1970
1971 memset (&lp, 0, sizeof (struct prefix_ls));
1972 lp.family = 0;
1973 lp.prefixlen = 64;
1974 lp.id = *area_id;
1975 lp.adv_router = *neighbor;
1976
1977 rn = route_node_lookup (ospf_snmp_vl_table, (struct prefix *) &lp);
1978 if (rn)
1979 {
1980 vl_data = rn->info;
1981 route_unlock_node (rn);
1982 return vl_data;
1983 }
1984 return NULL;
1985}
1986
0be8dfb2 1987static struct ospf_vl_data *
718e3744 1988ospf_snmp_vl_lookup_next (struct in_addr *area_id, struct in_addr *neighbor,
1989 int first)
1990{
1991 struct prefix_ls lp;
1992 struct route_node *rn;
1993 struct ospf_vl_data *vl_data;
1994
1995 memset (&lp, 0, sizeof (struct prefix_ls));
1996 lp.family = 0;
1997 lp.prefixlen = 64;
1998 lp.id = *area_id;
1999 lp.adv_router = *neighbor;
2000
2001 if (first)
2002 rn = route_top (ospf_snmp_vl_table);
2003 else
2004 {
2005 rn = route_node_get (ospf_snmp_vl_table, (struct prefix *) &lp);
2006 rn = route_next (rn);
2007 }
2008
2009 for (; rn; rn = route_next (rn))
2010 if (rn->info)
2011 break;
2012
2013 if (rn && rn->info)
2014 {
2015 vl_data = rn->info;
2016 *area_id = vl_data->vl_area_id;
2017 *neighbor = vl_data->vl_peer;
2018 route_unlock_node (rn);
2019 return vl_data;
2020 }
2021 return NULL;
2022}
2023
0be8dfb2 2024static struct ospf_vl_data *
718e3744 2025ospfVirtIfLookup (struct variable *v, oid *name, size_t *length,
2026 struct in_addr *area_id, struct in_addr *neighbor, int exact)
2027{
2028 int first;
6c835671 2029 unsigned int len;
718e3744 2030 struct ospf_vl_data *vl_data;
2031
2032 if (exact)
2033 {
2034 if (*length != v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE)
2035 return NULL;
2036
2037 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, area_id);
2038 oid2in_addr (name + v->namelen + IN_ADDR_SIZE, IN_ADDR_SIZE, neighbor);
2039
2040 return ospf_snmp_vl_lookup (area_id, neighbor);
2041 }
2042 else
2043 {
2044 first = 0;
2045
2046 len = *length - v->namelen;
2047 if (len <= 0)
2048 first = 1;
2049 if (len > IN_ADDR_SIZE)
2050 len = IN_ADDR_SIZE;
2051 oid2in_addr (name + v->namelen, len, area_id);
2052
2053 len = *length - v->namelen - IN_ADDR_SIZE;
2054 if (len > IN_ADDR_SIZE)
2055 len = IN_ADDR_SIZE;
2056 oid2in_addr (name + v->namelen + IN_ADDR_SIZE, len, neighbor);
2057
2058 vl_data = ospf_snmp_vl_lookup_next (area_id, neighbor, first);
2059
2060 if (vl_data)
2061 {
2062 *length = v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE;
2063 oid_copy_addr (name + v->namelen, area_id, IN_ADDR_SIZE);
2064 oid_copy_addr (name + v->namelen + IN_ADDR_SIZE, neighbor,
2065 IN_ADDR_SIZE);
2066 return vl_data;
2067 }
2068 }
2069 return NULL;
2070}
2071
2072static u_char *
2073ospfVirtIfEntry (struct variable *v, oid *name, size_t *length, int exact,
0be8dfb2 2074 size_t *var_len, WriteMethod **write_method)
718e3744 2075{
2076 struct ospf_vl_data *vl_data;
2077 struct ospf_interface *oi;
2078 struct in_addr area_id;
2079 struct in_addr neighbor;
2080
8046ba6e
VB
2081 if (smux_header_table(v, name, length, exact, var_len, write_method)
2082 == MATCH_FAILED)
2083 return NULL;
2084
718e3744 2085 memset (&area_id, 0, sizeof (struct in_addr));
2086 memset (&neighbor, 0, sizeof (struct in_addr));
2087
2088 vl_data = ospfVirtIfLookup (v, name, length, &area_id, &neighbor, exact);
2089 if (! vl_data)
2090 return NULL;
2091 oi = vl_data->vl_oi;
2092 if (! oi)
2093 return NULL;
2094
2095 /* Return the current value of the variable */
2096 switch (v->magic)
2097 {
2098 case OSPFVIRTIFAREAID:
2099 return SNMP_IPADDRESS (area_id);
2100 break;
2101 case OSPFVIRTIFNEIGHBOR:
2102 return SNMP_IPADDRESS (neighbor);
2103 break;
2104 case OSPFVIRTIFTRANSITDELAY:
2105 return SNMP_INTEGER (OSPF_IF_PARAM (oi, transmit_delay));
2106 break;
2107 case OSPFVIRTIFRETRANSINTERVAL:
2108 return SNMP_INTEGER (OSPF_IF_PARAM (oi, retransmit_interval));
2109 break;
2110 case OSPFVIRTIFHELLOINTERVAL:
2111 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_hello));
2112 break;
2113 case OSPFVIRTIFRTRDEADINTERVAL:
2114 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_wait));
2115 break;
2116 case OSPFVIRTIFSTATE:
2117 return SNMP_INTEGER (oi->state);
2118 break;
2119 case OSPFVIRTIFEVENTS:
2120 return SNMP_INTEGER (oi->state_change);
2121 break;
2122 case OSPFVIRTIFAUTHKEY:
2123 *var_len = 0;
2124 return (u_char *) OSPF_IF_PARAM (oi, auth_simple);
2125 break;
2126 case OSPFVIRTIFSTATUS:
2127 return SNMP_INTEGER (SNMP_VALID);
2128 break;
2129 case OSPFVIRTIFAUTHTYPE:
2130 if (oi->area)
2131 return SNMP_INTEGER (oi->area->auth_type);
2132 else
2133 return SNMP_INTEGER (0);
2134 break;
2135 default:
2136 return NULL;
2137 break;
2138 }
2139 return NULL;
2140}
6b0655a2 2141
0be8dfb2 2142static struct ospf_neighbor *
68980084 2143ospf_snmp_nbr_lookup (struct ospf *ospf, struct in_addr *nbr_addr,
b892f1dd 2144 ifindex_t *ifindex)
718e3744 2145{
1eb8ef25 2146 struct listnode *node, *nnode;
718e3744 2147 struct ospf_interface *oi;
2148 struct ospf_neighbor *nbr;
2149 struct route_node *rn;
2150
1eb8ef25 2151 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
718e3744 2152 {
2153 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2154 if ((nbr = rn->info) != NULL
2155 && nbr != oi->nbr_self
5e4914c3 2156/* If EXACT match is needed, provide ALL entry found
718e3744 2157 && nbr->state != NSM_Down
5e4914c3 2158 */
718e3744 2159 && nbr->src.s_addr != 0)
2160 {
2161 if (IPV4_ADDR_SAME (&nbr->src, nbr_addr))
2162 {
2163 route_unlock_node (rn);
2164 return nbr;
2165 }
2166 }
2167 }
2168 return NULL;
2169}
2170
0be8dfb2 2171static struct ospf_neighbor *
b892f1dd 2172ospf_snmp_nbr_lookup_next (struct in_addr *nbr_addr, ifindex_t *ifindex,
718e3744 2173 int first)
2174{
2175 struct listnode *nn;
2176 struct ospf_interface *oi;
2177 struct ospf_neighbor *nbr;
2178 struct route_node *rn;
2179 struct ospf_neighbor *min = NULL;
020709f9 2180 struct ospf *ospf = ospf;
718e3744 2181
020709f9 2182 ospf = ospf_lookup ();
1eb8ef25 2183
2184 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, nn, oi))
718e3744 2185 {
2186 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2187 if ((nbr = rn->info) != NULL
2188 && nbr != oi->nbr_self
2189 && nbr->state != NSM_Down
2190 && nbr->src.s_addr != 0)
2191 {
2192 if (first)
2193 {
2194 if (! min)
2195 min = nbr;
2196 else if (ntohl (nbr->src.s_addr) < ntohl (min->src.s_addr))
2197 min = nbr;
2198 }
2199 else if (ntohl (nbr->src.s_addr) > ntohl (nbr_addr->s_addr))
2200 {
2201 if (! min)
2202 min = nbr;
2203 else if (ntohl (nbr->src.s_addr) < ntohl (min->src.s_addr))
2204 min = nbr;
2205 }
2206 }
2207 }
2208 if (min)
2209 {
2210 *nbr_addr = min->src;
2211 *ifindex = 0;
2212 return min;
2213 }
2214 return NULL;
2215}
2216
0be8dfb2 2217static struct ospf_neighbor *
718e3744 2218ospfNbrLookup (struct variable *v, oid *name, size_t *length,
b892f1dd 2219 struct in_addr *nbr_addr, ifindex_t *ifindex, int exact)
718e3744 2220{
6c835671 2221 unsigned int len;
718e3744 2222 int first;
2223 struct ospf_neighbor *nbr;
020709f9 2224 struct ospf *ospf;
2225
2226 ospf = ospf_lookup ();
718e3744 2227
1b639047 2228 if (! ospf)
2229 return NULL;
2230
718e3744 2231 if (exact)
2232 {
2233 if (*length != v->namelen + IN_ADDR_SIZE + 1)
2234 return NULL;
2235
2236 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, nbr_addr);
2237 *ifindex = name[v->namelen + IN_ADDR_SIZE];
2238
68980084 2239 return ospf_snmp_nbr_lookup (ospf, nbr_addr, ifindex);
718e3744 2240 }
2241 else
2242 {
2243 first = 0;
2244 len = *length - v->namelen;
2245
2246 if (len <= 0)
2247 first = 1;
2248
2249 if (len > IN_ADDR_SIZE)
2250 len = IN_ADDR_SIZE;
2251
2252 oid2in_addr (name + v->namelen, len, nbr_addr);
2253
2254 len = *length - v->namelen - IN_ADDR_SIZE;
2255 if (len >= 1)
2256 *ifindex = name[v->namelen + IN_ADDR_SIZE];
2257
2258 nbr = ospf_snmp_nbr_lookup_next (nbr_addr, ifindex, first);
2259
2260 if (nbr)
2261 {
2262 *length = v->namelen + IN_ADDR_SIZE + 1;
2263 oid_copy_addr (name + v->namelen, nbr_addr, IN_ADDR_SIZE);
2264 name[v->namelen + IN_ADDR_SIZE] = *ifindex;
2265 return nbr;
2266 }
2267 }
2268 return NULL;
2269}
2270
ad81f8cc
AS
2271/* map internal quagga neighbor states to official MIB values:
2272
2273ospfNbrState OBJECT-TYPE
2274 SYNTAX INTEGER {
2275 down (1),
2276 attempt (2),
2277 init (3),
2278 twoWay (4),
2279 exchangeStart (5),
2280 exchange (6),
2281 loading (7),
2282 full (8)
2283 }
2284*/
2285static int32_t
2286ospf_snmp_neighbor_state(u_char nst)
2287{
2288 switch (nst)
2289 {
2290 case NSM_Attempt:
2291 return 2;
2292 case NSM_Init:
2293 return 3;
2294 case NSM_TwoWay:
2295 return 4;
2296 case NSM_ExStart:
2297 return 5;
2298 case NSM_Exchange:
2299 return 6;
2300 case NSM_Loading:
2301 return 7;
2302 case NSM_Full:
2303 return 8;
2304 default:
2305 return 1; /* down */
2306 }
2307}
2308
718e3744 2309static u_char *
2310ospfNbrEntry (struct variable *v, oid *name, size_t *length, int exact,
0be8dfb2 2311 size_t *var_len, WriteMethod **write_method)
718e3744 2312{
2313 struct in_addr nbr_addr;
b892f1dd 2314 ifindex_t ifindex;
718e3744 2315 struct ospf_neighbor *nbr;
2316 struct ospf_interface *oi;
2317
8046ba6e
VB
2318 if (smux_header_table(v, name, length, exact, var_len, write_method)
2319 == MATCH_FAILED)
2320 return NULL;
2321
718e3744 2322 memset (&nbr_addr, 0, sizeof (struct in_addr));
2323 ifindex = 0;
2324
2325 nbr = ospfNbrLookup (v, name, length, &nbr_addr, &ifindex, exact);
2326 if (! nbr)
2327 return NULL;
2328 oi = nbr->oi;
2329 if (! oi)
2330 return NULL;
2331
2332 /* Return the current value of the variable */
2333 switch (v->magic)
2334 {
2335 case OSPFNBRIPADDR:
2336 return SNMP_IPADDRESS (nbr_addr);
2337 break;
2338 case OSPFNBRADDRESSLESSINDEX:
2339 return SNMP_INTEGER (ifindex);
2340 break;
2341 case OSPFNBRRTRID:
2342 return SNMP_IPADDRESS (nbr->router_id);
2343 break;
2344 case OSPFNBROPTIONS:
2345 return SNMP_INTEGER (oi->nbr_self->options);
2346 break;
2347 case OSPFNBRPRIORITY:
2348 return SNMP_INTEGER (nbr->priority);
2349 break;
2350 case OSPFNBRSTATE:
ad81f8cc 2351 return SNMP_INTEGER (ospf_snmp_neighbor_state(nbr->state));
718e3744 2352 break;
2353 case OSPFNBREVENTS:
2354 return SNMP_INTEGER (nbr->state_change);
2355 break;
2356 case OSPFNBRLSRETRANSQLEN:
2357 return SNMP_INTEGER (ospf_ls_retransmit_count (nbr));
2358 break;
2359 case OSPFNBMANBRSTATUS:
2360 return SNMP_INTEGER (SNMP_VALID);
2361 break;
2362 case OSPFNBMANBRPERMANENCE:
2363 return SNMP_INTEGER (2);
2364 break;
2365 case OSPFNBRHELLOSUPPRESSED:
2366 return SNMP_INTEGER (SNMP_FALSE);
2367 break;
2368 default:
2369 return NULL;
2370 break;
2371 }
2372 return NULL;
2373}
6b0655a2 2374
718e3744 2375static u_char *
2376ospfVirtNbrEntry (struct variable *v, oid *name, size_t *length, int exact,
0be8dfb2 2377 size_t *var_len, WriteMethod **write_method)
718e3744 2378{
2379 struct ospf_vl_data *vl_data;
2380 struct in_addr area_id;
2381 struct in_addr neighbor;
020709f9 2382 struct ospf *ospf;
718e3744 2383
8046ba6e
VB
2384 if (smux_header_table(v, name, length, exact, var_len, write_method)
2385 == MATCH_FAILED)
2386 return NULL;
2387
718e3744 2388 memset (&area_id, 0, sizeof (struct in_addr));
2389 memset (&neighbor, 0, sizeof (struct in_addr));
2390
2391 /* Check OSPF instance. */
020709f9 2392 ospf = ospf_lookup ();
68980084 2393 if (ospf == NULL)
718e3744 2394 return NULL;
2395
2396 vl_data = ospfVirtIfLookup (v, name, length, &area_id, &neighbor, exact);
2397 if (! vl_data)
2398 return NULL;
2399
2400 /* Return the current value of the variable */
2401 switch (v->magic)
2402 {
2403 case OSPFVIRTNBRAREA:
2404 return (u_char *) NULL;
2405 break;
2406 case OSPFVIRTNBRRTRID:
2407 return (u_char *) NULL;
2408 break;
2409 case OSPFVIRTNBRIPADDR:
2410 return (u_char *) NULL;
2411 break;
2412 case OSPFVIRTNBROPTIONS:
2413 return (u_char *) NULL;
2414 break;
2415 case OSPFVIRTNBRSTATE:
2416 return (u_char *) NULL;
2417 break;
2418 case OSPFVIRTNBREVENTS:
2419 return (u_char *) NULL;
2420 break;
2421 case OSPFVIRTNBRLSRETRANSQLEN:
2422 return (u_char *) NULL;
2423 break;
2424 case OSPFVIRTNBRHELLOSUPPRESSED:
2425 return (u_char *) NULL;
2426 break;
2427 default:
2428 return NULL;
2429 break;
2430 }
2431 return NULL;
2432}
6b0655a2 2433
0be8dfb2 2434static struct ospf_lsa *
718e3744 2435ospfExtLsdbLookup (struct variable *v, oid *name, size_t *length, u_char *type,
2436 struct in_addr *ls_id, struct in_addr *router_id, int exact)
2437{
2438 int first;
2439 oid *offset;
2440 int offsetlen;
2441 u_char lsa_type;
6c835671 2442 unsigned int len;
718e3744 2443 struct ospf_lsa *lsa;
020709f9 2444 struct ospf *ospf;
718e3744 2445
020709f9 2446 ospf = ospf_lookup ();
718e3744 2447 if (exact)
2448 {
2449 if (*length != v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
2450 return NULL;
2451
2452 offset = name + v->namelen;
2453
2454 /* Make it sure given value match to type. */
2455 lsa_type = *offset;
2456 offset++;
2457
2458 if (lsa_type != *type)
2459 return NULL;
2460
2461 /* LS ID. */
2462 oid2in_addr (offset, IN_ADDR_SIZE, ls_id);
2463 offset += IN_ADDR_SIZE;
2464
2465 /* Router ID. */
2466 oid2in_addr (offset, IN_ADDR_SIZE, router_id);
2467
68980084 2468 return ospf_lsdb_lookup_by_id (ospf->lsdb, *type, *ls_id, *router_id);
718e3744 2469 }
2470 else
2471 {
2472 /* Get variable length. */
2473 first = 0;
2474 offset = name + v->namelen;
2475 offsetlen = *length - v->namelen;
2476
2477 /* LSA type value. */
2478 lsa_type = *offset;
2479 offset++;
2480 offsetlen--;
2481
2482 if (offsetlen <= 0 || lsa_type < OSPF_AS_EXTERNAL_LSA)
2483 first = 1;
2484
2485 /* LS ID. */
2486 len = offsetlen;
2487 if (len > IN_ADDR_SIZE)
2488 len = IN_ADDR_SIZE;
2489
2490 oid2in_addr (offset, len, ls_id);
2491
2492 offset += IN_ADDR_SIZE;
2493 offsetlen -= IN_ADDR_SIZE;
2494
2495 /* Router ID. */
2496 len = offsetlen;
2497 if (len > IN_ADDR_SIZE)
2498 len = IN_ADDR_SIZE;
2499
2500 oid2in_addr (offset, len, router_id);
2501
68980084 2502 lsa = ospf_lsdb_lookup_by_id_next (ospf->lsdb, *type, *ls_id,
718e3744 2503 *router_id, first);
2504
2505 if (lsa)
2506 {
2507 /* Fill in length. */
2508 *length = v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE;
2509
2510 /* Fill in value. */
2511 offset = name + v->namelen;
2512
2513 *offset = OSPF_AS_EXTERNAL_LSA;
2514 offset++;
2515 oid_copy_addr (offset, &lsa->data->id, IN_ADDR_SIZE);
2516 offset += IN_ADDR_SIZE;
2517 oid_copy_addr (offset, &lsa->data->adv_router, IN_ADDR_SIZE);
2518
2519 return lsa;
2520 }
2521 }
2522 return NULL;
2523}
2524
2525static u_char *
2526ospfExtLsdbEntry (struct variable *v, oid *name, size_t *length, int exact,
0be8dfb2 2527 size_t *var_len, WriteMethod **write_method)
718e3744 2528{
2529 struct ospf_lsa *lsa;
2530 struct lsa_header *lsah;
2531 u_char type;
2532 struct in_addr ls_id;
2533 struct in_addr router_id;
020709f9 2534 struct ospf *ospf;
718e3744 2535
8046ba6e
VB
2536 if (smux_header_table(v, name, length, exact, var_len, write_method)
2537 == MATCH_FAILED)
2538 return NULL;
2539
718e3744 2540 type = OSPF_AS_EXTERNAL_LSA;
2541 memset (&ls_id, 0, sizeof (struct in_addr));
2542 memset (&router_id, 0, sizeof (struct in_addr));
2543
2544 /* Check OSPF instance. */
020709f9 2545 ospf = ospf_lookup ();
68980084 2546 if (ospf == NULL)
718e3744 2547 return NULL;
2548
2549 lsa = ospfExtLsdbLookup (v, name, length, &type, &ls_id, &router_id, exact);
2550 if (! lsa)
2551 return NULL;
2552
2553 lsah = lsa->data;
2554
2555 /* Return the current value of the variable */
2556 switch (v->magic)
2557 {
2558 case OSPFEXTLSDBTYPE:
2559 return SNMP_INTEGER (OSPF_AS_EXTERNAL_LSA);
2560 break;
2561 case OSPFEXTLSDBLSID:
2562 return SNMP_IPADDRESS (lsah->id);
2563 break;
2564 case OSPFEXTLSDBROUTERID:
2565 return SNMP_IPADDRESS (lsah->adv_router);
2566 break;
2567 case OSPFEXTLSDBSEQUENCE:
2568 return SNMP_INTEGER (lsah->ls_seqnum);
2569 break;
2570 case OSPFEXTLSDBAGE:
2571 return SNMP_INTEGER (lsah->ls_age);
2572 break;
2573 case OSPFEXTLSDBCHECKSUM:
2574 return SNMP_INTEGER (lsah->checksum);
2575 break;
2576 case OSPFEXTLSDBADVERTISEMENT:
2577 *var_len = ntohs (lsah->length);
2578 return (u_char *) lsah;
2579 break;
2580 default:
2581 return NULL;
2582 break;
2583 }
2584 return NULL;
2585}
6b0655a2 2586
718e3744 2587static u_char *
2588ospfAreaAggregateEntry (struct variable *v, oid *name, size_t *length,
2589 int exact, size_t *var_len, WriteMethod **write_method)
2590{
8046ba6e
VB
2591 if (smux_header_table(v, name, length, exact, var_len, write_method)
2592 == MATCH_FAILED)
2593 return NULL;
2594
718e3744 2595 /* Return the current value of the variable */
2596 switch (v->magic)
2597 {
2598 case OSPFAREAAGGREGATEAREAID:
2599 return (u_char *) NULL;
2600 break;
2601 case OSPFAREAAGGREGATELSDBTYPE:
2602 return (u_char *) NULL;
2603 break;
2604 case OSPFAREAAGGREGATENET:
2605 return (u_char *) NULL;
2606 break;
2607 case OSPFAREAAGGREGATEMASK:
2608 return (u_char *) NULL;
2609 break;
2610 case OSPFAREAAGGREGATESTATUS:
2611 return (u_char *) NULL;
2612 break;
2613 case OSPFAREAAGGREGATEEFFECT:
2614 return (u_char *) NULL;
2615 break;
2616 default:
2617 return NULL;
2618 break;
2619 }
2620 return NULL;
2621}
6b0655a2 2622
5e4914c3 2623/* OSPF Traps. */
2624#define IFSTATECHANGE 16
2625#define VIRTIFSTATECHANGE 1
2626#define NBRSTATECHANGE 2
2627#define VIRTNBRSTATECHANGE 3
2628
1c6f50bf 2629static struct trap_object ospfNbrTrapList[] =
5e4914c3 2630{
b8cf46b7
VB
2631 {-2, {1, OSPFROUTERID}},
2632 {3, {10, 1, OSPFNBRIPADDR}},
2633 {3, {10, 1, OSPFNBRRTRID}},
2634 {3, {10, 1, OSPFNBRSTATE}}
5e4914c3 2635};
2636
2637
1c6f50bf 2638static struct trap_object ospfVirtNbrTrapList[] =
5e4914c3 2639{
b8cf46b7
VB
2640 {-2, {1, 1}},
2641 {3, {11, 1, OSPFVIRTNBRAREA}},
2642 {3, {11, 1, OSPFVIRTNBRRTRID}},
2643 {3, {11, 1, OSPFVIRTNBRSTATE}}
5e4914c3 2644};
2645
1c6f50bf 2646static struct trap_object ospfIfTrapList[] =
5e4914c3 2647{
b8cf46b7
VB
2648 {-2, {1, OSPFROUTERID}},
2649 {3, {7, 1, OSPFIFIPADDRESS}},
2650 {3, {7, 1, OSPFADDRESSLESSIF}},
2651 {3, {7, 1, OSPFIFSTATE}}
5e4914c3 2652};
2653
1c6f50bf 2654static struct trap_object ospfVirtIfTrapList[] =
5e4914c3 2655{
b8cf46b7
VB
2656 {-2, {1, OSPFROUTERID}},
2657 {3, {9, 1, OSPFVIRTIFAREAID}},
2658 {3, {9, 1, OSPFVIRTIFNEIGHBOR}},
2659 {3, {9, 1, OSPFVIRTIFSTATE}}
5e4914c3 2660};
2661
3012671f 2662static void
5e4914c3 2663ospfTrapNbrStateChange (struct ospf_neighbor *on)
2664{
2665 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
9aecfae2 2666 char msgbuf[16];
5e4914c3 2667
9aecfae2 2668 ospf_nbr_state_message(on, msgbuf, sizeof(msgbuf));
4525281a
DL
2669 zlog_info("ospfTrapNbrStateChange trap sent: %s now %s",
2670 inet_ntoa(on->address.u.prefix4), msgbuf);
5e4914c3 2671
2672 oid_copy_addr (index, &(on->address.u.prefix4), IN_ADDR_SIZE);
2673 index[IN_ADDR_SIZE] = 0;
2674
b7c0d065
VB
2675 smux_trap (ospf_variables, sizeof ospf_variables / sizeof (struct variable),
2676 ospf_trap_oid, sizeof ospf_trap_oid / sizeof (oid),
2677 ospf_oid, sizeof ospf_oid / sizeof (oid),
5e4914c3 2678 index, IN_ADDR_SIZE + 1,
2679 ospfNbrTrapList,
2680 sizeof ospfNbrTrapList / sizeof (struct trap_object),
4b89e45d 2681 NBRSTATECHANGE);
5e4914c3 2682}
2683
3012671f 2684static void
5e4914c3 2685ospfTrapVirtNbrStateChange (struct ospf_neighbor *on)
2686{
2687 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
2688
4525281a 2689 zlog_info("ospfTrapVirtNbrStateChange trap sent");
5e4914c3 2690
2691 oid_copy_addr (index, &(on->address.u.prefix4), IN_ADDR_SIZE);
2692 index[IN_ADDR_SIZE] = 0;
2693
b7c0d065
VB
2694 smux_trap (ospf_variables, sizeof ospf_variables / sizeof (struct variable),
2695 ospf_trap_oid, sizeof ospf_trap_oid / sizeof (oid),
2696 ospf_oid, sizeof ospf_oid / sizeof (oid),
5e4914c3 2697 index, IN_ADDR_SIZE + 1,
2698 ospfVirtNbrTrapList,
2699 sizeof ospfVirtNbrTrapList / sizeof (struct trap_object),
4b89e45d 2700 VIRTNBRSTATECHANGE);
5e4914c3 2701}
2702
3012671f
DL
2703static int
2704ospf_snmp_nsm_change (struct ospf_neighbor *nbr,
2705 int next_state, int old_state)
2706{
2707 /* Terminal state or regression */
2708 if ((next_state == NSM_Full)
2709 || (next_state == NSM_TwoWay)
2710 || (next_state < old_state))
2711 {
2712 /* ospfVirtNbrStateChange */
2713 if (nbr->oi->type == OSPF_IFTYPE_VIRTUALLINK)
2714 ospfTrapVirtNbrStateChange(nbr);
2715 /* ospfNbrStateChange trap */
2716 else
2717 /* To/From FULL, only managed by DR */
2718 if (((next_state != NSM_Full) && (nbr->state != NSM_Full))
2719 || (nbr->oi->state == ISM_DR))
2720 ospfTrapNbrStateChange(nbr);
2721 }
2722 return 0;
2723}
2724
2725static void
5e4914c3 2726ospfTrapIfStateChange (struct ospf_interface *oi)
2727{
2728 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
2729
4525281a
DL
2730 zlog_info("ospfTrapIfStateChange trap sent: %s now %s",
2731 inet_ntoa(oi->address->u.prefix4),
2732 LOOKUP(ospf_ism_state_msg, oi->state));
5e4914c3 2733
2734 oid_copy_addr (index, &(oi->address->u.prefix4), IN_ADDR_SIZE);
2735 index[IN_ADDR_SIZE] = 0;
2736
b7c0d065
VB
2737 smux_trap (ospf_variables, sizeof ospf_variables / sizeof (struct variable),
2738 ospf_trap_oid, sizeof ospf_trap_oid / sizeof (oid),
2739 ospf_oid, sizeof ospf_oid / sizeof (oid),
5e4914c3 2740 index, IN_ADDR_SIZE + 1,
2741 ospfIfTrapList,
2742 sizeof ospfIfTrapList / sizeof (struct trap_object),
4b89e45d 2743 IFSTATECHANGE);
5e4914c3 2744}
2745
3012671f 2746static void
5e4914c3 2747ospfTrapVirtIfStateChange (struct ospf_interface *oi)
2748{
2749 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
2750
4525281a 2751 zlog_info("ospfTrapVirtIfStateChange trap sent");
5e4914c3 2752
2753 oid_copy_addr (index, &(oi->address->u.prefix4), IN_ADDR_SIZE);
2754 index[IN_ADDR_SIZE] = 0;
2755
b7c0d065
VB
2756 smux_trap (ospf_variables, sizeof ospf_variables / sizeof (struct variable),
2757 ospf_trap_oid, sizeof ospf_trap_oid / sizeof (oid),
2758 ospf_oid, sizeof ospf_oid / sizeof (oid),
5e4914c3 2759 index, IN_ADDR_SIZE + 1,
2760 ospfVirtIfTrapList,
2761 sizeof ospfVirtIfTrapList / sizeof (struct trap_object),
4b89e45d 2762 VIRTIFSTATECHANGE);
5e4914c3 2763}
3012671f
DL
2764
2765static int
2766ospf_snmp_ism_change (struct ospf_interface *oi,
2767 int state, int old_state)
2768{
2769 /* Terminal state or regression */
2770 if ((state == ISM_DR) || (state == ISM_Backup) || (state == ISM_DROther) ||
2771 (state == ISM_PointToPoint) || (state < old_state))
2772 {
2773 /* ospfVirtIfStateChange */
2774 if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
2775 ospfTrapVirtIfStateChange (oi);
2776 /* ospfIfStateChange */
2777 else
2778 ospfTrapIfStateChange (oi);
2779 }
2780 return 0;
2781}
2782
718e3744 2783/* Register OSPF2-MIB. */
2784void
2785ospf_snmp_init ()
2786{
3012671f
DL
2787 hook_register(ospf_if_update, ospf_snmp_if_update);
2788 hook_register(ospf_if_delete, ospf_snmp_if_delete);
2789 hook_register(ospf_vl_add, ospf_snmp_vl_add);
2790 hook_register(ospf_vl_delete, ospf_snmp_vl_delete);
2791 hook_register(ospf_ism_change, ospf_snmp_ism_change);
2792 hook_register(ospf_nsm_change, ospf_snmp_nsm_change);
2793
718e3744 2794 ospf_snmp_iflist = list_new ();
2795 ospf_snmp_vl_table = route_table_init ();
c75105ab 2796 smux_init (om->master);
718e3744 2797 REGISTER_MIB("mibII/ospf", ospf_variables, variable, ospf_oid);
718e3744 2798}
2799#endif /* HAVE_SNMP */