blob: 6e972605f1f61533dabba974a53b820d9178f851 [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 {
Andrew J. Schorre4529632006-12-12 19:18:21 +00001442 p = CONNECTED_ID(ifc);
paul718e3742002-12-13 20:15:29 +00001443
1444 if (p->family == AF_INET)
1445 {
1446 addr = &p->u.prefix4;
1447 break;
1448 }
1449 }
1450 if (! addr)
1451 ifindex = ifp->ifindex;
1452
1453 /* Add interface to the list. */
1454 pn = NULL;
paul1eb8ef22005-04-07 07:30:20 +00001455 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, node, osif))
paul718e3742002-12-13 20:15:29 +00001456 {
1457 if (addr)
1458 {
vincent77df1f72005-10-06 07:46:22 +00001459 /* Usual interfaces --> Sort them based on interface IPv4 addresses */
paul718e3742002-12-13 20:15:29 +00001460 if (ntohl (osif->addr.s_addr) > ntohl (addr->s_addr))
1461 break;
1462 }
1463 else
1464 {
vincent77df1f72005-10-06 07:46:22 +00001465 /* Unnumbered interfaces --> Sort them based on interface indexes */
paul718e3742002-12-13 20:15:29 +00001466 if (osif->addr.s_addr != 0 || osif->ifindex > ifindex)
1467 break;
1468 }
paul1eb8ef22005-04-07 07:30:20 +00001469 pn = node;
paul718e3742002-12-13 20:15:29 +00001470 }
1471
1472 osif = ospf_snmp_if_new ();
vincent77df1f72005-10-06 07:46:22 +00001473 if (addr) /* Usual interface */
1474 {
paul718e3742002-12-13 20:15:29 +00001475 osif->addr = *addr;
vincent77df1f72005-10-06 07:46:22 +00001476
1477 /* This field is used for storing ospfAddressLessIf OID value,
1478 * conform to RFC1850 OSPF-MIB specification, it must be 0 for
1479 * usual interface */
1480 osif->ifindex = 0;
1481 }
1482 else /* Unnumbered interface */
paul718e3742002-12-13 20:15:29 +00001483 osif->ifindex = ifindex;
1484 osif->ifp = ifp;
1485
1486 listnode_add_after (ospf_snmp_iflist, pn, osif);
1487}
1488
vincent77df1f72005-10-06 07:46:22 +00001489int
1490ospf_snmp_is_if_have_addr (struct interface *ifp)
1491{
vincent77df1f72005-10-06 07:46:22 +00001492 struct listnode *nn;
1493 struct connected *ifc;
1494
1495 /* Is this interface having any connected IPv4 address ? */
1496 for (ALL_LIST_ELEMENTS_RO (ifp->connected, nn, ifc))
1497 {
Andrew J. Schorre4529632006-12-12 19:18:21 +00001498 if (CONNECTED_PREFIX(ifc)->family == AF_INET)
vincent77df1f72005-10-06 07:46:22 +00001499 return 1;
1500 }
1501
1502 return 0;
1503}
1504
1505struct ospf_interface *
paul718e3742002-12-13 20:15:29 +00001506ospf_snmp_if_lookup (struct in_addr *ifaddr, unsigned int *ifindex)
1507{
paul1eb8ef22005-04-07 07:30:20 +00001508 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001509 struct ospf_snmp_if *osif;
vincent77df1f72005-10-06 07:46:22 +00001510 struct ospf_interface *oi = NULL;
1511 struct ospf *ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +00001512
paul1eb8ef22005-04-07 07:30:20 +00001513 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, node, osif))
paul718e3742002-12-13 20:15:29 +00001514 {
1515 if (ifaddr->s_addr)
vincent77df1f72005-10-06 07:46:22 +00001516 {
1517 if (IPV4_ADDR_SAME (&osif->addr, ifaddr))
1518 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1519 }
paul718e3742002-12-13 20:15:29 +00001520 else
vincent77df1f72005-10-06 07:46:22 +00001521 {
1522 if (osif->ifindex == *ifindex)
1523 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1524 }
paul718e3742002-12-13 20:15:29 +00001525 }
vincent77df1f72005-10-06 07:46:22 +00001526 return oi;
paul718e3742002-12-13 20:15:29 +00001527}
1528
vincent77df1f72005-10-06 07:46:22 +00001529struct ospf_interface *
paul718e3742002-12-13 20:15:29 +00001530ospf_snmp_if_lookup_next (struct in_addr *ifaddr, unsigned int *ifindex,
1531 int ifaddr_next, int ifindex_next)
1532{
1533 struct ospf_snmp_if *osif;
1534 struct listnode *nn;
vincent77df1f72005-10-06 07:46:22 +00001535 struct ospf *ospf = ospf_lookup ();
1536 struct ospf_interface *oi = NULL;
paul718e3742002-12-13 20:15:29 +00001537
vincent77df1f72005-10-06 07:46:22 +00001538 if (ospf == NULL)
1539 return NULL;
1540
1541 /* No instance is specified --> Return the first OSPF interface */
paul718e3742002-12-13 20:15:29 +00001542 if (ifaddr_next)
1543 {
vincent77df1f72005-10-06 07:46:22 +00001544 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, nn, osif))
paul718e3742002-12-13 20:15:29 +00001545 {
paul1eb8ef22005-04-07 07:30:20 +00001546 osif = listgetdata (nn);
paul718e3742002-12-13 20:15:29 +00001547 *ifaddr = osif->addr;
1548 *ifindex = osif->ifindex;
vincent77df1f72005-10-06 07:46:22 +00001549 /* Because no instance is specified, we don't care about the kind of
1550 * interface (usual or unnumbered), just returning the first valid
1551 * OSPF interface */
1552 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1553 if (oi)
1554 return (oi);
paul718e3742002-12-13 20:15:29 +00001555 }
1556 return NULL;
1557 }
1558
vincent77df1f72005-10-06 07:46:22 +00001559 /* An instance is specified --> Return the next OSPF interface */
paul1eb8ef22005-04-07 07:30:20 +00001560 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, nn, osif))
paul718e3742002-12-13 20:15:29 +00001561 {
vincent77df1f72005-10-06 07:46:22 +00001562 /* Usual interface */
1563 if (ifaddr->s_addr)
1564 /* The interface must have valid AF_INET connected address */
1565 /* it must have lager IPv4 address value than the lookup entry */
1566 if ((ospf_snmp_is_if_have_addr(osif->ifp)) &&
1567 (ntohl (osif->addr.s_addr) > ntohl (ifaddr->s_addr)))
1568 {
1569 *ifaddr = osif->addr;
1570 *ifindex = osif->ifindex;
1571
1572 /* and it must be an OSPF interface */
1573 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1574 if (oi)
1575 return oi;
1576 }
1577 /* Unnumbered interface */
1578 else
1579 /* The interface must NOT have valid AF_INET connected address */
1580 /* it must have lager interface index than the lookup entry */
1581 if ((!ospf_snmp_is_if_have_addr(osif->ifp)) &&
1582 (osif->ifindex > *ifindex))
1583 {
1584 *ifaddr = osif->addr;
1585 *ifindex = osif->ifindex;
1586
1587 /* and it must be an OSPF interface */
1588 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1589 if (oi)
1590 return oi;
1591 }
paul718e3742002-12-13 20:15:29 +00001592 }
1593 return NULL;
1594}
1595
1596int
1597ospf_snmp_iftype (struct interface *ifp)
1598{
1599#define ospf_snmp_iftype_broadcast 1
1600#define ospf_snmp_iftype_nbma 2
1601#define ospf_snmp_iftype_pointToPoint 3
1602#define ospf_snmp_iftype_pointToMultipoint 5
1603 if (if_is_broadcast (ifp))
1604 return ospf_snmp_iftype_broadcast;
1605 if (if_is_pointopoint (ifp))
1606 return ospf_snmp_iftype_pointToPoint;
1607 return ospf_snmp_iftype_broadcast;
1608}
1609
vincent77df1f72005-10-06 07:46:22 +00001610struct ospf_interface *
paul718e3742002-12-13 20:15:29 +00001611ospfIfLookup (struct variable *v, oid *name, size_t *length,
1612 struct in_addr *ifaddr, unsigned int *ifindex, int exact)
1613{
paul6c835672004-10-11 11:00:30 +00001614 unsigned int len;
paul718e3742002-12-13 20:15:29 +00001615 int ifaddr_next = 0;
1616 int ifindex_next = 0;
vincent77df1f72005-10-06 07:46:22 +00001617 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001618 oid *offset;
1619
1620 if (exact)
1621 {
1622 if (*length != v->namelen + IN_ADDR_SIZE + 1)
1623 return NULL;
1624
1625 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, ifaddr);
1626 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1627
1628 return ospf_snmp_if_lookup (ifaddr, ifindex);
1629 }
1630 else
1631 {
1632 len = *length - v->namelen;
1633 if (len >= IN_ADDR_SIZE)
1634 len = IN_ADDR_SIZE;
1635 if (len <= 0)
1636 ifaddr_next = 1;
1637
1638 oid2in_addr (name + v->namelen, len, ifaddr);
1639
1640 len = *length - v->namelen - IN_ADDR_SIZE;
1641 if (len >= 1)
1642 len = 1;
1643 else
1644 ifindex_next = 1;
1645
1646 if (len == 1)
1647 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1648
vincent77df1f72005-10-06 07:46:22 +00001649 oi = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next,
paul718e3742002-12-13 20:15:29 +00001650 ifindex_next);
vincent77df1f72005-10-06 07:46:22 +00001651 if (oi)
paul718e3742002-12-13 20:15:29 +00001652 {
1653 *length = v->namelen + IN_ADDR_SIZE + 1;
1654 offset = name + v->namelen;
1655 oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE);
1656 offset += IN_ADDR_SIZE;
1657 *offset = *ifindex;
vincent77df1f72005-10-06 07:46:22 +00001658 return oi;
paul718e3742002-12-13 20:15:29 +00001659 }
1660 }
1661 return NULL;
1662}
1663
1664static u_char *
1665ospfIfEntry (struct variable *v, oid *name, size_t *length, int exact,
1666 size_t *var_len, WriteMethod **write_method)
1667{
paul718e3742002-12-13 20:15:29 +00001668 unsigned int ifindex;
1669 struct in_addr ifaddr;
1670 struct ospf_interface *oi;
paul020709f2003-04-04 02:44:16 +00001671 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001672
1673 ifindex = 0;
1674 memset (&ifaddr, 0, sizeof (struct in_addr));
1675
1676 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00001677 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00001678 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001679 return NULL;
1680
vincent77df1f72005-10-06 07:46:22 +00001681 oi = ospfIfLookup (v, name, length, &ifaddr, &ifindex, exact);
paul718e3742002-12-13 20:15:29 +00001682 if (oi == NULL)
1683 return NULL;
1684
1685 /* Return the current value of the variable */
1686 switch (v->magic)
1687 {
1688 case OSPFIFIPADDRESS: /* 1 */
1689 return SNMP_IPADDRESS (ifaddr);
1690 break;
1691 case OSPFADDRESSLESSIF: /* 2 */
1692 return SNMP_INTEGER (ifindex);
1693 break;
1694 case OSPFIFAREAID: /* 3 */
1695 if (oi->area)
1696 return SNMP_IPADDRESS (oi->area->area_id);
1697 else
1698 return SNMP_IPADDRESS (ospf_empty_addr);
1699 break;
1700 case OSPFIFTYPE: /* 4 */
vincent77df1f72005-10-06 07:46:22 +00001701 return SNMP_INTEGER (ospf_snmp_iftype (oi->ifp));
paul718e3742002-12-13 20:15:29 +00001702 break;
1703 case OSPFIFADMINSTAT: /* 5 */
1704 if (oi)
1705 return SNMP_INTEGER (OSPF_STATUS_ENABLED);
1706 else
1707 return SNMP_INTEGER (OSPF_STATUS_DISABLED);
1708 break;
1709 case OSPFIFRTRPRIORITY: /* 6 */
1710 return SNMP_INTEGER (PRIORITY (oi));
1711 break;
1712 case OSPFIFTRANSITDELAY: /* 7 */
1713 return SNMP_INTEGER (OSPF_IF_PARAM (oi, transmit_delay));
1714 break;
1715 case OSPFIFRETRANSINTERVAL: /* 8 */
1716 return SNMP_INTEGER (OSPF_IF_PARAM (oi, retransmit_interval));
1717 break;
1718 case OSPFIFHELLOINTERVAL: /* 9 */
1719 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_hello));
1720 break;
1721 case OSPFIFRTRDEADINTERVAL: /* 10 */
1722 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_wait));
1723 break;
1724 case OSPFIFPOLLINTERVAL: /* 11 */
1725 return SNMP_INTEGER (OSPF_POLL_INTERVAL_DEFAULT);
1726 break;
1727 case OSPFIFSTATE: /* 12 */
vincentba682532005-09-29 13:52:57 +00001728 return SNMP_INTEGER (ISM_SNMP(oi->state));
paul718e3742002-12-13 20:15:29 +00001729 break;
1730 case OSPFIFDESIGNATEDROUTER: /* 13 */
1731 return SNMP_IPADDRESS (DR (oi));
1732 break;
1733 case OSPFIFBACKUPDESIGNATEDROUTER: /* 14 */
1734 return SNMP_IPADDRESS (BDR (oi));
1735 break;
1736 case OSPFIFEVENTS: /* 15 */
1737 return SNMP_INTEGER (oi->state_change);
1738 break;
1739 case OSPFIFAUTHKEY: /* 16 */
1740 *var_len = 0;
1741 return (u_char *) OSPF_IF_PARAM (oi, auth_simple);
1742 break;
1743 case OSPFIFSTATUS: /* 17 */
1744 return SNMP_INTEGER (SNMP_VALID);
1745 break;
1746 case OSPFIFMULTICASTFORWARDING: /* 18 */
1747#define ospf_snmp_multiforward_blocked 1
1748#define ospf_snmp_multiforward_multicast 2
1749#define ospf_snmp_multiforward_unicast 3
1750 return SNMP_INTEGER (ospf_snmp_multiforward_blocked);
1751 break;
1752 case OSPFIFDEMAND: /* 19 */
1753 return SNMP_INTEGER (SNMP_FALSE);
1754 break;
1755 case OSPFIFAUTHTYPE: /* 20 */
1756 if (oi->area)
1757 return SNMP_INTEGER (oi->area->auth_type);
1758 else
1759 return SNMP_INTEGER (0);
1760 break;
1761 default:
1762 return NULL;
1763 break;
1764 }
1765 return NULL;
1766}
1767
1768#define OSPF_SNMP_METRIC_VALUE 1
1769
vincent77df1f72005-10-06 07:46:22 +00001770struct ospf_interface *
paul718e3742002-12-13 20:15:29 +00001771ospfIfMetricLookup (struct variable *v, oid *name, size_t *length,
1772 struct in_addr *ifaddr, unsigned int *ifindex, int exact)
1773{
paul6c835672004-10-11 11:00:30 +00001774 unsigned int len;
paul718e3742002-12-13 20:15:29 +00001775 int ifaddr_next = 0;
1776 int ifindex_next = 0;
vincent77df1f72005-10-06 07:46:22 +00001777 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001778 oid *offset;
1779 int metric;
1780
1781 if (exact)
1782 {
1783 if (*length != v->namelen + IN_ADDR_SIZE + 1 + 1)
1784 return NULL;
1785
1786 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, ifaddr);
1787 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1788 metric = name[v->namelen + IN_ADDR_SIZE + 1];
1789
1790 if (metric != OSPF_SNMP_METRIC_VALUE)
1791 return NULL;
1792
1793 return ospf_snmp_if_lookup (ifaddr, ifindex);
1794 }
1795 else
1796 {
1797 len = *length - v->namelen;
1798 if (len >= IN_ADDR_SIZE)
1799 len = IN_ADDR_SIZE;
1800 else
1801 ifaddr_next = 1;
1802
1803 oid2in_addr (name + v->namelen, len, ifaddr);
1804
1805 len = *length - v->namelen - IN_ADDR_SIZE;
1806 if (len >= 1)
1807 len = 1;
1808 else
1809 ifindex_next = 1;
1810
1811 if (len == 1)
1812 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1813
vincent77df1f72005-10-06 07:46:22 +00001814 oi = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next,
paul718e3742002-12-13 20:15:29 +00001815 ifindex_next);
vincent77df1f72005-10-06 07:46:22 +00001816 if (oi)
paul718e3742002-12-13 20:15:29 +00001817 {
1818 *length = v->namelen + IN_ADDR_SIZE + 1 + 1;
1819 offset = name + v->namelen;
1820 oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE);
1821 offset += IN_ADDR_SIZE;
1822 *offset = *ifindex;
1823 offset++;
1824 *offset = OSPF_SNMP_METRIC_VALUE;
vincent77df1f72005-10-06 07:46:22 +00001825 return oi;
paul718e3742002-12-13 20:15:29 +00001826 }
1827 }
1828 return NULL;
1829}
1830
1831static u_char *
1832ospfIfMetricEntry (struct variable *v, oid *name, size_t *length, int exact,
1833 size_t *var_len, WriteMethod **write_method)
1834{
1835 /* Currently we support metric 1 only. */
paul718e3742002-12-13 20:15:29 +00001836 unsigned int ifindex;
1837 struct in_addr ifaddr;
1838 struct ospf_interface *oi;
paul020709f2003-04-04 02:44:16 +00001839 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001840
1841 ifindex = 0;
1842 memset (&ifaddr, 0, sizeof (struct in_addr));
1843
1844 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00001845 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00001846 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001847 return NULL;
1848
vincent77df1f72005-10-06 07:46:22 +00001849 oi = ospfIfMetricLookup (v, name, length, &ifaddr, &ifindex, exact);
paul718e3742002-12-13 20:15:29 +00001850 if (oi == NULL)
1851 return NULL;
1852
1853 /* Return the current value of the variable */
1854 switch (v->magic)
1855 {
1856 case OSPFIFMETRICIPADDRESS:
1857 return SNMP_IPADDRESS (ifaddr);
1858 break;
1859 case OSPFIFMETRICADDRESSLESSIF:
1860 return SNMP_INTEGER (ifindex);
1861 break;
1862 case OSPFIFMETRICTOS:
1863 return SNMP_INTEGER (0);
1864 break;
1865 case OSPFIFMETRICVALUE:
1866 return SNMP_INTEGER (OSPF_SNMP_METRIC_VALUE);
1867 break;
1868 case OSPFIFMETRICSTATUS:
1869 return SNMP_INTEGER (1);
1870 break;
1871 default:
1872 return NULL;
1873 break;
1874 }
1875 return NULL;
1876}
1877
1878struct route_table *ospf_snmp_vl_table;
1879
1880void
1881ospf_snmp_vl_add (struct ospf_vl_data *vl_data)
1882{
1883 struct prefix_ls lp;
1884 struct route_node *rn;
1885
1886 memset (&lp, 0, sizeof (struct prefix_ls));
1887 lp.family = 0;
1888 lp.prefixlen = 64;
1889 lp.id = vl_data->vl_area_id;
1890 lp.adv_router = vl_data->vl_peer;
1891
1892 rn = route_node_get (ospf_snmp_vl_table, (struct prefix *) &lp);
1893 rn->info = vl_data;
1894}
1895
1896void
1897ospf_snmp_vl_delete (struct ospf_vl_data *vl_data)
1898{
1899 struct prefix_ls lp;
1900 struct route_node *rn;
1901
1902 memset (&lp, 0, sizeof (struct prefix_ls));
1903 lp.family = 0;
1904 lp.prefixlen = 64;
1905 lp.id = vl_data->vl_area_id;
1906 lp.adv_router = vl_data->vl_peer;
1907
1908 rn = route_node_lookup (ospf_snmp_vl_table, (struct prefix *) &lp);
1909 if (! rn)
1910 return;
1911 rn->info = NULL;
1912 route_unlock_node (rn);
1913 route_unlock_node (rn);
1914}
1915
1916struct ospf_vl_data *
1917ospf_snmp_vl_lookup (struct in_addr *area_id, struct in_addr *neighbor)
1918{
1919 struct prefix_ls lp;
1920 struct route_node *rn;
1921 struct ospf_vl_data *vl_data;
1922
1923 memset (&lp, 0, sizeof (struct prefix_ls));
1924 lp.family = 0;
1925 lp.prefixlen = 64;
1926 lp.id = *area_id;
1927 lp.adv_router = *neighbor;
1928
1929 rn = route_node_lookup (ospf_snmp_vl_table, (struct prefix *) &lp);
1930 if (rn)
1931 {
1932 vl_data = rn->info;
1933 route_unlock_node (rn);
1934 return vl_data;
1935 }
1936 return NULL;
1937}
1938
1939struct ospf_vl_data *
1940ospf_snmp_vl_lookup_next (struct in_addr *area_id, struct in_addr *neighbor,
1941 int first)
1942{
1943 struct prefix_ls lp;
1944 struct route_node *rn;
1945 struct ospf_vl_data *vl_data;
1946
1947 memset (&lp, 0, sizeof (struct prefix_ls));
1948 lp.family = 0;
1949 lp.prefixlen = 64;
1950 lp.id = *area_id;
1951 lp.adv_router = *neighbor;
1952
1953 if (first)
1954 rn = route_top (ospf_snmp_vl_table);
1955 else
1956 {
1957 rn = route_node_get (ospf_snmp_vl_table, (struct prefix *) &lp);
1958 rn = route_next (rn);
1959 }
1960
1961 for (; rn; rn = route_next (rn))
1962 if (rn->info)
1963 break;
1964
1965 if (rn && rn->info)
1966 {
1967 vl_data = rn->info;
1968 *area_id = vl_data->vl_area_id;
1969 *neighbor = vl_data->vl_peer;
1970 route_unlock_node (rn);
1971 return vl_data;
1972 }
1973 return NULL;
1974}
1975
1976struct ospf_vl_data *
1977ospfVirtIfLookup (struct variable *v, oid *name, size_t *length,
1978 struct in_addr *area_id, struct in_addr *neighbor, int exact)
1979{
1980 int first;
paul6c835672004-10-11 11:00:30 +00001981 unsigned int len;
paul718e3742002-12-13 20:15:29 +00001982 struct ospf_vl_data *vl_data;
1983
1984 if (exact)
1985 {
1986 if (*length != v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE)
1987 return NULL;
1988
1989 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, area_id);
1990 oid2in_addr (name + v->namelen + IN_ADDR_SIZE, IN_ADDR_SIZE, neighbor);
1991
1992 return ospf_snmp_vl_lookup (area_id, neighbor);
1993 }
1994 else
1995 {
1996 first = 0;
1997
1998 len = *length - v->namelen;
1999 if (len <= 0)
2000 first = 1;
2001 if (len > IN_ADDR_SIZE)
2002 len = IN_ADDR_SIZE;
2003 oid2in_addr (name + v->namelen, len, area_id);
2004
2005 len = *length - v->namelen - IN_ADDR_SIZE;
2006 if (len > IN_ADDR_SIZE)
2007 len = IN_ADDR_SIZE;
2008 oid2in_addr (name + v->namelen + IN_ADDR_SIZE, len, neighbor);
2009
2010 vl_data = ospf_snmp_vl_lookup_next (area_id, neighbor, first);
2011
2012 if (vl_data)
2013 {
2014 *length = v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE;
2015 oid_copy_addr (name + v->namelen, area_id, IN_ADDR_SIZE);
2016 oid_copy_addr (name + v->namelen + IN_ADDR_SIZE, neighbor,
2017 IN_ADDR_SIZE);
2018 return vl_data;
2019 }
2020 }
2021 return NULL;
2022}
2023
2024static u_char *
2025ospfVirtIfEntry (struct variable *v, oid *name, size_t *length, int exact,
2026 size_t *var_len, WriteMethod **write_method)
2027{
2028 struct ospf_vl_data *vl_data;
2029 struct ospf_interface *oi;
2030 struct in_addr area_id;
2031 struct in_addr neighbor;
2032
2033 memset (&area_id, 0, sizeof (struct in_addr));
2034 memset (&neighbor, 0, sizeof (struct in_addr));
2035
2036 vl_data = ospfVirtIfLookup (v, name, length, &area_id, &neighbor, exact);
2037 if (! vl_data)
2038 return NULL;
2039 oi = vl_data->vl_oi;
2040 if (! oi)
2041 return NULL;
2042
2043 /* Return the current value of the variable */
2044 switch (v->magic)
2045 {
2046 case OSPFVIRTIFAREAID:
2047 return SNMP_IPADDRESS (area_id);
2048 break;
2049 case OSPFVIRTIFNEIGHBOR:
2050 return SNMP_IPADDRESS (neighbor);
2051 break;
2052 case OSPFVIRTIFTRANSITDELAY:
2053 return SNMP_INTEGER (OSPF_IF_PARAM (oi, transmit_delay));
2054 break;
2055 case OSPFVIRTIFRETRANSINTERVAL:
2056 return SNMP_INTEGER (OSPF_IF_PARAM (oi, retransmit_interval));
2057 break;
2058 case OSPFVIRTIFHELLOINTERVAL:
2059 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_hello));
2060 break;
2061 case OSPFVIRTIFRTRDEADINTERVAL:
2062 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_wait));
2063 break;
2064 case OSPFVIRTIFSTATE:
2065 return SNMP_INTEGER (oi->state);
2066 break;
2067 case OSPFVIRTIFEVENTS:
2068 return SNMP_INTEGER (oi->state_change);
2069 break;
2070 case OSPFVIRTIFAUTHKEY:
2071 *var_len = 0;
2072 return (u_char *) OSPF_IF_PARAM (oi, auth_simple);
2073 break;
2074 case OSPFVIRTIFSTATUS:
2075 return SNMP_INTEGER (SNMP_VALID);
2076 break;
2077 case OSPFVIRTIFAUTHTYPE:
2078 if (oi->area)
2079 return SNMP_INTEGER (oi->area->auth_type);
2080 else
2081 return SNMP_INTEGER (0);
2082 break;
2083 default:
2084 return NULL;
2085 break;
2086 }
2087 return NULL;
2088}
2089
2090struct ospf_neighbor *
paul68980082003-03-25 05:07:42 +00002091ospf_snmp_nbr_lookup (struct ospf *ospf, struct in_addr *nbr_addr,
2092 unsigned int *ifindex)
paul718e3742002-12-13 20:15:29 +00002093{
paul1eb8ef22005-04-07 07:30:20 +00002094 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002095 struct ospf_interface *oi;
2096 struct ospf_neighbor *nbr;
2097 struct route_node *rn;
2098
paul1eb8ef22005-04-07 07:30:20 +00002099 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002100 {
2101 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2102 if ((nbr = rn->info) != NULL
2103 && nbr != oi->nbr_self
vincent5e4914c2005-09-29 16:34:30 +00002104/* If EXACT match is needed, provide ALL entry found
paul718e3742002-12-13 20:15:29 +00002105 && nbr->state != NSM_Down
vincent5e4914c2005-09-29 16:34:30 +00002106 */
paul718e3742002-12-13 20:15:29 +00002107 && nbr->src.s_addr != 0)
2108 {
2109 if (IPV4_ADDR_SAME (&nbr->src, nbr_addr))
2110 {
2111 route_unlock_node (rn);
2112 return nbr;
2113 }
2114 }
2115 }
2116 return NULL;
2117}
2118
2119struct ospf_neighbor *
2120ospf_snmp_nbr_lookup_next (struct in_addr *nbr_addr, unsigned int *ifindex,
2121 int first)
2122{
2123 struct listnode *nn;
2124 struct ospf_interface *oi;
2125 struct ospf_neighbor *nbr;
2126 struct route_node *rn;
2127 struct ospf_neighbor *min = NULL;
paul020709f2003-04-04 02:44:16 +00002128 struct ospf *ospf = ospf;
paul718e3742002-12-13 20:15:29 +00002129
paul020709f2003-04-04 02:44:16 +00002130 ospf = ospf_lookup ();
paul1eb8ef22005-04-07 07:30:20 +00002131
2132 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, nn, oi))
paul718e3742002-12-13 20:15:29 +00002133 {
2134 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2135 if ((nbr = rn->info) != NULL
2136 && nbr != oi->nbr_self
2137 && nbr->state != NSM_Down
2138 && nbr->src.s_addr != 0)
2139 {
2140 if (first)
2141 {
2142 if (! min)
2143 min = nbr;
2144 else if (ntohl (nbr->src.s_addr) < ntohl (min->src.s_addr))
2145 min = nbr;
2146 }
2147 else if (ntohl (nbr->src.s_addr) > ntohl (nbr_addr->s_addr))
2148 {
2149 if (! min)
2150 min = nbr;
2151 else if (ntohl (nbr->src.s_addr) < ntohl (min->src.s_addr))
2152 min = nbr;
2153 }
2154 }
2155 }
2156 if (min)
2157 {
2158 *nbr_addr = min->src;
2159 *ifindex = 0;
2160 return min;
2161 }
2162 return NULL;
2163}
2164
2165struct ospf_neighbor *
2166ospfNbrLookup (struct variable *v, oid *name, size_t *length,
2167 struct in_addr *nbr_addr, unsigned int *ifindex, int exact)
2168{
paul6c835672004-10-11 11:00:30 +00002169 unsigned int len;
paul718e3742002-12-13 20:15:29 +00002170 int first;
2171 struct ospf_neighbor *nbr;
paul020709f2003-04-04 02:44:16 +00002172 struct ospf *ospf;
2173
2174 ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +00002175
hasso1b639042005-03-27 13:32:25 +00002176 if (! ospf)
2177 return NULL;
2178
paul718e3742002-12-13 20:15:29 +00002179 if (exact)
2180 {
2181 if (*length != v->namelen + IN_ADDR_SIZE + 1)
2182 return NULL;
2183
2184 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, nbr_addr);
2185 *ifindex = name[v->namelen + IN_ADDR_SIZE];
2186
paul68980082003-03-25 05:07:42 +00002187 return ospf_snmp_nbr_lookup (ospf, nbr_addr, ifindex);
paul718e3742002-12-13 20:15:29 +00002188 }
2189 else
2190 {
2191 first = 0;
2192 len = *length - v->namelen;
2193
2194 if (len <= 0)
2195 first = 1;
2196
2197 if (len > IN_ADDR_SIZE)
2198 len = IN_ADDR_SIZE;
2199
2200 oid2in_addr (name + v->namelen, len, nbr_addr);
2201
2202 len = *length - v->namelen - IN_ADDR_SIZE;
2203 if (len >= 1)
2204 *ifindex = name[v->namelen + IN_ADDR_SIZE];
2205
2206 nbr = ospf_snmp_nbr_lookup_next (nbr_addr, ifindex, first);
2207
2208 if (nbr)
2209 {
2210 *length = v->namelen + IN_ADDR_SIZE + 1;
2211 oid_copy_addr (name + v->namelen, nbr_addr, IN_ADDR_SIZE);
2212 name[v->namelen + IN_ADDR_SIZE] = *ifindex;
2213 return nbr;
2214 }
2215 }
2216 return NULL;
2217}
2218
Andrew J. Schorrad81f8c2007-03-14 22:05:18 +00002219/* map internal quagga neighbor states to official MIB values:
2220
2221ospfNbrState OBJECT-TYPE
2222 SYNTAX INTEGER {
2223 down (1),
2224 attempt (2),
2225 init (3),
2226 twoWay (4),
2227 exchangeStart (5),
2228 exchange (6),
2229 loading (7),
2230 full (8)
2231 }
2232*/
2233static int32_t
2234ospf_snmp_neighbor_state(u_char nst)
2235{
2236 switch (nst)
2237 {
2238 case NSM_Attempt:
2239 return 2;
2240 case NSM_Init:
2241 return 3;
2242 case NSM_TwoWay:
2243 return 4;
2244 case NSM_ExStart:
2245 return 5;
2246 case NSM_Exchange:
2247 return 6;
2248 case NSM_Loading:
2249 return 7;
2250 case NSM_Full:
2251 return 8;
2252 default:
2253 return 1; /* down */
2254 }
2255}
2256
paul718e3742002-12-13 20:15:29 +00002257static u_char *
2258ospfNbrEntry (struct variable *v, oid *name, size_t *length, int exact,
2259 size_t *var_len, WriteMethod **write_method)
2260{
2261 struct in_addr nbr_addr;
2262 unsigned int ifindex;
2263 struct ospf_neighbor *nbr;
2264 struct ospf_interface *oi;
2265
2266 memset (&nbr_addr, 0, sizeof (struct in_addr));
2267 ifindex = 0;
2268
2269 nbr = ospfNbrLookup (v, name, length, &nbr_addr, &ifindex, exact);
2270 if (! nbr)
2271 return NULL;
2272 oi = nbr->oi;
2273 if (! oi)
2274 return NULL;
2275
2276 /* Return the current value of the variable */
2277 switch (v->magic)
2278 {
2279 case OSPFNBRIPADDR:
2280 return SNMP_IPADDRESS (nbr_addr);
2281 break;
2282 case OSPFNBRADDRESSLESSINDEX:
2283 return SNMP_INTEGER (ifindex);
2284 break;
2285 case OSPFNBRRTRID:
2286 return SNMP_IPADDRESS (nbr->router_id);
2287 break;
2288 case OSPFNBROPTIONS:
2289 return SNMP_INTEGER (oi->nbr_self->options);
2290 break;
2291 case OSPFNBRPRIORITY:
2292 return SNMP_INTEGER (nbr->priority);
2293 break;
2294 case OSPFNBRSTATE:
Andrew J. Schorrad81f8c2007-03-14 22:05:18 +00002295 return SNMP_INTEGER (ospf_snmp_neighbor_state(nbr->state));
paul718e3742002-12-13 20:15:29 +00002296 break;
2297 case OSPFNBREVENTS:
2298 return SNMP_INTEGER (nbr->state_change);
2299 break;
2300 case OSPFNBRLSRETRANSQLEN:
2301 return SNMP_INTEGER (ospf_ls_retransmit_count (nbr));
2302 break;
2303 case OSPFNBMANBRSTATUS:
2304 return SNMP_INTEGER (SNMP_VALID);
2305 break;
2306 case OSPFNBMANBRPERMANENCE:
2307 return SNMP_INTEGER (2);
2308 break;
2309 case OSPFNBRHELLOSUPPRESSED:
2310 return SNMP_INTEGER (SNMP_FALSE);
2311 break;
2312 default:
2313 return NULL;
2314 break;
2315 }
2316 return NULL;
2317}
2318
2319static u_char *
2320ospfVirtNbrEntry (struct variable *v, oid *name, size_t *length, int exact,
2321 size_t *var_len, WriteMethod **write_method)
2322{
2323 struct ospf_vl_data *vl_data;
2324 struct in_addr area_id;
2325 struct in_addr neighbor;
paul020709f2003-04-04 02:44:16 +00002326 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002327
2328 memset (&area_id, 0, sizeof (struct in_addr));
2329 memset (&neighbor, 0, sizeof (struct in_addr));
2330
2331 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00002332 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00002333 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00002334 return NULL;
2335
2336 vl_data = ospfVirtIfLookup (v, name, length, &area_id, &neighbor, exact);
2337 if (! vl_data)
2338 return NULL;
2339
2340 /* Return the current value of the variable */
2341 switch (v->magic)
2342 {
2343 case OSPFVIRTNBRAREA:
2344 return (u_char *) NULL;
2345 break;
2346 case OSPFVIRTNBRRTRID:
2347 return (u_char *) NULL;
2348 break;
2349 case OSPFVIRTNBRIPADDR:
2350 return (u_char *) NULL;
2351 break;
2352 case OSPFVIRTNBROPTIONS:
2353 return (u_char *) NULL;
2354 break;
2355 case OSPFVIRTNBRSTATE:
2356 return (u_char *) NULL;
2357 break;
2358 case OSPFVIRTNBREVENTS:
2359 return (u_char *) NULL;
2360 break;
2361 case OSPFVIRTNBRLSRETRANSQLEN:
2362 return (u_char *) NULL;
2363 break;
2364 case OSPFVIRTNBRHELLOSUPPRESSED:
2365 return (u_char *) NULL;
2366 break;
2367 default:
2368 return NULL;
2369 break;
2370 }
2371 return NULL;
2372}
2373
2374struct ospf_lsa *
2375ospfExtLsdbLookup (struct variable *v, oid *name, size_t *length, u_char *type,
2376 struct in_addr *ls_id, struct in_addr *router_id, int exact)
2377{
2378 int first;
2379 oid *offset;
2380 int offsetlen;
2381 u_char lsa_type;
paul6c835672004-10-11 11:00:30 +00002382 unsigned int len;
paul718e3742002-12-13 20:15:29 +00002383 struct ospf_lsa *lsa;
paul020709f2003-04-04 02:44:16 +00002384 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002385
paul020709f2003-04-04 02:44:16 +00002386 ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +00002387 if (exact)
2388 {
2389 if (*length != v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
2390 return NULL;
2391
2392 offset = name + v->namelen;
2393
2394 /* Make it sure given value match to type. */
2395 lsa_type = *offset;
2396 offset++;
2397
2398 if (lsa_type != *type)
2399 return NULL;
2400
2401 /* LS ID. */
2402 oid2in_addr (offset, IN_ADDR_SIZE, ls_id);
2403 offset += IN_ADDR_SIZE;
2404
2405 /* Router ID. */
2406 oid2in_addr (offset, IN_ADDR_SIZE, router_id);
2407
paul68980082003-03-25 05:07:42 +00002408 return ospf_lsdb_lookup_by_id (ospf->lsdb, *type, *ls_id, *router_id);
paul718e3742002-12-13 20:15:29 +00002409 }
2410 else
2411 {
2412 /* Get variable length. */
2413 first = 0;
2414 offset = name + v->namelen;
2415 offsetlen = *length - v->namelen;
2416
2417 /* LSA type value. */
2418 lsa_type = *offset;
2419 offset++;
2420 offsetlen--;
2421
2422 if (offsetlen <= 0 || lsa_type < OSPF_AS_EXTERNAL_LSA)
2423 first = 1;
2424
2425 /* LS ID. */
2426 len = offsetlen;
2427 if (len > IN_ADDR_SIZE)
2428 len = IN_ADDR_SIZE;
2429
2430 oid2in_addr (offset, len, ls_id);
2431
2432 offset += IN_ADDR_SIZE;
2433 offsetlen -= IN_ADDR_SIZE;
2434
2435 /* Router ID. */
2436 len = offsetlen;
2437 if (len > IN_ADDR_SIZE)
2438 len = IN_ADDR_SIZE;
2439
2440 oid2in_addr (offset, len, router_id);
2441
paul68980082003-03-25 05:07:42 +00002442 lsa = ospf_lsdb_lookup_by_id_next (ospf->lsdb, *type, *ls_id,
paul718e3742002-12-13 20:15:29 +00002443 *router_id, first);
2444
2445 if (lsa)
2446 {
2447 /* Fill in length. */
2448 *length = v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE;
2449
2450 /* Fill in value. */
2451 offset = name + v->namelen;
2452
2453 *offset = OSPF_AS_EXTERNAL_LSA;
2454 offset++;
2455 oid_copy_addr (offset, &lsa->data->id, IN_ADDR_SIZE);
2456 offset += IN_ADDR_SIZE;
2457 oid_copy_addr (offset, &lsa->data->adv_router, IN_ADDR_SIZE);
2458
2459 return lsa;
2460 }
2461 }
2462 return NULL;
2463}
2464
2465static u_char *
2466ospfExtLsdbEntry (struct variable *v, oid *name, size_t *length, int exact,
2467 size_t *var_len, WriteMethod **write_method)
2468{
2469 struct ospf_lsa *lsa;
2470 struct lsa_header *lsah;
2471 u_char type;
2472 struct in_addr ls_id;
2473 struct in_addr router_id;
paul020709f2003-04-04 02:44:16 +00002474 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002475
2476 type = OSPF_AS_EXTERNAL_LSA;
2477 memset (&ls_id, 0, sizeof (struct in_addr));
2478 memset (&router_id, 0, sizeof (struct in_addr));
2479
2480 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00002481 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00002482 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00002483 return NULL;
2484
2485 lsa = ospfExtLsdbLookup (v, name, length, &type, &ls_id, &router_id, exact);
2486 if (! lsa)
2487 return NULL;
2488
2489 lsah = lsa->data;
2490
2491 /* Return the current value of the variable */
2492 switch (v->magic)
2493 {
2494 case OSPFEXTLSDBTYPE:
2495 return SNMP_INTEGER (OSPF_AS_EXTERNAL_LSA);
2496 break;
2497 case OSPFEXTLSDBLSID:
2498 return SNMP_IPADDRESS (lsah->id);
2499 break;
2500 case OSPFEXTLSDBROUTERID:
2501 return SNMP_IPADDRESS (lsah->adv_router);
2502 break;
2503 case OSPFEXTLSDBSEQUENCE:
2504 return SNMP_INTEGER (lsah->ls_seqnum);
2505 break;
2506 case OSPFEXTLSDBAGE:
2507 return SNMP_INTEGER (lsah->ls_age);
2508 break;
2509 case OSPFEXTLSDBCHECKSUM:
2510 return SNMP_INTEGER (lsah->checksum);
2511 break;
2512 case OSPFEXTLSDBADVERTISEMENT:
2513 *var_len = ntohs (lsah->length);
2514 return (u_char *) lsah;
2515 break;
2516 default:
2517 return NULL;
2518 break;
2519 }
2520 return NULL;
2521}
2522
2523static u_char *
2524ospfAreaAggregateEntry (struct variable *v, oid *name, size_t *length,
2525 int exact, size_t *var_len, WriteMethod **write_method)
2526{
2527 /* Return the current value of the variable */
2528 switch (v->magic)
2529 {
2530 case OSPFAREAAGGREGATEAREAID:
2531 return (u_char *) NULL;
2532 break;
2533 case OSPFAREAAGGREGATELSDBTYPE:
2534 return (u_char *) NULL;
2535 break;
2536 case OSPFAREAAGGREGATENET:
2537 return (u_char *) NULL;
2538 break;
2539 case OSPFAREAAGGREGATEMASK:
2540 return (u_char *) NULL;
2541 break;
2542 case OSPFAREAAGGREGATESTATUS:
2543 return (u_char *) NULL;
2544 break;
2545 case OSPFAREAAGGREGATEEFFECT:
2546 return (u_char *) NULL;
2547 break;
2548 default:
2549 return NULL;
2550 break;
2551 }
2552 return NULL;
2553}
2554
vincent5e4914c2005-09-29 16:34:30 +00002555/* OSPF Traps. */
2556#define IFSTATECHANGE 16
2557#define VIRTIFSTATECHANGE 1
2558#define NBRSTATECHANGE 2
2559#define VIRTNBRSTATECHANGE 3
2560
2561struct trap_object ospfNbrTrapList[] =
2562{
2563 {ospfGeneralGroup, -2, {1, OSPFROUTERID}},
2564 {ospfNbrEntry, 3, {10, 1, OSPFNBRIPADDR}},
2565 {ospfNbrEntry, 3, {10, 1, OSPFNBRRTRID}},
2566 {ospfNbrEntry, 3, {10, 1, OSPFNBRSTATE}}
2567};
2568
2569
2570struct trap_object ospfVirtNbrTrapList[] =
2571{
2572 {ospfGeneralGroup, -2, {1, 1}},
2573 {ospfVirtNbrEntry, 3, {11, 1, OSPFVIRTNBRAREA}},
2574 {ospfVirtNbrEntry, 3, {11, 1, OSPFVIRTNBRRTRID}},
2575 {ospfVirtNbrEntry, 3, {11, 1, OSPFVIRTNBRSTATE}}
2576};
2577
2578struct trap_object ospfIfTrapList[] =
2579{
2580 {ospfGeneralGroup, -2, {1, OSPFROUTERID}},
2581 {ospfIfEntry, 3, {7, 1, OSPFIFIPADDRESS}},
2582 {ospfIfEntry, 3, {7, 1, OSPFADDRESSLESSIF}},
2583 {ospfIfEntry, 3, {7, 1, OSPFIFSTATE}}
2584};
2585
2586struct trap_object ospfVirtIfTrapList[] =
2587{
2588 {ospfGeneralGroup, -2, {1, OSPFROUTERID}},
2589 {ospfVirtIfEntry, 3, {9, 1, OSPFVIRTIFAREAID}},
2590 {ospfVirtIfEntry, 3, {9, 1, OSPFVIRTIFNEIGHBOR}},
2591 {ospfVirtIfEntry, 3, {9, 1, OSPFVIRTIFSTATE}}
2592};
2593
2594void
2595ospfTrapNbrStateChange (struct ospf_neighbor *on)
2596{
2597 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
Andrew J. Schorr9aecfae2006-06-24 20:05:02 +00002598 char msgbuf[16];
vincent5e4914c2005-09-29 16:34:30 +00002599
Andrew J. Schorr9aecfae2006-06-24 20:05:02 +00002600 ospf_nbr_state_message(on, msgbuf, sizeof(msgbuf));
2601 zlog (NULL, LOG_INFO, "ospfTrapNbrStateChange trap sent: %s now %s",
2602 inet_ntoa(on->address.u.prefix4), msgbuf);
vincent5e4914c2005-09-29 16:34:30 +00002603
2604 oid_copy_addr (index, &(on->address.u.prefix4), IN_ADDR_SIZE);
2605 index[IN_ADDR_SIZE] = 0;
2606
2607 smux_trap (ospf_oid, sizeof ospf_oid / sizeof (oid),
2608 index, IN_ADDR_SIZE + 1,
2609 ospfNbrTrapList,
2610 sizeof ospfNbrTrapList / sizeof (struct trap_object),
2611 time (NULL), NBRSTATECHANGE);
2612}
2613
2614void
2615ospfTrapVirtNbrStateChange (struct ospf_neighbor *on)
2616{
2617 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
2618
2619 zlog (NULL, LOG_INFO, "ospfTrapVirtNbrStateChange trap sent");
2620
2621 oid_copy_addr (index, &(on->address.u.prefix4), IN_ADDR_SIZE);
2622 index[IN_ADDR_SIZE] = 0;
2623
2624 smux_trap (ospf_oid, sizeof ospf_oid / sizeof (oid),
2625 index, IN_ADDR_SIZE + 1,
2626 ospfVirtNbrTrapList,
2627 sizeof ospfVirtNbrTrapList / sizeof (struct trap_object),
2628 time (NULL), VIRTNBRSTATECHANGE);
2629}
2630
2631void
2632ospfTrapIfStateChange (struct ospf_interface *oi)
2633{
2634 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
2635
Andrew J. Schorr9aecfae2006-06-24 20:05:02 +00002636 zlog (NULL, LOG_INFO, "ospfTrapIfStateChange trap sent: %s now %s",
2637 inet_ntoa(oi->address->u.prefix4),
2638 LOOKUP(ospf_ism_state_msg, oi->state));
vincent5e4914c2005-09-29 16:34:30 +00002639
2640 oid_copy_addr (index, &(oi->address->u.prefix4), IN_ADDR_SIZE);
2641 index[IN_ADDR_SIZE] = 0;
2642
2643 smux_trap (ospf_oid, sizeof ospf_oid / sizeof (oid),
2644 index, IN_ADDR_SIZE + 1,
2645 ospfIfTrapList,
2646 sizeof ospfIfTrapList / sizeof (struct trap_object),
2647 time (NULL), IFSTATECHANGE);
2648}
2649
2650void
2651ospfTrapVirtIfStateChange (struct ospf_interface *oi)
2652{
2653 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
2654
2655 zlog (NULL, LOG_INFO, "ospfTrapVirtIfStateChange trap sent");
2656
2657 oid_copy_addr (index, &(oi->address->u.prefix4), IN_ADDR_SIZE);
2658 index[IN_ADDR_SIZE] = 0;
2659
2660 smux_trap (ospf_oid, sizeof ospf_oid / sizeof (oid),
2661 index, IN_ADDR_SIZE + 1,
2662 ospfVirtIfTrapList,
2663 sizeof ospfVirtIfTrapList / sizeof (struct trap_object),
2664 time (NULL), VIRTIFSTATECHANGE);
2665}
paul718e3742002-12-13 20:15:29 +00002666/* Register OSPF2-MIB. */
2667void
2668ospf_snmp_init ()
2669{
2670 ospf_snmp_iflist = list_new ();
2671 ospf_snmp_vl_table = route_table_init ();
hassoc75105a2004-10-13 10:33:26 +00002672 smux_init (om->master);
paul718e3742002-12-13 20:15:29 +00002673 REGISTER_MIB("mibII/ospf", ospf_variables, variable, ospf_oid);
paul718e3742002-12-13 20:15:29 +00002674}
2675#endif /* HAVE_SNMP */