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