blob: e6ce1f018e63f36384920a006153574831eadcde [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>
Joakim Tjernlundfb62a3c2008-05-13 20:03:32 +020030#include <net-snmp/net-snmp-includes.h>
31#else
paul718e3742002-12-13 20:15:29 +000032#include <asn1.h>
33#include <snmp.h>
34#include <snmp_impl.h>
Joakim Tjernlundfb62a3c2008-05-13 20:03:32 +020035#endif
paul718e3742002-12-13 20:15:29 +000036
37#include "if.h"
38#include "log.h"
39#include "prefix.h"
40#include "table.h"
41#include "command.h"
42#include "memory.h"
43#include "smux.h"
44
45#include "ospfd/ospfd.h"
46#include "ospfd/ospf_interface.h"
47#include "ospfd/ospf_asbr.h"
48#include "ospfd/ospf_lsa.h"
49#include "ospfd/ospf_lsdb.h"
50#include "ospfd/ospf_abr.h"
51#include "ospfd/ospf_neighbor.h"
52#include "ospfd/ospf_nsm.h"
53#include "ospfd/ospf_flood.h"
vincente6217872005-09-29 13:56:14 +000054#include "ospfd/ospf_ism.h"
Andrew J. Schorr9aecfae2006-06-24 20:05:02 +000055#include "ospfd/ospf_dump.h"
paul718e3742002-12-13 20:15:29 +000056
57/* OSPF2-MIB. */
58#define OSPF2MIB 1,3,6,1,2,1,14
59
paul718e3742002-12-13 20:15:29 +000060/* OSPF MIB General Group values. */
61#define OSPFROUTERID 1
62#define OSPFADMINSTAT 2
63#define OSPFVERSIONNUMBER 3
64#define OSPFAREABDRRTRSTATUS 4
65#define OSPFASBDRRTRSTATUS 5
66#define OSPFEXTERNLSACOUNT 6
67#define OSPFEXTERNLSACKSUMSUM 7
68#define OSPFTOSSUPPORT 8
69#define OSPFORIGINATENEWLSAS 9
70#define OSPFRXNEWLSAS 10
71#define OSPFEXTLSDBLIMIT 11
72#define OSPFMULTICASTEXTENSIONS 12
73#define OSPFEXITOVERFLOWINTERVAL 13
74#define OSPFDEMANDEXTENSIONS 14
75
76/* OSPF MIB ospfAreaTable. */
77#define OSPFAREAID 1
78#define OSPFAUTHTYPE 2
79#define OSPFIMPORTASEXTERN 3
80#define OSPFSPFRUNS 4
81#define OSPFAREABDRRTRCOUNT 5
82#define OSPFASBDRRTRCOUNT 6
83#define OSPFAREALSACOUNT 7
84#define OSPFAREALSACKSUMSUM 8
85#define OSPFAREASUMMARY 9
86#define OSPFAREASTATUS 10
87
88/* OSPF MIB ospfStubAreaTable. */
89#define OSPFSTUBAREAID 1
90#define OSPFSTUBTOS 2
91#define OSPFSTUBMETRIC 3
92#define OSPFSTUBSTATUS 4
93#define OSPFSTUBMETRICTYPE 5
94
95/* OSPF MIB ospfLsdbTable. */
96#define OSPFLSDBAREAID 1
97#define OSPFLSDBTYPE 2
98#define OSPFLSDBLSID 3
99#define OSPFLSDBROUTERID 4
100#define OSPFLSDBSEQUENCE 5
101#define OSPFLSDBAGE 6
102#define OSPFLSDBCHECKSUM 7
103#define OSPFLSDBADVERTISEMENT 8
104
105/* OSPF MIB ospfAreaRangeTable. */
106#define OSPFAREARANGEAREAID 1
107#define OSPFAREARANGENET 2
108#define OSPFAREARANGEMASK 3
109#define OSPFAREARANGESTATUS 4
110#define OSPFAREARANGEEFFECT 5
111
112/* OSPF MIB ospfHostTable. */
113#define OSPFHOSTIPADDRESS 1
114#define OSPFHOSTTOS 2
115#define OSPFHOSTMETRIC 3
116#define OSPFHOSTSTATUS 4
117#define OSPFHOSTAREAID 5
118
119/* OSPF MIB ospfIfTable. */
120#define OSPFIFIPADDRESS 1
121#define OSPFADDRESSLESSIF 2
122#define OSPFIFAREAID 3
123#define OSPFIFTYPE 4
124#define OSPFIFADMINSTAT 5
125#define OSPFIFRTRPRIORITY 6
126#define OSPFIFTRANSITDELAY 7
127#define OSPFIFRETRANSINTERVAL 8
128#define OSPFIFHELLOINTERVAL 9
129#define OSPFIFRTRDEADINTERVAL 10
130#define OSPFIFPOLLINTERVAL 11
131#define OSPFIFSTATE 12
132#define OSPFIFDESIGNATEDROUTER 13
133#define OSPFIFBACKUPDESIGNATEDROUTER 14
134#define OSPFIFEVENTS 15
135#define OSPFIFAUTHKEY 16
136#define OSPFIFSTATUS 17
137#define OSPFIFMULTICASTFORWARDING 18
138#define OSPFIFDEMAND 19
139#define OSPFIFAUTHTYPE 20
140
141/* OSPF MIB ospfIfMetricTable. */
142#define OSPFIFMETRICIPADDRESS 1
143#define OSPFIFMETRICADDRESSLESSIF 2
144#define OSPFIFMETRICTOS 3
145#define OSPFIFMETRICVALUE 4
146#define OSPFIFMETRICSTATUS 5
147
148/* OSPF MIB ospfVirtIfTable. */
149#define OSPFVIRTIFAREAID 1
150#define OSPFVIRTIFNEIGHBOR 2
151#define OSPFVIRTIFTRANSITDELAY 3
152#define OSPFVIRTIFRETRANSINTERVAL 4
153#define OSPFVIRTIFHELLOINTERVAL 5
154#define OSPFVIRTIFRTRDEADINTERVAL 6
155#define OSPFVIRTIFSTATE 7
156#define OSPFVIRTIFEVENTS 8
157#define OSPFVIRTIFAUTHKEY 9
158#define OSPFVIRTIFSTATUS 10
159#define OSPFVIRTIFAUTHTYPE 11
160
161/* OSPF MIB ospfNbrTable. */
162#define OSPFNBRIPADDR 1
163#define OSPFNBRADDRESSLESSINDEX 2
164#define OSPFNBRRTRID 3
165#define OSPFNBROPTIONS 4
166#define OSPFNBRPRIORITY 5
167#define OSPFNBRSTATE 6
168#define OSPFNBREVENTS 7
169#define OSPFNBRLSRETRANSQLEN 8
170#define OSPFNBMANBRSTATUS 9
171#define OSPFNBMANBRPERMANENCE 10
172#define OSPFNBRHELLOSUPPRESSED 11
173
174/* OSPF MIB ospfVirtNbrTable. */
175#define OSPFVIRTNBRAREA 1
176#define OSPFVIRTNBRRTRID 2
177#define OSPFVIRTNBRIPADDR 3
178#define OSPFVIRTNBROPTIONS 4
179#define OSPFVIRTNBRSTATE 5
180#define OSPFVIRTNBREVENTS 6
181#define OSPFVIRTNBRLSRETRANSQLEN 7
182#define OSPFVIRTNBRHELLOSUPPRESSED 8
183
184/* OSPF MIB ospfExtLsdbTable. */
185#define OSPFEXTLSDBTYPE 1
186#define OSPFEXTLSDBLSID 2
187#define OSPFEXTLSDBROUTERID 3
188#define OSPFEXTLSDBSEQUENCE 4
189#define OSPFEXTLSDBAGE 5
190#define OSPFEXTLSDBCHECKSUM 6
191#define OSPFEXTLSDBADVERTISEMENT 7
192
193/* OSPF MIB ospfAreaAggregateTable. */
194#define OSPFAREAAGGREGATEAREAID 1
195#define OSPFAREAAGGREGATELSDBTYPE 2
196#define OSPFAREAAGGREGATENET 3
197#define OSPFAREAAGGREGATEMASK 4
198#define OSPFAREAAGGREGATESTATUS 5
199#define OSPFAREAAGGREGATEEFFECT 6
200
201/* SYNTAX Status from OSPF-MIB. */
202#define OSPF_STATUS_ENABLED 1
203#define OSPF_STATUS_DISABLED 2
204
205/* SNMP value hack. */
206#define COUNTER ASN_COUNTER
207#define INTEGER ASN_INTEGER
208#define GAUGE ASN_GAUGE
209#define TIMETICKS ASN_TIMETICKS
210#define IPADDRESS ASN_IPADDRESS
211#define STRING ASN_OCTET_STR
212
213/* Declare static local variables for convenience. */
214SNMP_LOCAL_VARIABLES
215
216/* OSPF-MIB instances. */
217oid ospf_oid [] = { OSPF2MIB };
paul718e3742002-12-13 20:15:29 +0000218
219/* IP address 0.0.0.0. */
220static struct in_addr ospf_empty_addr = {0};
221
222/* Hook functions. */
223static u_char *ospfGeneralGroup ();
224static u_char *ospfAreaEntry ();
225static u_char *ospfStubAreaEntry ();
226static u_char *ospfLsdbEntry ();
227static u_char *ospfAreaRangeEntry ();
228static u_char *ospfHostEntry ();
229static u_char *ospfIfEntry ();
230static u_char *ospfIfMetricEntry ();
231static u_char *ospfVirtIfEntry ();
232static u_char *ospfNbrEntry ();
233static u_char *ospfVirtNbrEntry ();
234static u_char *ospfExtLsdbEntry ();
235static u_char *ospfAreaAggregateEntry ();
236
237struct variable ospf_variables[] =
238{
239 /* OSPF general variables */
240 {OSPFROUTERID, IPADDRESS, RWRITE, ospfGeneralGroup,
241 2, {1, 1}},
242 {OSPFADMINSTAT, INTEGER, RWRITE, ospfGeneralGroup,
243 2, {1, 2}},
244 {OSPFVERSIONNUMBER, INTEGER, RONLY, ospfGeneralGroup,
245 2, {1, 3}},
246 {OSPFAREABDRRTRSTATUS, INTEGER, RONLY, ospfGeneralGroup,
247 2, {1, 4}},
248 {OSPFASBDRRTRSTATUS, INTEGER, RWRITE, ospfGeneralGroup,
249 2, {1, 5}},
250 {OSPFEXTERNLSACOUNT, GAUGE, RONLY, ospfGeneralGroup,
251 2, {1, 6}},
252 {OSPFEXTERNLSACKSUMSUM, INTEGER, RONLY, ospfGeneralGroup,
253 2, {1, 7}},
254 {OSPFTOSSUPPORT, INTEGER, RWRITE, ospfGeneralGroup,
255 2, {1, 8}},
256 {OSPFORIGINATENEWLSAS, COUNTER, RONLY, ospfGeneralGroup,
257 2, {1, 9}},
258 {OSPFRXNEWLSAS, COUNTER, RONLY, ospfGeneralGroup,
259 2, {1, 10}},
260 {OSPFEXTLSDBLIMIT, INTEGER, RWRITE, ospfGeneralGroup,
261 2, {1, 11}},
262 {OSPFMULTICASTEXTENSIONS, INTEGER, RWRITE, ospfGeneralGroup,
263 2, {1, 12}},
264 {OSPFEXITOVERFLOWINTERVAL, INTEGER, RWRITE, ospfGeneralGroup,
265 2, {1, 13}},
266 {OSPFDEMANDEXTENSIONS, INTEGER, RWRITE, ospfGeneralGroup,
267 2, {1, 14}},
268
269 /* OSPF area data structure. */
270 {OSPFAREAID, IPADDRESS, RONLY, ospfAreaEntry,
271 3, {2, 1, 1}},
272 {OSPFAUTHTYPE, INTEGER, RWRITE, ospfAreaEntry,
273 3, {2, 1, 2}},
274 {OSPFIMPORTASEXTERN, INTEGER, RWRITE, ospfAreaEntry,
275 3, {2, 1, 3}},
276 {OSPFSPFRUNS, COUNTER, RONLY, ospfAreaEntry,
277 3, {2, 1, 4}},
278 {OSPFAREABDRRTRCOUNT, GAUGE, RONLY, ospfAreaEntry,
279 3, {2, 1, 5}},
280 {OSPFASBDRRTRCOUNT, GAUGE, RONLY, ospfAreaEntry,
281 3, {2, 1, 6}},
282 {OSPFAREALSACOUNT, GAUGE, RONLY, ospfAreaEntry,
283 3, {2, 1, 7}},
284 {OSPFAREALSACKSUMSUM, INTEGER, RONLY, ospfAreaEntry,
285 3, {2, 1, 8}},
286 {OSPFAREASUMMARY, INTEGER, RWRITE, ospfAreaEntry,
287 3, {2, 1, 9}},
288 {OSPFAREASTATUS, INTEGER, RWRITE, ospfAreaEntry,
289 3, {2, 1, 10}},
290
291 /* OSPF stub area information. */
292 {OSPFSTUBAREAID, IPADDRESS, RONLY, ospfStubAreaEntry,
293 3, {3, 1, 1}},
294 {OSPFSTUBTOS, INTEGER, RONLY, ospfStubAreaEntry,
295 3, {3, 1, 2}},
296 {OSPFSTUBMETRIC, INTEGER, RWRITE, ospfStubAreaEntry,
297 3, {3, 1, 3}},
298 {OSPFSTUBSTATUS, INTEGER, RWRITE, ospfStubAreaEntry,
299 3, {3, 1, 4}},
300 {OSPFSTUBMETRICTYPE, INTEGER, RWRITE, ospfStubAreaEntry,
301 3, {3, 1, 5}},
302
303 /* OSPF link state database. */
304 {OSPFLSDBAREAID, IPADDRESS, RONLY, ospfLsdbEntry,
305 3, {4, 1, 1}},
306 {OSPFLSDBTYPE, INTEGER, RONLY, ospfLsdbEntry,
307 3, {4, 1, 2}},
308 {OSPFLSDBLSID, IPADDRESS, RONLY, ospfLsdbEntry,
309 3, {4, 1, 3}},
310 {OSPFLSDBROUTERID, IPADDRESS, RONLY, ospfLsdbEntry,
311 3, {4, 1, 4}},
312 {OSPFLSDBSEQUENCE, INTEGER, RONLY, ospfLsdbEntry,
313 3, {4, 1, 5}},
314 {OSPFLSDBAGE, INTEGER, RONLY, ospfLsdbEntry,
315 3, {4, 1, 6}},
316 {OSPFLSDBCHECKSUM, INTEGER, RONLY, ospfLsdbEntry,
317 3, {4, 1, 7}},
318 {OSPFLSDBADVERTISEMENT, STRING, RONLY, ospfLsdbEntry,
319 3, {4, 1, 8}},
320
321 /* Area range table. */
322 {OSPFAREARANGEAREAID, IPADDRESS, RONLY, ospfAreaRangeEntry,
323 3, {5, 1, 1}},
324 {OSPFAREARANGENET, IPADDRESS, RONLY, ospfAreaRangeEntry,
325 3, {5, 1, 2}},
326 {OSPFAREARANGEMASK, IPADDRESS, RWRITE, ospfAreaRangeEntry,
327 3, {5, 1, 3}},
328 {OSPFAREARANGESTATUS, INTEGER, RWRITE, ospfAreaRangeEntry,
329 3, {5, 1, 4}},
330 {OSPFAREARANGEEFFECT, INTEGER, RWRITE, ospfAreaRangeEntry,
331 3, {5, 1, 5}},
332
333 /* OSPF host table. */
334 {OSPFHOSTIPADDRESS, IPADDRESS, RONLY, ospfHostEntry,
335 3, {6, 1, 1}},
336 {OSPFHOSTTOS, INTEGER, RONLY, ospfHostEntry,
337 3, {6, 1, 2}},
338 {OSPFHOSTMETRIC, INTEGER, RWRITE, ospfHostEntry,
339 3, {6, 1, 3}},
340 {OSPFHOSTSTATUS, INTEGER, RWRITE, ospfHostEntry,
341 3, {6, 1, 4}},
342 {OSPFHOSTAREAID, IPADDRESS, RONLY, ospfHostEntry,
343 3, {6, 1, 5}},
344
345 /* OSPF interface table. */
346 {OSPFIFIPADDRESS, IPADDRESS, RONLY, ospfIfEntry,
347 3, {7, 1, 1}},
348 {OSPFADDRESSLESSIF, INTEGER, RONLY, ospfIfEntry,
349 3, {7, 1, 2}},
350 {OSPFIFAREAID, IPADDRESS, RWRITE, ospfIfEntry,
351 3, {7, 1, 3}},
352 {OSPFIFTYPE, INTEGER, RWRITE, ospfIfEntry,
353 3, {7, 1, 4}},
354 {OSPFIFADMINSTAT, INTEGER, RWRITE, ospfIfEntry,
355 3, {7, 1, 5}},
356 {OSPFIFRTRPRIORITY, INTEGER, RWRITE, ospfIfEntry,
357 3, {7, 1, 6}},
358 {OSPFIFTRANSITDELAY, INTEGER, RWRITE, ospfIfEntry,
359 3, {7, 1, 7}},
360 {OSPFIFRETRANSINTERVAL, INTEGER, RWRITE, ospfIfEntry,
361 3, {7, 1, 8}},
362 {OSPFIFHELLOINTERVAL, INTEGER, RWRITE, ospfIfEntry,
363 3, {7, 1, 9}},
364 {OSPFIFRTRDEADINTERVAL, INTEGER, RWRITE, ospfIfEntry,
365 3, {7, 1, 10}},
366 {OSPFIFPOLLINTERVAL, INTEGER, RWRITE, ospfIfEntry,
367 3, {7, 1, 11}},
368 {OSPFIFSTATE, INTEGER, RONLY, ospfIfEntry,
369 3, {7, 1, 12}},
370 {OSPFIFDESIGNATEDROUTER, IPADDRESS, RONLY, ospfIfEntry,
371 3, {7, 1, 13}},
372 {OSPFIFBACKUPDESIGNATEDROUTER, IPADDRESS, RONLY, ospfIfEntry,
373 3, {7, 1, 14}},
374 {OSPFIFEVENTS, COUNTER, RONLY, ospfIfEntry,
375 3, {7, 1, 15}},
376 {OSPFIFAUTHKEY, STRING, RWRITE, ospfIfEntry,
377 3, {7, 1, 16}},
378 {OSPFIFSTATUS, INTEGER, RWRITE, ospfIfEntry,
379 3, {7, 1, 17}},
380 {OSPFIFMULTICASTFORWARDING, INTEGER, RWRITE, ospfIfEntry,
381 3, {7, 1, 18}},
382 {OSPFIFDEMAND, INTEGER, RWRITE, ospfIfEntry,
383 3, {7, 1, 19}},
384 {OSPFIFAUTHTYPE, INTEGER, RWRITE, ospfIfEntry,
385 3, {7, 1, 20}},
386
387 /* OSPF interface metric table. */
388 {OSPFIFMETRICIPADDRESS, IPADDRESS, RONLY, ospfIfMetricEntry,
389 3, {8, 1, 1}},
390 {OSPFIFMETRICADDRESSLESSIF, INTEGER, RONLY, ospfIfMetricEntry,
391 3, {8, 1, 2}},
392 {OSPFIFMETRICTOS, INTEGER, RONLY, ospfIfMetricEntry,
393 3, {8, 1, 3}},
394 {OSPFIFMETRICVALUE, INTEGER, RWRITE, ospfIfMetricEntry,
395 3, {8, 1, 4}},
396 {OSPFIFMETRICSTATUS, INTEGER, RWRITE, ospfIfMetricEntry,
397 3, {8, 1, 5}},
398
399 /* OSPF virtual interface table. */
400 {OSPFVIRTIFAREAID, IPADDRESS, RONLY, ospfVirtIfEntry,
401 3, {9, 1, 1}},
402 {OSPFVIRTIFNEIGHBOR, IPADDRESS, RONLY, ospfVirtIfEntry,
403 3, {9, 1, 2}},
404 {OSPFVIRTIFTRANSITDELAY, INTEGER, RWRITE, ospfVirtIfEntry,
405 3, {9, 1, 3}},
406 {OSPFVIRTIFRETRANSINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry,
407 3, {9, 1, 4}},
408 {OSPFVIRTIFHELLOINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry,
409 3, {9, 1, 5}},
410 {OSPFVIRTIFRTRDEADINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry,
411 3, {9, 1, 6}},
412 {OSPFVIRTIFSTATE, INTEGER, RONLY, ospfVirtIfEntry,
413 3, {9, 1, 7}},
414 {OSPFVIRTIFEVENTS, COUNTER, RONLY, ospfVirtIfEntry,
415 3, {9, 1, 8}},
416 {OSPFVIRTIFAUTHKEY, STRING, RWRITE, ospfVirtIfEntry,
417 3, {9, 1, 9}},
418 {OSPFVIRTIFSTATUS, INTEGER, RWRITE, ospfVirtIfEntry,
419 3, {9, 1, 10}},
420 {OSPFVIRTIFAUTHTYPE, INTEGER, RWRITE, ospfVirtIfEntry,
421 3, {9, 1, 11}},
422
423 /* OSPF neighbor table. */
424 {OSPFNBRIPADDR, IPADDRESS, RONLY, ospfNbrEntry,
425 3, {10, 1, 1}},
426 {OSPFNBRADDRESSLESSINDEX, INTEGER, RONLY, ospfNbrEntry,
427 3, {10, 1, 2}},
428 {OSPFNBRRTRID, IPADDRESS, RONLY, ospfNbrEntry,
429 3, {10, 1, 3}},
430 {OSPFNBROPTIONS, INTEGER, RONLY, ospfNbrEntry,
431 3, {10, 1, 4}},
432 {OSPFNBRPRIORITY, INTEGER, RWRITE, ospfNbrEntry,
433 3, {10, 1, 5}},
434 {OSPFNBRSTATE, INTEGER, RONLY, ospfNbrEntry,
435 3, {10, 1, 6}},
436 {OSPFNBREVENTS, COUNTER, RONLY, ospfNbrEntry,
437 3, {10, 1, 7}},
438 {OSPFNBRLSRETRANSQLEN, GAUGE, RONLY, ospfNbrEntry,
439 3, {10, 1, 8}},
440 {OSPFNBMANBRSTATUS, INTEGER, RWRITE, ospfNbrEntry,
441 3, {10, 1, 9}},
442 {OSPFNBMANBRPERMANENCE, INTEGER, RONLY, ospfNbrEntry,
443 3, {10, 1, 10}},
444 {OSPFNBRHELLOSUPPRESSED, INTEGER, RONLY, ospfNbrEntry,
445 3, {10, 1, 11}},
446
447 /* OSPF virtual neighbor table. */
448 {OSPFVIRTNBRAREA, IPADDRESS, RONLY, ospfVirtNbrEntry,
449 3, {11, 1, 1}},
450 {OSPFVIRTNBRRTRID, IPADDRESS, RONLY, ospfVirtNbrEntry,
451 3, {11, 1, 2}},
452 {OSPFVIRTNBRIPADDR, IPADDRESS, RONLY, ospfVirtNbrEntry,
453 3, {11, 1, 3}},
454 {OSPFVIRTNBROPTIONS, INTEGER, RONLY, ospfVirtNbrEntry,
455 3, {11, 1, 4}},
456 {OSPFVIRTNBRSTATE, INTEGER, RONLY, ospfVirtNbrEntry,
457 3, {11, 1, 5}},
458 {OSPFVIRTNBREVENTS, COUNTER, RONLY, ospfVirtNbrEntry,
459 3, {11, 1, 6}},
460 {OSPFVIRTNBRLSRETRANSQLEN, INTEGER, RONLY, ospfVirtNbrEntry,
461 3, {11, 1, 7}},
462 {OSPFVIRTNBRHELLOSUPPRESSED, INTEGER, RONLY, ospfVirtNbrEntry,
463 3, {11, 1, 8}},
464
465 /* OSPF link state database, external. */
466 {OSPFEXTLSDBTYPE, INTEGER, RONLY, ospfExtLsdbEntry,
467 3, {12, 1, 1}},
468 {OSPFEXTLSDBLSID, IPADDRESS, RONLY, ospfExtLsdbEntry,
469 3, {12, 1, 2}},
470 {OSPFEXTLSDBROUTERID, IPADDRESS, RONLY, ospfExtLsdbEntry,
471 3, {12, 1, 3}},
472 {OSPFEXTLSDBSEQUENCE, INTEGER, RONLY, ospfExtLsdbEntry,
473 3, {12, 1, 4}},
474 {OSPFEXTLSDBAGE, INTEGER, RONLY, ospfExtLsdbEntry,
475 3, {12, 1, 5}},
476 {OSPFEXTLSDBCHECKSUM, INTEGER, RONLY, ospfExtLsdbEntry,
477 3, {12, 1, 6}},
478 {OSPFEXTLSDBADVERTISEMENT, STRING, RONLY, ospfExtLsdbEntry,
479 3, {12, 1, 7}},
480
481 /* OSPF area aggregate table. */
482 {OSPFAREAAGGREGATEAREAID, IPADDRESS, RONLY, ospfAreaAggregateEntry,
483 3, {14, 1, 1}},
484 {OSPFAREAAGGREGATELSDBTYPE, INTEGER, RONLY, ospfAreaAggregateEntry,
485 3, {14, 1, 2}},
486 {OSPFAREAAGGREGATENET, IPADDRESS, RONLY, ospfAreaAggregateEntry,
487 3, {14, 1, 3}},
488 {OSPFAREAAGGREGATEMASK, IPADDRESS, RONLY, ospfAreaAggregateEntry,
489 3, {14, 1, 4}},
490 {OSPFAREAAGGREGATESTATUS, INTEGER, RWRITE, ospfAreaAggregateEntry,
491 3, {14, 1, 5}},
492 {OSPFAREAAGGREGATEEFFECT, INTEGER, RWRITE, ospfAreaAggregateEntry,
493 3, {14, 1, 6}}
494};
495
496/* The administrative status of OSPF. When OSPF is enbled on at least
497 one interface return 1. */
498int
paul68980082003-03-25 05:07:42 +0000499ospf_admin_stat (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +0000500{
paulaa20c6f2004-10-07 14:19:36 +0000501 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000502 struct ospf_interface *oi;
503
paul68980082003-03-25 05:07:42 +0000504 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +0000505 return 0;
506
paul1eb8ef22005-04-07 07:30:20 +0000507 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
508 if (oi && oi->address)
509 return 1;
paul718e3742002-12-13 20:15:29 +0000510
paul718e3742002-12-13 20:15:29 +0000511 return 0;
512}
513
514static u_char *
515ospfGeneralGroup (struct variable *v, oid *name, size_t *length,
516 int exact, size_t *var_len, WriteMethod **write_method)
517{
paul020709f2003-04-04 02:44:16 +0000518 struct ospf *ospf;
519
520 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +0000521
paul718e3742002-12-13 20:15:29 +0000522 /* Check whether the instance identifier is valid */
523 if (smux_header_generic (v, name, length, exact, var_len, write_method)
524 == MATCH_FAILED)
525 return NULL;
526
527 /* Return the current value of the variable */
528 switch (v->magic)
529 {
530 case OSPFROUTERID: /* 1 */
531 /* Router-ID of this OSPF instance. */
paul68980082003-03-25 05:07:42 +0000532 if (ospf)
533 return SNMP_IPADDRESS (ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000534 else
535 return SNMP_IPADDRESS (ospf_empty_addr);
536 break;
537 case OSPFADMINSTAT: /* 2 */
538 /* The administrative status of OSPF in the router. */
paul68980082003-03-25 05:07:42 +0000539 if (ospf_admin_stat (ospf))
paul718e3742002-12-13 20:15:29 +0000540 return SNMP_INTEGER (OSPF_STATUS_ENABLED);
541 else
542 return SNMP_INTEGER (OSPF_STATUS_DISABLED);
543 break;
544 case OSPFVERSIONNUMBER: /* 3 */
545 /* OSPF version 2. */
546 return SNMP_INTEGER (OSPF_VERSION);
547 break;
548 case OSPFAREABDRRTRSTATUS: /* 4 */
549 /* Area Border router status. */
paul68980082003-03-25 05:07:42 +0000550 if (ospf && CHECK_FLAG (ospf->flags, OSPF_FLAG_ABR))
paul718e3742002-12-13 20:15:29 +0000551 return SNMP_INTEGER (SNMP_TRUE);
552 else
553 return SNMP_INTEGER (SNMP_FALSE);
554 break;
555 case OSPFASBDRRTRSTATUS: /* 5 */
556 /* AS Border router status. */
paul68980082003-03-25 05:07:42 +0000557 if (ospf && CHECK_FLAG (ospf->flags, OSPF_FLAG_ASBR))
paul718e3742002-12-13 20:15:29 +0000558 return SNMP_INTEGER (SNMP_TRUE);
559 else
560 return SNMP_INTEGER (SNMP_FALSE);
561 break;
562 case OSPFEXTERNLSACOUNT: /* 6 */
563 /* External LSA counts. */
paul68980082003-03-25 05:07:42 +0000564 if (ospf)
565 return SNMP_INTEGER (ospf_lsdb_count_all (ospf->lsdb));
paul718e3742002-12-13 20:15:29 +0000566 else
567 return SNMP_INTEGER (0);
568 break;
569 case OSPFEXTERNLSACKSUMSUM: /* 7 */
570 /* External LSA checksum. */
571 return SNMP_INTEGER (0);
572 break;
573 case OSPFTOSSUPPORT: /* 8 */
574 /* TOS is not supported. */
575 return SNMP_INTEGER (SNMP_FALSE);
576 break;
577 case OSPFORIGINATENEWLSAS: /* 9 */
578 /* The number of new link-state advertisements. */
paul68980082003-03-25 05:07:42 +0000579 if (ospf)
580 return SNMP_INTEGER (ospf->lsa_originate_count);
paul718e3742002-12-13 20:15:29 +0000581 else
582 return SNMP_INTEGER (0);
583 break;
584 case OSPFRXNEWLSAS: /* 10 */
585 /* The number of link-state advertisements received determined
586 to be new instantiations. */
paul68980082003-03-25 05:07:42 +0000587 if (ospf)
588 return SNMP_INTEGER (ospf->rx_lsa_count);
paul718e3742002-12-13 20:15:29 +0000589 else
590 return SNMP_INTEGER (0);
591 break;
592 case OSPFEXTLSDBLIMIT: /* 11 */
593 /* There is no limit for the number of non-default
594 AS-external-LSAs. */
595 return SNMP_INTEGER (-1);
596 break;
597 case OSPFMULTICASTEXTENSIONS: /* 12 */
598 /* Multicast Extensions to OSPF is not supported. */
599 return SNMP_INTEGER (0);
600 break;
601 case OSPFEXITOVERFLOWINTERVAL: /* 13 */
602 /* Overflow is not supported. */
603 return SNMP_INTEGER (0);
604 break;
605 case OSPFDEMANDEXTENSIONS: /* 14 */
606 /* Demand routing is not supported. */
607 return SNMP_INTEGER (SNMP_FALSE);
608 break;
609 default:
610 return NULL;
611 }
612 return NULL;
613}
614
615struct ospf_area *
paul68980082003-03-25 05:07:42 +0000616ospf_area_lookup_next (struct ospf *ospf, struct in_addr *area_id, int first)
paul718e3742002-12-13 20:15:29 +0000617{
618 struct ospf_area *area;
paulaa20c6f2004-10-07 14:19:36 +0000619 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000620
paul020709f2003-04-04 02:44:16 +0000621 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +0000622 return NULL;
623
624 if (first)
625 {
paul68980082003-03-25 05:07:42 +0000626 node = listhead (ospf->areas);
paul718e3742002-12-13 20:15:29 +0000627 if (node)
628 {
paul1eb8ef22005-04-07 07:30:20 +0000629 area = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000630 *area_id = area->area_id;
631 return area;
632 }
633 return NULL;
634 }
paul1eb8ef22005-04-07 07:30:20 +0000635 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
paul718e3742002-12-13 20:15:29 +0000636 {
paul718e3742002-12-13 20:15:29 +0000637 if (ntohl (area->area_id.s_addr) > ntohl (area_id->s_addr))
638 {
639 *area_id = area->area_id;
640 return area;
641 }
642 }
643 return NULL;
644}
645
646struct ospf_area *
647ospfAreaLookup (struct variable *v, oid name[], size_t *length,
648 struct in_addr *addr, int exact)
649{
paul020709f2003-04-04 02:44:16 +0000650 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000651 struct ospf_area *area;
paul68980082003-03-25 05:07:42 +0000652 int len;
paul718e3742002-12-13 20:15:29 +0000653
paul020709f2003-04-04 02:44:16 +0000654 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +0000655 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +0000656 return NULL;
657
658 if (exact)
659 {
660 /* Length is insufficient to lookup OSPF area. */
661 if (*length - v->namelen != sizeof (struct in_addr))
662 return NULL;
663
664 oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr);
665
paul68980082003-03-25 05:07:42 +0000666 area = ospf_area_lookup_by_area_id (ospf, *addr);
paul718e3742002-12-13 20:15:29 +0000667
668 return area;
669 }
670 else
671 {
672 len = *length - v->namelen;
673 if (len > 4)
674 len = 4;
675
676 oid2in_addr (name + v->namelen, len, addr);
677
paul68980082003-03-25 05:07:42 +0000678 area = ospf_area_lookup_next (ospf, addr, len == 0 ? 1 : 0);
paul718e3742002-12-13 20:15:29 +0000679
680 if (area == NULL)
681 return NULL;
682
683 oid_copy_addr (name + v->namelen, addr, sizeof (struct in_addr));
684 *length = sizeof (struct in_addr) + v->namelen;
685
686 return area;
687 }
688 return NULL;
689}
690
691static u_char *
692ospfAreaEntry (struct variable *v, oid *name, size_t *length, int exact,
693 size_t *var_len, WriteMethod **write_method)
694{
695 struct ospf_area *area;
696 struct in_addr addr;
697
698 memset (&addr, 0, sizeof (struct in_addr));
699
700 area = ospfAreaLookup (v, name, length, &addr, exact);
701 if (! area)
702 return NULL;
703
704 /* Return the current value of the variable */
705 switch (v->magic)
706 {
707 case OSPFAREAID: /* 1 */
708 return SNMP_IPADDRESS (area->area_id);
709 break;
710 case OSPFAUTHTYPE: /* 2 */
711 return SNMP_INTEGER (area->auth_type);
712 break;
713 case OSPFIMPORTASEXTERN: /* 3 */
714 return SNMP_INTEGER (area->external_routing + 1);
715 break;
716 case OSPFSPFRUNS: /* 4 */
717 return SNMP_INTEGER (area->spf_calculation);
718 break;
719 case OSPFAREABDRRTRCOUNT: /* 5 */
720 return SNMP_INTEGER (area->abr_count);
721 break;
722 case OSPFASBDRRTRCOUNT: /* 6 */
723 return SNMP_INTEGER (area->asbr_count);
724 break;
725 case OSPFAREALSACOUNT: /* 7 */
726 return SNMP_INTEGER (area->lsdb->total);
727 break;
728 case OSPFAREALSACKSUMSUM: /* 8 */
729 return SNMP_INTEGER (0);
730 break;
731 case OSPFAREASUMMARY: /* 9 */
732#define OSPF_noAreaSummary 1
733#define OSPF_sendAreaSummary 2
734 if (area->no_summary)
735 return SNMP_INTEGER (OSPF_noAreaSummary);
736 else
737 return SNMP_INTEGER (OSPF_sendAreaSummary);
738 break;
739 case OSPFAREASTATUS: /* 10 */
740 return SNMP_INTEGER (SNMP_VALID);
741 break;
742 default:
743 return NULL;
744 break;
745 }
746 return NULL;
747}
748
749struct ospf_area *
750ospf_stub_area_lookup_next (struct in_addr *area_id, int first)
751{
752 struct ospf_area *area;
paulaa20c6f2004-10-07 14:19:36 +0000753 struct listnode *node;
paul020709f2003-04-04 02:44:16 +0000754 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000755
paul020709f2003-04-04 02:44:16 +0000756 ospf = ospf_lookup ();
757 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +0000758 return NULL;
759
paul1eb8ef22005-04-07 07:30:20 +0000760 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
paul718e3742002-12-13 20:15:29 +0000761 {
paul718e3742002-12-13 20:15:29 +0000762 if (area->external_routing == OSPF_AREA_STUB)
763 {
764 if (first)
765 {
766 *area_id = area->area_id;
767 return area;
768 }
769 else if (ntohl (area->area_id.s_addr) > ntohl (area_id->s_addr))
770 {
771 *area_id = area->area_id;
772 return area;
773 }
774 }
775 }
776 return NULL;
777}
778
779struct ospf_area *
780ospfStubAreaLookup (struct variable *v, oid name[], size_t *length,
781 struct in_addr *addr, int exact)
782{
paul020709f2003-04-04 02:44:16 +0000783 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000784 struct ospf_area *area;
paul68980082003-03-25 05:07:42 +0000785 int len;
paul718e3742002-12-13 20:15:29 +0000786
paul020709f2003-04-04 02:44:16 +0000787 ospf = ospf_lookup ();
788 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +0000789 return NULL;
790
791 /* Exact lookup. */
792 if (exact)
793 {
794 /* ospfStubAreaID + ospfStubTOS. */
795 if (*length != v->namelen + sizeof (struct in_addr) + 1)
796 return NULL;
797
798 /* Check ospfStubTOS is zero. */
799 if (name[*length - 1] != 0)
800 return NULL;
801
802 oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr);
803
paul68980082003-03-25 05:07:42 +0000804 area = ospf_area_lookup_by_area_id (ospf, *addr);
paul718e3742002-12-13 20:15:29 +0000805
806 if (area->external_routing == OSPF_AREA_STUB)
807 return area;
808 else
809 return NULL;
810 }
811 else
812 {
813 len = *length - v->namelen;
814 if (len > 4)
815 len = 4;
816
817 oid2in_addr (name + v->namelen, len, addr);
818
819 area = ospf_stub_area_lookup_next (addr, len == 0 ? 1 : 0);
820
821 if (area == NULL)
822 return NULL;
823
824 oid_copy_addr (name + v->namelen, addr, sizeof (struct in_addr));
825 /* Set TOS 0. */
826 name[v->namelen + sizeof (struct in_addr)] = 0;
827 *length = v->namelen + sizeof (struct in_addr) + 1;
828
829 return area;
830 }
831 return NULL;
832}
833
834static u_char *
835ospfStubAreaEntry (struct variable *v, oid *name, size_t *length,
836 int exact, size_t *var_len, WriteMethod **write_method)
837{
838 struct ospf_area *area;
839 struct in_addr addr;
840
841 memset (&addr, 0, sizeof (struct in_addr));
842
843 area = ospfStubAreaLookup (v, name, length, &addr, exact);
844 if (! area)
845 return NULL;
846
847 /* Return the current value of the variable */
848 switch (v->magic)
849 {
850 case OSPFSTUBAREAID: /* 1 */
851 /* OSPF stub area id. */
852 return SNMP_IPADDRESS (area->area_id);
853 break;
854 case OSPFSTUBTOS: /* 2 */
855 /* TOS value is not supported. */
856 return SNMP_INTEGER (0);
857 break;
858 case OSPFSTUBMETRIC: /* 3 */
859 /* Default cost to stub area. */
860 return SNMP_INTEGER (area->default_cost);
861 break;
862 case OSPFSTUBSTATUS: /* 4 */
863 /* Status of the stub area. */
864 return SNMP_INTEGER (SNMP_VALID);
865 break;
866 case OSPFSTUBMETRICTYPE: /* 5 */
867 /* OSPF Metric type. */
868#define OSPF_ospfMetric 1
869#define OSPF_comparableCost 2
870#define OSPF_nonComparable 3
871 return SNMP_INTEGER (OSPF_ospfMetric);
872 break;
873 default:
874 return NULL;
875 break;
876 }
877 return NULL;
878}
879
880struct ospf_lsa *
881lsdb_lookup_next (struct ospf_area *area, u_char *type, int type_next,
882 struct in_addr *ls_id, int ls_id_next,
883 struct in_addr *router_id, int router_id_next)
884{
885 struct ospf_lsa *lsa;
886 int i;
887
888 if (type_next)
889 i = OSPF_MIN_LSA;
890 else
891 i = *type;
892
vincentba682532005-09-29 13:52:57 +0000893 /* Sanity check, if LSA type unknwon
894 merley skip any LSA */
895 if ((i < OSPF_MIN_LSA) || (i >= OSPF_MAX_LSA))
896 {
897 zlog_debug("Strange request with LSA type %d\n", i);
898 return NULL;
899 }
900
paul718e3742002-12-13 20:15:29 +0000901 for (; i < OSPF_MAX_LSA; i++)
902 {
903 *type = i;
904
905 lsa = ospf_lsdb_lookup_by_id_next (area->lsdb, *type, *ls_id, *router_id,
906 ls_id_next);
907 if (lsa)
908 return lsa;
909
910 ls_id_next = 1;
911 }
912 return NULL;
913}
914
915struct ospf_lsa *
916ospfLsdbLookup (struct variable *v, oid *name, size_t *length,
917 struct in_addr *area_id, u_char *type,
918 struct in_addr *ls_id, struct in_addr *router_id, int exact)
919{
paul020709f2003-04-04 02:44:16 +0000920 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000921 struct ospf_area *area;
922 struct ospf_lsa *lsa;
paul6c835672004-10-11 11:00:30 +0000923 unsigned int len;
paul718e3742002-12-13 20:15:29 +0000924 int type_next;
925 int ls_id_next;
926 int router_id_next;
927 oid *offset;
928 int offsetlen;
929
paul020709f2003-04-04 02:44:16 +0000930 ospf = ospf_lookup ();
931
paul718e3742002-12-13 20:15:29 +0000932#define OSPF_LSDB_ENTRY_OFFSET \
933 (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
934
935 if (exact)
936 {
937 /* Area ID + Type + LS ID + Router ID. */
938 if (*length - v->namelen != OSPF_LSDB_ENTRY_OFFSET)
939 return NULL;
940
941 /* Set OID offset for Area ID. */
942 offset = name + v->namelen;
943
944 /* Lookup area first. */
945 oid2in_addr (offset, IN_ADDR_SIZE, area_id);
paul68980082003-03-25 05:07:42 +0000946 area = ospf_area_lookup_by_area_id (ospf, *area_id);
paul718e3742002-12-13 20:15:29 +0000947 if (! area)
948 return NULL;
949 offset += IN_ADDR_SIZE;
950
951 /* Type. */
952 *type = *offset;
953 offset++;
954
955 /* LS ID. */
956 oid2in_addr (offset, IN_ADDR_SIZE, ls_id);
957 offset += IN_ADDR_SIZE;
958
959 /* Router ID. */
960 oid2in_addr (offset, IN_ADDR_SIZE, router_id);
961
962 /* Lookup LSDB. */
963 return ospf_lsdb_lookup_by_id (area->lsdb, *type, *ls_id, *router_id);
964 }
965 else
966 {
967 /* Get variable length. */
968 offset = name + v->namelen;
969 offsetlen = *length - v->namelen;
970 len = offsetlen;
971
972 if (len > IN_ADDR_SIZE)
973 len = IN_ADDR_SIZE;
974
975 oid2in_addr (offset, len, area_id);
976
977 /* First we search area. */
978 if (len == IN_ADDR_SIZE)
paul68980082003-03-25 05:07:42 +0000979 area = ospf_area_lookup_by_area_id (ospf, *area_id);
paul718e3742002-12-13 20:15:29 +0000980 else
paul68980082003-03-25 05:07:42 +0000981 area = ospf_area_lookup_next (ospf, area_id, len == 0 ? 1 : 0);
paul718e3742002-12-13 20:15:29 +0000982
983 if (area == NULL)
984 return NULL;
985
986 do
987 {
988 /* Next we lookup type. */
989 offset += IN_ADDR_SIZE;
990 offsetlen -= IN_ADDR_SIZE;
991 len = offsetlen;
992
993 if (len <= 0)
994 type_next = 1;
995 else
996 {
997 len = 1;
998 type_next = 0;
999 *type = *offset;
1000 }
1001
1002 /* LS ID. */
1003 offset++;
1004 offsetlen--;
1005 len = offsetlen;
1006
1007 if (len <= 0)
1008 ls_id_next = 1;
1009 else
1010 {
1011 ls_id_next = 0;
1012 if (len > IN_ADDR_SIZE)
1013 len = IN_ADDR_SIZE;
1014
1015 oid2in_addr (offset, len, ls_id);
1016 }
1017
1018 /* Router ID. */
1019 offset += IN_ADDR_SIZE;
1020 offsetlen -= IN_ADDR_SIZE;
1021 len = offsetlen;
1022
1023 if (len <= 0)
1024 router_id_next = 1;
1025 else
1026 {
1027 router_id_next = 0;
1028 if (len > IN_ADDR_SIZE)
1029 len = IN_ADDR_SIZE;
1030
1031 oid2in_addr (offset, len, router_id);
1032 }
1033
1034 lsa = lsdb_lookup_next (area, type, type_next, ls_id, ls_id_next,
1035 router_id, router_id_next);
1036
1037 if (lsa)
1038 {
1039 /* Fill in length. */
1040 *length = v->namelen + OSPF_LSDB_ENTRY_OFFSET;
1041
1042 /* Fill in value. */
1043 offset = name + v->namelen;
1044 oid_copy_addr (offset, area_id, IN_ADDR_SIZE);
1045 offset += IN_ADDR_SIZE;
1046 *offset = lsa->data->type;
1047 offset++;
1048 oid_copy_addr (offset, &lsa->data->id, IN_ADDR_SIZE);
1049 offset += IN_ADDR_SIZE;
1050 oid_copy_addr (offset, &lsa->data->adv_router, IN_ADDR_SIZE);
1051
1052 return lsa;
1053 }
1054 }
paul68980082003-03-25 05:07:42 +00001055 while ((area = ospf_area_lookup_next (ospf, area_id, 0)) != NULL);
paul718e3742002-12-13 20:15:29 +00001056 }
1057 return NULL;
1058}
1059
1060static u_char *
1061ospfLsdbEntry (struct variable *v, oid *name, size_t *length, int exact,
1062 size_t *var_len, WriteMethod **write_method)
1063{
1064 struct ospf_lsa *lsa;
1065 struct lsa_header *lsah;
1066 struct in_addr area_id;
1067 u_char type;
1068 struct in_addr ls_id;
1069 struct in_addr router_id;
paul020709f2003-04-04 02:44:16 +00001070 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001071
1072 /* INDEX { ospfLsdbAreaId, ospfLsdbType,
1073 ospfLsdbLsid, ospfLsdbRouterId } */
1074
1075 memset (&area_id, 0, sizeof (struct in_addr));
1076 type = 0;
1077 memset (&ls_id, 0, sizeof (struct in_addr));
1078 memset (&router_id, 0, sizeof (struct in_addr));
1079
1080 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00001081 ospf = ospf_lookup ();
1082 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001083 return NULL;
1084
1085 lsa = ospfLsdbLookup (v, name, length, &area_id, &type, &ls_id, &router_id,
1086 exact);
1087 if (! lsa)
1088 return NULL;
1089
1090 lsah = lsa->data;
1091
1092 /* Return the current value of the variable */
1093 switch (v->magic)
1094 {
1095 case OSPFLSDBAREAID: /* 1 */
1096 return SNMP_IPADDRESS (lsa->area->area_id);
1097 break;
1098 case OSPFLSDBTYPE: /* 2 */
1099 return SNMP_INTEGER (lsah->type);
1100 break;
1101 case OSPFLSDBLSID: /* 3 */
1102 return SNMP_IPADDRESS (lsah->id);
1103 break;
1104 case OSPFLSDBROUTERID: /* 4 */
1105 return SNMP_IPADDRESS (lsah->adv_router);
1106 break;
1107 case OSPFLSDBSEQUENCE: /* 5 */
1108 return SNMP_INTEGER (lsah->ls_seqnum);
1109 break;
1110 case OSPFLSDBAGE: /* 6 */
1111 return SNMP_INTEGER (lsah->ls_age);
1112 break;
1113 case OSPFLSDBCHECKSUM: /* 7 */
1114 return SNMP_INTEGER (lsah->checksum);
1115 break;
1116 case OSPFLSDBADVERTISEMENT: /* 8 */
1117 *var_len = ntohs (lsah->length);
1118 return (u_char *) lsah;
1119 break;
1120 default:
1121 return NULL;
1122 break;
1123 }
1124 return NULL;
1125}
1126
1127struct ospf_area_range *
1128ospfAreaRangeLookup (struct variable *v, oid *name, size_t *length,
1129 struct in_addr *area_id, struct in_addr *range_net,
1130 int exact)
1131{
1132 oid *offset;
1133 int offsetlen;
paul6c835672004-10-11 11:00:30 +00001134 unsigned int len;
paul020709f2003-04-04 02:44:16 +00001135 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001136 struct ospf_area *area;
1137 struct ospf_area_range *range;
1138 struct prefix_ipv4 p;
1139 p.family = AF_INET;
1140 p.prefixlen = IPV4_MAX_BITLEN;
1141
paul020709f2003-04-04 02:44:16 +00001142 ospf = ospf_lookup ();
1143
paul718e3742002-12-13 20:15:29 +00001144 if (exact)
1145 {
1146 /* Area ID + Range Network. */
1147 if (v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE != *length)
1148 return NULL;
1149
1150 /* Set OID offset for Area ID. */
1151 offset = name + v->namelen;
1152
1153 /* Lookup area first. */
1154 oid2in_addr (offset, IN_ADDR_SIZE, area_id);
1155
paul68980082003-03-25 05:07:42 +00001156 area = ospf_area_lookup_by_area_id (ospf, *area_id);
paul718e3742002-12-13 20:15:29 +00001157 if (! area)
1158 return NULL;
1159
1160 offset += IN_ADDR_SIZE;
1161
1162 /* Lookup area range. */
1163 oid2in_addr (offset, IN_ADDR_SIZE, range_net);
1164 p.prefix = *range_net;
1165
1166 return ospf_area_range_lookup (area, &p);
1167 }
1168 else
1169 {
1170 /* Set OID offset for Area ID. */
1171 offset = name + v->namelen;
1172 offsetlen = *length - v->namelen;
1173
1174 len = offsetlen;
1175 if (len > IN_ADDR_SIZE)
1176 len = IN_ADDR_SIZE;
1177
1178 oid2in_addr (offset, len, area_id);
1179
1180 /* First we search area. */
1181 if (len == IN_ADDR_SIZE)
paul68980082003-03-25 05:07:42 +00001182 area = ospf_area_lookup_by_area_id (ospf,*area_id);
paul718e3742002-12-13 20:15:29 +00001183 else
paul68980082003-03-25 05:07:42 +00001184 area = ospf_area_lookup_next (ospf, area_id, len == 0 ? 1 : 0);
paul718e3742002-12-13 20:15:29 +00001185
1186 if (area == NULL)
1187 return NULL;
1188
1189 do
1190 {
1191 offset += IN_ADDR_SIZE;
1192 offsetlen -= IN_ADDR_SIZE;
1193 len = offsetlen;
1194
1195 if (len < 0)
1196 len = 0;
1197 if (len > IN_ADDR_SIZE)
1198 len = IN_ADDR_SIZE;
1199
1200 oid2in_addr (offset, len, range_net);
1201
1202 range = ospf_area_range_lookup_next (area, range_net,
1203 len == 0 ? 1 : 0);
1204
1205 if (range)
1206 {
1207 /* Fill in length. */
1208 *length = v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE;
1209
1210 /* Fill in value. */
1211 offset = name + v->namelen;
1212 oid_copy_addr (offset, area_id, IN_ADDR_SIZE);
1213 offset += IN_ADDR_SIZE;
1214 oid_copy_addr (offset, range_net, IN_ADDR_SIZE);
1215
1216 return range;
1217 }
1218 }
paul68980082003-03-25 05:07:42 +00001219 while ((area = ospf_area_lookup_next (ospf, area_id, 0)) != NULL);
paul718e3742002-12-13 20:15:29 +00001220 }
1221 return NULL;
1222}
1223
1224static u_char *
1225ospfAreaRangeEntry (struct variable *v, oid *name, size_t *length, int exact,
1226 size_t *var_len, WriteMethod **write_method)
1227{
1228 struct ospf_area_range *range;
1229 struct in_addr area_id;
1230 struct in_addr range_net;
1231 struct in_addr mask;
paul020709f2003-04-04 02:44:16 +00001232 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001233
1234 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00001235 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00001236 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001237 return NULL;
1238
1239 memset (&area_id, 0, IN_ADDR_SIZE);
1240 memset (&range_net, 0, IN_ADDR_SIZE);
1241
1242 range = ospfAreaRangeLookup (v, name, length, &area_id, &range_net, exact);
1243 if (! range)
1244 return NULL;
1245
1246 /* Convert prefixlen to network mask format. */
1247 masklen2ip (range->subst_masklen, &mask);
1248
1249 /* Return the current value of the variable */
1250 switch (v->magic)
1251 {
1252 case OSPFAREARANGEAREAID: /* 1 */
1253 return SNMP_IPADDRESS (area_id);
1254 break;
1255 case OSPFAREARANGENET: /* 2 */
1256 return SNMP_IPADDRESS (range_net);
1257 break;
1258 case OSPFAREARANGEMASK: /* 3 */
1259 return SNMP_IPADDRESS (mask);
1260 break;
1261 case OSPFAREARANGESTATUS: /* 4 */
1262 return SNMP_INTEGER (SNMP_VALID);
1263 break;
1264 case OSPFAREARANGEEFFECT: /* 5 */
1265#define OSPF_advertiseMatching 1
1266#define OSPF_doNotAdvertiseMatching 2
1267 return SNMP_INTEGER (OSPF_advertiseMatching);
1268 break;
1269 default:
1270 return NULL;
1271 break;
1272 }
1273 return NULL;
1274}
1275
1276struct ospf_nbr_nbma *
1277ospfHostLookup (struct variable *v, oid *name, size_t *length,
1278 struct in_addr *addr, int exact)
1279{
1280 int len;
1281 struct ospf_nbr_nbma *nbr_nbma;
paul020709f2003-04-04 02:44:16 +00001282 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001283
paul020709f2003-04-04 02:44:16 +00001284 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00001285 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001286 return NULL;
1287
1288 if (exact)
1289 {
1290 /* INDEX { ospfHostIpAddress, ospfHostTOS } */
1291 if (*length != v->namelen + IN_ADDR_SIZE + 1)
1292 return NULL;
1293
1294 /* Check ospfHostTOS. */
1295 if (name[*length - 1] != 0)
1296 return NULL;
1297
1298 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, addr);
1299
paul68980082003-03-25 05:07:42 +00001300 nbr_nbma = ospf_nbr_nbma_lookup (ospf, *addr);
paul718e3742002-12-13 20:15:29 +00001301
1302 return nbr_nbma;
1303 }
1304 else
1305 {
1306 len = *length - v->namelen;
1307 if (len > 4)
1308 len = 4;
1309
1310 oid2in_addr (name + v->namelen, len, addr);
1311
paul68980082003-03-25 05:07:42 +00001312 nbr_nbma = ospf_nbr_nbma_lookup_next (ospf, addr, len == 0 ? 1 : 0);
paul718e3742002-12-13 20:15:29 +00001313
1314 if (nbr_nbma == NULL)
1315 return NULL;
1316
1317 oid_copy_addr (name + v->namelen, addr, IN_ADDR_SIZE);
1318
1319 /* Set TOS 0. */
1320 name[v->namelen + IN_ADDR_SIZE] = 0;
1321
1322 *length = v->namelen + IN_ADDR_SIZE + 1;
1323
1324 return nbr_nbma;
1325 }
1326 return NULL;
1327}
1328
1329static u_char *
1330ospfHostEntry (struct variable *v, oid *name, size_t *length, int exact,
1331 size_t *var_len, WriteMethod **write_method)
1332{
1333 struct ospf_nbr_nbma *nbr_nbma;
1334 struct ospf_interface *oi;
1335 struct in_addr addr;
paul020709f2003-04-04 02:44:16 +00001336 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001337
1338 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00001339 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00001340 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001341 return NULL;
1342
1343 memset (&addr, 0, sizeof (struct in_addr));
1344
1345 nbr_nbma = ospfHostLookup (v, name, length, &addr, exact);
1346 if (nbr_nbma == NULL)
1347 return NULL;
1348
1349 oi = nbr_nbma->oi;
1350
1351 /* Return the current value of the variable */
1352 switch (v->magic)
1353 {
1354 case OSPFHOSTIPADDRESS: /* 1 */
1355 return SNMP_IPADDRESS (nbr_nbma->addr);
1356 break;
1357 case OSPFHOSTTOS: /* 2 */
1358 return SNMP_INTEGER (0);
1359 break;
1360 case OSPFHOSTMETRIC: /* 3 */
1361 if (oi)
1362 return SNMP_INTEGER (oi->output_cost);
1363 else
1364 return SNMP_INTEGER (1);
1365 break;
1366 case OSPFHOSTSTATUS: /* 4 */
1367 return SNMP_INTEGER (SNMP_VALID);
1368 break;
1369 case OSPFHOSTAREAID: /* 5 */
1370 if (oi && oi->area)
1371 return SNMP_IPADDRESS (oi->area->area_id);
1372 else
1373 return SNMP_IPADDRESS (ospf_empty_addr);
1374 break;
1375 default:
1376 return NULL;
1377 break;
1378 }
1379 return NULL;
1380}
1381
1382struct list *ospf_snmp_iflist;
1383
1384struct ospf_snmp_if
1385{
1386 struct in_addr addr;
1387 unsigned int ifindex;
1388 struct interface *ifp;
1389};
1390
1391struct ospf_snmp_if *
1392ospf_snmp_if_new ()
1393{
1394 struct ospf_snmp_if *osif;
1395
1396 osif = XMALLOC (0, sizeof (struct ospf_snmp_if));
1397 memset (osif, 0, sizeof (struct ospf_snmp_if));
1398 return osif;
1399}
1400
1401void
1402ospf_snmp_if_free (struct ospf_snmp_if *osif)
1403{
1404 XFREE (0, osif);
1405}
1406
1407void
1408ospf_snmp_if_delete (struct interface *ifp)
1409{
paul1eb8ef22005-04-07 07:30:20 +00001410 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001411 struct ospf_snmp_if *osif;
1412
paul1eb8ef22005-04-07 07:30:20 +00001413 for (ALL_LIST_ELEMENTS (ospf_snmp_iflist, node, nnode, osif))
paul718e3742002-12-13 20:15:29 +00001414 {
1415 if (osif->ifp == ifp)
1416 {
paul1eb8ef22005-04-07 07:30:20 +00001417 list_delete_node (ospf_snmp_iflist, node);
paul718e3742002-12-13 20:15:29 +00001418 ospf_snmp_if_free (osif);
1419 return;
1420 }
1421 }
1422}
1423
1424void
1425ospf_snmp_if_update (struct interface *ifp)
1426{
paul1eb8ef22005-04-07 07:30:20 +00001427 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001428 struct listnode *pn;
1429 struct connected *ifc;
1430 struct prefix *p;
1431 struct ospf_snmp_if *osif;
1432 struct in_addr *addr;
1433 unsigned int ifindex;
1434
1435 ospf_snmp_if_delete (ifp);
1436
1437 p = NULL;
1438 addr = NULL;
1439 ifindex = 0;
1440
1441 /* Lookup first IPv4 address entry. */
paul1eb8ef22005-04-07 07:30:20 +00001442 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc))
paul718e3742002-12-13 20:15:29 +00001443 {
Andrew J. Schorre4529632006-12-12 19:18:21 +00001444 p = CONNECTED_ID(ifc);
paul718e3742002-12-13 20:15:29 +00001445
1446 if (p->family == AF_INET)
1447 {
1448 addr = &p->u.prefix4;
1449 break;
1450 }
1451 }
1452 if (! addr)
1453 ifindex = ifp->ifindex;
1454
1455 /* Add interface to the list. */
1456 pn = NULL;
paul1eb8ef22005-04-07 07:30:20 +00001457 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, node, osif))
paul718e3742002-12-13 20:15:29 +00001458 {
1459 if (addr)
1460 {
vincent77df1f72005-10-06 07:46:22 +00001461 /* Usual interfaces --> Sort them based on interface IPv4 addresses */
paul718e3742002-12-13 20:15:29 +00001462 if (ntohl (osif->addr.s_addr) > ntohl (addr->s_addr))
1463 break;
1464 }
1465 else
1466 {
vincent77df1f72005-10-06 07:46:22 +00001467 /* Unnumbered interfaces --> Sort them based on interface indexes */
paul718e3742002-12-13 20:15:29 +00001468 if (osif->addr.s_addr != 0 || osif->ifindex > ifindex)
1469 break;
1470 }
paul1eb8ef22005-04-07 07:30:20 +00001471 pn = node;
paul718e3742002-12-13 20:15:29 +00001472 }
1473
1474 osif = ospf_snmp_if_new ();
vincent77df1f72005-10-06 07:46:22 +00001475 if (addr) /* Usual interface */
1476 {
paul718e3742002-12-13 20:15:29 +00001477 osif->addr = *addr;
vincent77df1f72005-10-06 07:46:22 +00001478
1479 /* This field is used for storing ospfAddressLessIf OID value,
1480 * conform to RFC1850 OSPF-MIB specification, it must be 0 for
1481 * usual interface */
1482 osif->ifindex = 0;
1483 }
1484 else /* Unnumbered interface */
paul718e3742002-12-13 20:15:29 +00001485 osif->ifindex = ifindex;
1486 osif->ifp = ifp;
1487
1488 listnode_add_after (ospf_snmp_iflist, pn, osif);
1489}
1490
vincent77df1f72005-10-06 07:46:22 +00001491int
1492ospf_snmp_is_if_have_addr (struct interface *ifp)
1493{
vincent77df1f72005-10-06 07:46:22 +00001494 struct listnode *nn;
1495 struct connected *ifc;
1496
1497 /* Is this interface having any connected IPv4 address ? */
1498 for (ALL_LIST_ELEMENTS_RO (ifp->connected, nn, ifc))
1499 {
Andrew J. Schorre4529632006-12-12 19:18:21 +00001500 if (CONNECTED_PREFIX(ifc)->family == AF_INET)
vincent77df1f72005-10-06 07:46:22 +00001501 return 1;
1502 }
1503
1504 return 0;
1505}
1506
1507struct ospf_interface *
paul718e3742002-12-13 20:15:29 +00001508ospf_snmp_if_lookup (struct in_addr *ifaddr, unsigned int *ifindex)
1509{
paul1eb8ef22005-04-07 07:30:20 +00001510 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001511 struct ospf_snmp_if *osif;
vincent77df1f72005-10-06 07:46:22 +00001512 struct ospf_interface *oi = NULL;
1513 struct ospf *ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +00001514
paul1eb8ef22005-04-07 07:30:20 +00001515 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, node, osif))
paul718e3742002-12-13 20:15:29 +00001516 {
1517 if (ifaddr->s_addr)
vincent77df1f72005-10-06 07:46:22 +00001518 {
1519 if (IPV4_ADDR_SAME (&osif->addr, ifaddr))
1520 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1521 }
paul718e3742002-12-13 20:15:29 +00001522 else
vincent77df1f72005-10-06 07:46:22 +00001523 {
1524 if (osif->ifindex == *ifindex)
1525 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1526 }
paul718e3742002-12-13 20:15:29 +00001527 }
vincent77df1f72005-10-06 07:46:22 +00001528 return oi;
paul718e3742002-12-13 20:15:29 +00001529}
1530
vincent77df1f72005-10-06 07:46:22 +00001531struct ospf_interface *
paul718e3742002-12-13 20:15:29 +00001532ospf_snmp_if_lookup_next (struct in_addr *ifaddr, unsigned int *ifindex,
1533 int ifaddr_next, int ifindex_next)
1534{
1535 struct ospf_snmp_if *osif;
1536 struct listnode *nn;
vincent77df1f72005-10-06 07:46:22 +00001537 struct ospf *ospf = ospf_lookup ();
1538 struct ospf_interface *oi = NULL;
paul718e3742002-12-13 20:15:29 +00001539
vincent77df1f72005-10-06 07:46:22 +00001540 if (ospf == NULL)
1541 return NULL;
1542
1543 /* No instance is specified --> Return the first OSPF interface */
paul718e3742002-12-13 20:15:29 +00001544 if (ifaddr_next)
1545 {
vincent77df1f72005-10-06 07:46:22 +00001546 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, nn, osif))
paul718e3742002-12-13 20:15:29 +00001547 {
paul1eb8ef22005-04-07 07:30:20 +00001548 osif = listgetdata (nn);
paul718e3742002-12-13 20:15:29 +00001549 *ifaddr = osif->addr;
1550 *ifindex = osif->ifindex;
vincent77df1f72005-10-06 07:46:22 +00001551 /* Because no instance is specified, we don't care about the kind of
1552 * interface (usual or unnumbered), just returning the first valid
1553 * OSPF interface */
1554 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1555 if (oi)
1556 return (oi);
paul718e3742002-12-13 20:15:29 +00001557 }
1558 return NULL;
1559 }
1560
vincent77df1f72005-10-06 07:46:22 +00001561 /* An instance is specified --> Return the next OSPF interface */
paul1eb8ef22005-04-07 07:30:20 +00001562 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, nn, osif))
paul718e3742002-12-13 20:15:29 +00001563 {
vincent77df1f72005-10-06 07:46:22 +00001564 /* Usual interface */
1565 if (ifaddr->s_addr)
1566 /* The interface must have valid AF_INET connected address */
1567 /* it must have lager IPv4 address value than the lookup entry */
1568 if ((ospf_snmp_is_if_have_addr(osif->ifp)) &&
1569 (ntohl (osif->addr.s_addr) > ntohl (ifaddr->s_addr)))
1570 {
1571 *ifaddr = osif->addr;
1572 *ifindex = osif->ifindex;
1573
1574 /* and it must be an OSPF interface */
1575 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1576 if (oi)
1577 return oi;
1578 }
1579 /* Unnumbered interface */
1580 else
1581 /* The interface must NOT have valid AF_INET connected address */
1582 /* it must have lager interface index than the lookup entry */
1583 if ((!ospf_snmp_is_if_have_addr(osif->ifp)) &&
1584 (osif->ifindex > *ifindex))
1585 {
1586 *ifaddr = osif->addr;
1587 *ifindex = osif->ifindex;
1588
1589 /* and it must be an OSPF interface */
1590 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1591 if (oi)
1592 return oi;
1593 }
paul718e3742002-12-13 20:15:29 +00001594 }
1595 return NULL;
1596}
1597
1598int
1599ospf_snmp_iftype (struct interface *ifp)
1600{
1601#define ospf_snmp_iftype_broadcast 1
1602#define ospf_snmp_iftype_nbma 2
1603#define ospf_snmp_iftype_pointToPoint 3
1604#define ospf_snmp_iftype_pointToMultipoint 5
1605 if (if_is_broadcast (ifp))
1606 return ospf_snmp_iftype_broadcast;
1607 if (if_is_pointopoint (ifp))
1608 return ospf_snmp_iftype_pointToPoint;
1609 return ospf_snmp_iftype_broadcast;
1610}
1611
vincent77df1f72005-10-06 07:46:22 +00001612struct ospf_interface *
paul718e3742002-12-13 20:15:29 +00001613ospfIfLookup (struct variable *v, oid *name, size_t *length,
1614 struct in_addr *ifaddr, unsigned int *ifindex, int exact)
1615{
paul6c835672004-10-11 11:00:30 +00001616 unsigned int len;
paul718e3742002-12-13 20:15:29 +00001617 int ifaddr_next = 0;
1618 int ifindex_next = 0;
vincent77df1f72005-10-06 07:46:22 +00001619 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001620 oid *offset;
1621
1622 if (exact)
1623 {
1624 if (*length != v->namelen + IN_ADDR_SIZE + 1)
1625 return NULL;
1626
1627 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, ifaddr);
1628 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1629
1630 return ospf_snmp_if_lookup (ifaddr, ifindex);
1631 }
1632 else
1633 {
1634 len = *length - v->namelen;
1635 if (len >= IN_ADDR_SIZE)
1636 len = IN_ADDR_SIZE;
1637 if (len <= 0)
1638 ifaddr_next = 1;
1639
1640 oid2in_addr (name + v->namelen, len, ifaddr);
1641
1642 len = *length - v->namelen - IN_ADDR_SIZE;
1643 if (len >= 1)
1644 len = 1;
1645 else
1646 ifindex_next = 1;
1647
1648 if (len == 1)
1649 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1650
vincent77df1f72005-10-06 07:46:22 +00001651 oi = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next,
paul718e3742002-12-13 20:15:29 +00001652 ifindex_next);
vincent77df1f72005-10-06 07:46:22 +00001653 if (oi)
paul718e3742002-12-13 20:15:29 +00001654 {
1655 *length = v->namelen + IN_ADDR_SIZE + 1;
1656 offset = name + v->namelen;
1657 oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE);
1658 offset += IN_ADDR_SIZE;
1659 *offset = *ifindex;
vincent77df1f72005-10-06 07:46:22 +00001660 return oi;
paul718e3742002-12-13 20:15:29 +00001661 }
1662 }
1663 return NULL;
1664}
1665
1666static u_char *
1667ospfIfEntry (struct variable *v, oid *name, size_t *length, int exact,
1668 size_t *var_len, WriteMethod **write_method)
1669{
paul718e3742002-12-13 20:15:29 +00001670 unsigned int ifindex;
1671 struct in_addr ifaddr;
1672 struct ospf_interface *oi;
paul020709f2003-04-04 02:44:16 +00001673 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001674
1675 ifindex = 0;
1676 memset (&ifaddr, 0, sizeof (struct in_addr));
1677
1678 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00001679 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00001680 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001681 return NULL;
1682
vincent77df1f72005-10-06 07:46:22 +00001683 oi = ospfIfLookup (v, name, length, &ifaddr, &ifindex, exact);
paul718e3742002-12-13 20:15:29 +00001684 if (oi == NULL)
1685 return NULL;
1686
1687 /* Return the current value of the variable */
1688 switch (v->magic)
1689 {
1690 case OSPFIFIPADDRESS: /* 1 */
1691 return SNMP_IPADDRESS (ifaddr);
1692 break;
1693 case OSPFADDRESSLESSIF: /* 2 */
1694 return SNMP_INTEGER (ifindex);
1695 break;
1696 case OSPFIFAREAID: /* 3 */
1697 if (oi->area)
1698 return SNMP_IPADDRESS (oi->area->area_id);
1699 else
1700 return SNMP_IPADDRESS (ospf_empty_addr);
1701 break;
1702 case OSPFIFTYPE: /* 4 */
vincent77df1f72005-10-06 07:46:22 +00001703 return SNMP_INTEGER (ospf_snmp_iftype (oi->ifp));
paul718e3742002-12-13 20:15:29 +00001704 break;
1705 case OSPFIFADMINSTAT: /* 5 */
1706 if (oi)
1707 return SNMP_INTEGER (OSPF_STATUS_ENABLED);
1708 else
1709 return SNMP_INTEGER (OSPF_STATUS_DISABLED);
1710 break;
1711 case OSPFIFRTRPRIORITY: /* 6 */
1712 return SNMP_INTEGER (PRIORITY (oi));
1713 break;
1714 case OSPFIFTRANSITDELAY: /* 7 */
1715 return SNMP_INTEGER (OSPF_IF_PARAM (oi, transmit_delay));
1716 break;
1717 case OSPFIFRETRANSINTERVAL: /* 8 */
1718 return SNMP_INTEGER (OSPF_IF_PARAM (oi, retransmit_interval));
1719 break;
1720 case OSPFIFHELLOINTERVAL: /* 9 */
1721 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_hello));
1722 break;
1723 case OSPFIFRTRDEADINTERVAL: /* 10 */
1724 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_wait));
1725 break;
1726 case OSPFIFPOLLINTERVAL: /* 11 */
1727 return SNMP_INTEGER (OSPF_POLL_INTERVAL_DEFAULT);
1728 break;
1729 case OSPFIFSTATE: /* 12 */
vincentba682532005-09-29 13:52:57 +00001730 return SNMP_INTEGER (ISM_SNMP(oi->state));
paul718e3742002-12-13 20:15:29 +00001731 break;
1732 case OSPFIFDESIGNATEDROUTER: /* 13 */
1733 return SNMP_IPADDRESS (DR (oi));
1734 break;
1735 case OSPFIFBACKUPDESIGNATEDROUTER: /* 14 */
1736 return SNMP_IPADDRESS (BDR (oi));
1737 break;
1738 case OSPFIFEVENTS: /* 15 */
1739 return SNMP_INTEGER (oi->state_change);
1740 break;
1741 case OSPFIFAUTHKEY: /* 16 */
1742 *var_len = 0;
1743 return (u_char *) OSPF_IF_PARAM (oi, auth_simple);
1744 break;
1745 case OSPFIFSTATUS: /* 17 */
1746 return SNMP_INTEGER (SNMP_VALID);
1747 break;
1748 case OSPFIFMULTICASTFORWARDING: /* 18 */
1749#define ospf_snmp_multiforward_blocked 1
1750#define ospf_snmp_multiforward_multicast 2
1751#define ospf_snmp_multiforward_unicast 3
1752 return SNMP_INTEGER (ospf_snmp_multiforward_blocked);
1753 break;
1754 case OSPFIFDEMAND: /* 19 */
1755 return SNMP_INTEGER (SNMP_FALSE);
1756 break;
1757 case OSPFIFAUTHTYPE: /* 20 */
1758 if (oi->area)
1759 return SNMP_INTEGER (oi->area->auth_type);
1760 else
1761 return SNMP_INTEGER (0);
1762 break;
1763 default:
1764 return NULL;
1765 break;
1766 }
1767 return NULL;
1768}
1769
1770#define OSPF_SNMP_METRIC_VALUE 1
1771
vincent77df1f72005-10-06 07:46:22 +00001772struct ospf_interface *
paul718e3742002-12-13 20:15:29 +00001773ospfIfMetricLookup (struct variable *v, oid *name, size_t *length,
1774 struct in_addr *ifaddr, unsigned int *ifindex, int exact)
1775{
paul6c835672004-10-11 11:00:30 +00001776 unsigned int len;
paul718e3742002-12-13 20:15:29 +00001777 int ifaddr_next = 0;
1778 int ifindex_next = 0;
vincent77df1f72005-10-06 07:46:22 +00001779 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001780 oid *offset;
1781 int metric;
1782
1783 if (exact)
1784 {
1785 if (*length != v->namelen + IN_ADDR_SIZE + 1 + 1)
1786 return NULL;
1787
1788 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, ifaddr);
1789 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1790 metric = name[v->namelen + IN_ADDR_SIZE + 1];
1791
1792 if (metric != OSPF_SNMP_METRIC_VALUE)
1793 return NULL;
1794
1795 return ospf_snmp_if_lookup (ifaddr, ifindex);
1796 }
1797 else
1798 {
1799 len = *length - v->namelen;
1800 if (len >= IN_ADDR_SIZE)
1801 len = IN_ADDR_SIZE;
1802 else
1803 ifaddr_next = 1;
1804
1805 oid2in_addr (name + v->namelen, len, ifaddr);
1806
1807 len = *length - v->namelen - IN_ADDR_SIZE;
1808 if (len >= 1)
1809 len = 1;
1810 else
1811 ifindex_next = 1;
1812
1813 if (len == 1)
1814 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1815
vincent77df1f72005-10-06 07:46:22 +00001816 oi = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next,
paul718e3742002-12-13 20:15:29 +00001817 ifindex_next);
vincent77df1f72005-10-06 07:46:22 +00001818 if (oi)
paul718e3742002-12-13 20:15:29 +00001819 {
1820 *length = v->namelen + IN_ADDR_SIZE + 1 + 1;
1821 offset = name + v->namelen;
1822 oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE);
1823 offset += IN_ADDR_SIZE;
1824 *offset = *ifindex;
1825 offset++;
1826 *offset = OSPF_SNMP_METRIC_VALUE;
vincent77df1f72005-10-06 07:46:22 +00001827 return oi;
paul718e3742002-12-13 20:15:29 +00001828 }
1829 }
1830 return NULL;
1831}
1832
1833static u_char *
1834ospfIfMetricEntry (struct variable *v, oid *name, size_t *length, int exact,
1835 size_t *var_len, WriteMethod **write_method)
1836{
1837 /* Currently we support metric 1 only. */
paul718e3742002-12-13 20:15:29 +00001838 unsigned int ifindex;
1839 struct in_addr ifaddr;
1840 struct ospf_interface *oi;
paul020709f2003-04-04 02:44:16 +00001841 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001842
1843 ifindex = 0;
1844 memset (&ifaddr, 0, sizeof (struct in_addr));
1845
1846 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00001847 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00001848 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001849 return NULL;
1850
vincent77df1f72005-10-06 07:46:22 +00001851 oi = ospfIfMetricLookup (v, name, length, &ifaddr, &ifindex, exact);
paul718e3742002-12-13 20:15:29 +00001852 if (oi == NULL)
1853 return NULL;
1854
1855 /* Return the current value of the variable */
1856 switch (v->magic)
1857 {
1858 case OSPFIFMETRICIPADDRESS:
1859 return SNMP_IPADDRESS (ifaddr);
1860 break;
1861 case OSPFIFMETRICADDRESSLESSIF:
1862 return SNMP_INTEGER (ifindex);
1863 break;
1864 case OSPFIFMETRICTOS:
1865 return SNMP_INTEGER (0);
1866 break;
1867 case OSPFIFMETRICVALUE:
1868 return SNMP_INTEGER (OSPF_SNMP_METRIC_VALUE);
1869 break;
1870 case OSPFIFMETRICSTATUS:
1871 return SNMP_INTEGER (1);
1872 break;
1873 default:
1874 return NULL;
1875 break;
1876 }
1877 return NULL;
1878}
1879
1880struct route_table *ospf_snmp_vl_table;
1881
1882void
1883ospf_snmp_vl_add (struct ospf_vl_data *vl_data)
1884{
1885 struct prefix_ls lp;
1886 struct route_node *rn;
1887
1888 memset (&lp, 0, sizeof (struct prefix_ls));
1889 lp.family = 0;
1890 lp.prefixlen = 64;
1891 lp.id = vl_data->vl_area_id;
1892 lp.adv_router = vl_data->vl_peer;
1893
1894 rn = route_node_get (ospf_snmp_vl_table, (struct prefix *) &lp);
1895 rn->info = vl_data;
1896}
1897
1898void
1899ospf_snmp_vl_delete (struct ospf_vl_data *vl_data)
1900{
1901 struct prefix_ls lp;
1902 struct route_node *rn;
1903
1904 memset (&lp, 0, sizeof (struct prefix_ls));
1905 lp.family = 0;
1906 lp.prefixlen = 64;
1907 lp.id = vl_data->vl_area_id;
1908 lp.adv_router = vl_data->vl_peer;
1909
1910 rn = route_node_lookup (ospf_snmp_vl_table, (struct prefix *) &lp);
1911 if (! rn)
1912 return;
1913 rn->info = NULL;
1914 route_unlock_node (rn);
1915 route_unlock_node (rn);
1916}
1917
1918struct ospf_vl_data *
1919ospf_snmp_vl_lookup (struct in_addr *area_id, struct in_addr *neighbor)
1920{
1921 struct prefix_ls lp;
1922 struct route_node *rn;
1923 struct ospf_vl_data *vl_data;
1924
1925 memset (&lp, 0, sizeof (struct prefix_ls));
1926 lp.family = 0;
1927 lp.prefixlen = 64;
1928 lp.id = *area_id;
1929 lp.adv_router = *neighbor;
1930
1931 rn = route_node_lookup (ospf_snmp_vl_table, (struct prefix *) &lp);
1932 if (rn)
1933 {
1934 vl_data = rn->info;
1935 route_unlock_node (rn);
1936 return vl_data;
1937 }
1938 return NULL;
1939}
1940
1941struct ospf_vl_data *
1942ospf_snmp_vl_lookup_next (struct in_addr *area_id, struct in_addr *neighbor,
1943 int first)
1944{
1945 struct prefix_ls lp;
1946 struct route_node *rn;
1947 struct ospf_vl_data *vl_data;
1948
1949 memset (&lp, 0, sizeof (struct prefix_ls));
1950 lp.family = 0;
1951 lp.prefixlen = 64;
1952 lp.id = *area_id;
1953 lp.adv_router = *neighbor;
1954
1955 if (first)
1956 rn = route_top (ospf_snmp_vl_table);
1957 else
1958 {
1959 rn = route_node_get (ospf_snmp_vl_table, (struct prefix *) &lp);
1960 rn = route_next (rn);
1961 }
1962
1963 for (; rn; rn = route_next (rn))
1964 if (rn->info)
1965 break;
1966
1967 if (rn && rn->info)
1968 {
1969 vl_data = rn->info;
1970 *area_id = vl_data->vl_area_id;
1971 *neighbor = vl_data->vl_peer;
1972 route_unlock_node (rn);
1973 return vl_data;
1974 }
1975 return NULL;
1976}
1977
1978struct ospf_vl_data *
1979ospfVirtIfLookup (struct variable *v, oid *name, size_t *length,
1980 struct in_addr *area_id, struct in_addr *neighbor, int exact)
1981{
1982 int first;
paul6c835672004-10-11 11:00:30 +00001983 unsigned int len;
paul718e3742002-12-13 20:15:29 +00001984 struct ospf_vl_data *vl_data;
1985
1986 if (exact)
1987 {
1988 if (*length != v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE)
1989 return NULL;
1990
1991 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, area_id);
1992 oid2in_addr (name + v->namelen + IN_ADDR_SIZE, IN_ADDR_SIZE, neighbor);
1993
1994 return ospf_snmp_vl_lookup (area_id, neighbor);
1995 }
1996 else
1997 {
1998 first = 0;
1999
2000 len = *length - v->namelen;
2001 if (len <= 0)
2002 first = 1;
2003 if (len > IN_ADDR_SIZE)
2004 len = IN_ADDR_SIZE;
2005 oid2in_addr (name + v->namelen, len, area_id);
2006
2007 len = *length - v->namelen - IN_ADDR_SIZE;
2008 if (len > IN_ADDR_SIZE)
2009 len = IN_ADDR_SIZE;
2010 oid2in_addr (name + v->namelen + IN_ADDR_SIZE, len, neighbor);
2011
2012 vl_data = ospf_snmp_vl_lookup_next (area_id, neighbor, first);
2013
2014 if (vl_data)
2015 {
2016 *length = v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE;
2017 oid_copy_addr (name + v->namelen, area_id, IN_ADDR_SIZE);
2018 oid_copy_addr (name + v->namelen + IN_ADDR_SIZE, neighbor,
2019 IN_ADDR_SIZE);
2020 return vl_data;
2021 }
2022 }
2023 return NULL;
2024}
2025
2026static u_char *
2027ospfVirtIfEntry (struct variable *v, oid *name, size_t *length, int exact,
2028 size_t *var_len, WriteMethod **write_method)
2029{
2030 struct ospf_vl_data *vl_data;
2031 struct ospf_interface *oi;
2032 struct in_addr area_id;
2033 struct in_addr neighbor;
2034
2035 memset (&area_id, 0, sizeof (struct in_addr));
2036 memset (&neighbor, 0, sizeof (struct in_addr));
2037
2038 vl_data = ospfVirtIfLookup (v, name, length, &area_id, &neighbor, exact);
2039 if (! vl_data)
2040 return NULL;
2041 oi = vl_data->vl_oi;
2042 if (! oi)
2043 return NULL;
2044
2045 /* Return the current value of the variable */
2046 switch (v->magic)
2047 {
2048 case OSPFVIRTIFAREAID:
2049 return SNMP_IPADDRESS (area_id);
2050 break;
2051 case OSPFVIRTIFNEIGHBOR:
2052 return SNMP_IPADDRESS (neighbor);
2053 break;
2054 case OSPFVIRTIFTRANSITDELAY:
2055 return SNMP_INTEGER (OSPF_IF_PARAM (oi, transmit_delay));
2056 break;
2057 case OSPFVIRTIFRETRANSINTERVAL:
2058 return SNMP_INTEGER (OSPF_IF_PARAM (oi, retransmit_interval));
2059 break;
2060 case OSPFVIRTIFHELLOINTERVAL:
2061 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_hello));
2062 break;
2063 case OSPFVIRTIFRTRDEADINTERVAL:
2064 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_wait));
2065 break;
2066 case OSPFVIRTIFSTATE:
2067 return SNMP_INTEGER (oi->state);
2068 break;
2069 case OSPFVIRTIFEVENTS:
2070 return SNMP_INTEGER (oi->state_change);
2071 break;
2072 case OSPFVIRTIFAUTHKEY:
2073 *var_len = 0;
2074 return (u_char *) OSPF_IF_PARAM (oi, auth_simple);
2075 break;
2076 case OSPFVIRTIFSTATUS:
2077 return SNMP_INTEGER (SNMP_VALID);
2078 break;
2079 case OSPFVIRTIFAUTHTYPE:
2080 if (oi->area)
2081 return SNMP_INTEGER (oi->area->auth_type);
2082 else
2083 return SNMP_INTEGER (0);
2084 break;
2085 default:
2086 return NULL;
2087 break;
2088 }
2089 return NULL;
2090}
2091
2092struct ospf_neighbor *
paul68980082003-03-25 05:07:42 +00002093ospf_snmp_nbr_lookup (struct ospf *ospf, struct in_addr *nbr_addr,
2094 unsigned int *ifindex)
paul718e3742002-12-13 20:15:29 +00002095{
paul1eb8ef22005-04-07 07:30:20 +00002096 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002097 struct ospf_interface *oi;
2098 struct ospf_neighbor *nbr;
2099 struct route_node *rn;
2100
paul1eb8ef22005-04-07 07:30:20 +00002101 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002102 {
2103 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2104 if ((nbr = rn->info) != NULL
2105 && nbr != oi->nbr_self
vincent5e4914c2005-09-29 16:34:30 +00002106/* If EXACT match is needed, provide ALL entry found
paul718e3742002-12-13 20:15:29 +00002107 && nbr->state != NSM_Down
vincent5e4914c2005-09-29 16:34:30 +00002108 */
paul718e3742002-12-13 20:15:29 +00002109 && nbr->src.s_addr != 0)
2110 {
2111 if (IPV4_ADDR_SAME (&nbr->src, nbr_addr))
2112 {
2113 route_unlock_node (rn);
2114 return nbr;
2115 }
2116 }
2117 }
2118 return NULL;
2119}
2120
2121struct ospf_neighbor *
2122ospf_snmp_nbr_lookup_next (struct in_addr *nbr_addr, unsigned int *ifindex,
2123 int first)
2124{
2125 struct listnode *nn;
2126 struct ospf_interface *oi;
2127 struct ospf_neighbor *nbr;
2128 struct route_node *rn;
2129 struct ospf_neighbor *min = NULL;
paul020709f2003-04-04 02:44:16 +00002130 struct ospf *ospf = ospf;
paul718e3742002-12-13 20:15:29 +00002131
paul020709f2003-04-04 02:44:16 +00002132 ospf = ospf_lookup ();
paul1eb8ef22005-04-07 07:30:20 +00002133
2134 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, nn, oi))
paul718e3742002-12-13 20:15:29 +00002135 {
2136 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2137 if ((nbr = rn->info) != NULL
2138 && nbr != oi->nbr_self
2139 && nbr->state != NSM_Down
2140 && nbr->src.s_addr != 0)
2141 {
2142 if (first)
2143 {
2144 if (! min)
2145 min = nbr;
2146 else if (ntohl (nbr->src.s_addr) < ntohl (min->src.s_addr))
2147 min = nbr;
2148 }
2149 else if (ntohl (nbr->src.s_addr) > ntohl (nbr_addr->s_addr))
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 }
2157 }
2158 if (min)
2159 {
2160 *nbr_addr = min->src;
2161 *ifindex = 0;
2162 return min;
2163 }
2164 return NULL;
2165}
2166
2167struct ospf_neighbor *
2168ospfNbrLookup (struct variable *v, oid *name, size_t *length,
2169 struct in_addr *nbr_addr, unsigned int *ifindex, int exact)
2170{
paul6c835672004-10-11 11:00:30 +00002171 unsigned int len;
paul718e3742002-12-13 20:15:29 +00002172 int first;
2173 struct ospf_neighbor *nbr;
paul020709f2003-04-04 02:44:16 +00002174 struct ospf *ospf;
2175
2176 ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +00002177
hasso1b639042005-03-27 13:32:25 +00002178 if (! ospf)
2179 return NULL;
2180
paul718e3742002-12-13 20:15:29 +00002181 if (exact)
2182 {
2183 if (*length != v->namelen + IN_ADDR_SIZE + 1)
2184 return NULL;
2185
2186 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, nbr_addr);
2187 *ifindex = name[v->namelen + IN_ADDR_SIZE];
2188
paul68980082003-03-25 05:07:42 +00002189 return ospf_snmp_nbr_lookup (ospf, nbr_addr, ifindex);
paul718e3742002-12-13 20:15:29 +00002190 }
2191 else
2192 {
2193 first = 0;
2194 len = *length - v->namelen;
2195
2196 if (len <= 0)
2197 first = 1;
2198
2199 if (len > IN_ADDR_SIZE)
2200 len = IN_ADDR_SIZE;
2201
2202 oid2in_addr (name + v->namelen, len, nbr_addr);
2203
2204 len = *length - v->namelen - IN_ADDR_SIZE;
2205 if (len >= 1)
2206 *ifindex = name[v->namelen + IN_ADDR_SIZE];
2207
2208 nbr = ospf_snmp_nbr_lookup_next (nbr_addr, ifindex, first);
2209
2210 if (nbr)
2211 {
2212 *length = v->namelen + IN_ADDR_SIZE + 1;
2213 oid_copy_addr (name + v->namelen, nbr_addr, IN_ADDR_SIZE);
2214 name[v->namelen + IN_ADDR_SIZE] = *ifindex;
2215 return nbr;
2216 }
2217 }
2218 return NULL;
2219}
2220
Andrew J. Schorrad81f8c2007-03-14 22:05:18 +00002221/* map internal quagga neighbor states to official MIB values:
2222
2223ospfNbrState OBJECT-TYPE
2224 SYNTAX INTEGER {
2225 down (1),
2226 attempt (2),
2227 init (3),
2228 twoWay (4),
2229 exchangeStart (5),
2230 exchange (6),
2231 loading (7),
2232 full (8)
2233 }
2234*/
2235static int32_t
2236ospf_snmp_neighbor_state(u_char nst)
2237{
2238 switch (nst)
2239 {
2240 case NSM_Attempt:
2241 return 2;
2242 case NSM_Init:
2243 return 3;
2244 case NSM_TwoWay:
2245 return 4;
2246 case NSM_ExStart:
2247 return 5;
2248 case NSM_Exchange:
2249 return 6;
2250 case NSM_Loading:
2251 return 7;
2252 case NSM_Full:
2253 return 8;
2254 default:
2255 return 1; /* down */
2256 }
2257}
2258
paul718e3742002-12-13 20:15:29 +00002259static u_char *
2260ospfNbrEntry (struct variable *v, oid *name, size_t *length, int exact,
2261 size_t *var_len, WriteMethod **write_method)
2262{
2263 struct in_addr nbr_addr;
2264 unsigned int ifindex;
2265 struct ospf_neighbor *nbr;
2266 struct ospf_interface *oi;
2267
2268 memset (&nbr_addr, 0, sizeof (struct in_addr));
2269 ifindex = 0;
2270
2271 nbr = ospfNbrLookup (v, name, length, &nbr_addr, &ifindex, exact);
2272 if (! nbr)
2273 return NULL;
2274 oi = nbr->oi;
2275 if (! oi)
2276 return NULL;
2277
2278 /* Return the current value of the variable */
2279 switch (v->magic)
2280 {
2281 case OSPFNBRIPADDR:
2282 return SNMP_IPADDRESS (nbr_addr);
2283 break;
2284 case OSPFNBRADDRESSLESSINDEX:
2285 return SNMP_INTEGER (ifindex);
2286 break;
2287 case OSPFNBRRTRID:
2288 return SNMP_IPADDRESS (nbr->router_id);
2289 break;
2290 case OSPFNBROPTIONS:
2291 return SNMP_INTEGER (oi->nbr_self->options);
2292 break;
2293 case OSPFNBRPRIORITY:
2294 return SNMP_INTEGER (nbr->priority);
2295 break;
2296 case OSPFNBRSTATE:
Andrew J. Schorrad81f8c2007-03-14 22:05:18 +00002297 return SNMP_INTEGER (ospf_snmp_neighbor_state(nbr->state));
paul718e3742002-12-13 20:15:29 +00002298 break;
2299 case OSPFNBREVENTS:
2300 return SNMP_INTEGER (nbr->state_change);
2301 break;
2302 case OSPFNBRLSRETRANSQLEN:
2303 return SNMP_INTEGER (ospf_ls_retransmit_count (nbr));
2304 break;
2305 case OSPFNBMANBRSTATUS:
2306 return SNMP_INTEGER (SNMP_VALID);
2307 break;
2308 case OSPFNBMANBRPERMANENCE:
2309 return SNMP_INTEGER (2);
2310 break;
2311 case OSPFNBRHELLOSUPPRESSED:
2312 return SNMP_INTEGER (SNMP_FALSE);
2313 break;
2314 default:
2315 return NULL;
2316 break;
2317 }
2318 return NULL;
2319}
2320
2321static u_char *
2322ospfVirtNbrEntry (struct variable *v, oid *name, size_t *length, int exact,
2323 size_t *var_len, WriteMethod **write_method)
2324{
2325 struct ospf_vl_data *vl_data;
2326 struct in_addr area_id;
2327 struct in_addr neighbor;
paul020709f2003-04-04 02:44:16 +00002328 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002329
2330 memset (&area_id, 0, sizeof (struct in_addr));
2331 memset (&neighbor, 0, sizeof (struct in_addr));
2332
2333 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00002334 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00002335 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00002336 return NULL;
2337
2338 vl_data = ospfVirtIfLookup (v, name, length, &area_id, &neighbor, exact);
2339 if (! vl_data)
2340 return NULL;
2341
2342 /* Return the current value of the variable */
2343 switch (v->magic)
2344 {
2345 case OSPFVIRTNBRAREA:
2346 return (u_char *) NULL;
2347 break;
2348 case OSPFVIRTNBRRTRID:
2349 return (u_char *) NULL;
2350 break;
2351 case OSPFVIRTNBRIPADDR:
2352 return (u_char *) NULL;
2353 break;
2354 case OSPFVIRTNBROPTIONS:
2355 return (u_char *) NULL;
2356 break;
2357 case OSPFVIRTNBRSTATE:
2358 return (u_char *) NULL;
2359 break;
2360 case OSPFVIRTNBREVENTS:
2361 return (u_char *) NULL;
2362 break;
2363 case OSPFVIRTNBRLSRETRANSQLEN:
2364 return (u_char *) NULL;
2365 break;
2366 case OSPFVIRTNBRHELLOSUPPRESSED:
2367 return (u_char *) NULL;
2368 break;
2369 default:
2370 return NULL;
2371 break;
2372 }
2373 return NULL;
2374}
2375
2376struct ospf_lsa *
2377ospfExtLsdbLookup (struct variable *v, oid *name, size_t *length, u_char *type,
2378 struct in_addr *ls_id, struct in_addr *router_id, int exact)
2379{
2380 int first;
2381 oid *offset;
2382 int offsetlen;
2383 u_char lsa_type;
paul6c835672004-10-11 11:00:30 +00002384 unsigned int len;
paul718e3742002-12-13 20:15:29 +00002385 struct ospf_lsa *lsa;
paul020709f2003-04-04 02:44:16 +00002386 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002387
paul020709f2003-04-04 02:44:16 +00002388 ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +00002389 if (exact)
2390 {
2391 if (*length != v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
2392 return NULL;
2393
2394 offset = name + v->namelen;
2395
2396 /* Make it sure given value match to type. */
2397 lsa_type = *offset;
2398 offset++;
2399
2400 if (lsa_type != *type)
2401 return NULL;
2402
2403 /* LS ID. */
2404 oid2in_addr (offset, IN_ADDR_SIZE, ls_id);
2405 offset += IN_ADDR_SIZE;
2406
2407 /* Router ID. */
2408 oid2in_addr (offset, IN_ADDR_SIZE, router_id);
2409
paul68980082003-03-25 05:07:42 +00002410 return ospf_lsdb_lookup_by_id (ospf->lsdb, *type, *ls_id, *router_id);
paul718e3742002-12-13 20:15:29 +00002411 }
2412 else
2413 {
2414 /* Get variable length. */
2415 first = 0;
2416 offset = name + v->namelen;
2417 offsetlen = *length - v->namelen;
2418
2419 /* LSA type value. */
2420 lsa_type = *offset;
2421 offset++;
2422 offsetlen--;
2423
2424 if (offsetlen <= 0 || lsa_type < OSPF_AS_EXTERNAL_LSA)
2425 first = 1;
2426
2427 /* LS ID. */
2428 len = offsetlen;
2429 if (len > IN_ADDR_SIZE)
2430 len = IN_ADDR_SIZE;
2431
2432 oid2in_addr (offset, len, ls_id);
2433
2434 offset += IN_ADDR_SIZE;
2435 offsetlen -= IN_ADDR_SIZE;
2436
2437 /* Router ID. */
2438 len = offsetlen;
2439 if (len > IN_ADDR_SIZE)
2440 len = IN_ADDR_SIZE;
2441
2442 oid2in_addr (offset, len, router_id);
2443
paul68980082003-03-25 05:07:42 +00002444 lsa = ospf_lsdb_lookup_by_id_next (ospf->lsdb, *type, *ls_id,
paul718e3742002-12-13 20:15:29 +00002445 *router_id, first);
2446
2447 if (lsa)
2448 {
2449 /* Fill in length. */
2450 *length = v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE;
2451
2452 /* Fill in value. */
2453 offset = name + v->namelen;
2454
2455 *offset = OSPF_AS_EXTERNAL_LSA;
2456 offset++;
2457 oid_copy_addr (offset, &lsa->data->id, IN_ADDR_SIZE);
2458 offset += IN_ADDR_SIZE;
2459 oid_copy_addr (offset, &lsa->data->adv_router, IN_ADDR_SIZE);
2460
2461 return lsa;
2462 }
2463 }
2464 return NULL;
2465}
2466
2467static u_char *
2468ospfExtLsdbEntry (struct variable *v, oid *name, size_t *length, int exact,
2469 size_t *var_len, WriteMethod **write_method)
2470{
2471 struct ospf_lsa *lsa;
2472 struct lsa_header *lsah;
2473 u_char type;
2474 struct in_addr ls_id;
2475 struct in_addr router_id;
paul020709f2003-04-04 02:44:16 +00002476 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002477
2478 type = OSPF_AS_EXTERNAL_LSA;
2479 memset (&ls_id, 0, sizeof (struct in_addr));
2480 memset (&router_id, 0, sizeof (struct in_addr));
2481
2482 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00002483 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00002484 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00002485 return NULL;
2486
2487 lsa = ospfExtLsdbLookup (v, name, length, &type, &ls_id, &router_id, exact);
2488 if (! lsa)
2489 return NULL;
2490
2491 lsah = lsa->data;
2492
2493 /* Return the current value of the variable */
2494 switch (v->magic)
2495 {
2496 case OSPFEXTLSDBTYPE:
2497 return SNMP_INTEGER (OSPF_AS_EXTERNAL_LSA);
2498 break;
2499 case OSPFEXTLSDBLSID:
2500 return SNMP_IPADDRESS (lsah->id);
2501 break;
2502 case OSPFEXTLSDBROUTERID:
2503 return SNMP_IPADDRESS (lsah->adv_router);
2504 break;
2505 case OSPFEXTLSDBSEQUENCE:
2506 return SNMP_INTEGER (lsah->ls_seqnum);
2507 break;
2508 case OSPFEXTLSDBAGE:
2509 return SNMP_INTEGER (lsah->ls_age);
2510 break;
2511 case OSPFEXTLSDBCHECKSUM:
2512 return SNMP_INTEGER (lsah->checksum);
2513 break;
2514 case OSPFEXTLSDBADVERTISEMENT:
2515 *var_len = ntohs (lsah->length);
2516 return (u_char *) lsah;
2517 break;
2518 default:
2519 return NULL;
2520 break;
2521 }
2522 return NULL;
2523}
2524
2525static u_char *
2526ospfAreaAggregateEntry (struct variable *v, oid *name, size_t *length,
2527 int exact, size_t *var_len, WriteMethod **write_method)
2528{
2529 /* Return the current value of the variable */
2530 switch (v->magic)
2531 {
2532 case OSPFAREAAGGREGATEAREAID:
2533 return (u_char *) NULL;
2534 break;
2535 case OSPFAREAAGGREGATELSDBTYPE:
2536 return (u_char *) NULL;
2537 break;
2538 case OSPFAREAAGGREGATENET:
2539 return (u_char *) NULL;
2540 break;
2541 case OSPFAREAAGGREGATEMASK:
2542 return (u_char *) NULL;
2543 break;
2544 case OSPFAREAAGGREGATESTATUS:
2545 return (u_char *) NULL;
2546 break;
2547 case OSPFAREAAGGREGATEEFFECT:
2548 return (u_char *) NULL;
2549 break;
2550 default:
2551 return NULL;
2552 break;
2553 }
2554 return NULL;
2555}
2556
vincent5e4914c2005-09-29 16:34:30 +00002557/* OSPF Traps. */
2558#define IFSTATECHANGE 16
2559#define VIRTIFSTATECHANGE 1
2560#define NBRSTATECHANGE 2
2561#define VIRTNBRSTATECHANGE 3
2562
2563struct trap_object ospfNbrTrapList[] =
2564{
2565 {ospfGeneralGroup, -2, {1, OSPFROUTERID}},
2566 {ospfNbrEntry, 3, {10, 1, OSPFNBRIPADDR}},
2567 {ospfNbrEntry, 3, {10, 1, OSPFNBRRTRID}},
2568 {ospfNbrEntry, 3, {10, 1, OSPFNBRSTATE}}
2569};
2570
2571
2572struct trap_object ospfVirtNbrTrapList[] =
2573{
2574 {ospfGeneralGroup, -2, {1, 1}},
2575 {ospfVirtNbrEntry, 3, {11, 1, OSPFVIRTNBRAREA}},
2576 {ospfVirtNbrEntry, 3, {11, 1, OSPFVIRTNBRRTRID}},
2577 {ospfVirtNbrEntry, 3, {11, 1, OSPFVIRTNBRSTATE}}
2578};
2579
2580struct trap_object ospfIfTrapList[] =
2581{
2582 {ospfGeneralGroup, -2, {1, OSPFROUTERID}},
2583 {ospfIfEntry, 3, {7, 1, OSPFIFIPADDRESS}},
2584 {ospfIfEntry, 3, {7, 1, OSPFADDRESSLESSIF}},
2585 {ospfIfEntry, 3, {7, 1, OSPFIFSTATE}}
2586};
2587
2588struct trap_object ospfVirtIfTrapList[] =
2589{
2590 {ospfGeneralGroup, -2, {1, OSPFROUTERID}},
2591 {ospfVirtIfEntry, 3, {9, 1, OSPFVIRTIFAREAID}},
2592 {ospfVirtIfEntry, 3, {9, 1, OSPFVIRTIFNEIGHBOR}},
2593 {ospfVirtIfEntry, 3, {9, 1, OSPFVIRTIFSTATE}}
2594};
2595
2596void
2597ospfTrapNbrStateChange (struct ospf_neighbor *on)
2598{
2599 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
Andrew J. Schorr9aecfae2006-06-24 20:05:02 +00002600 char msgbuf[16];
vincent5e4914c2005-09-29 16:34:30 +00002601
Andrew J. Schorr9aecfae2006-06-24 20:05:02 +00002602 ospf_nbr_state_message(on, msgbuf, sizeof(msgbuf));
2603 zlog (NULL, LOG_INFO, "ospfTrapNbrStateChange trap sent: %s now %s",
2604 inet_ntoa(on->address.u.prefix4), msgbuf);
vincent5e4914c2005-09-29 16:34:30 +00002605
2606 oid_copy_addr (index, &(on->address.u.prefix4), IN_ADDR_SIZE);
2607 index[IN_ADDR_SIZE] = 0;
2608
2609 smux_trap (ospf_oid, sizeof ospf_oid / sizeof (oid),
2610 index, IN_ADDR_SIZE + 1,
2611 ospfNbrTrapList,
2612 sizeof ospfNbrTrapList / sizeof (struct trap_object),
2613 time (NULL), NBRSTATECHANGE);
2614}
2615
2616void
2617ospfTrapVirtNbrStateChange (struct ospf_neighbor *on)
2618{
2619 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
2620
2621 zlog (NULL, LOG_INFO, "ospfTrapVirtNbrStateChange trap sent");
2622
2623 oid_copy_addr (index, &(on->address.u.prefix4), IN_ADDR_SIZE);
2624 index[IN_ADDR_SIZE] = 0;
2625
2626 smux_trap (ospf_oid, sizeof ospf_oid / sizeof (oid),
2627 index, IN_ADDR_SIZE + 1,
2628 ospfVirtNbrTrapList,
2629 sizeof ospfVirtNbrTrapList / sizeof (struct trap_object),
2630 time (NULL), VIRTNBRSTATECHANGE);
2631}
2632
2633void
2634ospfTrapIfStateChange (struct ospf_interface *oi)
2635{
2636 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
2637
Andrew J. Schorr9aecfae2006-06-24 20:05:02 +00002638 zlog (NULL, LOG_INFO, "ospfTrapIfStateChange trap sent: %s now %s",
2639 inet_ntoa(oi->address->u.prefix4),
2640 LOOKUP(ospf_ism_state_msg, oi->state));
vincent5e4914c2005-09-29 16:34:30 +00002641
2642 oid_copy_addr (index, &(oi->address->u.prefix4), IN_ADDR_SIZE);
2643 index[IN_ADDR_SIZE] = 0;
2644
2645 smux_trap (ospf_oid, sizeof ospf_oid / sizeof (oid),
2646 index, IN_ADDR_SIZE + 1,
2647 ospfIfTrapList,
2648 sizeof ospfIfTrapList / sizeof (struct trap_object),
2649 time (NULL), IFSTATECHANGE);
2650}
2651
2652void
2653ospfTrapVirtIfStateChange (struct ospf_interface *oi)
2654{
2655 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
2656
2657 zlog (NULL, LOG_INFO, "ospfTrapVirtIfStateChange trap sent");
2658
2659 oid_copy_addr (index, &(oi->address->u.prefix4), IN_ADDR_SIZE);
2660 index[IN_ADDR_SIZE] = 0;
2661
2662 smux_trap (ospf_oid, sizeof ospf_oid / sizeof (oid),
2663 index, IN_ADDR_SIZE + 1,
2664 ospfVirtIfTrapList,
2665 sizeof ospfVirtIfTrapList / sizeof (struct trap_object),
2666 time (NULL), VIRTIFSTATECHANGE);
2667}
paul718e3742002-12-13 20:15:29 +00002668/* Register OSPF2-MIB. */
2669void
2670ospf_snmp_init ()
2671{
2672 ospf_snmp_iflist = list_new ();
2673 ospf_snmp_vl_table = route_table_init ();
hassoc75105a2004-10-13 10:33:26 +00002674 smux_init (om->master);
paul718e3742002-12-13 20:15:29 +00002675 REGISTER_MIB("mibII/ospf", ospf_variables, variable, ospf_oid);
paul718e3742002-12-13 20:15:29 +00002676}
2677#endif /* HAVE_SNMP */