blob: 71cb3085fd47c9aff9833329df99e33083176501 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* OSPFv2 SNMP support
vincentba682532005-09-29 13:52:57 +00002 * Copyright (C) 2005 6WIND <alain.ritoux@6wind.com>
paul718e3742002-12-13 20:15:29 +00003 * 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
paul07661cb2003-03-18 00:03:05 +000028#ifdef HAVE_NETSNMP
29#include <net-snmp/net-snmp-config.h>
30#endif
paul718e3742002-12-13 20:15:29 +000031#include <asn1.h>
32#include <snmp.h>
33#include <snmp_impl.h>
34
35#include "if.h"
36#include "log.h"
37#include "prefix.h"
38#include "table.h"
39#include "command.h"
40#include "memory.h"
41#include "smux.h"
42
43#include "ospfd/ospfd.h"
44#include "ospfd/ospf_interface.h"
45#include "ospfd/ospf_asbr.h"
46#include "ospfd/ospf_lsa.h"
47#include "ospfd/ospf_lsdb.h"
48#include "ospfd/ospf_abr.h"
49#include "ospfd/ospf_neighbor.h"
50#include "ospfd/ospf_nsm.h"
51#include "ospfd/ospf_flood.h"
vincente6217872005-09-29 13:56:14 +000052#include "ospfd/ospf_ism.h"
paul718e3742002-12-13 20:15:29 +000053
54/* OSPF2-MIB. */
55#define OSPF2MIB 1,3,6,1,2,1,14
56
paul718e3742002-12-13 20:15:29 +000057/* OSPF MIB General Group values. */
58#define OSPFROUTERID 1
59#define OSPFADMINSTAT 2
60#define OSPFVERSIONNUMBER 3
61#define OSPFAREABDRRTRSTATUS 4
62#define OSPFASBDRRTRSTATUS 5
63#define OSPFEXTERNLSACOUNT 6
64#define OSPFEXTERNLSACKSUMSUM 7
65#define OSPFTOSSUPPORT 8
66#define OSPFORIGINATENEWLSAS 9
67#define OSPFRXNEWLSAS 10
68#define OSPFEXTLSDBLIMIT 11
69#define OSPFMULTICASTEXTENSIONS 12
70#define OSPFEXITOVERFLOWINTERVAL 13
71#define OSPFDEMANDEXTENSIONS 14
72
73/* OSPF MIB ospfAreaTable. */
74#define OSPFAREAID 1
75#define OSPFAUTHTYPE 2
76#define OSPFIMPORTASEXTERN 3
77#define OSPFSPFRUNS 4
78#define OSPFAREABDRRTRCOUNT 5
79#define OSPFASBDRRTRCOUNT 6
80#define OSPFAREALSACOUNT 7
81#define OSPFAREALSACKSUMSUM 8
82#define OSPFAREASUMMARY 9
83#define OSPFAREASTATUS 10
84
85/* OSPF MIB ospfStubAreaTable. */
86#define OSPFSTUBAREAID 1
87#define OSPFSTUBTOS 2
88#define OSPFSTUBMETRIC 3
89#define OSPFSTUBSTATUS 4
90#define OSPFSTUBMETRICTYPE 5
91
92/* OSPF MIB ospfLsdbTable. */
93#define OSPFLSDBAREAID 1
94#define OSPFLSDBTYPE 2
95#define OSPFLSDBLSID 3
96#define OSPFLSDBROUTERID 4
97#define OSPFLSDBSEQUENCE 5
98#define OSPFLSDBAGE 6
99#define OSPFLSDBCHECKSUM 7
100#define OSPFLSDBADVERTISEMENT 8
101
102/* OSPF MIB ospfAreaRangeTable. */
103#define OSPFAREARANGEAREAID 1
104#define OSPFAREARANGENET 2
105#define OSPFAREARANGEMASK 3
106#define OSPFAREARANGESTATUS 4
107#define OSPFAREARANGEEFFECT 5
108
109/* OSPF MIB ospfHostTable. */
110#define OSPFHOSTIPADDRESS 1
111#define OSPFHOSTTOS 2
112#define OSPFHOSTMETRIC 3
113#define OSPFHOSTSTATUS 4
114#define OSPFHOSTAREAID 5
115
116/* OSPF MIB ospfIfTable. */
117#define OSPFIFIPADDRESS 1
118#define OSPFADDRESSLESSIF 2
119#define OSPFIFAREAID 3
120#define OSPFIFTYPE 4
121#define OSPFIFADMINSTAT 5
122#define OSPFIFRTRPRIORITY 6
123#define OSPFIFTRANSITDELAY 7
124#define OSPFIFRETRANSINTERVAL 8
125#define OSPFIFHELLOINTERVAL 9
126#define OSPFIFRTRDEADINTERVAL 10
127#define OSPFIFPOLLINTERVAL 11
128#define OSPFIFSTATE 12
129#define OSPFIFDESIGNATEDROUTER 13
130#define OSPFIFBACKUPDESIGNATEDROUTER 14
131#define OSPFIFEVENTS 15
132#define OSPFIFAUTHKEY 16
133#define OSPFIFSTATUS 17
134#define OSPFIFMULTICASTFORWARDING 18
135#define OSPFIFDEMAND 19
136#define OSPFIFAUTHTYPE 20
137
138/* OSPF MIB ospfIfMetricTable. */
139#define OSPFIFMETRICIPADDRESS 1
140#define OSPFIFMETRICADDRESSLESSIF 2
141#define OSPFIFMETRICTOS 3
142#define OSPFIFMETRICVALUE 4
143#define OSPFIFMETRICSTATUS 5
144
145/* OSPF MIB ospfVirtIfTable. */
146#define OSPFVIRTIFAREAID 1
147#define OSPFVIRTIFNEIGHBOR 2
148#define OSPFVIRTIFTRANSITDELAY 3
149#define OSPFVIRTIFRETRANSINTERVAL 4
150#define OSPFVIRTIFHELLOINTERVAL 5
151#define OSPFVIRTIFRTRDEADINTERVAL 6
152#define OSPFVIRTIFSTATE 7
153#define OSPFVIRTIFEVENTS 8
154#define OSPFVIRTIFAUTHKEY 9
155#define OSPFVIRTIFSTATUS 10
156#define OSPFVIRTIFAUTHTYPE 11
157
158/* OSPF MIB ospfNbrTable. */
159#define OSPFNBRIPADDR 1
160#define OSPFNBRADDRESSLESSINDEX 2
161#define OSPFNBRRTRID 3
162#define OSPFNBROPTIONS 4
163#define OSPFNBRPRIORITY 5
164#define OSPFNBRSTATE 6
165#define OSPFNBREVENTS 7
166#define OSPFNBRLSRETRANSQLEN 8
167#define OSPFNBMANBRSTATUS 9
168#define OSPFNBMANBRPERMANENCE 10
169#define OSPFNBRHELLOSUPPRESSED 11
170
171/* OSPF MIB ospfVirtNbrTable. */
172#define OSPFVIRTNBRAREA 1
173#define OSPFVIRTNBRRTRID 2
174#define OSPFVIRTNBRIPADDR 3
175#define OSPFVIRTNBROPTIONS 4
176#define OSPFVIRTNBRSTATE 5
177#define OSPFVIRTNBREVENTS 6
178#define OSPFVIRTNBRLSRETRANSQLEN 7
179#define OSPFVIRTNBRHELLOSUPPRESSED 8
180
181/* OSPF MIB ospfExtLsdbTable. */
182#define OSPFEXTLSDBTYPE 1
183#define OSPFEXTLSDBLSID 2
184#define OSPFEXTLSDBROUTERID 3
185#define OSPFEXTLSDBSEQUENCE 4
186#define OSPFEXTLSDBAGE 5
187#define OSPFEXTLSDBCHECKSUM 6
188#define OSPFEXTLSDBADVERTISEMENT 7
189
190/* OSPF MIB ospfAreaAggregateTable. */
191#define OSPFAREAAGGREGATEAREAID 1
192#define OSPFAREAAGGREGATELSDBTYPE 2
193#define OSPFAREAAGGREGATENET 3
194#define OSPFAREAAGGREGATEMASK 4
195#define OSPFAREAAGGREGATESTATUS 5
196#define OSPFAREAAGGREGATEEFFECT 6
197
198/* SYNTAX Status from OSPF-MIB. */
199#define OSPF_STATUS_ENABLED 1
200#define OSPF_STATUS_DISABLED 2
201
202/* SNMP value hack. */
203#define COUNTER ASN_COUNTER
204#define INTEGER ASN_INTEGER
205#define GAUGE ASN_GAUGE
206#define TIMETICKS ASN_TIMETICKS
207#define IPADDRESS ASN_IPADDRESS
208#define STRING ASN_OCTET_STR
209
210/* Declare static local variables for convenience. */
211SNMP_LOCAL_VARIABLES
212
213/* OSPF-MIB instances. */
214oid ospf_oid [] = { OSPF2MIB };
paul718e3742002-12-13 20:15:29 +0000215
216/* IP address 0.0.0.0. */
217static struct in_addr ospf_empty_addr = {0};
218
219/* Hook functions. */
220static u_char *ospfGeneralGroup ();
221static u_char *ospfAreaEntry ();
222static u_char *ospfStubAreaEntry ();
223static u_char *ospfLsdbEntry ();
224static u_char *ospfAreaRangeEntry ();
225static u_char *ospfHostEntry ();
226static u_char *ospfIfEntry ();
227static u_char *ospfIfMetricEntry ();
228static u_char *ospfVirtIfEntry ();
229static u_char *ospfNbrEntry ();
230static u_char *ospfVirtNbrEntry ();
231static u_char *ospfExtLsdbEntry ();
232static u_char *ospfAreaAggregateEntry ();
233
234struct variable ospf_variables[] =
235{
236 /* OSPF general variables */
237 {OSPFROUTERID, IPADDRESS, RWRITE, ospfGeneralGroup,
238 2, {1, 1}},
239 {OSPFADMINSTAT, INTEGER, RWRITE, ospfGeneralGroup,
240 2, {1, 2}},
241 {OSPFVERSIONNUMBER, INTEGER, RONLY, ospfGeneralGroup,
242 2, {1, 3}},
243 {OSPFAREABDRRTRSTATUS, INTEGER, RONLY, ospfGeneralGroup,
244 2, {1, 4}},
245 {OSPFASBDRRTRSTATUS, INTEGER, RWRITE, ospfGeneralGroup,
246 2, {1, 5}},
247 {OSPFEXTERNLSACOUNT, GAUGE, RONLY, ospfGeneralGroup,
248 2, {1, 6}},
249 {OSPFEXTERNLSACKSUMSUM, INTEGER, RONLY, ospfGeneralGroup,
250 2, {1, 7}},
251 {OSPFTOSSUPPORT, INTEGER, RWRITE, ospfGeneralGroup,
252 2, {1, 8}},
253 {OSPFORIGINATENEWLSAS, COUNTER, RONLY, ospfGeneralGroup,
254 2, {1, 9}},
255 {OSPFRXNEWLSAS, COUNTER, RONLY, ospfGeneralGroup,
256 2, {1, 10}},
257 {OSPFEXTLSDBLIMIT, INTEGER, RWRITE, ospfGeneralGroup,
258 2, {1, 11}},
259 {OSPFMULTICASTEXTENSIONS, INTEGER, RWRITE, ospfGeneralGroup,
260 2, {1, 12}},
261 {OSPFEXITOVERFLOWINTERVAL, INTEGER, RWRITE, ospfGeneralGroup,
262 2, {1, 13}},
263 {OSPFDEMANDEXTENSIONS, INTEGER, RWRITE, ospfGeneralGroup,
264 2, {1, 14}},
265
266 /* OSPF area data structure. */
267 {OSPFAREAID, IPADDRESS, RONLY, ospfAreaEntry,
268 3, {2, 1, 1}},
269 {OSPFAUTHTYPE, INTEGER, RWRITE, ospfAreaEntry,
270 3, {2, 1, 2}},
271 {OSPFIMPORTASEXTERN, INTEGER, RWRITE, ospfAreaEntry,
272 3, {2, 1, 3}},
273 {OSPFSPFRUNS, COUNTER, RONLY, ospfAreaEntry,
274 3, {2, 1, 4}},
275 {OSPFAREABDRRTRCOUNT, GAUGE, RONLY, ospfAreaEntry,
276 3, {2, 1, 5}},
277 {OSPFASBDRRTRCOUNT, GAUGE, RONLY, ospfAreaEntry,
278 3, {2, 1, 6}},
279 {OSPFAREALSACOUNT, GAUGE, RONLY, ospfAreaEntry,
280 3, {2, 1, 7}},
281 {OSPFAREALSACKSUMSUM, INTEGER, RONLY, ospfAreaEntry,
282 3, {2, 1, 8}},
283 {OSPFAREASUMMARY, INTEGER, RWRITE, ospfAreaEntry,
284 3, {2, 1, 9}},
285 {OSPFAREASTATUS, INTEGER, RWRITE, ospfAreaEntry,
286 3, {2, 1, 10}},
287
288 /* OSPF stub area information. */
289 {OSPFSTUBAREAID, IPADDRESS, RONLY, ospfStubAreaEntry,
290 3, {3, 1, 1}},
291 {OSPFSTUBTOS, INTEGER, RONLY, ospfStubAreaEntry,
292 3, {3, 1, 2}},
293 {OSPFSTUBMETRIC, INTEGER, RWRITE, ospfStubAreaEntry,
294 3, {3, 1, 3}},
295 {OSPFSTUBSTATUS, INTEGER, RWRITE, ospfStubAreaEntry,
296 3, {3, 1, 4}},
297 {OSPFSTUBMETRICTYPE, INTEGER, RWRITE, ospfStubAreaEntry,
298 3, {3, 1, 5}},
299
300 /* OSPF link state database. */
301 {OSPFLSDBAREAID, IPADDRESS, RONLY, ospfLsdbEntry,
302 3, {4, 1, 1}},
303 {OSPFLSDBTYPE, INTEGER, RONLY, ospfLsdbEntry,
304 3, {4, 1, 2}},
305 {OSPFLSDBLSID, IPADDRESS, RONLY, ospfLsdbEntry,
306 3, {4, 1, 3}},
307 {OSPFLSDBROUTERID, IPADDRESS, RONLY, ospfLsdbEntry,
308 3, {4, 1, 4}},
309 {OSPFLSDBSEQUENCE, INTEGER, RONLY, ospfLsdbEntry,
310 3, {4, 1, 5}},
311 {OSPFLSDBAGE, INTEGER, RONLY, ospfLsdbEntry,
312 3, {4, 1, 6}},
313 {OSPFLSDBCHECKSUM, INTEGER, RONLY, ospfLsdbEntry,
314 3, {4, 1, 7}},
315 {OSPFLSDBADVERTISEMENT, STRING, RONLY, ospfLsdbEntry,
316 3, {4, 1, 8}},
317
318 /* Area range table. */
319 {OSPFAREARANGEAREAID, IPADDRESS, RONLY, ospfAreaRangeEntry,
320 3, {5, 1, 1}},
321 {OSPFAREARANGENET, IPADDRESS, RONLY, ospfAreaRangeEntry,
322 3, {5, 1, 2}},
323 {OSPFAREARANGEMASK, IPADDRESS, RWRITE, ospfAreaRangeEntry,
324 3, {5, 1, 3}},
325 {OSPFAREARANGESTATUS, INTEGER, RWRITE, ospfAreaRangeEntry,
326 3, {5, 1, 4}},
327 {OSPFAREARANGEEFFECT, INTEGER, RWRITE, ospfAreaRangeEntry,
328 3, {5, 1, 5}},
329
330 /* OSPF host table. */
331 {OSPFHOSTIPADDRESS, IPADDRESS, RONLY, ospfHostEntry,
332 3, {6, 1, 1}},
333 {OSPFHOSTTOS, INTEGER, RONLY, ospfHostEntry,
334 3, {6, 1, 2}},
335 {OSPFHOSTMETRIC, INTEGER, RWRITE, ospfHostEntry,
336 3, {6, 1, 3}},
337 {OSPFHOSTSTATUS, INTEGER, RWRITE, ospfHostEntry,
338 3, {6, 1, 4}},
339 {OSPFHOSTAREAID, IPADDRESS, RONLY, ospfHostEntry,
340 3, {6, 1, 5}},
341
342 /* OSPF interface table. */
343 {OSPFIFIPADDRESS, IPADDRESS, RONLY, ospfIfEntry,
344 3, {7, 1, 1}},
345 {OSPFADDRESSLESSIF, INTEGER, RONLY, ospfIfEntry,
346 3, {7, 1, 2}},
347 {OSPFIFAREAID, IPADDRESS, RWRITE, ospfIfEntry,
348 3, {7, 1, 3}},
349 {OSPFIFTYPE, INTEGER, RWRITE, ospfIfEntry,
350 3, {7, 1, 4}},
351 {OSPFIFADMINSTAT, INTEGER, RWRITE, ospfIfEntry,
352 3, {7, 1, 5}},
353 {OSPFIFRTRPRIORITY, INTEGER, RWRITE, ospfIfEntry,
354 3, {7, 1, 6}},
355 {OSPFIFTRANSITDELAY, INTEGER, RWRITE, ospfIfEntry,
356 3, {7, 1, 7}},
357 {OSPFIFRETRANSINTERVAL, INTEGER, RWRITE, ospfIfEntry,
358 3, {7, 1, 8}},
359 {OSPFIFHELLOINTERVAL, INTEGER, RWRITE, ospfIfEntry,
360 3, {7, 1, 9}},
361 {OSPFIFRTRDEADINTERVAL, INTEGER, RWRITE, ospfIfEntry,
362 3, {7, 1, 10}},
363 {OSPFIFPOLLINTERVAL, INTEGER, RWRITE, ospfIfEntry,
364 3, {7, 1, 11}},
365 {OSPFIFSTATE, INTEGER, RONLY, ospfIfEntry,
366 3, {7, 1, 12}},
367 {OSPFIFDESIGNATEDROUTER, IPADDRESS, RONLY, ospfIfEntry,
368 3, {7, 1, 13}},
369 {OSPFIFBACKUPDESIGNATEDROUTER, IPADDRESS, RONLY, ospfIfEntry,
370 3, {7, 1, 14}},
371 {OSPFIFEVENTS, COUNTER, RONLY, ospfIfEntry,
372 3, {7, 1, 15}},
373 {OSPFIFAUTHKEY, STRING, RWRITE, ospfIfEntry,
374 3, {7, 1, 16}},
375 {OSPFIFSTATUS, INTEGER, RWRITE, ospfIfEntry,
376 3, {7, 1, 17}},
377 {OSPFIFMULTICASTFORWARDING, INTEGER, RWRITE, ospfIfEntry,
378 3, {7, 1, 18}},
379 {OSPFIFDEMAND, INTEGER, RWRITE, ospfIfEntry,
380 3, {7, 1, 19}},
381 {OSPFIFAUTHTYPE, INTEGER, RWRITE, ospfIfEntry,
382 3, {7, 1, 20}},
383
384 /* OSPF interface metric table. */
385 {OSPFIFMETRICIPADDRESS, IPADDRESS, RONLY, ospfIfMetricEntry,
386 3, {8, 1, 1}},
387 {OSPFIFMETRICADDRESSLESSIF, INTEGER, RONLY, ospfIfMetricEntry,
388 3, {8, 1, 2}},
389 {OSPFIFMETRICTOS, INTEGER, RONLY, ospfIfMetricEntry,
390 3, {8, 1, 3}},
391 {OSPFIFMETRICVALUE, INTEGER, RWRITE, ospfIfMetricEntry,
392 3, {8, 1, 4}},
393 {OSPFIFMETRICSTATUS, INTEGER, RWRITE, ospfIfMetricEntry,
394 3, {8, 1, 5}},
395
396 /* OSPF virtual interface table. */
397 {OSPFVIRTIFAREAID, IPADDRESS, RONLY, ospfVirtIfEntry,
398 3, {9, 1, 1}},
399 {OSPFVIRTIFNEIGHBOR, IPADDRESS, RONLY, ospfVirtIfEntry,
400 3, {9, 1, 2}},
401 {OSPFVIRTIFTRANSITDELAY, INTEGER, RWRITE, ospfVirtIfEntry,
402 3, {9, 1, 3}},
403 {OSPFVIRTIFRETRANSINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry,
404 3, {9, 1, 4}},
405 {OSPFVIRTIFHELLOINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry,
406 3, {9, 1, 5}},
407 {OSPFVIRTIFRTRDEADINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry,
408 3, {9, 1, 6}},
409 {OSPFVIRTIFSTATE, INTEGER, RONLY, ospfVirtIfEntry,
410 3, {9, 1, 7}},
411 {OSPFVIRTIFEVENTS, COUNTER, RONLY, ospfVirtIfEntry,
412 3, {9, 1, 8}},
413 {OSPFVIRTIFAUTHKEY, STRING, RWRITE, ospfVirtIfEntry,
414 3, {9, 1, 9}},
415 {OSPFVIRTIFSTATUS, INTEGER, RWRITE, ospfVirtIfEntry,
416 3, {9, 1, 10}},
417 {OSPFVIRTIFAUTHTYPE, INTEGER, RWRITE, ospfVirtIfEntry,
418 3, {9, 1, 11}},
419
420 /* OSPF neighbor table. */
421 {OSPFNBRIPADDR, IPADDRESS, RONLY, ospfNbrEntry,
422 3, {10, 1, 1}},
423 {OSPFNBRADDRESSLESSINDEX, INTEGER, RONLY, ospfNbrEntry,
424 3, {10, 1, 2}},
425 {OSPFNBRRTRID, IPADDRESS, RONLY, ospfNbrEntry,
426 3, {10, 1, 3}},
427 {OSPFNBROPTIONS, INTEGER, RONLY, ospfNbrEntry,
428 3, {10, 1, 4}},
429 {OSPFNBRPRIORITY, INTEGER, RWRITE, ospfNbrEntry,
430 3, {10, 1, 5}},
431 {OSPFNBRSTATE, INTEGER, RONLY, ospfNbrEntry,
432 3, {10, 1, 6}},
433 {OSPFNBREVENTS, COUNTER, RONLY, ospfNbrEntry,
434 3, {10, 1, 7}},
435 {OSPFNBRLSRETRANSQLEN, GAUGE, RONLY, ospfNbrEntry,
436 3, {10, 1, 8}},
437 {OSPFNBMANBRSTATUS, INTEGER, RWRITE, ospfNbrEntry,
438 3, {10, 1, 9}},
439 {OSPFNBMANBRPERMANENCE, INTEGER, RONLY, ospfNbrEntry,
440 3, {10, 1, 10}},
441 {OSPFNBRHELLOSUPPRESSED, INTEGER, RONLY, ospfNbrEntry,
442 3, {10, 1, 11}},
443
444 /* OSPF virtual neighbor table. */
445 {OSPFVIRTNBRAREA, IPADDRESS, RONLY, ospfVirtNbrEntry,
446 3, {11, 1, 1}},
447 {OSPFVIRTNBRRTRID, IPADDRESS, RONLY, ospfVirtNbrEntry,
448 3, {11, 1, 2}},
449 {OSPFVIRTNBRIPADDR, IPADDRESS, RONLY, ospfVirtNbrEntry,
450 3, {11, 1, 3}},
451 {OSPFVIRTNBROPTIONS, INTEGER, RONLY, ospfVirtNbrEntry,
452 3, {11, 1, 4}},
453 {OSPFVIRTNBRSTATE, INTEGER, RONLY, ospfVirtNbrEntry,
454 3, {11, 1, 5}},
455 {OSPFVIRTNBREVENTS, COUNTER, RONLY, ospfVirtNbrEntry,
456 3, {11, 1, 6}},
457 {OSPFVIRTNBRLSRETRANSQLEN, INTEGER, RONLY, ospfVirtNbrEntry,
458 3, {11, 1, 7}},
459 {OSPFVIRTNBRHELLOSUPPRESSED, INTEGER, RONLY, ospfVirtNbrEntry,
460 3, {11, 1, 8}},
461
462 /* OSPF link state database, external. */
463 {OSPFEXTLSDBTYPE, INTEGER, RONLY, ospfExtLsdbEntry,
464 3, {12, 1, 1}},
465 {OSPFEXTLSDBLSID, IPADDRESS, RONLY, ospfExtLsdbEntry,
466 3, {12, 1, 2}},
467 {OSPFEXTLSDBROUTERID, IPADDRESS, RONLY, ospfExtLsdbEntry,
468 3, {12, 1, 3}},
469 {OSPFEXTLSDBSEQUENCE, INTEGER, RONLY, ospfExtLsdbEntry,
470 3, {12, 1, 4}},
471 {OSPFEXTLSDBAGE, INTEGER, RONLY, ospfExtLsdbEntry,
472 3, {12, 1, 5}},
473 {OSPFEXTLSDBCHECKSUM, INTEGER, RONLY, ospfExtLsdbEntry,
474 3, {12, 1, 6}},
475 {OSPFEXTLSDBADVERTISEMENT, STRING, RONLY, ospfExtLsdbEntry,
476 3, {12, 1, 7}},
477
478 /* OSPF area aggregate table. */
479 {OSPFAREAAGGREGATEAREAID, IPADDRESS, RONLY, ospfAreaAggregateEntry,
480 3, {14, 1, 1}},
481 {OSPFAREAAGGREGATELSDBTYPE, INTEGER, RONLY, ospfAreaAggregateEntry,
482 3, {14, 1, 2}},
483 {OSPFAREAAGGREGATENET, IPADDRESS, RONLY, ospfAreaAggregateEntry,
484 3, {14, 1, 3}},
485 {OSPFAREAAGGREGATEMASK, IPADDRESS, RONLY, ospfAreaAggregateEntry,
486 3, {14, 1, 4}},
487 {OSPFAREAAGGREGATESTATUS, INTEGER, RWRITE, ospfAreaAggregateEntry,
488 3, {14, 1, 5}},
489 {OSPFAREAAGGREGATEEFFECT, INTEGER, RWRITE, ospfAreaAggregateEntry,
490 3, {14, 1, 6}}
491};
492
493/* The administrative status of OSPF. When OSPF is enbled on at least
494 one interface return 1. */
495int
paul68980082003-03-25 05:07:42 +0000496ospf_admin_stat (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +0000497{
paulaa20c6f2004-10-07 14:19:36 +0000498 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000499 struct ospf_interface *oi;
500
paul68980082003-03-25 05:07:42 +0000501 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +0000502 return 0;
503
paul1eb8ef22005-04-07 07:30:20 +0000504 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
505 if (oi && oi->address)
506 return 1;
paul718e3742002-12-13 20:15:29 +0000507
paul718e3742002-12-13 20:15:29 +0000508 return 0;
509}
510
511static u_char *
512ospfGeneralGroup (struct variable *v, oid *name, size_t *length,
513 int exact, size_t *var_len, WriteMethod **write_method)
514{
paul020709f2003-04-04 02:44:16 +0000515 struct ospf *ospf;
516
517 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +0000518
paul718e3742002-12-13 20:15:29 +0000519 /* Check whether the instance identifier is valid */
520 if (smux_header_generic (v, name, length, exact, var_len, write_method)
521 == MATCH_FAILED)
522 return NULL;
523
524 /* Return the current value of the variable */
525 switch (v->magic)
526 {
527 case OSPFROUTERID: /* 1 */
528 /* Router-ID of this OSPF instance. */
paul68980082003-03-25 05:07:42 +0000529 if (ospf)
530 return SNMP_IPADDRESS (ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000531 else
532 return SNMP_IPADDRESS (ospf_empty_addr);
533 break;
534 case OSPFADMINSTAT: /* 2 */
535 /* The administrative status of OSPF in the router. */
paul68980082003-03-25 05:07:42 +0000536 if (ospf_admin_stat (ospf))
paul718e3742002-12-13 20:15:29 +0000537 return SNMP_INTEGER (OSPF_STATUS_ENABLED);
538 else
539 return SNMP_INTEGER (OSPF_STATUS_DISABLED);
540 break;
541 case OSPFVERSIONNUMBER: /* 3 */
542 /* OSPF version 2. */
543 return SNMP_INTEGER (OSPF_VERSION);
544 break;
545 case OSPFAREABDRRTRSTATUS: /* 4 */
546 /* Area Border router status. */
paul68980082003-03-25 05:07:42 +0000547 if (ospf && CHECK_FLAG (ospf->flags, OSPF_FLAG_ABR))
paul718e3742002-12-13 20:15:29 +0000548 return SNMP_INTEGER (SNMP_TRUE);
549 else
550 return SNMP_INTEGER (SNMP_FALSE);
551 break;
552 case OSPFASBDRRTRSTATUS: /* 5 */
553 /* AS Border router status. */
paul68980082003-03-25 05:07:42 +0000554 if (ospf && CHECK_FLAG (ospf->flags, OSPF_FLAG_ASBR))
paul718e3742002-12-13 20:15:29 +0000555 return SNMP_INTEGER (SNMP_TRUE);
556 else
557 return SNMP_INTEGER (SNMP_FALSE);
558 break;
559 case OSPFEXTERNLSACOUNT: /* 6 */
560 /* External LSA counts. */
paul68980082003-03-25 05:07:42 +0000561 if (ospf)
562 return SNMP_INTEGER (ospf_lsdb_count_all (ospf->lsdb));
paul718e3742002-12-13 20:15:29 +0000563 else
564 return SNMP_INTEGER (0);
565 break;
566 case OSPFEXTERNLSACKSUMSUM: /* 7 */
567 /* External LSA checksum. */
568 return SNMP_INTEGER (0);
569 break;
570 case OSPFTOSSUPPORT: /* 8 */
571 /* TOS is not supported. */
572 return SNMP_INTEGER (SNMP_FALSE);
573 break;
574 case OSPFORIGINATENEWLSAS: /* 9 */
575 /* The number of new link-state advertisements. */
paul68980082003-03-25 05:07:42 +0000576 if (ospf)
577 return SNMP_INTEGER (ospf->lsa_originate_count);
paul718e3742002-12-13 20:15:29 +0000578 else
579 return SNMP_INTEGER (0);
580 break;
581 case OSPFRXNEWLSAS: /* 10 */
582 /* The number of link-state advertisements received determined
583 to be new instantiations. */
paul68980082003-03-25 05:07:42 +0000584 if (ospf)
585 return SNMP_INTEGER (ospf->rx_lsa_count);
paul718e3742002-12-13 20:15:29 +0000586 else
587 return SNMP_INTEGER (0);
588 break;
589 case OSPFEXTLSDBLIMIT: /* 11 */
590 /* There is no limit for the number of non-default
591 AS-external-LSAs. */
592 return SNMP_INTEGER (-1);
593 break;
594 case OSPFMULTICASTEXTENSIONS: /* 12 */
595 /* Multicast Extensions to OSPF is not supported. */
596 return SNMP_INTEGER (0);
597 break;
598 case OSPFEXITOVERFLOWINTERVAL: /* 13 */
599 /* Overflow is not supported. */
600 return SNMP_INTEGER (0);
601 break;
602 case OSPFDEMANDEXTENSIONS: /* 14 */
603 /* Demand routing is not supported. */
604 return SNMP_INTEGER (SNMP_FALSE);
605 break;
606 default:
607 return NULL;
608 }
609 return NULL;
610}
611
612struct ospf_area *
paul68980082003-03-25 05:07:42 +0000613ospf_area_lookup_next (struct ospf *ospf, struct in_addr *area_id, int first)
paul718e3742002-12-13 20:15:29 +0000614{
615 struct ospf_area *area;
paulaa20c6f2004-10-07 14:19:36 +0000616 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000617
paul020709f2003-04-04 02:44:16 +0000618 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +0000619 return NULL;
620
621 if (first)
622 {
paul68980082003-03-25 05:07:42 +0000623 node = listhead (ospf->areas);
paul718e3742002-12-13 20:15:29 +0000624 if (node)
625 {
paul1eb8ef22005-04-07 07:30:20 +0000626 area = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000627 *area_id = area->area_id;
628 return area;
629 }
630 return NULL;
631 }
paul1eb8ef22005-04-07 07:30:20 +0000632 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
paul718e3742002-12-13 20:15:29 +0000633 {
paul718e3742002-12-13 20:15:29 +0000634 if (ntohl (area->area_id.s_addr) > ntohl (area_id->s_addr))
635 {
636 *area_id = area->area_id;
637 return area;
638 }
639 }
640 return NULL;
641}
642
643struct ospf_area *
644ospfAreaLookup (struct variable *v, oid name[], size_t *length,
645 struct in_addr *addr, int exact)
646{
paul020709f2003-04-04 02:44:16 +0000647 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000648 struct ospf_area *area;
paul68980082003-03-25 05:07:42 +0000649 int len;
paul718e3742002-12-13 20:15:29 +0000650
paul020709f2003-04-04 02:44:16 +0000651 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +0000652 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +0000653 return NULL;
654
655 if (exact)
656 {
657 /* Length is insufficient to lookup OSPF area. */
658 if (*length - v->namelen != sizeof (struct in_addr))
659 return NULL;
660
661 oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr);
662
paul68980082003-03-25 05:07:42 +0000663 area = ospf_area_lookup_by_area_id (ospf, *addr);
paul718e3742002-12-13 20:15:29 +0000664
665 return area;
666 }
667 else
668 {
669 len = *length - v->namelen;
670 if (len > 4)
671 len = 4;
672
673 oid2in_addr (name + v->namelen, len, addr);
674
paul68980082003-03-25 05:07:42 +0000675 area = ospf_area_lookup_next (ospf, addr, len == 0 ? 1 : 0);
paul718e3742002-12-13 20:15:29 +0000676
677 if (area == NULL)
678 return NULL;
679
680 oid_copy_addr (name + v->namelen, addr, sizeof (struct in_addr));
681 *length = sizeof (struct in_addr) + v->namelen;
682
683 return area;
684 }
685 return NULL;
686}
687
688static u_char *
689ospfAreaEntry (struct variable *v, oid *name, size_t *length, int exact,
690 size_t *var_len, WriteMethod **write_method)
691{
692 struct ospf_area *area;
693 struct in_addr addr;
694
695 memset (&addr, 0, sizeof (struct in_addr));
696
697 area = ospfAreaLookup (v, name, length, &addr, exact);
698 if (! area)
699 return NULL;
700
701 /* Return the current value of the variable */
702 switch (v->magic)
703 {
704 case OSPFAREAID: /* 1 */
705 return SNMP_IPADDRESS (area->area_id);
706 break;
707 case OSPFAUTHTYPE: /* 2 */
708 return SNMP_INTEGER (area->auth_type);
709 break;
710 case OSPFIMPORTASEXTERN: /* 3 */
711 return SNMP_INTEGER (area->external_routing + 1);
712 break;
713 case OSPFSPFRUNS: /* 4 */
714 return SNMP_INTEGER (area->spf_calculation);
715 break;
716 case OSPFAREABDRRTRCOUNT: /* 5 */
717 return SNMP_INTEGER (area->abr_count);
718 break;
719 case OSPFASBDRRTRCOUNT: /* 6 */
720 return SNMP_INTEGER (area->asbr_count);
721 break;
722 case OSPFAREALSACOUNT: /* 7 */
723 return SNMP_INTEGER (area->lsdb->total);
724 break;
725 case OSPFAREALSACKSUMSUM: /* 8 */
726 return SNMP_INTEGER (0);
727 break;
728 case OSPFAREASUMMARY: /* 9 */
729#define OSPF_noAreaSummary 1
730#define OSPF_sendAreaSummary 2
731 if (area->no_summary)
732 return SNMP_INTEGER (OSPF_noAreaSummary);
733 else
734 return SNMP_INTEGER (OSPF_sendAreaSummary);
735 break;
736 case OSPFAREASTATUS: /* 10 */
737 return SNMP_INTEGER (SNMP_VALID);
738 break;
739 default:
740 return NULL;
741 break;
742 }
743 return NULL;
744}
745
746struct ospf_area *
747ospf_stub_area_lookup_next (struct in_addr *area_id, int first)
748{
749 struct ospf_area *area;
paulaa20c6f2004-10-07 14:19:36 +0000750 struct listnode *node;
paul020709f2003-04-04 02:44:16 +0000751 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000752
paul020709f2003-04-04 02:44:16 +0000753 ospf = ospf_lookup ();
754 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +0000755 return NULL;
756
paul1eb8ef22005-04-07 07:30:20 +0000757 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
paul718e3742002-12-13 20:15:29 +0000758 {
paul718e3742002-12-13 20:15:29 +0000759 if (area->external_routing == OSPF_AREA_STUB)
760 {
761 if (first)
762 {
763 *area_id = area->area_id;
764 return area;
765 }
766 else if (ntohl (area->area_id.s_addr) > ntohl (area_id->s_addr))
767 {
768 *area_id = area->area_id;
769 return area;
770 }
771 }
772 }
773 return NULL;
774}
775
776struct ospf_area *
777ospfStubAreaLookup (struct variable *v, oid name[], size_t *length,
778 struct in_addr *addr, int exact)
779{
paul020709f2003-04-04 02:44:16 +0000780 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000781 struct ospf_area *area;
paul68980082003-03-25 05:07:42 +0000782 int len;
paul718e3742002-12-13 20:15:29 +0000783
paul020709f2003-04-04 02:44:16 +0000784 ospf = ospf_lookup ();
785 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +0000786 return NULL;
787
788 /* Exact lookup. */
789 if (exact)
790 {
791 /* ospfStubAreaID + ospfStubTOS. */
792 if (*length != v->namelen + sizeof (struct in_addr) + 1)
793 return NULL;
794
795 /* Check ospfStubTOS is zero. */
796 if (name[*length - 1] != 0)
797 return NULL;
798
799 oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr);
800
paul68980082003-03-25 05:07:42 +0000801 area = ospf_area_lookup_by_area_id (ospf, *addr);
paul718e3742002-12-13 20:15:29 +0000802
803 if (area->external_routing == OSPF_AREA_STUB)
804 return area;
805 else
806 return NULL;
807 }
808 else
809 {
810 len = *length - v->namelen;
811 if (len > 4)
812 len = 4;
813
814 oid2in_addr (name + v->namelen, len, addr);
815
816 area = ospf_stub_area_lookup_next (addr, len == 0 ? 1 : 0);
817
818 if (area == NULL)
819 return NULL;
820
821 oid_copy_addr (name + v->namelen, addr, sizeof (struct in_addr));
822 /* Set TOS 0. */
823 name[v->namelen + sizeof (struct in_addr)] = 0;
824 *length = v->namelen + sizeof (struct in_addr) + 1;
825
826 return area;
827 }
828 return NULL;
829}
830
831static u_char *
832ospfStubAreaEntry (struct variable *v, oid *name, size_t *length,
833 int exact, size_t *var_len, WriteMethod **write_method)
834{
835 struct ospf_area *area;
836 struct in_addr addr;
837
838 memset (&addr, 0, sizeof (struct in_addr));
839
840 area = ospfStubAreaLookup (v, name, length, &addr, exact);
841 if (! area)
842 return NULL;
843
844 /* Return the current value of the variable */
845 switch (v->magic)
846 {
847 case OSPFSTUBAREAID: /* 1 */
848 /* OSPF stub area id. */
849 return SNMP_IPADDRESS (area->area_id);
850 break;
851 case OSPFSTUBTOS: /* 2 */
852 /* TOS value is not supported. */
853 return SNMP_INTEGER (0);
854 break;
855 case OSPFSTUBMETRIC: /* 3 */
856 /* Default cost to stub area. */
857 return SNMP_INTEGER (area->default_cost);
858 break;
859 case OSPFSTUBSTATUS: /* 4 */
860 /* Status of the stub area. */
861 return SNMP_INTEGER (SNMP_VALID);
862 break;
863 case OSPFSTUBMETRICTYPE: /* 5 */
864 /* OSPF Metric type. */
865#define OSPF_ospfMetric 1
866#define OSPF_comparableCost 2
867#define OSPF_nonComparable 3
868 return SNMP_INTEGER (OSPF_ospfMetric);
869 break;
870 default:
871 return NULL;
872 break;
873 }
874 return NULL;
875}
876
877struct ospf_lsa *
878lsdb_lookup_next (struct ospf_area *area, u_char *type, int type_next,
879 struct in_addr *ls_id, int ls_id_next,
880 struct in_addr *router_id, int router_id_next)
881{
882 struct ospf_lsa *lsa;
883 int i;
884
885 if (type_next)
886 i = OSPF_MIN_LSA;
887 else
888 i = *type;
889
vincentba682532005-09-29 13:52:57 +0000890 /* Sanity check, if LSA type unknwon
891 merley skip any LSA */
892 if ((i < OSPF_MIN_LSA) || (i >= OSPF_MAX_LSA))
893 {
894 zlog_debug("Strange request with LSA type %d\n", i);
895 return NULL;
896 }
897
paul718e3742002-12-13 20:15:29 +0000898 for (; i < OSPF_MAX_LSA; i++)
899 {
900 *type = i;
901
902 lsa = ospf_lsdb_lookup_by_id_next (area->lsdb, *type, *ls_id, *router_id,
903 ls_id_next);
904 if (lsa)
905 return lsa;
906
907 ls_id_next = 1;
908 }
909 return NULL;
910}
911
912struct ospf_lsa *
913ospfLsdbLookup (struct variable *v, oid *name, size_t *length,
914 struct in_addr *area_id, u_char *type,
915 struct in_addr *ls_id, struct in_addr *router_id, int exact)
916{
paul020709f2003-04-04 02:44:16 +0000917 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000918 struct ospf_area *area;
919 struct ospf_lsa *lsa;
paul6c835672004-10-11 11:00:30 +0000920 unsigned int len;
paul718e3742002-12-13 20:15:29 +0000921 int type_next;
922 int ls_id_next;
923 int router_id_next;
924 oid *offset;
925 int offsetlen;
926
paul020709f2003-04-04 02:44:16 +0000927 ospf = ospf_lookup ();
928
paul718e3742002-12-13 20:15:29 +0000929#define OSPF_LSDB_ENTRY_OFFSET \
930 (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
931
932 if (exact)
933 {
934 /* Area ID + Type + LS ID + Router ID. */
935 if (*length - v->namelen != OSPF_LSDB_ENTRY_OFFSET)
936 return NULL;
937
938 /* Set OID offset for Area ID. */
939 offset = name + v->namelen;
940
941 /* Lookup area first. */
942 oid2in_addr (offset, IN_ADDR_SIZE, area_id);
paul68980082003-03-25 05:07:42 +0000943 area = ospf_area_lookup_by_area_id (ospf, *area_id);
paul718e3742002-12-13 20:15:29 +0000944 if (! area)
945 return NULL;
946 offset += IN_ADDR_SIZE;
947
948 /* Type. */
949 *type = *offset;
950 offset++;
951
952 /* LS ID. */
953 oid2in_addr (offset, IN_ADDR_SIZE, ls_id);
954 offset += IN_ADDR_SIZE;
955
956 /* Router ID. */
957 oid2in_addr (offset, IN_ADDR_SIZE, router_id);
958
959 /* Lookup LSDB. */
960 return ospf_lsdb_lookup_by_id (area->lsdb, *type, *ls_id, *router_id);
961 }
962 else
963 {
964 /* Get variable length. */
965 offset = name + v->namelen;
966 offsetlen = *length - v->namelen;
967 len = offsetlen;
968
969 if (len > IN_ADDR_SIZE)
970 len = IN_ADDR_SIZE;
971
972 oid2in_addr (offset, len, area_id);
973
974 /* First we search area. */
975 if (len == IN_ADDR_SIZE)
paul68980082003-03-25 05:07:42 +0000976 area = ospf_area_lookup_by_area_id (ospf, *area_id);
paul718e3742002-12-13 20:15:29 +0000977 else
paul68980082003-03-25 05:07:42 +0000978 area = ospf_area_lookup_next (ospf, area_id, len == 0 ? 1 : 0);
paul718e3742002-12-13 20:15:29 +0000979
980 if (area == NULL)
981 return NULL;
982
983 do
984 {
985 /* Next we lookup type. */
986 offset += IN_ADDR_SIZE;
987 offsetlen -= IN_ADDR_SIZE;
988 len = offsetlen;
989
990 if (len <= 0)
991 type_next = 1;
992 else
993 {
994 len = 1;
995 type_next = 0;
996 *type = *offset;
997 }
998
999 /* LS ID. */
1000 offset++;
1001 offsetlen--;
1002 len = offsetlen;
1003
1004 if (len <= 0)
1005 ls_id_next = 1;
1006 else
1007 {
1008 ls_id_next = 0;
1009 if (len > IN_ADDR_SIZE)
1010 len = IN_ADDR_SIZE;
1011
1012 oid2in_addr (offset, len, ls_id);
1013 }
1014
1015 /* Router ID. */
1016 offset += IN_ADDR_SIZE;
1017 offsetlen -= IN_ADDR_SIZE;
1018 len = offsetlen;
1019
1020 if (len <= 0)
1021 router_id_next = 1;
1022 else
1023 {
1024 router_id_next = 0;
1025 if (len > IN_ADDR_SIZE)
1026 len = IN_ADDR_SIZE;
1027
1028 oid2in_addr (offset, len, router_id);
1029 }
1030
1031 lsa = lsdb_lookup_next (area, type, type_next, ls_id, ls_id_next,
1032 router_id, router_id_next);
1033
1034 if (lsa)
1035 {
1036 /* Fill in length. */
1037 *length = v->namelen + OSPF_LSDB_ENTRY_OFFSET;
1038
1039 /* Fill in value. */
1040 offset = name + v->namelen;
1041 oid_copy_addr (offset, area_id, IN_ADDR_SIZE);
1042 offset += IN_ADDR_SIZE;
1043 *offset = lsa->data->type;
1044 offset++;
1045 oid_copy_addr (offset, &lsa->data->id, IN_ADDR_SIZE);
1046 offset += IN_ADDR_SIZE;
1047 oid_copy_addr (offset, &lsa->data->adv_router, IN_ADDR_SIZE);
1048
1049 return lsa;
1050 }
1051 }
paul68980082003-03-25 05:07:42 +00001052 while ((area = ospf_area_lookup_next (ospf, area_id, 0)) != NULL);
paul718e3742002-12-13 20:15:29 +00001053 }
1054 return NULL;
1055}
1056
1057static u_char *
1058ospfLsdbEntry (struct variable *v, oid *name, size_t *length, int exact,
1059 size_t *var_len, WriteMethod **write_method)
1060{
1061 struct ospf_lsa *lsa;
1062 struct lsa_header *lsah;
1063 struct in_addr area_id;
1064 u_char type;
1065 struct in_addr ls_id;
1066 struct in_addr router_id;
paul020709f2003-04-04 02:44:16 +00001067 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001068
1069 /* INDEX { ospfLsdbAreaId, ospfLsdbType,
1070 ospfLsdbLsid, ospfLsdbRouterId } */
1071
1072 memset (&area_id, 0, sizeof (struct in_addr));
1073 type = 0;
1074 memset (&ls_id, 0, sizeof (struct in_addr));
1075 memset (&router_id, 0, sizeof (struct in_addr));
1076
1077 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00001078 ospf = ospf_lookup ();
1079 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001080 return NULL;
1081
1082 lsa = ospfLsdbLookup (v, name, length, &area_id, &type, &ls_id, &router_id,
1083 exact);
1084 if (! lsa)
1085 return NULL;
1086
1087 lsah = lsa->data;
1088
1089 /* Return the current value of the variable */
1090 switch (v->magic)
1091 {
1092 case OSPFLSDBAREAID: /* 1 */
1093 return SNMP_IPADDRESS (lsa->area->area_id);
1094 break;
1095 case OSPFLSDBTYPE: /* 2 */
1096 return SNMP_INTEGER (lsah->type);
1097 break;
1098 case OSPFLSDBLSID: /* 3 */
1099 return SNMP_IPADDRESS (lsah->id);
1100 break;
1101 case OSPFLSDBROUTERID: /* 4 */
1102 return SNMP_IPADDRESS (lsah->adv_router);
1103 break;
1104 case OSPFLSDBSEQUENCE: /* 5 */
1105 return SNMP_INTEGER (lsah->ls_seqnum);
1106 break;
1107 case OSPFLSDBAGE: /* 6 */
1108 return SNMP_INTEGER (lsah->ls_age);
1109 break;
1110 case OSPFLSDBCHECKSUM: /* 7 */
1111 return SNMP_INTEGER (lsah->checksum);
1112 break;
1113 case OSPFLSDBADVERTISEMENT: /* 8 */
1114 *var_len = ntohs (lsah->length);
1115 return (u_char *) lsah;
1116 break;
1117 default:
1118 return NULL;
1119 break;
1120 }
1121 return NULL;
1122}
1123
1124struct ospf_area_range *
1125ospfAreaRangeLookup (struct variable *v, oid *name, size_t *length,
1126 struct in_addr *area_id, struct in_addr *range_net,
1127 int exact)
1128{
1129 oid *offset;
1130 int offsetlen;
paul6c835672004-10-11 11:00:30 +00001131 unsigned int len;
paul020709f2003-04-04 02:44:16 +00001132 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001133 struct ospf_area *area;
1134 struct ospf_area_range *range;
1135 struct prefix_ipv4 p;
1136 p.family = AF_INET;
1137 p.prefixlen = IPV4_MAX_BITLEN;
1138
paul020709f2003-04-04 02:44:16 +00001139 ospf = ospf_lookup ();
1140
paul718e3742002-12-13 20:15:29 +00001141 if (exact)
1142 {
1143 /* Area ID + Range Network. */
1144 if (v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE != *length)
1145 return NULL;
1146
1147 /* Set OID offset for Area ID. */
1148 offset = name + v->namelen;
1149
1150 /* Lookup area first. */
1151 oid2in_addr (offset, IN_ADDR_SIZE, area_id);
1152
paul68980082003-03-25 05:07:42 +00001153 area = ospf_area_lookup_by_area_id (ospf, *area_id);
paul718e3742002-12-13 20:15:29 +00001154 if (! area)
1155 return NULL;
1156
1157 offset += IN_ADDR_SIZE;
1158
1159 /* Lookup area range. */
1160 oid2in_addr (offset, IN_ADDR_SIZE, range_net);
1161 p.prefix = *range_net;
1162
1163 return ospf_area_range_lookup (area, &p);
1164 }
1165 else
1166 {
1167 /* Set OID offset for Area ID. */
1168 offset = name + v->namelen;
1169 offsetlen = *length - v->namelen;
1170
1171 len = offsetlen;
1172 if (len > IN_ADDR_SIZE)
1173 len = IN_ADDR_SIZE;
1174
1175 oid2in_addr (offset, len, area_id);
1176
1177 /* First we search area. */
1178 if (len == IN_ADDR_SIZE)
paul68980082003-03-25 05:07:42 +00001179 area = ospf_area_lookup_by_area_id (ospf,*area_id);
paul718e3742002-12-13 20:15:29 +00001180 else
paul68980082003-03-25 05:07:42 +00001181 area = ospf_area_lookup_next (ospf, area_id, len == 0 ? 1 : 0);
paul718e3742002-12-13 20:15:29 +00001182
1183 if (area == NULL)
1184 return NULL;
1185
1186 do
1187 {
1188 offset += IN_ADDR_SIZE;
1189 offsetlen -= IN_ADDR_SIZE;
1190 len = offsetlen;
1191
1192 if (len < 0)
1193 len = 0;
1194 if (len > IN_ADDR_SIZE)
1195 len = IN_ADDR_SIZE;
1196
1197 oid2in_addr (offset, len, range_net);
1198
1199 range = ospf_area_range_lookup_next (area, range_net,
1200 len == 0 ? 1 : 0);
1201
1202 if (range)
1203 {
1204 /* Fill in length. */
1205 *length = v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE;
1206
1207 /* Fill in value. */
1208 offset = name + v->namelen;
1209 oid_copy_addr (offset, area_id, IN_ADDR_SIZE);
1210 offset += IN_ADDR_SIZE;
1211 oid_copy_addr (offset, range_net, IN_ADDR_SIZE);
1212
1213 return range;
1214 }
1215 }
paul68980082003-03-25 05:07:42 +00001216 while ((area = ospf_area_lookup_next (ospf, area_id, 0)) != NULL);
paul718e3742002-12-13 20:15:29 +00001217 }
1218 return NULL;
1219}
1220
1221static u_char *
1222ospfAreaRangeEntry (struct variable *v, oid *name, size_t *length, int exact,
1223 size_t *var_len, WriteMethod **write_method)
1224{
1225 struct ospf_area_range *range;
1226 struct in_addr area_id;
1227 struct in_addr range_net;
1228 struct in_addr mask;
paul020709f2003-04-04 02:44:16 +00001229 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001230
1231 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00001232 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00001233 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001234 return NULL;
1235
1236 memset (&area_id, 0, IN_ADDR_SIZE);
1237 memset (&range_net, 0, IN_ADDR_SIZE);
1238
1239 range = ospfAreaRangeLookup (v, name, length, &area_id, &range_net, exact);
1240 if (! range)
1241 return NULL;
1242
1243 /* Convert prefixlen to network mask format. */
1244 masklen2ip (range->subst_masklen, &mask);
1245
1246 /* Return the current value of the variable */
1247 switch (v->magic)
1248 {
1249 case OSPFAREARANGEAREAID: /* 1 */
1250 return SNMP_IPADDRESS (area_id);
1251 break;
1252 case OSPFAREARANGENET: /* 2 */
1253 return SNMP_IPADDRESS (range_net);
1254 break;
1255 case OSPFAREARANGEMASK: /* 3 */
1256 return SNMP_IPADDRESS (mask);
1257 break;
1258 case OSPFAREARANGESTATUS: /* 4 */
1259 return SNMP_INTEGER (SNMP_VALID);
1260 break;
1261 case OSPFAREARANGEEFFECT: /* 5 */
1262#define OSPF_advertiseMatching 1
1263#define OSPF_doNotAdvertiseMatching 2
1264 return SNMP_INTEGER (OSPF_advertiseMatching);
1265 break;
1266 default:
1267 return NULL;
1268 break;
1269 }
1270 return NULL;
1271}
1272
1273struct ospf_nbr_nbma *
1274ospfHostLookup (struct variable *v, oid *name, size_t *length,
1275 struct in_addr *addr, int exact)
1276{
1277 int len;
1278 struct ospf_nbr_nbma *nbr_nbma;
paul020709f2003-04-04 02:44:16 +00001279 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001280
paul020709f2003-04-04 02:44:16 +00001281 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00001282 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001283 return NULL;
1284
1285 if (exact)
1286 {
1287 /* INDEX { ospfHostIpAddress, ospfHostTOS } */
1288 if (*length != v->namelen + IN_ADDR_SIZE + 1)
1289 return NULL;
1290
1291 /* Check ospfHostTOS. */
1292 if (name[*length - 1] != 0)
1293 return NULL;
1294
1295 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, addr);
1296
paul68980082003-03-25 05:07:42 +00001297 nbr_nbma = ospf_nbr_nbma_lookup (ospf, *addr);
paul718e3742002-12-13 20:15:29 +00001298
1299 return nbr_nbma;
1300 }
1301 else
1302 {
1303 len = *length - v->namelen;
1304 if (len > 4)
1305 len = 4;
1306
1307 oid2in_addr (name + v->namelen, len, addr);
1308
paul68980082003-03-25 05:07:42 +00001309 nbr_nbma = ospf_nbr_nbma_lookup_next (ospf, addr, len == 0 ? 1 : 0);
paul718e3742002-12-13 20:15:29 +00001310
1311 if (nbr_nbma == NULL)
1312 return NULL;
1313
1314 oid_copy_addr (name + v->namelen, addr, IN_ADDR_SIZE);
1315
1316 /* Set TOS 0. */
1317 name[v->namelen + IN_ADDR_SIZE] = 0;
1318
1319 *length = v->namelen + IN_ADDR_SIZE + 1;
1320
1321 return nbr_nbma;
1322 }
1323 return NULL;
1324}
1325
1326static u_char *
1327ospfHostEntry (struct variable *v, oid *name, size_t *length, int exact,
1328 size_t *var_len, WriteMethod **write_method)
1329{
1330 struct ospf_nbr_nbma *nbr_nbma;
1331 struct ospf_interface *oi;
1332 struct in_addr addr;
paul020709f2003-04-04 02:44:16 +00001333 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001334
1335 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00001336 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00001337 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001338 return NULL;
1339
1340 memset (&addr, 0, sizeof (struct in_addr));
1341
1342 nbr_nbma = ospfHostLookup (v, name, length, &addr, exact);
1343 if (nbr_nbma == NULL)
1344 return NULL;
1345
1346 oi = nbr_nbma->oi;
1347
1348 /* Return the current value of the variable */
1349 switch (v->magic)
1350 {
1351 case OSPFHOSTIPADDRESS: /* 1 */
1352 return SNMP_IPADDRESS (nbr_nbma->addr);
1353 break;
1354 case OSPFHOSTTOS: /* 2 */
1355 return SNMP_INTEGER (0);
1356 break;
1357 case OSPFHOSTMETRIC: /* 3 */
1358 if (oi)
1359 return SNMP_INTEGER (oi->output_cost);
1360 else
1361 return SNMP_INTEGER (1);
1362 break;
1363 case OSPFHOSTSTATUS: /* 4 */
1364 return SNMP_INTEGER (SNMP_VALID);
1365 break;
1366 case OSPFHOSTAREAID: /* 5 */
1367 if (oi && oi->area)
1368 return SNMP_IPADDRESS (oi->area->area_id);
1369 else
1370 return SNMP_IPADDRESS (ospf_empty_addr);
1371 break;
1372 default:
1373 return NULL;
1374 break;
1375 }
1376 return NULL;
1377}
1378
1379struct list *ospf_snmp_iflist;
1380
1381struct ospf_snmp_if
1382{
1383 struct in_addr addr;
1384 unsigned int ifindex;
1385 struct interface *ifp;
1386};
1387
1388struct ospf_snmp_if *
1389ospf_snmp_if_new ()
1390{
1391 struct ospf_snmp_if *osif;
1392
1393 osif = XMALLOC (0, sizeof (struct ospf_snmp_if));
1394 memset (osif, 0, sizeof (struct ospf_snmp_if));
1395 return osif;
1396}
1397
1398void
1399ospf_snmp_if_free (struct ospf_snmp_if *osif)
1400{
1401 XFREE (0, osif);
1402}
1403
1404void
1405ospf_snmp_if_delete (struct interface *ifp)
1406{
paul1eb8ef22005-04-07 07:30:20 +00001407 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001408 struct ospf_snmp_if *osif;
1409
paul1eb8ef22005-04-07 07:30:20 +00001410 for (ALL_LIST_ELEMENTS (ospf_snmp_iflist, node, nnode, osif))
paul718e3742002-12-13 20:15:29 +00001411 {
1412 if (osif->ifp == ifp)
1413 {
paul1eb8ef22005-04-07 07:30:20 +00001414 list_delete_node (ospf_snmp_iflist, node);
paul718e3742002-12-13 20:15:29 +00001415 ospf_snmp_if_free (osif);
1416 return;
1417 }
1418 }
1419}
1420
1421void
1422ospf_snmp_if_update (struct interface *ifp)
1423{
paul1eb8ef22005-04-07 07:30:20 +00001424 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001425 struct listnode *pn;
1426 struct connected *ifc;
1427 struct prefix *p;
1428 struct ospf_snmp_if *osif;
1429 struct in_addr *addr;
1430 unsigned int ifindex;
1431
1432 ospf_snmp_if_delete (ifp);
1433
1434 p = NULL;
1435 addr = NULL;
1436 ifindex = 0;
1437
1438 /* Lookup first IPv4 address entry. */
paul1eb8ef22005-04-07 07:30:20 +00001439 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc))
paul718e3742002-12-13 20:15:29 +00001440 {
hasso3fb9cd62004-10-19 19:44:43 +00001441 if (CONNECTED_POINTOPOINT_HOST(ifc))
paul718e3742002-12-13 20:15:29 +00001442 p = ifc->destination;
1443 else
1444 p = ifc->address;
1445
1446 if (p->family == AF_INET)
1447 {
1448 addr = &p->u.prefix4;
1449 break;
1450 }
1451 }
1452 if (! addr)
1453 ifindex = ifp->ifindex;
1454
1455 /* Add interface to the list. */
1456 pn = NULL;
paul1eb8ef22005-04-07 07:30:20 +00001457 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, node, osif))
paul718e3742002-12-13 20:15:29 +00001458 {
1459 if (addr)
1460 {
vincent77df1f72005-10-06 07:46:22 +00001461 /* Usual interfaces --> Sort them based on interface IPv4 addresses */
paul718e3742002-12-13 20:15:29 +00001462 if (ntohl (osif->addr.s_addr) > ntohl (addr->s_addr))
1463 break;
1464 }
1465 else
1466 {
vincent77df1f72005-10-06 07:46:22 +00001467 /* Unnumbered interfaces --> Sort them based on interface indexes */
paul718e3742002-12-13 20:15:29 +00001468 if (osif->addr.s_addr != 0 || osif->ifindex > ifindex)
1469 break;
1470 }
paul1eb8ef22005-04-07 07:30:20 +00001471 pn = node;
paul718e3742002-12-13 20:15:29 +00001472 }
1473
1474 osif = ospf_snmp_if_new ();
vincent77df1f72005-10-06 07:46:22 +00001475 if (addr) /* Usual interface */
1476 {
paul718e3742002-12-13 20:15:29 +00001477 osif->addr = *addr;
vincent77df1f72005-10-06 07:46:22 +00001478
1479 /* This field is used for storing ospfAddressLessIf OID value,
1480 * conform to RFC1850 OSPF-MIB specification, it must be 0 for
1481 * usual interface */
1482 osif->ifindex = 0;
1483 }
1484 else /* Unnumbered interface */
paul718e3742002-12-13 20:15:29 +00001485 osif->ifindex = ifindex;
1486 osif->ifp = ifp;
1487
1488 listnode_add_after (ospf_snmp_iflist, pn, osif);
1489}
1490
vincent77df1f72005-10-06 07:46:22 +00001491int
1492ospf_snmp_is_if_have_addr (struct interface *ifp)
1493{
1494 struct prefix *p;
1495 struct listnode *nn;
1496 struct connected *ifc;
1497
1498 /* Is this interface having any connected IPv4 address ? */
1499 for (ALL_LIST_ELEMENTS_RO (ifp->connected, nn, ifc))
1500 {
1501 if (if_is_pointopoint (ifp))
1502 p = ifc->destination;
1503 else
1504 p = ifc->address;
1505
1506 if (p->family == AF_INET)
1507 return 1;
1508 }
1509
1510 return 0;
1511}
1512
1513struct ospf_interface *
paul718e3742002-12-13 20:15:29 +00001514ospf_snmp_if_lookup (struct in_addr *ifaddr, unsigned int *ifindex)
1515{
paul1eb8ef22005-04-07 07:30:20 +00001516 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001517 struct ospf_snmp_if *osif;
vincent77df1f72005-10-06 07:46:22 +00001518 struct ospf_interface *oi = NULL;
1519 struct ospf *ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +00001520
paul1eb8ef22005-04-07 07:30:20 +00001521 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, node, osif))
paul718e3742002-12-13 20:15:29 +00001522 {
1523 if (ifaddr->s_addr)
vincent77df1f72005-10-06 07:46:22 +00001524 {
1525 if (IPV4_ADDR_SAME (&osif->addr, ifaddr))
1526 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1527 }
paul718e3742002-12-13 20:15:29 +00001528 else
vincent77df1f72005-10-06 07:46:22 +00001529 {
1530 if (osif->ifindex == *ifindex)
1531 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1532 }
paul718e3742002-12-13 20:15:29 +00001533 }
vincent77df1f72005-10-06 07:46:22 +00001534 return oi;
paul718e3742002-12-13 20:15:29 +00001535}
1536
vincent77df1f72005-10-06 07:46:22 +00001537struct ospf_interface *
paul718e3742002-12-13 20:15:29 +00001538ospf_snmp_if_lookup_next (struct in_addr *ifaddr, unsigned int *ifindex,
1539 int ifaddr_next, int ifindex_next)
1540{
1541 struct ospf_snmp_if *osif;
1542 struct listnode *nn;
vincent77df1f72005-10-06 07:46:22 +00001543 struct ospf *ospf = ospf_lookup ();
1544 struct ospf_interface *oi = NULL;
paul718e3742002-12-13 20:15:29 +00001545
vincent77df1f72005-10-06 07:46:22 +00001546 if (ospf == NULL)
1547 return NULL;
1548
1549 /* No instance is specified --> Return the first OSPF interface */
paul718e3742002-12-13 20:15:29 +00001550 if (ifaddr_next)
1551 {
vincent77df1f72005-10-06 07:46:22 +00001552 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, nn, osif))
paul718e3742002-12-13 20:15:29 +00001553 {
paul1eb8ef22005-04-07 07:30:20 +00001554 osif = listgetdata (nn);
paul718e3742002-12-13 20:15:29 +00001555 *ifaddr = osif->addr;
1556 *ifindex = osif->ifindex;
vincent77df1f72005-10-06 07:46:22 +00001557 /* Because no instance is specified, we don't care about the kind of
1558 * interface (usual or unnumbered), just returning the first valid
1559 * OSPF interface */
1560 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1561 if (oi)
1562 return (oi);
paul718e3742002-12-13 20:15:29 +00001563 }
1564 return NULL;
1565 }
1566
vincent77df1f72005-10-06 07:46:22 +00001567 /* An instance is specified --> Return the next OSPF interface */
paul1eb8ef22005-04-07 07:30:20 +00001568 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, nn, osif))
paul718e3742002-12-13 20:15:29 +00001569 {
vincent77df1f72005-10-06 07:46:22 +00001570 /* Usual interface */
1571 if (ifaddr->s_addr)
1572 /* The interface must have valid AF_INET connected address */
1573 /* it must have lager IPv4 address value than the lookup entry */
1574 if ((ospf_snmp_is_if_have_addr(osif->ifp)) &&
1575 (ntohl (osif->addr.s_addr) > ntohl (ifaddr->s_addr)))
1576 {
1577 *ifaddr = osif->addr;
1578 *ifindex = osif->ifindex;
1579
1580 /* and it must be an OSPF interface */
1581 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1582 if (oi)
1583 return oi;
1584 }
1585 /* Unnumbered interface */
1586 else
1587 /* The interface must NOT have valid AF_INET connected address */
1588 /* it must have lager interface index than the lookup entry */
1589 if ((!ospf_snmp_is_if_have_addr(osif->ifp)) &&
1590 (osif->ifindex > *ifindex))
1591 {
1592 *ifaddr = osif->addr;
1593 *ifindex = osif->ifindex;
1594
1595 /* and it must be an OSPF interface */
1596 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1597 if (oi)
1598 return oi;
1599 }
paul718e3742002-12-13 20:15:29 +00001600 }
1601 return NULL;
1602}
1603
1604int
1605ospf_snmp_iftype (struct interface *ifp)
1606{
1607#define ospf_snmp_iftype_broadcast 1
1608#define ospf_snmp_iftype_nbma 2
1609#define ospf_snmp_iftype_pointToPoint 3
1610#define ospf_snmp_iftype_pointToMultipoint 5
1611 if (if_is_broadcast (ifp))
1612 return ospf_snmp_iftype_broadcast;
1613 if (if_is_pointopoint (ifp))
1614 return ospf_snmp_iftype_pointToPoint;
1615 return ospf_snmp_iftype_broadcast;
1616}
1617
vincent77df1f72005-10-06 07:46:22 +00001618struct ospf_interface *
paul718e3742002-12-13 20:15:29 +00001619ospfIfLookup (struct variable *v, oid *name, size_t *length,
1620 struct in_addr *ifaddr, unsigned int *ifindex, int exact)
1621{
paul6c835672004-10-11 11:00:30 +00001622 unsigned int len;
paul718e3742002-12-13 20:15:29 +00001623 int ifaddr_next = 0;
1624 int ifindex_next = 0;
vincent77df1f72005-10-06 07:46:22 +00001625 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001626 oid *offset;
1627
1628 if (exact)
1629 {
1630 if (*length != v->namelen + IN_ADDR_SIZE + 1)
1631 return NULL;
1632
1633 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, ifaddr);
1634 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1635
1636 return ospf_snmp_if_lookup (ifaddr, ifindex);
1637 }
1638 else
1639 {
1640 len = *length - v->namelen;
1641 if (len >= IN_ADDR_SIZE)
1642 len = IN_ADDR_SIZE;
1643 if (len <= 0)
1644 ifaddr_next = 1;
1645
1646 oid2in_addr (name + v->namelen, len, ifaddr);
1647
1648 len = *length - v->namelen - IN_ADDR_SIZE;
1649 if (len >= 1)
1650 len = 1;
1651 else
1652 ifindex_next = 1;
1653
1654 if (len == 1)
1655 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1656
vincent77df1f72005-10-06 07:46:22 +00001657 oi = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next,
paul718e3742002-12-13 20:15:29 +00001658 ifindex_next);
vincent77df1f72005-10-06 07:46:22 +00001659 if (oi)
paul718e3742002-12-13 20:15:29 +00001660 {
1661 *length = v->namelen + IN_ADDR_SIZE + 1;
1662 offset = name + v->namelen;
1663 oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE);
1664 offset += IN_ADDR_SIZE;
1665 *offset = *ifindex;
vincent77df1f72005-10-06 07:46:22 +00001666 return oi;
paul718e3742002-12-13 20:15:29 +00001667 }
1668 }
1669 return NULL;
1670}
1671
1672static u_char *
1673ospfIfEntry (struct variable *v, oid *name, size_t *length, int exact,
1674 size_t *var_len, WriteMethod **write_method)
1675{
paul718e3742002-12-13 20:15:29 +00001676 unsigned int ifindex;
1677 struct in_addr ifaddr;
1678 struct ospf_interface *oi;
paul020709f2003-04-04 02:44:16 +00001679 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001680
1681 ifindex = 0;
1682 memset (&ifaddr, 0, sizeof (struct in_addr));
1683
1684 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00001685 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00001686 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001687 return NULL;
1688
vincent77df1f72005-10-06 07:46:22 +00001689 oi = ospfIfLookup (v, name, length, &ifaddr, &ifindex, exact);
paul718e3742002-12-13 20:15:29 +00001690 if (oi == NULL)
1691 return NULL;
1692
1693 /* Return the current value of the variable */
1694 switch (v->magic)
1695 {
1696 case OSPFIFIPADDRESS: /* 1 */
1697 return SNMP_IPADDRESS (ifaddr);
1698 break;
1699 case OSPFADDRESSLESSIF: /* 2 */
1700 return SNMP_INTEGER (ifindex);
1701 break;
1702 case OSPFIFAREAID: /* 3 */
1703 if (oi->area)
1704 return SNMP_IPADDRESS (oi->area->area_id);
1705 else
1706 return SNMP_IPADDRESS (ospf_empty_addr);
1707 break;
1708 case OSPFIFTYPE: /* 4 */
vincent77df1f72005-10-06 07:46:22 +00001709 return SNMP_INTEGER (ospf_snmp_iftype (oi->ifp));
paul718e3742002-12-13 20:15:29 +00001710 break;
1711 case OSPFIFADMINSTAT: /* 5 */
1712 if (oi)
1713 return SNMP_INTEGER (OSPF_STATUS_ENABLED);
1714 else
1715 return SNMP_INTEGER (OSPF_STATUS_DISABLED);
1716 break;
1717 case OSPFIFRTRPRIORITY: /* 6 */
1718 return SNMP_INTEGER (PRIORITY (oi));
1719 break;
1720 case OSPFIFTRANSITDELAY: /* 7 */
1721 return SNMP_INTEGER (OSPF_IF_PARAM (oi, transmit_delay));
1722 break;
1723 case OSPFIFRETRANSINTERVAL: /* 8 */
1724 return SNMP_INTEGER (OSPF_IF_PARAM (oi, retransmit_interval));
1725 break;
1726 case OSPFIFHELLOINTERVAL: /* 9 */
1727 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_hello));
1728 break;
1729 case OSPFIFRTRDEADINTERVAL: /* 10 */
1730 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_wait));
1731 break;
1732 case OSPFIFPOLLINTERVAL: /* 11 */
1733 return SNMP_INTEGER (OSPF_POLL_INTERVAL_DEFAULT);
1734 break;
1735 case OSPFIFSTATE: /* 12 */
vincentba682532005-09-29 13:52:57 +00001736 return SNMP_INTEGER (ISM_SNMP(oi->state));
paul718e3742002-12-13 20:15:29 +00001737 break;
1738 case OSPFIFDESIGNATEDROUTER: /* 13 */
1739 return SNMP_IPADDRESS (DR (oi));
1740 break;
1741 case OSPFIFBACKUPDESIGNATEDROUTER: /* 14 */
1742 return SNMP_IPADDRESS (BDR (oi));
1743 break;
1744 case OSPFIFEVENTS: /* 15 */
1745 return SNMP_INTEGER (oi->state_change);
1746 break;
1747 case OSPFIFAUTHKEY: /* 16 */
1748 *var_len = 0;
1749 return (u_char *) OSPF_IF_PARAM (oi, auth_simple);
1750 break;
1751 case OSPFIFSTATUS: /* 17 */
1752 return SNMP_INTEGER (SNMP_VALID);
1753 break;
1754 case OSPFIFMULTICASTFORWARDING: /* 18 */
1755#define ospf_snmp_multiforward_blocked 1
1756#define ospf_snmp_multiforward_multicast 2
1757#define ospf_snmp_multiforward_unicast 3
1758 return SNMP_INTEGER (ospf_snmp_multiforward_blocked);
1759 break;
1760 case OSPFIFDEMAND: /* 19 */
1761 return SNMP_INTEGER (SNMP_FALSE);
1762 break;
1763 case OSPFIFAUTHTYPE: /* 20 */
1764 if (oi->area)
1765 return SNMP_INTEGER (oi->area->auth_type);
1766 else
1767 return SNMP_INTEGER (0);
1768 break;
1769 default:
1770 return NULL;
1771 break;
1772 }
1773 return NULL;
1774}
1775
1776#define OSPF_SNMP_METRIC_VALUE 1
1777
vincent77df1f72005-10-06 07:46:22 +00001778struct ospf_interface *
paul718e3742002-12-13 20:15:29 +00001779ospfIfMetricLookup (struct variable *v, oid *name, size_t *length,
1780 struct in_addr *ifaddr, unsigned int *ifindex, int exact)
1781{
paul6c835672004-10-11 11:00:30 +00001782 unsigned int len;
paul718e3742002-12-13 20:15:29 +00001783 int ifaddr_next = 0;
1784 int ifindex_next = 0;
vincent77df1f72005-10-06 07:46:22 +00001785 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001786 oid *offset;
1787 int metric;
1788
1789 if (exact)
1790 {
1791 if (*length != v->namelen + IN_ADDR_SIZE + 1 + 1)
1792 return NULL;
1793
1794 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, ifaddr);
1795 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1796 metric = name[v->namelen + IN_ADDR_SIZE + 1];
1797
1798 if (metric != OSPF_SNMP_METRIC_VALUE)
1799 return NULL;
1800
1801 return ospf_snmp_if_lookup (ifaddr, ifindex);
1802 }
1803 else
1804 {
1805 len = *length - v->namelen;
1806 if (len >= IN_ADDR_SIZE)
1807 len = IN_ADDR_SIZE;
1808 else
1809 ifaddr_next = 1;
1810
1811 oid2in_addr (name + v->namelen, len, ifaddr);
1812
1813 len = *length - v->namelen - IN_ADDR_SIZE;
1814 if (len >= 1)
1815 len = 1;
1816 else
1817 ifindex_next = 1;
1818
1819 if (len == 1)
1820 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1821
vincent77df1f72005-10-06 07:46:22 +00001822 oi = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next,
paul718e3742002-12-13 20:15:29 +00001823 ifindex_next);
vincent77df1f72005-10-06 07:46:22 +00001824 if (oi)
paul718e3742002-12-13 20:15:29 +00001825 {
1826 *length = v->namelen + IN_ADDR_SIZE + 1 + 1;
1827 offset = name + v->namelen;
1828 oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE);
1829 offset += IN_ADDR_SIZE;
1830 *offset = *ifindex;
1831 offset++;
1832 *offset = OSPF_SNMP_METRIC_VALUE;
vincent77df1f72005-10-06 07:46:22 +00001833 return oi;
paul718e3742002-12-13 20:15:29 +00001834 }
1835 }
1836 return NULL;
1837}
1838
1839static u_char *
1840ospfIfMetricEntry (struct variable *v, oid *name, size_t *length, int exact,
1841 size_t *var_len, WriteMethod **write_method)
1842{
1843 /* Currently we support metric 1 only. */
paul718e3742002-12-13 20:15:29 +00001844 unsigned int ifindex;
1845 struct in_addr ifaddr;
1846 struct ospf_interface *oi;
paul020709f2003-04-04 02:44:16 +00001847 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001848
1849 ifindex = 0;
1850 memset (&ifaddr, 0, sizeof (struct in_addr));
1851
1852 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00001853 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00001854 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001855 return NULL;
1856
vincent77df1f72005-10-06 07:46:22 +00001857 oi = ospfIfMetricLookup (v, name, length, &ifaddr, &ifindex, exact);
paul718e3742002-12-13 20:15:29 +00001858 if (oi == NULL)
1859 return NULL;
1860
1861 /* Return the current value of the variable */
1862 switch (v->magic)
1863 {
1864 case OSPFIFMETRICIPADDRESS:
1865 return SNMP_IPADDRESS (ifaddr);
1866 break;
1867 case OSPFIFMETRICADDRESSLESSIF:
1868 return SNMP_INTEGER (ifindex);
1869 break;
1870 case OSPFIFMETRICTOS:
1871 return SNMP_INTEGER (0);
1872 break;
1873 case OSPFIFMETRICVALUE:
1874 return SNMP_INTEGER (OSPF_SNMP_METRIC_VALUE);
1875 break;
1876 case OSPFIFMETRICSTATUS:
1877 return SNMP_INTEGER (1);
1878 break;
1879 default:
1880 return NULL;
1881 break;
1882 }
1883 return NULL;
1884}
1885
1886struct route_table *ospf_snmp_vl_table;
1887
1888void
1889ospf_snmp_vl_add (struct ospf_vl_data *vl_data)
1890{
1891 struct prefix_ls lp;
1892 struct route_node *rn;
1893
1894 memset (&lp, 0, sizeof (struct prefix_ls));
1895 lp.family = 0;
1896 lp.prefixlen = 64;
1897 lp.id = vl_data->vl_area_id;
1898 lp.adv_router = vl_data->vl_peer;
1899
1900 rn = route_node_get (ospf_snmp_vl_table, (struct prefix *) &lp);
1901 rn->info = vl_data;
1902}
1903
1904void
1905ospf_snmp_vl_delete (struct ospf_vl_data *vl_data)
1906{
1907 struct prefix_ls lp;
1908 struct route_node *rn;
1909
1910 memset (&lp, 0, sizeof (struct prefix_ls));
1911 lp.family = 0;
1912 lp.prefixlen = 64;
1913 lp.id = vl_data->vl_area_id;
1914 lp.adv_router = vl_data->vl_peer;
1915
1916 rn = route_node_lookup (ospf_snmp_vl_table, (struct prefix *) &lp);
1917 if (! rn)
1918 return;
1919 rn->info = NULL;
1920 route_unlock_node (rn);
1921 route_unlock_node (rn);
1922}
1923
1924struct ospf_vl_data *
1925ospf_snmp_vl_lookup (struct in_addr *area_id, struct in_addr *neighbor)
1926{
1927 struct prefix_ls lp;
1928 struct route_node *rn;
1929 struct ospf_vl_data *vl_data;
1930
1931 memset (&lp, 0, sizeof (struct prefix_ls));
1932 lp.family = 0;
1933 lp.prefixlen = 64;
1934 lp.id = *area_id;
1935 lp.adv_router = *neighbor;
1936
1937 rn = route_node_lookup (ospf_snmp_vl_table, (struct prefix *) &lp);
1938 if (rn)
1939 {
1940 vl_data = rn->info;
1941 route_unlock_node (rn);
1942 return vl_data;
1943 }
1944 return NULL;
1945}
1946
1947struct ospf_vl_data *
1948ospf_snmp_vl_lookup_next (struct in_addr *area_id, struct in_addr *neighbor,
1949 int first)
1950{
1951 struct prefix_ls lp;
1952 struct route_node *rn;
1953 struct ospf_vl_data *vl_data;
1954
1955 memset (&lp, 0, sizeof (struct prefix_ls));
1956 lp.family = 0;
1957 lp.prefixlen = 64;
1958 lp.id = *area_id;
1959 lp.adv_router = *neighbor;
1960
1961 if (first)
1962 rn = route_top (ospf_snmp_vl_table);
1963 else
1964 {
1965 rn = route_node_get (ospf_snmp_vl_table, (struct prefix *) &lp);
1966 rn = route_next (rn);
1967 }
1968
1969 for (; rn; rn = route_next (rn))
1970 if (rn->info)
1971 break;
1972
1973 if (rn && rn->info)
1974 {
1975 vl_data = rn->info;
1976 *area_id = vl_data->vl_area_id;
1977 *neighbor = vl_data->vl_peer;
1978 route_unlock_node (rn);
1979 return vl_data;
1980 }
1981 return NULL;
1982}
1983
1984struct ospf_vl_data *
1985ospfVirtIfLookup (struct variable *v, oid *name, size_t *length,
1986 struct in_addr *area_id, struct in_addr *neighbor, int exact)
1987{
1988 int first;
paul6c835672004-10-11 11:00:30 +00001989 unsigned int len;
paul718e3742002-12-13 20:15:29 +00001990 struct ospf_vl_data *vl_data;
1991
1992 if (exact)
1993 {
1994 if (*length != v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE)
1995 return NULL;
1996
1997 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, area_id);
1998 oid2in_addr (name + v->namelen + IN_ADDR_SIZE, IN_ADDR_SIZE, neighbor);
1999
2000 return ospf_snmp_vl_lookup (area_id, neighbor);
2001 }
2002 else
2003 {
2004 first = 0;
2005
2006 len = *length - v->namelen;
2007 if (len <= 0)
2008 first = 1;
2009 if (len > IN_ADDR_SIZE)
2010 len = IN_ADDR_SIZE;
2011 oid2in_addr (name + v->namelen, len, area_id);
2012
2013 len = *length - v->namelen - IN_ADDR_SIZE;
2014 if (len > IN_ADDR_SIZE)
2015 len = IN_ADDR_SIZE;
2016 oid2in_addr (name + v->namelen + IN_ADDR_SIZE, len, neighbor);
2017
2018 vl_data = ospf_snmp_vl_lookup_next (area_id, neighbor, first);
2019
2020 if (vl_data)
2021 {
2022 *length = v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE;
2023 oid_copy_addr (name + v->namelen, area_id, IN_ADDR_SIZE);
2024 oid_copy_addr (name + v->namelen + IN_ADDR_SIZE, neighbor,
2025 IN_ADDR_SIZE);
2026 return vl_data;
2027 }
2028 }
2029 return NULL;
2030}
2031
2032static u_char *
2033ospfVirtIfEntry (struct variable *v, oid *name, size_t *length, int exact,
2034 size_t *var_len, WriteMethod **write_method)
2035{
2036 struct ospf_vl_data *vl_data;
2037 struct ospf_interface *oi;
2038 struct in_addr area_id;
2039 struct in_addr neighbor;
2040
2041 memset (&area_id, 0, sizeof (struct in_addr));
2042 memset (&neighbor, 0, sizeof (struct in_addr));
2043
2044 vl_data = ospfVirtIfLookup (v, name, length, &area_id, &neighbor, exact);
2045 if (! vl_data)
2046 return NULL;
2047 oi = vl_data->vl_oi;
2048 if (! oi)
2049 return NULL;
2050
2051 /* Return the current value of the variable */
2052 switch (v->magic)
2053 {
2054 case OSPFVIRTIFAREAID:
2055 return SNMP_IPADDRESS (area_id);
2056 break;
2057 case OSPFVIRTIFNEIGHBOR:
2058 return SNMP_IPADDRESS (neighbor);
2059 break;
2060 case OSPFVIRTIFTRANSITDELAY:
2061 return SNMP_INTEGER (OSPF_IF_PARAM (oi, transmit_delay));
2062 break;
2063 case OSPFVIRTIFRETRANSINTERVAL:
2064 return SNMP_INTEGER (OSPF_IF_PARAM (oi, retransmit_interval));
2065 break;
2066 case OSPFVIRTIFHELLOINTERVAL:
2067 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_hello));
2068 break;
2069 case OSPFVIRTIFRTRDEADINTERVAL:
2070 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_wait));
2071 break;
2072 case OSPFVIRTIFSTATE:
2073 return SNMP_INTEGER (oi->state);
2074 break;
2075 case OSPFVIRTIFEVENTS:
2076 return SNMP_INTEGER (oi->state_change);
2077 break;
2078 case OSPFVIRTIFAUTHKEY:
2079 *var_len = 0;
2080 return (u_char *) OSPF_IF_PARAM (oi, auth_simple);
2081 break;
2082 case OSPFVIRTIFSTATUS:
2083 return SNMP_INTEGER (SNMP_VALID);
2084 break;
2085 case OSPFVIRTIFAUTHTYPE:
2086 if (oi->area)
2087 return SNMP_INTEGER (oi->area->auth_type);
2088 else
2089 return SNMP_INTEGER (0);
2090 break;
2091 default:
2092 return NULL;
2093 break;
2094 }
2095 return NULL;
2096}
2097
2098struct ospf_neighbor *
paul68980082003-03-25 05:07:42 +00002099ospf_snmp_nbr_lookup (struct ospf *ospf, struct in_addr *nbr_addr,
2100 unsigned int *ifindex)
paul718e3742002-12-13 20:15:29 +00002101{
paul1eb8ef22005-04-07 07:30:20 +00002102 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002103 struct ospf_interface *oi;
2104 struct ospf_neighbor *nbr;
2105 struct route_node *rn;
2106
paul1eb8ef22005-04-07 07:30:20 +00002107 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002108 {
2109 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2110 if ((nbr = rn->info) != NULL
2111 && nbr != oi->nbr_self
vincent5e4914c2005-09-29 16:34:30 +00002112/* If EXACT match is needed, provide ALL entry found
paul718e3742002-12-13 20:15:29 +00002113 && nbr->state != NSM_Down
vincent5e4914c2005-09-29 16:34:30 +00002114 */
paul718e3742002-12-13 20:15:29 +00002115 && nbr->src.s_addr != 0)
2116 {
2117 if (IPV4_ADDR_SAME (&nbr->src, nbr_addr))
2118 {
2119 route_unlock_node (rn);
2120 return nbr;
2121 }
2122 }
2123 }
2124 return NULL;
2125}
2126
2127struct ospf_neighbor *
2128ospf_snmp_nbr_lookup_next (struct in_addr *nbr_addr, unsigned int *ifindex,
2129 int first)
2130{
2131 struct listnode *nn;
2132 struct ospf_interface *oi;
2133 struct ospf_neighbor *nbr;
2134 struct route_node *rn;
2135 struct ospf_neighbor *min = NULL;
paul020709f2003-04-04 02:44:16 +00002136 struct ospf *ospf = ospf;
paul718e3742002-12-13 20:15:29 +00002137
paul020709f2003-04-04 02:44:16 +00002138 ospf = ospf_lookup ();
paul1eb8ef22005-04-07 07:30:20 +00002139
2140 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, nn, oi))
paul718e3742002-12-13 20:15:29 +00002141 {
2142 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2143 if ((nbr = rn->info) != NULL
2144 && nbr != oi->nbr_self
2145 && nbr->state != NSM_Down
2146 && nbr->src.s_addr != 0)
2147 {
2148 if (first)
2149 {
2150 if (! min)
2151 min = nbr;
2152 else if (ntohl (nbr->src.s_addr) < ntohl (min->src.s_addr))
2153 min = nbr;
2154 }
2155 else if (ntohl (nbr->src.s_addr) > ntohl (nbr_addr->s_addr))
2156 {
2157 if (! min)
2158 min = nbr;
2159 else if (ntohl (nbr->src.s_addr) < ntohl (min->src.s_addr))
2160 min = nbr;
2161 }
2162 }
2163 }
2164 if (min)
2165 {
2166 *nbr_addr = min->src;
2167 *ifindex = 0;
2168 return min;
2169 }
2170 return NULL;
2171}
2172
2173struct ospf_neighbor *
2174ospfNbrLookup (struct variable *v, oid *name, size_t *length,
2175 struct in_addr *nbr_addr, unsigned int *ifindex, int exact)
2176{
paul6c835672004-10-11 11:00:30 +00002177 unsigned int len;
paul718e3742002-12-13 20:15:29 +00002178 int first;
2179 struct ospf_neighbor *nbr;
paul020709f2003-04-04 02:44:16 +00002180 struct ospf *ospf;
2181
2182 ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +00002183
hasso1b639042005-03-27 13:32:25 +00002184 if (! ospf)
2185 return NULL;
2186
paul718e3742002-12-13 20:15:29 +00002187 if (exact)
2188 {
2189 if (*length != v->namelen + IN_ADDR_SIZE + 1)
2190 return NULL;
2191
2192 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, nbr_addr);
2193 *ifindex = name[v->namelen + IN_ADDR_SIZE];
2194
paul68980082003-03-25 05:07:42 +00002195 return ospf_snmp_nbr_lookup (ospf, nbr_addr, ifindex);
paul718e3742002-12-13 20:15:29 +00002196 }
2197 else
2198 {
2199 first = 0;
2200 len = *length - v->namelen;
2201
2202 if (len <= 0)
2203 first = 1;
2204
2205 if (len > IN_ADDR_SIZE)
2206 len = IN_ADDR_SIZE;
2207
2208 oid2in_addr (name + v->namelen, len, nbr_addr);
2209
2210 len = *length - v->namelen - IN_ADDR_SIZE;
2211 if (len >= 1)
2212 *ifindex = name[v->namelen + IN_ADDR_SIZE];
2213
2214 nbr = ospf_snmp_nbr_lookup_next (nbr_addr, ifindex, first);
2215
2216 if (nbr)
2217 {
2218 *length = v->namelen + IN_ADDR_SIZE + 1;
2219 oid_copy_addr (name + v->namelen, nbr_addr, IN_ADDR_SIZE);
2220 name[v->namelen + IN_ADDR_SIZE] = *ifindex;
2221 return nbr;
2222 }
2223 }
2224 return NULL;
2225}
2226
2227static u_char *
2228ospfNbrEntry (struct variable *v, oid *name, size_t *length, int exact,
2229 size_t *var_len, WriteMethod **write_method)
2230{
2231 struct in_addr nbr_addr;
2232 unsigned int ifindex;
2233 struct ospf_neighbor *nbr;
2234 struct ospf_interface *oi;
2235
2236 memset (&nbr_addr, 0, sizeof (struct in_addr));
2237 ifindex = 0;
2238
2239 nbr = ospfNbrLookup (v, name, length, &nbr_addr, &ifindex, exact);
2240 if (! nbr)
2241 return NULL;
2242 oi = nbr->oi;
2243 if (! oi)
2244 return NULL;
2245
2246 /* Return the current value of the variable */
2247 switch (v->magic)
2248 {
2249 case OSPFNBRIPADDR:
2250 return SNMP_IPADDRESS (nbr_addr);
2251 break;
2252 case OSPFNBRADDRESSLESSINDEX:
2253 return SNMP_INTEGER (ifindex);
2254 break;
2255 case OSPFNBRRTRID:
2256 return SNMP_IPADDRESS (nbr->router_id);
2257 break;
2258 case OSPFNBROPTIONS:
2259 return SNMP_INTEGER (oi->nbr_self->options);
2260 break;
2261 case OSPFNBRPRIORITY:
2262 return SNMP_INTEGER (nbr->priority);
2263 break;
2264 case OSPFNBRSTATE:
2265 return SNMP_INTEGER (nbr->state);
2266 break;
2267 case OSPFNBREVENTS:
2268 return SNMP_INTEGER (nbr->state_change);
2269 break;
2270 case OSPFNBRLSRETRANSQLEN:
2271 return SNMP_INTEGER (ospf_ls_retransmit_count (nbr));
2272 break;
2273 case OSPFNBMANBRSTATUS:
2274 return SNMP_INTEGER (SNMP_VALID);
2275 break;
2276 case OSPFNBMANBRPERMANENCE:
2277 return SNMP_INTEGER (2);
2278 break;
2279 case OSPFNBRHELLOSUPPRESSED:
2280 return SNMP_INTEGER (SNMP_FALSE);
2281 break;
2282 default:
2283 return NULL;
2284 break;
2285 }
2286 return NULL;
2287}
2288
2289static u_char *
2290ospfVirtNbrEntry (struct variable *v, oid *name, size_t *length, int exact,
2291 size_t *var_len, WriteMethod **write_method)
2292{
2293 struct ospf_vl_data *vl_data;
2294 struct in_addr area_id;
2295 struct in_addr neighbor;
paul020709f2003-04-04 02:44:16 +00002296 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002297
2298 memset (&area_id, 0, sizeof (struct in_addr));
2299 memset (&neighbor, 0, sizeof (struct in_addr));
2300
2301 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00002302 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00002303 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00002304 return NULL;
2305
2306 vl_data = ospfVirtIfLookup (v, name, length, &area_id, &neighbor, exact);
2307 if (! vl_data)
2308 return NULL;
2309
2310 /* Return the current value of the variable */
2311 switch (v->magic)
2312 {
2313 case OSPFVIRTNBRAREA:
2314 return (u_char *) NULL;
2315 break;
2316 case OSPFVIRTNBRRTRID:
2317 return (u_char *) NULL;
2318 break;
2319 case OSPFVIRTNBRIPADDR:
2320 return (u_char *) NULL;
2321 break;
2322 case OSPFVIRTNBROPTIONS:
2323 return (u_char *) NULL;
2324 break;
2325 case OSPFVIRTNBRSTATE:
2326 return (u_char *) NULL;
2327 break;
2328 case OSPFVIRTNBREVENTS:
2329 return (u_char *) NULL;
2330 break;
2331 case OSPFVIRTNBRLSRETRANSQLEN:
2332 return (u_char *) NULL;
2333 break;
2334 case OSPFVIRTNBRHELLOSUPPRESSED:
2335 return (u_char *) NULL;
2336 break;
2337 default:
2338 return NULL;
2339 break;
2340 }
2341 return NULL;
2342}
2343
2344struct ospf_lsa *
2345ospfExtLsdbLookup (struct variable *v, oid *name, size_t *length, u_char *type,
2346 struct in_addr *ls_id, struct in_addr *router_id, int exact)
2347{
2348 int first;
2349 oid *offset;
2350 int offsetlen;
2351 u_char lsa_type;
paul6c835672004-10-11 11:00:30 +00002352 unsigned int len;
paul718e3742002-12-13 20:15:29 +00002353 struct ospf_lsa *lsa;
paul020709f2003-04-04 02:44:16 +00002354 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002355
paul020709f2003-04-04 02:44:16 +00002356 ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +00002357 if (exact)
2358 {
2359 if (*length != v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
2360 return NULL;
2361
2362 offset = name + v->namelen;
2363
2364 /* Make it sure given value match to type. */
2365 lsa_type = *offset;
2366 offset++;
2367
2368 if (lsa_type != *type)
2369 return NULL;
2370
2371 /* LS ID. */
2372 oid2in_addr (offset, IN_ADDR_SIZE, ls_id);
2373 offset += IN_ADDR_SIZE;
2374
2375 /* Router ID. */
2376 oid2in_addr (offset, IN_ADDR_SIZE, router_id);
2377
paul68980082003-03-25 05:07:42 +00002378 return ospf_lsdb_lookup_by_id (ospf->lsdb, *type, *ls_id, *router_id);
paul718e3742002-12-13 20:15:29 +00002379 }
2380 else
2381 {
2382 /* Get variable length. */
2383 first = 0;
2384 offset = name + v->namelen;
2385 offsetlen = *length - v->namelen;
2386
2387 /* LSA type value. */
2388 lsa_type = *offset;
2389 offset++;
2390 offsetlen--;
2391
2392 if (offsetlen <= 0 || lsa_type < OSPF_AS_EXTERNAL_LSA)
2393 first = 1;
2394
2395 /* LS ID. */
2396 len = offsetlen;
2397 if (len > IN_ADDR_SIZE)
2398 len = IN_ADDR_SIZE;
2399
2400 oid2in_addr (offset, len, ls_id);
2401
2402 offset += IN_ADDR_SIZE;
2403 offsetlen -= IN_ADDR_SIZE;
2404
2405 /* Router ID. */
2406 len = offsetlen;
2407 if (len > IN_ADDR_SIZE)
2408 len = IN_ADDR_SIZE;
2409
2410 oid2in_addr (offset, len, router_id);
2411
paul68980082003-03-25 05:07:42 +00002412 lsa = ospf_lsdb_lookup_by_id_next (ospf->lsdb, *type, *ls_id,
paul718e3742002-12-13 20:15:29 +00002413 *router_id, first);
2414
2415 if (lsa)
2416 {
2417 /* Fill in length. */
2418 *length = v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE;
2419
2420 /* Fill in value. */
2421 offset = name + v->namelen;
2422
2423 *offset = OSPF_AS_EXTERNAL_LSA;
2424 offset++;
2425 oid_copy_addr (offset, &lsa->data->id, IN_ADDR_SIZE);
2426 offset += IN_ADDR_SIZE;
2427 oid_copy_addr (offset, &lsa->data->adv_router, IN_ADDR_SIZE);
2428
2429 return lsa;
2430 }
2431 }
2432 return NULL;
2433}
2434
2435static u_char *
2436ospfExtLsdbEntry (struct variable *v, oid *name, size_t *length, int exact,
2437 size_t *var_len, WriteMethod **write_method)
2438{
2439 struct ospf_lsa *lsa;
2440 struct lsa_header *lsah;
2441 u_char type;
2442 struct in_addr ls_id;
2443 struct in_addr router_id;
paul020709f2003-04-04 02:44:16 +00002444 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002445
2446 type = OSPF_AS_EXTERNAL_LSA;
2447 memset (&ls_id, 0, sizeof (struct in_addr));
2448 memset (&router_id, 0, sizeof (struct in_addr));
2449
2450 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00002451 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00002452 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00002453 return NULL;
2454
2455 lsa = ospfExtLsdbLookup (v, name, length, &type, &ls_id, &router_id, exact);
2456 if (! lsa)
2457 return NULL;
2458
2459 lsah = lsa->data;
2460
2461 /* Return the current value of the variable */
2462 switch (v->magic)
2463 {
2464 case OSPFEXTLSDBTYPE:
2465 return SNMP_INTEGER (OSPF_AS_EXTERNAL_LSA);
2466 break;
2467 case OSPFEXTLSDBLSID:
2468 return SNMP_IPADDRESS (lsah->id);
2469 break;
2470 case OSPFEXTLSDBROUTERID:
2471 return SNMP_IPADDRESS (lsah->adv_router);
2472 break;
2473 case OSPFEXTLSDBSEQUENCE:
2474 return SNMP_INTEGER (lsah->ls_seqnum);
2475 break;
2476 case OSPFEXTLSDBAGE:
2477 return SNMP_INTEGER (lsah->ls_age);
2478 break;
2479 case OSPFEXTLSDBCHECKSUM:
2480 return SNMP_INTEGER (lsah->checksum);
2481 break;
2482 case OSPFEXTLSDBADVERTISEMENT:
2483 *var_len = ntohs (lsah->length);
2484 return (u_char *) lsah;
2485 break;
2486 default:
2487 return NULL;
2488 break;
2489 }
2490 return NULL;
2491}
2492
2493static u_char *
2494ospfAreaAggregateEntry (struct variable *v, oid *name, size_t *length,
2495 int exact, size_t *var_len, WriteMethod **write_method)
2496{
2497 /* Return the current value of the variable */
2498 switch (v->magic)
2499 {
2500 case OSPFAREAAGGREGATEAREAID:
2501 return (u_char *) NULL;
2502 break;
2503 case OSPFAREAAGGREGATELSDBTYPE:
2504 return (u_char *) NULL;
2505 break;
2506 case OSPFAREAAGGREGATENET:
2507 return (u_char *) NULL;
2508 break;
2509 case OSPFAREAAGGREGATEMASK:
2510 return (u_char *) NULL;
2511 break;
2512 case OSPFAREAAGGREGATESTATUS:
2513 return (u_char *) NULL;
2514 break;
2515 case OSPFAREAAGGREGATEEFFECT:
2516 return (u_char *) NULL;
2517 break;
2518 default:
2519 return NULL;
2520 break;
2521 }
2522 return NULL;
2523}
2524
vincent5e4914c2005-09-29 16:34:30 +00002525/* OSPF Traps. */
2526#define IFSTATECHANGE 16
2527#define VIRTIFSTATECHANGE 1
2528#define NBRSTATECHANGE 2
2529#define VIRTNBRSTATECHANGE 3
2530
2531struct trap_object ospfNbrTrapList[] =
2532{
2533 {ospfGeneralGroup, -2, {1, OSPFROUTERID}},
2534 {ospfNbrEntry, 3, {10, 1, OSPFNBRIPADDR}},
2535 {ospfNbrEntry, 3, {10, 1, OSPFNBRRTRID}},
2536 {ospfNbrEntry, 3, {10, 1, OSPFNBRSTATE}}
2537};
2538
2539
2540struct trap_object ospfVirtNbrTrapList[] =
2541{
2542 {ospfGeneralGroup, -2, {1, 1}},
2543 {ospfVirtNbrEntry, 3, {11, 1, OSPFVIRTNBRAREA}},
2544 {ospfVirtNbrEntry, 3, {11, 1, OSPFVIRTNBRRTRID}},
2545 {ospfVirtNbrEntry, 3, {11, 1, OSPFVIRTNBRSTATE}}
2546};
2547
2548struct trap_object ospfIfTrapList[] =
2549{
2550 {ospfGeneralGroup, -2, {1, OSPFROUTERID}},
2551 {ospfIfEntry, 3, {7, 1, OSPFIFIPADDRESS}},
2552 {ospfIfEntry, 3, {7, 1, OSPFADDRESSLESSIF}},
2553 {ospfIfEntry, 3, {7, 1, OSPFIFSTATE}}
2554};
2555
2556struct trap_object ospfVirtIfTrapList[] =
2557{
2558 {ospfGeneralGroup, -2, {1, OSPFROUTERID}},
2559 {ospfVirtIfEntry, 3, {9, 1, OSPFVIRTIFAREAID}},
2560 {ospfVirtIfEntry, 3, {9, 1, OSPFVIRTIFNEIGHBOR}},
2561 {ospfVirtIfEntry, 3, {9, 1, OSPFVIRTIFSTATE}}
2562};
2563
2564void
2565ospfTrapNbrStateChange (struct ospf_neighbor *on)
2566{
2567 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
2568
2569 zlog (NULL, LOG_INFO, "ospfTrapNbrStateChange trap sent");
2570
2571 oid_copy_addr (index, &(on->address.u.prefix4), IN_ADDR_SIZE);
2572 index[IN_ADDR_SIZE] = 0;
2573
2574 smux_trap (ospf_oid, sizeof ospf_oid / sizeof (oid),
2575 index, IN_ADDR_SIZE + 1,
2576 ospfNbrTrapList,
2577 sizeof ospfNbrTrapList / sizeof (struct trap_object),
2578 time (NULL), NBRSTATECHANGE);
2579}
2580
2581void
2582ospfTrapVirtNbrStateChange (struct ospf_neighbor *on)
2583{
2584 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
2585
2586 zlog (NULL, LOG_INFO, "ospfTrapVirtNbrStateChange trap sent");
2587
2588 oid_copy_addr (index, &(on->address.u.prefix4), IN_ADDR_SIZE);
2589 index[IN_ADDR_SIZE] = 0;
2590
2591 smux_trap (ospf_oid, sizeof ospf_oid / sizeof (oid),
2592 index, IN_ADDR_SIZE + 1,
2593 ospfVirtNbrTrapList,
2594 sizeof ospfVirtNbrTrapList / sizeof (struct trap_object),
2595 time (NULL), VIRTNBRSTATECHANGE);
2596}
2597
2598void
2599ospfTrapIfStateChange (struct ospf_interface *oi)
2600{
2601 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
2602
2603 zlog (NULL, LOG_INFO, "ospfTrapIfStateChange trap sent");
2604
2605 oid_copy_addr (index, &(oi->address->u.prefix4), IN_ADDR_SIZE);
2606 index[IN_ADDR_SIZE] = 0;
2607
2608 smux_trap (ospf_oid, sizeof ospf_oid / sizeof (oid),
2609 index, IN_ADDR_SIZE + 1,
2610 ospfIfTrapList,
2611 sizeof ospfIfTrapList / sizeof (struct trap_object),
2612 time (NULL), IFSTATECHANGE);
2613}
2614
2615void
2616ospfTrapVirtIfStateChange (struct ospf_interface *oi)
2617{
2618 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
2619
2620 zlog (NULL, LOG_INFO, "ospfTrapVirtIfStateChange trap sent");
2621
2622 oid_copy_addr (index, &(oi->address->u.prefix4), IN_ADDR_SIZE);
2623 index[IN_ADDR_SIZE] = 0;
2624
2625 smux_trap (ospf_oid, sizeof ospf_oid / sizeof (oid),
2626 index, IN_ADDR_SIZE + 1,
2627 ospfVirtIfTrapList,
2628 sizeof ospfVirtIfTrapList / sizeof (struct trap_object),
2629 time (NULL), VIRTIFSTATECHANGE);
2630}
paul718e3742002-12-13 20:15:29 +00002631/* Register OSPF2-MIB. */
2632void
2633ospf_snmp_init ()
2634{
2635 ospf_snmp_iflist = list_new ();
2636 ospf_snmp_vl_table = route_table_init ();
hassoc75105a2004-10-13 10:33:26 +00002637 smux_init (om->master);
paul718e3742002-12-13 20:15:29 +00002638 REGISTER_MIB("mibII/ospf", ospf_variables, variable, ospf_oid);
paul718e3742002-12-13 20:15:29 +00002639}
2640#endif /* HAVE_SNMP */