blob: c8416de6fbe391942f97937af4349f677dec3aef [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#include <net-snmp/net-snmp-config.h>
Joakim Tjernlundfb62a3c2008-05-13 20:03:32 +020029#include <net-snmp/net-snmp-includes.h>
paul718e3742002-12-13 20:15:29 +000030
31#include "if.h"
32#include "log.h"
33#include "prefix.h"
34#include "table.h"
35#include "command.h"
36#include "memory.h"
37#include "smux.h"
38
39#include "ospfd/ospfd.h"
40#include "ospfd/ospf_interface.h"
41#include "ospfd/ospf_asbr.h"
42#include "ospfd/ospf_lsa.h"
43#include "ospfd/ospf_lsdb.h"
44#include "ospfd/ospf_abr.h"
45#include "ospfd/ospf_neighbor.h"
46#include "ospfd/ospf_nsm.h"
47#include "ospfd/ospf_flood.h"
vincente6217872005-09-29 13:56:14 +000048#include "ospfd/ospf_ism.h"
Andrew J. Schorr9aecfae2006-06-24 20:05:02 +000049#include "ospfd/ospf_dump.h"
Chris Caputo0be8dfb2009-06-02 18:40:07 +010050#include "ospfd/ospf_snmp.h"
paul718e3742002-12-13 20:15:29 +000051
52/* OSPF2-MIB. */
53#define OSPF2MIB 1,3,6,1,2,1,14
54
paul718e3742002-12-13 20:15:29 +000055/* OSPF MIB General Group values. */
56#define OSPFROUTERID 1
57#define OSPFADMINSTAT 2
58#define OSPFVERSIONNUMBER 3
59#define OSPFAREABDRRTRSTATUS 4
60#define OSPFASBDRRTRSTATUS 5
61#define OSPFEXTERNLSACOUNT 6
62#define OSPFEXTERNLSACKSUMSUM 7
63#define OSPFTOSSUPPORT 8
64#define OSPFORIGINATENEWLSAS 9
65#define OSPFRXNEWLSAS 10
66#define OSPFEXTLSDBLIMIT 11
67#define OSPFMULTICASTEXTENSIONS 12
68#define OSPFEXITOVERFLOWINTERVAL 13
69#define OSPFDEMANDEXTENSIONS 14
70
71/* OSPF MIB ospfAreaTable. */
72#define OSPFAREAID 1
73#define OSPFAUTHTYPE 2
74#define OSPFIMPORTASEXTERN 3
75#define OSPFSPFRUNS 4
76#define OSPFAREABDRRTRCOUNT 5
77#define OSPFASBDRRTRCOUNT 6
78#define OSPFAREALSACOUNT 7
79#define OSPFAREALSACKSUMSUM 8
80#define OSPFAREASUMMARY 9
81#define OSPFAREASTATUS 10
82
83/* OSPF MIB ospfStubAreaTable. */
84#define OSPFSTUBAREAID 1
85#define OSPFSTUBTOS 2
86#define OSPFSTUBMETRIC 3
87#define OSPFSTUBSTATUS 4
88#define OSPFSTUBMETRICTYPE 5
89
90/* OSPF MIB ospfLsdbTable. */
91#define OSPFLSDBAREAID 1
92#define OSPFLSDBTYPE 2
93#define OSPFLSDBLSID 3
94#define OSPFLSDBROUTERID 4
95#define OSPFLSDBSEQUENCE 5
96#define OSPFLSDBAGE 6
97#define OSPFLSDBCHECKSUM 7
98#define OSPFLSDBADVERTISEMENT 8
99
100/* OSPF MIB ospfAreaRangeTable. */
101#define OSPFAREARANGEAREAID 1
102#define OSPFAREARANGENET 2
103#define OSPFAREARANGEMASK 3
104#define OSPFAREARANGESTATUS 4
105#define OSPFAREARANGEEFFECT 5
106
107/* OSPF MIB ospfHostTable. */
108#define OSPFHOSTIPADDRESS 1
109#define OSPFHOSTTOS 2
110#define OSPFHOSTMETRIC 3
111#define OSPFHOSTSTATUS 4
112#define OSPFHOSTAREAID 5
113
114/* OSPF MIB ospfIfTable. */
115#define OSPFIFIPADDRESS 1
116#define OSPFADDRESSLESSIF 2
117#define OSPFIFAREAID 3
118#define OSPFIFTYPE 4
119#define OSPFIFADMINSTAT 5
120#define OSPFIFRTRPRIORITY 6
121#define OSPFIFTRANSITDELAY 7
122#define OSPFIFRETRANSINTERVAL 8
123#define OSPFIFHELLOINTERVAL 9
124#define OSPFIFRTRDEADINTERVAL 10
125#define OSPFIFPOLLINTERVAL 11
126#define OSPFIFSTATE 12
127#define OSPFIFDESIGNATEDROUTER 13
128#define OSPFIFBACKUPDESIGNATEDROUTER 14
129#define OSPFIFEVENTS 15
130#define OSPFIFAUTHKEY 16
131#define OSPFIFSTATUS 17
132#define OSPFIFMULTICASTFORWARDING 18
133#define OSPFIFDEMAND 19
134#define OSPFIFAUTHTYPE 20
135
136/* OSPF MIB ospfIfMetricTable. */
137#define OSPFIFMETRICIPADDRESS 1
138#define OSPFIFMETRICADDRESSLESSIF 2
139#define OSPFIFMETRICTOS 3
140#define OSPFIFMETRICVALUE 4
141#define OSPFIFMETRICSTATUS 5
142
143/* OSPF MIB ospfVirtIfTable. */
144#define OSPFVIRTIFAREAID 1
145#define OSPFVIRTIFNEIGHBOR 2
146#define OSPFVIRTIFTRANSITDELAY 3
147#define OSPFVIRTIFRETRANSINTERVAL 4
148#define OSPFVIRTIFHELLOINTERVAL 5
149#define OSPFVIRTIFRTRDEADINTERVAL 6
150#define OSPFVIRTIFSTATE 7
151#define OSPFVIRTIFEVENTS 8
152#define OSPFVIRTIFAUTHKEY 9
153#define OSPFVIRTIFSTATUS 10
154#define OSPFVIRTIFAUTHTYPE 11
155
156/* OSPF MIB ospfNbrTable. */
157#define OSPFNBRIPADDR 1
158#define OSPFNBRADDRESSLESSINDEX 2
159#define OSPFNBRRTRID 3
160#define OSPFNBROPTIONS 4
161#define OSPFNBRPRIORITY 5
162#define OSPFNBRSTATE 6
163#define OSPFNBREVENTS 7
164#define OSPFNBRLSRETRANSQLEN 8
165#define OSPFNBMANBRSTATUS 9
166#define OSPFNBMANBRPERMANENCE 10
167#define OSPFNBRHELLOSUPPRESSED 11
168
169/* OSPF MIB ospfVirtNbrTable. */
170#define OSPFVIRTNBRAREA 1
171#define OSPFVIRTNBRRTRID 2
172#define OSPFVIRTNBRIPADDR 3
173#define OSPFVIRTNBROPTIONS 4
174#define OSPFVIRTNBRSTATE 5
175#define OSPFVIRTNBREVENTS 6
176#define OSPFVIRTNBRLSRETRANSQLEN 7
177#define OSPFVIRTNBRHELLOSUPPRESSED 8
178
179/* OSPF MIB ospfExtLsdbTable. */
180#define OSPFEXTLSDBTYPE 1
181#define OSPFEXTLSDBLSID 2
182#define OSPFEXTLSDBROUTERID 3
183#define OSPFEXTLSDBSEQUENCE 4
184#define OSPFEXTLSDBAGE 5
185#define OSPFEXTLSDBCHECKSUM 6
186#define OSPFEXTLSDBADVERTISEMENT 7
187
188/* OSPF MIB ospfAreaAggregateTable. */
189#define OSPFAREAAGGREGATEAREAID 1
190#define OSPFAREAAGGREGATELSDBTYPE 2
191#define OSPFAREAAGGREGATENET 3
192#define OSPFAREAAGGREGATEMASK 4
193#define OSPFAREAAGGREGATESTATUS 5
194#define OSPFAREAAGGREGATEEFFECT 6
195
196/* SYNTAX Status from OSPF-MIB. */
197#define OSPF_STATUS_ENABLED 1
198#define OSPF_STATUS_DISABLED 2
199
200/* SNMP value hack. */
201#define COUNTER ASN_COUNTER
202#define INTEGER ASN_INTEGER
203#define GAUGE ASN_GAUGE
204#define TIMETICKS ASN_TIMETICKS
205#define IPADDRESS ASN_IPADDRESS
206#define STRING ASN_OCTET_STR
207
208/* Declare static local variables for convenience. */
209SNMP_LOCAL_VARIABLES
210
211/* OSPF-MIB instances. */
212oid ospf_oid [] = { OSPF2MIB };
Vincent Bernatb7c0d062012-05-25 11:17:01 +0200213oid ospf_trap_oid [] = { OSPF2MIB, 16, 2 }; /* Not reverse mappable! */
paul718e3742002-12-13 20:15:29 +0000214
215/* IP address 0.0.0.0. */
216static struct in_addr ospf_empty_addr = {0};
217
218/* Hook functions. */
Chris Caputo0be8dfb2009-06-02 18:40:07 +0100219static u_char *ospfGeneralGroup (struct variable *, oid *, size_t *,
220 int, size_t *, WriteMethod **);
221static u_char *ospfAreaEntry (struct variable *, oid *, size_t *, int,
222 size_t *, WriteMethod **);
223static u_char *ospfStubAreaEntry (struct variable *, oid *, size_t *,
224 int, size_t *, WriteMethod **);
225static u_char *ospfLsdbEntry (struct variable *, oid *, size_t *, int,
226 size_t *, WriteMethod **);
227static u_char *ospfAreaRangeEntry (struct variable *, oid *, size_t *, int,
228 size_t *, WriteMethod **);
229static u_char *ospfHostEntry (struct variable *, oid *, size_t *, int,
230 size_t *, WriteMethod **);
231static u_char *ospfIfEntry (struct variable *, oid *, size_t *, int,
232 size_t *, WriteMethod **);
233static u_char *ospfIfMetricEntry (struct variable *, oid *, size_t *, int,
234 size_t *, WriteMethod **);
235static u_char *ospfVirtIfEntry (struct variable *, oid *, size_t *, int,
236 size_t *, WriteMethod **);
237static u_char *ospfNbrEntry (struct variable *, oid *, size_t *, int,
238 size_t *, WriteMethod **);
239static u_char *ospfVirtNbrEntry (struct variable *, oid *, size_t *, int,
240 size_t *, WriteMethod **);
241static u_char *ospfExtLsdbEntry (struct variable *, oid *, size_t *, int,
242 size_t *, WriteMethod **);
243static u_char *ospfAreaAggregateEntry (struct variable *, oid *, size_t *,
244 int, size_t *, WriteMethod **);
paul718e3742002-12-13 20:15:29 +0000245
246struct variable ospf_variables[] =
247{
248 /* OSPF general variables */
249 {OSPFROUTERID, IPADDRESS, RWRITE, ospfGeneralGroup,
250 2, {1, 1}},
251 {OSPFADMINSTAT, INTEGER, RWRITE, ospfGeneralGroup,
252 2, {1, 2}},
253 {OSPFVERSIONNUMBER, INTEGER, RONLY, ospfGeneralGroup,
254 2, {1, 3}},
255 {OSPFAREABDRRTRSTATUS, INTEGER, RONLY, ospfGeneralGroup,
256 2, {1, 4}},
257 {OSPFASBDRRTRSTATUS, INTEGER, RWRITE, ospfGeneralGroup,
258 2, {1, 5}},
259 {OSPFEXTERNLSACOUNT, GAUGE, RONLY, ospfGeneralGroup,
260 2, {1, 6}},
261 {OSPFEXTERNLSACKSUMSUM, INTEGER, RONLY, ospfGeneralGroup,
262 2, {1, 7}},
263 {OSPFTOSSUPPORT, INTEGER, RWRITE, ospfGeneralGroup,
264 2, {1, 8}},
265 {OSPFORIGINATENEWLSAS, COUNTER, RONLY, ospfGeneralGroup,
266 2, {1, 9}},
267 {OSPFRXNEWLSAS, COUNTER, RONLY, ospfGeneralGroup,
268 2, {1, 10}},
269 {OSPFEXTLSDBLIMIT, INTEGER, RWRITE, ospfGeneralGroup,
270 2, {1, 11}},
271 {OSPFMULTICASTEXTENSIONS, INTEGER, RWRITE, ospfGeneralGroup,
272 2, {1, 12}},
273 {OSPFEXITOVERFLOWINTERVAL, INTEGER, RWRITE, ospfGeneralGroup,
274 2, {1, 13}},
275 {OSPFDEMANDEXTENSIONS, INTEGER, RWRITE, ospfGeneralGroup,
276 2, {1, 14}},
277
278 /* OSPF area data structure. */
279 {OSPFAREAID, IPADDRESS, RONLY, ospfAreaEntry,
280 3, {2, 1, 1}},
281 {OSPFAUTHTYPE, INTEGER, RWRITE, ospfAreaEntry,
282 3, {2, 1, 2}},
283 {OSPFIMPORTASEXTERN, INTEGER, RWRITE, ospfAreaEntry,
284 3, {2, 1, 3}},
285 {OSPFSPFRUNS, COUNTER, RONLY, ospfAreaEntry,
286 3, {2, 1, 4}},
287 {OSPFAREABDRRTRCOUNT, GAUGE, RONLY, ospfAreaEntry,
288 3, {2, 1, 5}},
289 {OSPFASBDRRTRCOUNT, GAUGE, RONLY, ospfAreaEntry,
290 3, {2, 1, 6}},
291 {OSPFAREALSACOUNT, GAUGE, RONLY, ospfAreaEntry,
292 3, {2, 1, 7}},
293 {OSPFAREALSACKSUMSUM, INTEGER, RONLY, ospfAreaEntry,
294 3, {2, 1, 8}},
295 {OSPFAREASUMMARY, INTEGER, RWRITE, ospfAreaEntry,
296 3, {2, 1, 9}},
297 {OSPFAREASTATUS, INTEGER, RWRITE, ospfAreaEntry,
298 3, {2, 1, 10}},
299
300 /* OSPF stub area information. */
301 {OSPFSTUBAREAID, IPADDRESS, RONLY, ospfStubAreaEntry,
302 3, {3, 1, 1}},
303 {OSPFSTUBTOS, INTEGER, RONLY, ospfStubAreaEntry,
304 3, {3, 1, 2}},
305 {OSPFSTUBMETRIC, INTEGER, RWRITE, ospfStubAreaEntry,
306 3, {3, 1, 3}},
307 {OSPFSTUBSTATUS, INTEGER, RWRITE, ospfStubAreaEntry,
308 3, {3, 1, 4}},
309 {OSPFSTUBMETRICTYPE, INTEGER, RWRITE, ospfStubAreaEntry,
310 3, {3, 1, 5}},
311
312 /* OSPF link state database. */
313 {OSPFLSDBAREAID, IPADDRESS, RONLY, ospfLsdbEntry,
314 3, {4, 1, 1}},
315 {OSPFLSDBTYPE, INTEGER, RONLY, ospfLsdbEntry,
316 3, {4, 1, 2}},
317 {OSPFLSDBLSID, IPADDRESS, RONLY, ospfLsdbEntry,
318 3, {4, 1, 3}},
319 {OSPFLSDBROUTERID, IPADDRESS, RONLY, ospfLsdbEntry,
320 3, {4, 1, 4}},
321 {OSPFLSDBSEQUENCE, INTEGER, RONLY, ospfLsdbEntry,
322 3, {4, 1, 5}},
323 {OSPFLSDBAGE, INTEGER, RONLY, ospfLsdbEntry,
324 3, {4, 1, 6}},
325 {OSPFLSDBCHECKSUM, INTEGER, RONLY, ospfLsdbEntry,
326 3, {4, 1, 7}},
327 {OSPFLSDBADVERTISEMENT, STRING, RONLY, ospfLsdbEntry,
328 3, {4, 1, 8}},
329
330 /* Area range table. */
331 {OSPFAREARANGEAREAID, IPADDRESS, RONLY, ospfAreaRangeEntry,
332 3, {5, 1, 1}},
333 {OSPFAREARANGENET, IPADDRESS, RONLY, ospfAreaRangeEntry,
334 3, {5, 1, 2}},
335 {OSPFAREARANGEMASK, IPADDRESS, RWRITE, ospfAreaRangeEntry,
336 3, {5, 1, 3}},
337 {OSPFAREARANGESTATUS, INTEGER, RWRITE, ospfAreaRangeEntry,
338 3, {5, 1, 4}},
339 {OSPFAREARANGEEFFECT, INTEGER, RWRITE, ospfAreaRangeEntry,
340 3, {5, 1, 5}},
341
342 /* OSPF host table. */
343 {OSPFHOSTIPADDRESS, IPADDRESS, RONLY, ospfHostEntry,
344 3, {6, 1, 1}},
345 {OSPFHOSTTOS, INTEGER, RONLY, ospfHostEntry,
346 3, {6, 1, 2}},
347 {OSPFHOSTMETRIC, INTEGER, RWRITE, ospfHostEntry,
348 3, {6, 1, 3}},
349 {OSPFHOSTSTATUS, INTEGER, RWRITE, ospfHostEntry,
350 3, {6, 1, 4}},
351 {OSPFHOSTAREAID, IPADDRESS, RONLY, ospfHostEntry,
352 3, {6, 1, 5}},
353
354 /* OSPF interface table. */
355 {OSPFIFIPADDRESS, IPADDRESS, RONLY, ospfIfEntry,
356 3, {7, 1, 1}},
357 {OSPFADDRESSLESSIF, INTEGER, RONLY, ospfIfEntry,
358 3, {7, 1, 2}},
359 {OSPFIFAREAID, IPADDRESS, RWRITE, ospfIfEntry,
360 3, {7, 1, 3}},
361 {OSPFIFTYPE, INTEGER, RWRITE, ospfIfEntry,
362 3, {7, 1, 4}},
363 {OSPFIFADMINSTAT, INTEGER, RWRITE, ospfIfEntry,
364 3, {7, 1, 5}},
365 {OSPFIFRTRPRIORITY, INTEGER, RWRITE, ospfIfEntry,
366 3, {7, 1, 6}},
367 {OSPFIFTRANSITDELAY, INTEGER, RWRITE, ospfIfEntry,
368 3, {7, 1, 7}},
369 {OSPFIFRETRANSINTERVAL, INTEGER, RWRITE, ospfIfEntry,
370 3, {7, 1, 8}},
371 {OSPFIFHELLOINTERVAL, INTEGER, RWRITE, ospfIfEntry,
372 3, {7, 1, 9}},
373 {OSPFIFRTRDEADINTERVAL, INTEGER, RWRITE, ospfIfEntry,
374 3, {7, 1, 10}},
375 {OSPFIFPOLLINTERVAL, INTEGER, RWRITE, ospfIfEntry,
376 3, {7, 1, 11}},
377 {OSPFIFSTATE, INTEGER, RONLY, ospfIfEntry,
378 3, {7, 1, 12}},
379 {OSPFIFDESIGNATEDROUTER, IPADDRESS, RONLY, ospfIfEntry,
380 3, {7, 1, 13}},
381 {OSPFIFBACKUPDESIGNATEDROUTER, IPADDRESS, RONLY, ospfIfEntry,
382 3, {7, 1, 14}},
383 {OSPFIFEVENTS, COUNTER, RONLY, ospfIfEntry,
384 3, {7, 1, 15}},
385 {OSPFIFAUTHKEY, STRING, RWRITE, ospfIfEntry,
386 3, {7, 1, 16}},
387 {OSPFIFSTATUS, INTEGER, RWRITE, ospfIfEntry,
388 3, {7, 1, 17}},
389 {OSPFIFMULTICASTFORWARDING, INTEGER, RWRITE, ospfIfEntry,
390 3, {7, 1, 18}},
391 {OSPFIFDEMAND, INTEGER, RWRITE, ospfIfEntry,
392 3, {7, 1, 19}},
393 {OSPFIFAUTHTYPE, INTEGER, RWRITE, ospfIfEntry,
394 3, {7, 1, 20}},
395
396 /* OSPF interface metric table. */
397 {OSPFIFMETRICIPADDRESS, IPADDRESS, RONLY, ospfIfMetricEntry,
398 3, {8, 1, 1}},
399 {OSPFIFMETRICADDRESSLESSIF, INTEGER, RONLY, ospfIfMetricEntry,
400 3, {8, 1, 2}},
401 {OSPFIFMETRICTOS, INTEGER, RONLY, ospfIfMetricEntry,
402 3, {8, 1, 3}},
403 {OSPFIFMETRICVALUE, INTEGER, RWRITE, ospfIfMetricEntry,
404 3, {8, 1, 4}},
405 {OSPFIFMETRICSTATUS, INTEGER, RWRITE, ospfIfMetricEntry,
406 3, {8, 1, 5}},
407
408 /* OSPF virtual interface table. */
409 {OSPFVIRTIFAREAID, IPADDRESS, RONLY, ospfVirtIfEntry,
410 3, {9, 1, 1}},
411 {OSPFVIRTIFNEIGHBOR, IPADDRESS, RONLY, ospfVirtIfEntry,
412 3, {9, 1, 2}},
413 {OSPFVIRTIFTRANSITDELAY, INTEGER, RWRITE, ospfVirtIfEntry,
414 3, {9, 1, 3}},
415 {OSPFVIRTIFRETRANSINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry,
416 3, {9, 1, 4}},
417 {OSPFVIRTIFHELLOINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry,
418 3, {9, 1, 5}},
419 {OSPFVIRTIFRTRDEADINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry,
420 3, {9, 1, 6}},
421 {OSPFVIRTIFSTATE, INTEGER, RONLY, ospfVirtIfEntry,
422 3, {9, 1, 7}},
423 {OSPFVIRTIFEVENTS, COUNTER, RONLY, ospfVirtIfEntry,
424 3, {9, 1, 8}},
425 {OSPFVIRTIFAUTHKEY, STRING, RWRITE, ospfVirtIfEntry,
426 3, {9, 1, 9}},
427 {OSPFVIRTIFSTATUS, INTEGER, RWRITE, ospfVirtIfEntry,
428 3, {9, 1, 10}},
429 {OSPFVIRTIFAUTHTYPE, INTEGER, RWRITE, ospfVirtIfEntry,
430 3, {9, 1, 11}},
431
432 /* OSPF neighbor table. */
433 {OSPFNBRIPADDR, IPADDRESS, RONLY, ospfNbrEntry,
434 3, {10, 1, 1}},
435 {OSPFNBRADDRESSLESSINDEX, INTEGER, RONLY, ospfNbrEntry,
436 3, {10, 1, 2}},
437 {OSPFNBRRTRID, IPADDRESS, RONLY, ospfNbrEntry,
438 3, {10, 1, 3}},
439 {OSPFNBROPTIONS, INTEGER, RONLY, ospfNbrEntry,
440 3, {10, 1, 4}},
441 {OSPFNBRPRIORITY, INTEGER, RWRITE, ospfNbrEntry,
442 3, {10, 1, 5}},
443 {OSPFNBRSTATE, INTEGER, RONLY, ospfNbrEntry,
444 3, {10, 1, 6}},
445 {OSPFNBREVENTS, COUNTER, RONLY, ospfNbrEntry,
446 3, {10, 1, 7}},
447 {OSPFNBRLSRETRANSQLEN, GAUGE, RONLY, ospfNbrEntry,
448 3, {10, 1, 8}},
449 {OSPFNBMANBRSTATUS, INTEGER, RWRITE, ospfNbrEntry,
450 3, {10, 1, 9}},
451 {OSPFNBMANBRPERMANENCE, INTEGER, RONLY, ospfNbrEntry,
452 3, {10, 1, 10}},
453 {OSPFNBRHELLOSUPPRESSED, INTEGER, RONLY, ospfNbrEntry,
454 3, {10, 1, 11}},
455
456 /* OSPF virtual neighbor table. */
457 {OSPFVIRTNBRAREA, IPADDRESS, RONLY, ospfVirtNbrEntry,
458 3, {11, 1, 1}},
459 {OSPFVIRTNBRRTRID, IPADDRESS, RONLY, ospfVirtNbrEntry,
460 3, {11, 1, 2}},
461 {OSPFVIRTNBRIPADDR, IPADDRESS, RONLY, ospfVirtNbrEntry,
462 3, {11, 1, 3}},
463 {OSPFVIRTNBROPTIONS, INTEGER, RONLY, ospfVirtNbrEntry,
464 3, {11, 1, 4}},
465 {OSPFVIRTNBRSTATE, INTEGER, RONLY, ospfVirtNbrEntry,
466 3, {11, 1, 5}},
467 {OSPFVIRTNBREVENTS, COUNTER, RONLY, ospfVirtNbrEntry,
468 3, {11, 1, 6}},
469 {OSPFVIRTNBRLSRETRANSQLEN, INTEGER, RONLY, ospfVirtNbrEntry,
470 3, {11, 1, 7}},
471 {OSPFVIRTNBRHELLOSUPPRESSED, INTEGER, RONLY, ospfVirtNbrEntry,
472 3, {11, 1, 8}},
473
474 /* OSPF link state database, external. */
475 {OSPFEXTLSDBTYPE, INTEGER, RONLY, ospfExtLsdbEntry,
476 3, {12, 1, 1}},
477 {OSPFEXTLSDBLSID, IPADDRESS, RONLY, ospfExtLsdbEntry,
478 3, {12, 1, 2}},
479 {OSPFEXTLSDBROUTERID, IPADDRESS, RONLY, ospfExtLsdbEntry,
480 3, {12, 1, 3}},
481 {OSPFEXTLSDBSEQUENCE, INTEGER, RONLY, ospfExtLsdbEntry,
482 3, {12, 1, 4}},
483 {OSPFEXTLSDBAGE, INTEGER, RONLY, ospfExtLsdbEntry,
484 3, {12, 1, 5}},
485 {OSPFEXTLSDBCHECKSUM, INTEGER, RONLY, ospfExtLsdbEntry,
486 3, {12, 1, 6}},
487 {OSPFEXTLSDBADVERTISEMENT, STRING, RONLY, ospfExtLsdbEntry,
488 3, {12, 1, 7}},
489
490 /* OSPF area aggregate table. */
491 {OSPFAREAAGGREGATEAREAID, IPADDRESS, RONLY, ospfAreaAggregateEntry,
492 3, {14, 1, 1}},
493 {OSPFAREAAGGREGATELSDBTYPE, INTEGER, RONLY, ospfAreaAggregateEntry,
494 3, {14, 1, 2}},
495 {OSPFAREAAGGREGATENET, IPADDRESS, RONLY, ospfAreaAggregateEntry,
496 3, {14, 1, 3}},
497 {OSPFAREAAGGREGATEMASK, IPADDRESS, RONLY, ospfAreaAggregateEntry,
498 3, {14, 1, 4}},
499 {OSPFAREAAGGREGATESTATUS, INTEGER, RWRITE, ospfAreaAggregateEntry,
500 3, {14, 1, 5}},
501 {OSPFAREAAGGREGATEEFFECT, INTEGER, RWRITE, ospfAreaAggregateEntry,
502 3, {14, 1, 6}}
503};
504
505/* The administrative status of OSPF. When OSPF is enbled on at least
506 one interface return 1. */
Chris Caputo0be8dfb2009-06-02 18:40:07 +0100507static int
paul68980082003-03-25 05:07:42 +0000508ospf_admin_stat (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +0000509{
paulaa20c6f2004-10-07 14:19:36 +0000510 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000511 struct ospf_interface *oi;
512
paul68980082003-03-25 05:07:42 +0000513 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +0000514 return 0;
515
paul1eb8ef22005-04-07 07:30:20 +0000516 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
517 if (oi && oi->address)
518 return 1;
paul718e3742002-12-13 20:15:29 +0000519
paul718e3742002-12-13 20:15:29 +0000520 return 0;
521}
522
523static u_char *
524ospfGeneralGroup (struct variable *v, oid *name, size_t *length,
525 int exact, size_t *var_len, WriteMethod **write_method)
526{
paul020709f2003-04-04 02:44:16 +0000527 struct ospf *ospf;
528
529 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +0000530
paul718e3742002-12-13 20:15:29 +0000531 /* Check whether the instance identifier is valid */
532 if (smux_header_generic (v, name, length, exact, var_len, write_method)
533 == MATCH_FAILED)
534 return NULL;
535
536 /* Return the current value of the variable */
537 switch (v->magic)
538 {
539 case OSPFROUTERID: /* 1 */
540 /* Router-ID of this OSPF instance. */
paul68980082003-03-25 05:07:42 +0000541 if (ospf)
542 return SNMP_IPADDRESS (ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000543 else
544 return SNMP_IPADDRESS (ospf_empty_addr);
545 break;
546 case OSPFADMINSTAT: /* 2 */
547 /* The administrative status of OSPF in the router. */
paul68980082003-03-25 05:07:42 +0000548 if (ospf_admin_stat (ospf))
paul718e3742002-12-13 20:15:29 +0000549 return SNMP_INTEGER (OSPF_STATUS_ENABLED);
550 else
551 return SNMP_INTEGER (OSPF_STATUS_DISABLED);
552 break;
553 case OSPFVERSIONNUMBER: /* 3 */
554 /* OSPF version 2. */
555 return SNMP_INTEGER (OSPF_VERSION);
556 break;
557 case OSPFAREABDRRTRSTATUS: /* 4 */
558 /* Area Border router status. */
paul68980082003-03-25 05:07:42 +0000559 if (ospf && CHECK_FLAG (ospf->flags, OSPF_FLAG_ABR))
paul718e3742002-12-13 20:15:29 +0000560 return SNMP_INTEGER (SNMP_TRUE);
561 else
562 return SNMP_INTEGER (SNMP_FALSE);
563 break;
564 case OSPFASBDRRTRSTATUS: /* 5 */
565 /* AS Border router status. */
paul68980082003-03-25 05:07:42 +0000566 if (ospf && CHECK_FLAG (ospf->flags, OSPF_FLAG_ASBR))
paul718e3742002-12-13 20:15:29 +0000567 return SNMP_INTEGER (SNMP_TRUE);
568 else
569 return SNMP_INTEGER (SNMP_FALSE);
570 break;
571 case OSPFEXTERNLSACOUNT: /* 6 */
572 /* External LSA counts. */
paul68980082003-03-25 05:07:42 +0000573 if (ospf)
574 return SNMP_INTEGER (ospf_lsdb_count_all (ospf->lsdb));
paul718e3742002-12-13 20:15:29 +0000575 else
576 return SNMP_INTEGER (0);
577 break;
578 case OSPFEXTERNLSACKSUMSUM: /* 7 */
579 /* External LSA checksum. */
580 return SNMP_INTEGER (0);
581 break;
582 case OSPFTOSSUPPORT: /* 8 */
583 /* TOS is not supported. */
584 return SNMP_INTEGER (SNMP_FALSE);
585 break;
586 case OSPFORIGINATENEWLSAS: /* 9 */
587 /* The number of new link-state advertisements. */
paul68980082003-03-25 05:07:42 +0000588 if (ospf)
589 return SNMP_INTEGER (ospf->lsa_originate_count);
paul718e3742002-12-13 20:15:29 +0000590 else
591 return SNMP_INTEGER (0);
592 break;
593 case OSPFRXNEWLSAS: /* 10 */
594 /* The number of link-state advertisements received determined
595 to be new instantiations. */
paul68980082003-03-25 05:07:42 +0000596 if (ospf)
597 return SNMP_INTEGER (ospf->rx_lsa_count);
paul718e3742002-12-13 20:15:29 +0000598 else
599 return SNMP_INTEGER (0);
600 break;
601 case OSPFEXTLSDBLIMIT: /* 11 */
602 /* There is no limit for the number of non-default
603 AS-external-LSAs. */
604 return SNMP_INTEGER (-1);
605 break;
606 case OSPFMULTICASTEXTENSIONS: /* 12 */
607 /* Multicast Extensions to OSPF is not supported. */
608 return SNMP_INTEGER (0);
609 break;
610 case OSPFEXITOVERFLOWINTERVAL: /* 13 */
611 /* Overflow is not supported. */
612 return SNMP_INTEGER (0);
613 break;
614 case OSPFDEMANDEXTENSIONS: /* 14 */
615 /* Demand routing is not supported. */
616 return SNMP_INTEGER (SNMP_FALSE);
617 break;
618 default:
619 return NULL;
620 }
621 return NULL;
622}
623
Chris Caputo0be8dfb2009-06-02 18:40:07 +0100624static struct ospf_area *
paul68980082003-03-25 05:07:42 +0000625ospf_area_lookup_next (struct ospf *ospf, struct in_addr *area_id, int first)
paul718e3742002-12-13 20:15:29 +0000626{
627 struct ospf_area *area;
paulaa20c6f2004-10-07 14:19:36 +0000628 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000629
paul020709f2003-04-04 02:44:16 +0000630 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +0000631 return NULL;
632
633 if (first)
634 {
paul68980082003-03-25 05:07:42 +0000635 node = listhead (ospf->areas);
paul718e3742002-12-13 20:15:29 +0000636 if (node)
637 {
paul1eb8ef22005-04-07 07:30:20 +0000638 area = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000639 *area_id = area->area_id;
640 return area;
641 }
642 return NULL;
643 }
paul1eb8ef22005-04-07 07:30:20 +0000644 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
paul718e3742002-12-13 20:15:29 +0000645 {
paul718e3742002-12-13 20:15:29 +0000646 if (ntohl (area->area_id.s_addr) > ntohl (area_id->s_addr))
647 {
648 *area_id = area->area_id;
649 return area;
650 }
651 }
652 return NULL;
653}
654
Chris Caputo0be8dfb2009-06-02 18:40:07 +0100655static struct ospf_area *
paul718e3742002-12-13 20:15:29 +0000656ospfAreaLookup (struct variable *v, oid name[], size_t *length,
657 struct in_addr *addr, int exact)
658{
paul020709f2003-04-04 02:44:16 +0000659 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000660 struct ospf_area *area;
paul68980082003-03-25 05:07:42 +0000661 int len;
paul718e3742002-12-13 20:15:29 +0000662
paul020709f2003-04-04 02:44:16 +0000663 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +0000664 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +0000665 return NULL;
666
667 if (exact)
668 {
669 /* Length is insufficient to lookup OSPF area. */
670 if (*length - v->namelen != sizeof (struct in_addr))
671 return NULL;
672
673 oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr);
674
paul68980082003-03-25 05:07:42 +0000675 area = ospf_area_lookup_by_area_id (ospf, *addr);
paul718e3742002-12-13 20:15:29 +0000676
677 return area;
678 }
679 else
680 {
681 len = *length - v->namelen;
682 if (len > 4)
683 len = 4;
684
685 oid2in_addr (name + v->namelen, len, addr);
686
paul68980082003-03-25 05:07:42 +0000687 area = ospf_area_lookup_next (ospf, addr, len == 0 ? 1 : 0);
paul718e3742002-12-13 20:15:29 +0000688
689 if (area == NULL)
690 return NULL;
691
692 oid_copy_addr (name + v->namelen, addr, sizeof (struct in_addr));
693 *length = sizeof (struct in_addr) + v->namelen;
694
695 return area;
696 }
697 return NULL;
698}
699
700static u_char *
701ospfAreaEntry (struct variable *v, oid *name, size_t *length, int exact,
702 size_t *var_len, WriteMethod **write_method)
703{
704 struct ospf_area *area;
705 struct in_addr addr;
706
707 memset (&addr, 0, sizeof (struct in_addr));
708
709 area = ospfAreaLookup (v, name, length, &addr, exact);
710 if (! area)
711 return NULL;
712
713 /* Return the current value of the variable */
714 switch (v->magic)
715 {
716 case OSPFAREAID: /* 1 */
717 return SNMP_IPADDRESS (area->area_id);
718 break;
719 case OSPFAUTHTYPE: /* 2 */
720 return SNMP_INTEGER (area->auth_type);
721 break;
722 case OSPFIMPORTASEXTERN: /* 3 */
723 return SNMP_INTEGER (area->external_routing + 1);
724 break;
725 case OSPFSPFRUNS: /* 4 */
726 return SNMP_INTEGER (area->spf_calculation);
727 break;
728 case OSPFAREABDRRTRCOUNT: /* 5 */
729 return SNMP_INTEGER (area->abr_count);
730 break;
731 case OSPFASBDRRTRCOUNT: /* 6 */
732 return SNMP_INTEGER (area->asbr_count);
733 break;
734 case OSPFAREALSACOUNT: /* 7 */
735 return SNMP_INTEGER (area->lsdb->total);
736 break;
737 case OSPFAREALSACKSUMSUM: /* 8 */
738 return SNMP_INTEGER (0);
739 break;
740 case OSPFAREASUMMARY: /* 9 */
741#define OSPF_noAreaSummary 1
742#define OSPF_sendAreaSummary 2
743 if (area->no_summary)
744 return SNMP_INTEGER (OSPF_noAreaSummary);
745 else
746 return SNMP_INTEGER (OSPF_sendAreaSummary);
747 break;
748 case OSPFAREASTATUS: /* 10 */
749 return SNMP_INTEGER (SNMP_VALID);
750 break;
751 default:
752 return NULL;
753 break;
754 }
755 return NULL;
756}
757
Chris Caputo0be8dfb2009-06-02 18:40:07 +0100758static struct ospf_area *
paul718e3742002-12-13 20:15:29 +0000759ospf_stub_area_lookup_next (struct in_addr *area_id, int first)
760{
761 struct ospf_area *area;
paulaa20c6f2004-10-07 14:19:36 +0000762 struct listnode *node;
paul020709f2003-04-04 02:44:16 +0000763 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000764
paul020709f2003-04-04 02:44:16 +0000765 ospf = ospf_lookup ();
766 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +0000767 return NULL;
768
paul1eb8ef22005-04-07 07:30:20 +0000769 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
paul718e3742002-12-13 20:15:29 +0000770 {
paul718e3742002-12-13 20:15:29 +0000771 if (area->external_routing == OSPF_AREA_STUB)
772 {
773 if (first)
774 {
775 *area_id = area->area_id;
776 return area;
777 }
778 else if (ntohl (area->area_id.s_addr) > ntohl (area_id->s_addr))
779 {
780 *area_id = area->area_id;
781 return area;
782 }
783 }
784 }
785 return NULL;
786}
787
Chris Caputo0be8dfb2009-06-02 18:40:07 +0100788static struct ospf_area *
paul718e3742002-12-13 20:15:29 +0000789ospfStubAreaLookup (struct variable *v, oid name[], size_t *length,
790 struct in_addr *addr, int exact)
791{
paul020709f2003-04-04 02:44:16 +0000792 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000793 struct ospf_area *area;
paul68980082003-03-25 05:07:42 +0000794 int len;
paul718e3742002-12-13 20:15:29 +0000795
paul020709f2003-04-04 02:44:16 +0000796 ospf = ospf_lookup ();
797 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +0000798 return NULL;
799
800 /* Exact lookup. */
801 if (exact)
802 {
803 /* ospfStubAreaID + ospfStubTOS. */
804 if (*length != v->namelen + sizeof (struct in_addr) + 1)
805 return NULL;
806
807 /* Check ospfStubTOS is zero. */
808 if (name[*length - 1] != 0)
809 return NULL;
810
811 oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr);
812
paul68980082003-03-25 05:07:42 +0000813 area = ospf_area_lookup_by_area_id (ospf, *addr);
paul718e3742002-12-13 20:15:29 +0000814
815 if (area->external_routing == OSPF_AREA_STUB)
816 return area;
817 else
818 return NULL;
819 }
820 else
821 {
822 len = *length - v->namelen;
823 if (len > 4)
824 len = 4;
825
826 oid2in_addr (name + v->namelen, len, addr);
827
828 area = ospf_stub_area_lookup_next (addr, len == 0 ? 1 : 0);
829
830 if (area == NULL)
831 return NULL;
832
833 oid_copy_addr (name + v->namelen, addr, sizeof (struct in_addr));
834 /* Set TOS 0. */
835 name[v->namelen + sizeof (struct in_addr)] = 0;
836 *length = v->namelen + sizeof (struct in_addr) + 1;
837
838 return area;
839 }
840 return NULL;
841}
842
843static u_char *
844ospfStubAreaEntry (struct variable *v, oid *name, size_t *length,
845 int exact, size_t *var_len, WriteMethod **write_method)
846{
847 struct ospf_area *area;
848 struct in_addr addr;
849
850 memset (&addr, 0, sizeof (struct in_addr));
851
852 area = ospfStubAreaLookup (v, name, length, &addr, exact);
853 if (! area)
854 return NULL;
855
856 /* Return the current value of the variable */
857 switch (v->magic)
858 {
859 case OSPFSTUBAREAID: /* 1 */
860 /* OSPF stub area id. */
861 return SNMP_IPADDRESS (area->area_id);
862 break;
863 case OSPFSTUBTOS: /* 2 */
864 /* TOS value is not supported. */
865 return SNMP_INTEGER (0);
866 break;
867 case OSPFSTUBMETRIC: /* 3 */
868 /* Default cost to stub area. */
869 return SNMP_INTEGER (area->default_cost);
870 break;
871 case OSPFSTUBSTATUS: /* 4 */
872 /* Status of the stub area. */
873 return SNMP_INTEGER (SNMP_VALID);
874 break;
875 case OSPFSTUBMETRICTYPE: /* 5 */
876 /* OSPF Metric type. */
877#define OSPF_ospfMetric 1
878#define OSPF_comparableCost 2
879#define OSPF_nonComparable 3
880 return SNMP_INTEGER (OSPF_ospfMetric);
881 break;
882 default:
883 return NULL;
884 break;
885 }
886 return NULL;
887}
888
Chris Caputo0be8dfb2009-06-02 18:40:07 +0100889static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000890lsdb_lookup_next (struct ospf_area *area, u_char *type, int type_next,
891 struct in_addr *ls_id, int ls_id_next,
892 struct in_addr *router_id, int router_id_next)
893{
894 struct ospf_lsa *lsa;
895 int i;
896
897 if (type_next)
898 i = OSPF_MIN_LSA;
899 else
900 i = *type;
901
vincentba682532005-09-29 13:52:57 +0000902 /* Sanity check, if LSA type unknwon
903 merley skip any LSA */
904 if ((i < OSPF_MIN_LSA) || (i >= OSPF_MAX_LSA))
905 {
906 zlog_debug("Strange request with LSA type %d\n", i);
907 return NULL;
908 }
909
paul718e3742002-12-13 20:15:29 +0000910 for (; i < OSPF_MAX_LSA; i++)
911 {
912 *type = i;
913
914 lsa = ospf_lsdb_lookup_by_id_next (area->lsdb, *type, *ls_id, *router_id,
915 ls_id_next);
916 if (lsa)
917 return lsa;
918
919 ls_id_next = 1;
920 }
921 return NULL;
922}
923
Chris Caputo0be8dfb2009-06-02 18:40:07 +0100924static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000925ospfLsdbLookup (struct variable *v, oid *name, size_t *length,
926 struct in_addr *area_id, u_char *type,
927 struct in_addr *ls_id, struct in_addr *router_id, int exact)
928{
paul020709f2003-04-04 02:44:16 +0000929 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000930 struct ospf_area *area;
931 struct ospf_lsa *lsa;
Jorge Boncompte [DTI2]7939e012012-04-09 18:03:57 +0200932 int len;
paul718e3742002-12-13 20:15:29 +0000933 int type_next;
934 int ls_id_next;
935 int router_id_next;
936 oid *offset;
937 int offsetlen;
938
paul020709f2003-04-04 02:44:16 +0000939 ospf = ospf_lookup ();
940
paul718e3742002-12-13 20:15:29 +0000941#define OSPF_LSDB_ENTRY_OFFSET \
942 (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
943
944 if (exact)
945 {
946 /* Area ID + Type + LS ID + Router ID. */
947 if (*length - v->namelen != OSPF_LSDB_ENTRY_OFFSET)
948 return NULL;
949
950 /* Set OID offset for Area ID. */
951 offset = name + v->namelen;
952
953 /* Lookup area first. */
954 oid2in_addr (offset, IN_ADDR_SIZE, area_id);
paul68980082003-03-25 05:07:42 +0000955 area = ospf_area_lookup_by_area_id (ospf, *area_id);
paul718e3742002-12-13 20:15:29 +0000956 if (! area)
957 return NULL;
958 offset += IN_ADDR_SIZE;
959
960 /* Type. */
961 *type = *offset;
962 offset++;
963
964 /* LS ID. */
965 oid2in_addr (offset, IN_ADDR_SIZE, ls_id);
966 offset += IN_ADDR_SIZE;
967
968 /* Router ID. */
969 oid2in_addr (offset, IN_ADDR_SIZE, router_id);
970
971 /* Lookup LSDB. */
972 return ospf_lsdb_lookup_by_id (area->lsdb, *type, *ls_id, *router_id);
973 }
974 else
975 {
976 /* Get variable length. */
977 offset = name + v->namelen;
978 offsetlen = *length - v->namelen;
979 len = offsetlen;
980
981 if (len > IN_ADDR_SIZE)
982 len = IN_ADDR_SIZE;
983
984 oid2in_addr (offset, len, area_id);
985
986 /* First we search area. */
987 if (len == IN_ADDR_SIZE)
paul68980082003-03-25 05:07:42 +0000988 area = ospf_area_lookup_by_area_id (ospf, *area_id);
paul718e3742002-12-13 20:15:29 +0000989 else
Jorge Boncompte [DTI2]7939e012012-04-09 18:03:57 +0200990 area = ospf_area_lookup_next (ospf, area_id, 1);
paul718e3742002-12-13 20:15:29 +0000991
992 if (area == NULL)
993 return NULL;
994
995 do
996 {
997 /* Next we lookup type. */
Jorge Boncompte [DTI2]7939e012012-04-09 18:03:57 +0200998 offset += len;
999 offsetlen -= len;
paul718e3742002-12-13 20:15:29 +00001000 len = offsetlen;
1001
1002 if (len <= 0)
1003 type_next = 1;
1004 else
1005 {
1006 len = 1;
1007 type_next = 0;
1008 *type = *offset;
1009 }
1010
1011 /* LS ID. */
1012 offset++;
1013 offsetlen--;
1014 len = offsetlen;
1015
1016 if (len <= 0)
1017 ls_id_next = 1;
1018 else
1019 {
1020 ls_id_next = 0;
1021 if (len > IN_ADDR_SIZE)
1022 len = IN_ADDR_SIZE;
1023
1024 oid2in_addr (offset, len, ls_id);
1025 }
1026
1027 /* Router ID. */
1028 offset += IN_ADDR_SIZE;
1029 offsetlen -= IN_ADDR_SIZE;
1030 len = offsetlen;
1031
1032 if (len <= 0)
1033 router_id_next = 1;
1034 else
1035 {
1036 router_id_next = 0;
1037 if (len > IN_ADDR_SIZE)
1038 len = IN_ADDR_SIZE;
1039
1040 oid2in_addr (offset, len, router_id);
1041 }
1042
1043 lsa = lsdb_lookup_next (area, type, type_next, ls_id, ls_id_next,
1044 router_id, router_id_next);
1045
1046 if (lsa)
1047 {
1048 /* Fill in length. */
1049 *length = v->namelen + OSPF_LSDB_ENTRY_OFFSET;
1050
1051 /* Fill in value. */
1052 offset = name + v->namelen;
1053 oid_copy_addr (offset, area_id, IN_ADDR_SIZE);
1054 offset += IN_ADDR_SIZE;
1055 *offset = lsa->data->type;
1056 offset++;
1057 oid_copy_addr (offset, &lsa->data->id, IN_ADDR_SIZE);
1058 offset += IN_ADDR_SIZE;
1059 oid_copy_addr (offset, &lsa->data->adv_router, IN_ADDR_SIZE);
1060
1061 return lsa;
1062 }
1063 }
paul68980082003-03-25 05:07:42 +00001064 while ((area = ospf_area_lookup_next (ospf, area_id, 0)) != NULL);
paul718e3742002-12-13 20:15:29 +00001065 }
1066 return NULL;
1067}
1068
1069static u_char *
1070ospfLsdbEntry (struct variable *v, oid *name, size_t *length, int exact,
1071 size_t *var_len, WriteMethod **write_method)
1072{
1073 struct ospf_lsa *lsa;
1074 struct lsa_header *lsah;
1075 struct in_addr area_id;
1076 u_char type;
1077 struct in_addr ls_id;
1078 struct in_addr router_id;
paul020709f2003-04-04 02:44:16 +00001079 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001080
1081 /* INDEX { ospfLsdbAreaId, ospfLsdbType,
1082 ospfLsdbLsid, ospfLsdbRouterId } */
1083
1084 memset (&area_id, 0, sizeof (struct in_addr));
1085 type = 0;
1086 memset (&ls_id, 0, sizeof (struct in_addr));
1087 memset (&router_id, 0, sizeof (struct in_addr));
1088
1089 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00001090 ospf = ospf_lookup ();
1091 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001092 return NULL;
1093
1094 lsa = ospfLsdbLookup (v, name, length, &area_id, &type, &ls_id, &router_id,
1095 exact);
1096 if (! lsa)
1097 return NULL;
1098
1099 lsah = lsa->data;
1100
1101 /* Return the current value of the variable */
1102 switch (v->magic)
1103 {
1104 case OSPFLSDBAREAID: /* 1 */
1105 return SNMP_IPADDRESS (lsa->area->area_id);
1106 break;
1107 case OSPFLSDBTYPE: /* 2 */
1108 return SNMP_INTEGER (lsah->type);
1109 break;
1110 case OSPFLSDBLSID: /* 3 */
1111 return SNMP_IPADDRESS (lsah->id);
1112 break;
1113 case OSPFLSDBROUTERID: /* 4 */
1114 return SNMP_IPADDRESS (lsah->adv_router);
1115 break;
1116 case OSPFLSDBSEQUENCE: /* 5 */
1117 return SNMP_INTEGER (lsah->ls_seqnum);
1118 break;
1119 case OSPFLSDBAGE: /* 6 */
1120 return SNMP_INTEGER (lsah->ls_age);
1121 break;
1122 case OSPFLSDBCHECKSUM: /* 7 */
1123 return SNMP_INTEGER (lsah->checksum);
1124 break;
1125 case OSPFLSDBADVERTISEMENT: /* 8 */
1126 *var_len = ntohs (lsah->length);
1127 return (u_char *) lsah;
1128 break;
1129 default:
1130 return NULL;
1131 break;
1132 }
1133 return NULL;
1134}
1135
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001136static struct ospf_area_range *
paul718e3742002-12-13 20:15:29 +00001137ospfAreaRangeLookup (struct variable *v, oid *name, size_t *length,
1138 struct in_addr *area_id, struct in_addr *range_net,
1139 int exact)
1140{
1141 oid *offset;
1142 int offsetlen;
paul6c835672004-10-11 11:00:30 +00001143 unsigned int len;
paul020709f2003-04-04 02:44:16 +00001144 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001145 struct ospf_area *area;
1146 struct ospf_area_range *range;
1147 struct prefix_ipv4 p;
1148 p.family = AF_INET;
1149 p.prefixlen = IPV4_MAX_BITLEN;
1150
paul020709f2003-04-04 02:44:16 +00001151 ospf = ospf_lookup ();
1152
paul718e3742002-12-13 20:15:29 +00001153 if (exact)
1154 {
1155 /* Area ID + Range Network. */
1156 if (v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE != *length)
1157 return NULL;
1158
1159 /* Set OID offset for Area ID. */
1160 offset = name + v->namelen;
1161
1162 /* Lookup area first. */
1163 oid2in_addr (offset, IN_ADDR_SIZE, area_id);
1164
paul68980082003-03-25 05:07:42 +00001165 area = ospf_area_lookup_by_area_id (ospf, *area_id);
paul718e3742002-12-13 20:15:29 +00001166 if (! area)
1167 return NULL;
1168
1169 offset += IN_ADDR_SIZE;
1170
1171 /* Lookup area range. */
1172 oid2in_addr (offset, IN_ADDR_SIZE, range_net);
1173 p.prefix = *range_net;
1174
1175 return ospf_area_range_lookup (area, &p);
1176 }
1177 else
1178 {
1179 /* Set OID offset for Area ID. */
1180 offset = name + v->namelen;
1181 offsetlen = *length - v->namelen;
1182
1183 len = offsetlen;
1184 if (len > IN_ADDR_SIZE)
1185 len = IN_ADDR_SIZE;
1186
1187 oid2in_addr (offset, len, area_id);
1188
1189 /* First we search area. */
1190 if (len == IN_ADDR_SIZE)
paul68980082003-03-25 05:07:42 +00001191 area = ospf_area_lookup_by_area_id (ospf,*area_id);
paul718e3742002-12-13 20:15:29 +00001192 else
paul68980082003-03-25 05:07:42 +00001193 area = ospf_area_lookup_next (ospf, area_id, len == 0 ? 1 : 0);
paul718e3742002-12-13 20:15:29 +00001194
1195 if (area == NULL)
1196 return NULL;
1197
1198 do
1199 {
1200 offset += IN_ADDR_SIZE;
1201 offsetlen -= IN_ADDR_SIZE;
1202 len = offsetlen;
1203
1204 if (len < 0)
1205 len = 0;
1206 if (len > IN_ADDR_SIZE)
1207 len = IN_ADDR_SIZE;
1208
1209 oid2in_addr (offset, len, range_net);
1210
1211 range = ospf_area_range_lookup_next (area, range_net,
1212 len == 0 ? 1 : 0);
1213
1214 if (range)
1215 {
1216 /* Fill in length. */
1217 *length = v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE;
1218
1219 /* Fill in value. */
1220 offset = name + v->namelen;
1221 oid_copy_addr (offset, area_id, IN_ADDR_SIZE);
1222 offset += IN_ADDR_SIZE;
1223 oid_copy_addr (offset, range_net, IN_ADDR_SIZE);
1224
1225 return range;
1226 }
1227 }
paul68980082003-03-25 05:07:42 +00001228 while ((area = ospf_area_lookup_next (ospf, area_id, 0)) != NULL);
paul718e3742002-12-13 20:15:29 +00001229 }
1230 return NULL;
1231}
1232
1233static u_char *
1234ospfAreaRangeEntry (struct variable *v, oid *name, size_t *length, int exact,
1235 size_t *var_len, WriteMethod **write_method)
1236{
1237 struct ospf_area_range *range;
1238 struct in_addr area_id;
1239 struct in_addr range_net;
1240 struct in_addr mask;
paul020709f2003-04-04 02:44:16 +00001241 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001242
1243 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00001244 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00001245 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001246 return NULL;
1247
1248 memset (&area_id, 0, IN_ADDR_SIZE);
1249 memset (&range_net, 0, IN_ADDR_SIZE);
1250
1251 range = ospfAreaRangeLookup (v, name, length, &area_id, &range_net, exact);
1252 if (! range)
1253 return NULL;
1254
1255 /* Convert prefixlen to network mask format. */
1256 masklen2ip (range->subst_masklen, &mask);
1257
1258 /* Return the current value of the variable */
1259 switch (v->magic)
1260 {
1261 case OSPFAREARANGEAREAID: /* 1 */
1262 return SNMP_IPADDRESS (area_id);
1263 break;
1264 case OSPFAREARANGENET: /* 2 */
1265 return SNMP_IPADDRESS (range_net);
1266 break;
1267 case OSPFAREARANGEMASK: /* 3 */
1268 return SNMP_IPADDRESS (mask);
1269 break;
1270 case OSPFAREARANGESTATUS: /* 4 */
1271 return SNMP_INTEGER (SNMP_VALID);
1272 break;
1273 case OSPFAREARANGEEFFECT: /* 5 */
1274#define OSPF_advertiseMatching 1
1275#define OSPF_doNotAdvertiseMatching 2
1276 return SNMP_INTEGER (OSPF_advertiseMatching);
1277 break;
1278 default:
1279 return NULL;
1280 break;
1281 }
1282 return NULL;
1283}
1284
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001285static struct ospf_nbr_nbma *
paul718e3742002-12-13 20:15:29 +00001286ospfHostLookup (struct variable *v, oid *name, size_t *length,
1287 struct in_addr *addr, int exact)
1288{
1289 int len;
1290 struct ospf_nbr_nbma *nbr_nbma;
paul020709f2003-04-04 02:44:16 +00001291 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001292
paul020709f2003-04-04 02:44:16 +00001293 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00001294 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001295 return NULL;
1296
1297 if (exact)
1298 {
1299 /* INDEX { ospfHostIpAddress, ospfHostTOS } */
1300 if (*length != v->namelen + IN_ADDR_SIZE + 1)
1301 return NULL;
1302
1303 /* Check ospfHostTOS. */
1304 if (name[*length - 1] != 0)
1305 return NULL;
1306
1307 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, addr);
1308
paul68980082003-03-25 05:07:42 +00001309 nbr_nbma = ospf_nbr_nbma_lookup (ospf, *addr);
paul718e3742002-12-13 20:15:29 +00001310
1311 return nbr_nbma;
1312 }
1313 else
1314 {
1315 len = *length - v->namelen;
1316 if (len > 4)
1317 len = 4;
1318
1319 oid2in_addr (name + v->namelen, len, addr);
1320
paul68980082003-03-25 05:07:42 +00001321 nbr_nbma = ospf_nbr_nbma_lookup_next (ospf, addr, len == 0 ? 1 : 0);
paul718e3742002-12-13 20:15:29 +00001322
1323 if (nbr_nbma == NULL)
1324 return NULL;
1325
1326 oid_copy_addr (name + v->namelen, addr, IN_ADDR_SIZE);
1327
1328 /* Set TOS 0. */
1329 name[v->namelen + IN_ADDR_SIZE] = 0;
1330
1331 *length = v->namelen + IN_ADDR_SIZE + 1;
1332
1333 return nbr_nbma;
1334 }
1335 return NULL;
1336}
1337
1338static u_char *
1339ospfHostEntry (struct variable *v, oid *name, size_t *length, int exact,
1340 size_t *var_len, WriteMethod **write_method)
1341{
1342 struct ospf_nbr_nbma *nbr_nbma;
1343 struct ospf_interface *oi;
1344 struct in_addr addr;
paul020709f2003-04-04 02:44:16 +00001345 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001346
1347 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00001348 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00001349 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001350 return NULL;
1351
1352 memset (&addr, 0, sizeof (struct in_addr));
1353
1354 nbr_nbma = ospfHostLookup (v, name, length, &addr, exact);
1355 if (nbr_nbma == NULL)
1356 return NULL;
1357
1358 oi = nbr_nbma->oi;
1359
1360 /* Return the current value of the variable */
1361 switch (v->magic)
1362 {
1363 case OSPFHOSTIPADDRESS: /* 1 */
1364 return SNMP_IPADDRESS (nbr_nbma->addr);
1365 break;
1366 case OSPFHOSTTOS: /* 2 */
1367 return SNMP_INTEGER (0);
1368 break;
1369 case OSPFHOSTMETRIC: /* 3 */
1370 if (oi)
1371 return SNMP_INTEGER (oi->output_cost);
1372 else
1373 return SNMP_INTEGER (1);
1374 break;
1375 case OSPFHOSTSTATUS: /* 4 */
1376 return SNMP_INTEGER (SNMP_VALID);
1377 break;
1378 case OSPFHOSTAREAID: /* 5 */
1379 if (oi && oi->area)
1380 return SNMP_IPADDRESS (oi->area->area_id);
1381 else
1382 return SNMP_IPADDRESS (ospf_empty_addr);
1383 break;
1384 default:
1385 return NULL;
1386 break;
1387 }
1388 return NULL;
1389}
1390
1391struct list *ospf_snmp_iflist;
1392
1393struct ospf_snmp_if
1394{
1395 struct in_addr addr;
1396 unsigned int ifindex;
1397 struct interface *ifp;
1398};
1399
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001400static struct ospf_snmp_if *
Stephen Hemminger66e5cd82009-02-09 10:14:16 -08001401ospf_snmp_if_new (void)
paul718e3742002-12-13 20:15:29 +00001402{
Stephen Hemminger393deb92008-08-18 14:13:29 -07001403 return XCALLOC (0, sizeof (struct ospf_snmp_if));
paul718e3742002-12-13 20:15:29 +00001404}
1405
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001406static void
paul718e3742002-12-13 20:15:29 +00001407ospf_snmp_if_free (struct ospf_snmp_if *osif)
1408{
1409 XFREE (0, osif);
1410}
1411
1412void
1413ospf_snmp_if_delete (struct interface *ifp)
1414{
paul1eb8ef22005-04-07 07:30:20 +00001415 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001416 struct ospf_snmp_if *osif;
1417
paul1eb8ef22005-04-07 07:30:20 +00001418 for (ALL_LIST_ELEMENTS (ospf_snmp_iflist, node, nnode, osif))
paul718e3742002-12-13 20:15:29 +00001419 {
1420 if (osif->ifp == ifp)
1421 {
paul1eb8ef22005-04-07 07:30:20 +00001422 list_delete_node (ospf_snmp_iflist, node);
paul718e3742002-12-13 20:15:29 +00001423 ospf_snmp_if_free (osif);
1424 return;
1425 }
1426 }
1427}
1428
1429void
1430ospf_snmp_if_update (struct interface *ifp)
1431{
paul1eb8ef22005-04-07 07:30:20 +00001432 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001433 struct listnode *pn;
1434 struct connected *ifc;
1435 struct prefix *p;
1436 struct ospf_snmp_if *osif;
1437 struct in_addr *addr;
1438 unsigned int ifindex;
1439
1440 ospf_snmp_if_delete (ifp);
1441
1442 p = NULL;
1443 addr = NULL;
1444 ifindex = 0;
1445
1446 /* Lookup first IPv4 address entry. */
paul1eb8ef22005-04-07 07:30:20 +00001447 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc))
paul718e3742002-12-13 20:15:29 +00001448 {
Andrew J. Schorre4529632006-12-12 19:18:21 +00001449 p = CONNECTED_ID(ifc);
paul718e3742002-12-13 20:15:29 +00001450
1451 if (p->family == AF_INET)
1452 {
1453 addr = &p->u.prefix4;
1454 break;
1455 }
1456 }
1457 if (! addr)
1458 ifindex = ifp->ifindex;
1459
1460 /* Add interface to the list. */
1461 pn = NULL;
paul1eb8ef22005-04-07 07:30:20 +00001462 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, node, osif))
paul718e3742002-12-13 20:15:29 +00001463 {
1464 if (addr)
1465 {
vincent77df1f72005-10-06 07:46:22 +00001466 /* Usual interfaces --> Sort them based on interface IPv4 addresses */
paul718e3742002-12-13 20:15:29 +00001467 if (ntohl (osif->addr.s_addr) > ntohl (addr->s_addr))
1468 break;
1469 }
1470 else
1471 {
vincent77df1f72005-10-06 07:46:22 +00001472 /* Unnumbered interfaces --> Sort them based on interface indexes */
paul718e3742002-12-13 20:15:29 +00001473 if (osif->addr.s_addr != 0 || osif->ifindex > ifindex)
1474 break;
1475 }
paul1eb8ef22005-04-07 07:30:20 +00001476 pn = node;
paul718e3742002-12-13 20:15:29 +00001477 }
1478
1479 osif = ospf_snmp_if_new ();
vincent77df1f72005-10-06 07:46:22 +00001480 if (addr) /* Usual interface */
1481 {
paul718e3742002-12-13 20:15:29 +00001482 osif->addr = *addr;
vincent77df1f72005-10-06 07:46:22 +00001483
1484 /* This field is used for storing ospfAddressLessIf OID value,
1485 * conform to RFC1850 OSPF-MIB specification, it must be 0 for
1486 * usual interface */
1487 osif->ifindex = 0;
1488 }
1489 else /* Unnumbered interface */
paul718e3742002-12-13 20:15:29 +00001490 osif->ifindex = ifindex;
1491 osif->ifp = ifp;
1492
1493 listnode_add_after (ospf_snmp_iflist, pn, osif);
1494}
1495
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001496static int
vincent77df1f72005-10-06 07:46:22 +00001497ospf_snmp_is_if_have_addr (struct interface *ifp)
1498{
vincent77df1f72005-10-06 07:46:22 +00001499 struct listnode *nn;
1500 struct connected *ifc;
1501
1502 /* Is this interface having any connected IPv4 address ? */
1503 for (ALL_LIST_ELEMENTS_RO (ifp->connected, nn, ifc))
1504 {
Andrew J. Schorre4529632006-12-12 19:18:21 +00001505 if (CONNECTED_PREFIX(ifc)->family == AF_INET)
vincent77df1f72005-10-06 07:46:22 +00001506 return 1;
1507 }
1508
1509 return 0;
1510}
1511
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001512static struct ospf_interface *
paul718e3742002-12-13 20:15:29 +00001513ospf_snmp_if_lookup (struct in_addr *ifaddr, unsigned int *ifindex)
1514{
paul1eb8ef22005-04-07 07:30:20 +00001515 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001516 struct ospf_snmp_if *osif;
vincent77df1f72005-10-06 07:46:22 +00001517 struct ospf_interface *oi = NULL;
1518 struct ospf *ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +00001519
paul1eb8ef22005-04-07 07:30:20 +00001520 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, node, osif))
paul718e3742002-12-13 20:15:29 +00001521 {
1522 if (ifaddr->s_addr)
vincent77df1f72005-10-06 07:46:22 +00001523 {
1524 if (IPV4_ADDR_SAME (&osif->addr, ifaddr))
1525 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1526 }
paul718e3742002-12-13 20:15:29 +00001527 else
vincent77df1f72005-10-06 07:46:22 +00001528 {
1529 if (osif->ifindex == *ifindex)
1530 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1531 }
paul718e3742002-12-13 20:15:29 +00001532 }
vincent77df1f72005-10-06 07:46:22 +00001533 return oi;
paul718e3742002-12-13 20:15:29 +00001534}
1535
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001536static struct ospf_interface *
paul718e3742002-12-13 20:15:29 +00001537ospf_snmp_if_lookup_next (struct in_addr *ifaddr, unsigned int *ifindex,
1538 int ifaddr_next, int ifindex_next)
1539{
1540 struct ospf_snmp_if *osif;
1541 struct listnode *nn;
vincent77df1f72005-10-06 07:46:22 +00001542 struct ospf *ospf = ospf_lookup ();
1543 struct ospf_interface *oi = NULL;
paul718e3742002-12-13 20:15:29 +00001544
vincent77df1f72005-10-06 07:46:22 +00001545 if (ospf == NULL)
1546 return NULL;
1547
1548 /* No instance is specified --> Return the first OSPF interface */
paul718e3742002-12-13 20:15:29 +00001549 if (ifaddr_next)
1550 {
vincent77df1f72005-10-06 07:46:22 +00001551 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, nn, osif))
paul718e3742002-12-13 20:15:29 +00001552 {
paul1eb8ef22005-04-07 07:30:20 +00001553 osif = listgetdata (nn);
paul718e3742002-12-13 20:15:29 +00001554 *ifaddr = osif->addr;
1555 *ifindex = osif->ifindex;
vincent77df1f72005-10-06 07:46:22 +00001556 /* Because no instance is specified, we don't care about the kind of
1557 * interface (usual or unnumbered), just returning the first valid
1558 * OSPF interface */
1559 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1560 if (oi)
1561 return (oi);
paul718e3742002-12-13 20:15:29 +00001562 }
1563 return NULL;
1564 }
1565
vincent77df1f72005-10-06 07:46:22 +00001566 /* An instance is specified --> Return the next OSPF interface */
paul1eb8ef22005-04-07 07:30:20 +00001567 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, nn, osif))
paul718e3742002-12-13 20:15:29 +00001568 {
vincent77df1f72005-10-06 07:46:22 +00001569 /* Usual interface */
1570 if (ifaddr->s_addr)
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001571 {
1572 /* The interface must have valid AF_INET connected address */
1573 /* it must have lager IPv4 address value than the lookup entry */
1574 if ((ospf_snmp_is_if_have_addr(osif->ifp)) &&
1575 (ntohl (osif->addr.s_addr) > ntohl (ifaddr->s_addr)))
1576 {
1577 *ifaddr = osif->addr;
1578 *ifindex = osif->ifindex;
vincent77df1f72005-10-06 07:46:22 +00001579
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001580 /* and it must be an OSPF interface */
1581 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1582 if (oi)
1583 return oi;
1584 }
1585 }
vincent77df1f72005-10-06 07:46:22 +00001586 /* Unnumbered interface */
1587 else
1588 /* The interface must NOT have valid AF_INET connected address */
1589 /* it must have lager interface index than the lookup entry */
1590 if ((!ospf_snmp_is_if_have_addr(osif->ifp)) &&
1591 (osif->ifindex > *ifindex))
1592 {
1593 *ifaddr = osif->addr;
1594 *ifindex = osif->ifindex;
1595
1596 /* and it must be an OSPF interface */
1597 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1598 if (oi)
1599 return oi;
1600 }
paul718e3742002-12-13 20:15:29 +00001601 }
1602 return NULL;
1603}
1604
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001605static int
paul718e3742002-12-13 20:15:29 +00001606ospf_snmp_iftype (struct interface *ifp)
1607{
1608#define ospf_snmp_iftype_broadcast 1
1609#define ospf_snmp_iftype_nbma 2
1610#define ospf_snmp_iftype_pointToPoint 3
1611#define ospf_snmp_iftype_pointToMultipoint 5
1612 if (if_is_broadcast (ifp))
1613 return ospf_snmp_iftype_broadcast;
1614 if (if_is_pointopoint (ifp))
1615 return ospf_snmp_iftype_pointToPoint;
1616 return ospf_snmp_iftype_broadcast;
1617}
1618
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001619static struct ospf_interface *
paul718e3742002-12-13 20:15:29 +00001620ospfIfLookup (struct variable *v, oid *name, size_t *length,
1621 struct in_addr *ifaddr, unsigned int *ifindex, int exact)
1622{
paul6c835672004-10-11 11:00:30 +00001623 unsigned int len;
paul718e3742002-12-13 20:15:29 +00001624 int ifaddr_next = 0;
1625 int ifindex_next = 0;
vincent77df1f72005-10-06 07:46:22 +00001626 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001627 oid *offset;
1628
1629 if (exact)
1630 {
1631 if (*length != v->namelen + IN_ADDR_SIZE + 1)
1632 return NULL;
1633
1634 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, ifaddr);
1635 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1636
1637 return ospf_snmp_if_lookup (ifaddr, ifindex);
1638 }
1639 else
1640 {
1641 len = *length - v->namelen;
1642 if (len >= IN_ADDR_SIZE)
1643 len = IN_ADDR_SIZE;
1644 if (len <= 0)
1645 ifaddr_next = 1;
1646
1647 oid2in_addr (name + v->namelen, len, ifaddr);
1648
1649 len = *length - v->namelen - IN_ADDR_SIZE;
1650 if (len >= 1)
1651 len = 1;
1652 else
1653 ifindex_next = 1;
1654
1655 if (len == 1)
1656 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1657
vincent77df1f72005-10-06 07:46:22 +00001658 oi = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next,
paul718e3742002-12-13 20:15:29 +00001659 ifindex_next);
vincent77df1f72005-10-06 07:46:22 +00001660 if (oi)
paul718e3742002-12-13 20:15:29 +00001661 {
1662 *length = v->namelen + IN_ADDR_SIZE + 1;
1663 offset = name + v->namelen;
1664 oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE);
1665 offset += IN_ADDR_SIZE;
1666 *offset = *ifindex;
vincent77df1f72005-10-06 07:46:22 +00001667 return oi;
paul718e3742002-12-13 20:15:29 +00001668 }
1669 }
1670 return NULL;
1671}
1672
1673static u_char *
1674ospfIfEntry (struct variable *v, oid *name, size_t *length, int exact,
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001675 size_t *var_len, WriteMethod **write_method)
paul718e3742002-12-13 20:15:29 +00001676{
paul718e3742002-12-13 20:15:29 +00001677 unsigned int ifindex;
1678 struct in_addr ifaddr;
1679 struct ospf_interface *oi;
paul020709f2003-04-04 02:44:16 +00001680 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001681
1682 ifindex = 0;
1683 memset (&ifaddr, 0, sizeof (struct in_addr));
1684
1685 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00001686 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00001687 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001688 return NULL;
1689
vincent77df1f72005-10-06 07:46:22 +00001690 oi = ospfIfLookup (v, name, length, &ifaddr, &ifindex, exact);
paul718e3742002-12-13 20:15:29 +00001691 if (oi == NULL)
1692 return NULL;
1693
1694 /* Return the current value of the variable */
1695 switch (v->magic)
1696 {
1697 case OSPFIFIPADDRESS: /* 1 */
1698 return SNMP_IPADDRESS (ifaddr);
1699 break;
1700 case OSPFADDRESSLESSIF: /* 2 */
1701 return SNMP_INTEGER (ifindex);
1702 break;
1703 case OSPFIFAREAID: /* 3 */
1704 if (oi->area)
1705 return SNMP_IPADDRESS (oi->area->area_id);
1706 else
1707 return SNMP_IPADDRESS (ospf_empty_addr);
1708 break;
1709 case OSPFIFTYPE: /* 4 */
vincent77df1f72005-10-06 07:46:22 +00001710 return SNMP_INTEGER (ospf_snmp_iftype (oi->ifp));
paul718e3742002-12-13 20:15:29 +00001711 break;
1712 case OSPFIFADMINSTAT: /* 5 */
1713 if (oi)
1714 return SNMP_INTEGER (OSPF_STATUS_ENABLED);
1715 else
1716 return SNMP_INTEGER (OSPF_STATUS_DISABLED);
1717 break;
1718 case OSPFIFRTRPRIORITY: /* 6 */
1719 return SNMP_INTEGER (PRIORITY (oi));
1720 break;
1721 case OSPFIFTRANSITDELAY: /* 7 */
1722 return SNMP_INTEGER (OSPF_IF_PARAM (oi, transmit_delay));
1723 break;
1724 case OSPFIFRETRANSINTERVAL: /* 8 */
1725 return SNMP_INTEGER (OSPF_IF_PARAM (oi, retransmit_interval));
1726 break;
1727 case OSPFIFHELLOINTERVAL: /* 9 */
1728 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_hello));
1729 break;
1730 case OSPFIFRTRDEADINTERVAL: /* 10 */
1731 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_wait));
1732 break;
1733 case OSPFIFPOLLINTERVAL: /* 11 */
1734 return SNMP_INTEGER (OSPF_POLL_INTERVAL_DEFAULT);
1735 break;
1736 case OSPFIFSTATE: /* 12 */
vincentba682532005-09-29 13:52:57 +00001737 return SNMP_INTEGER (ISM_SNMP(oi->state));
paul718e3742002-12-13 20:15:29 +00001738 break;
1739 case OSPFIFDESIGNATEDROUTER: /* 13 */
1740 return SNMP_IPADDRESS (DR (oi));
1741 break;
1742 case OSPFIFBACKUPDESIGNATEDROUTER: /* 14 */
1743 return SNMP_IPADDRESS (BDR (oi));
1744 break;
1745 case OSPFIFEVENTS: /* 15 */
1746 return SNMP_INTEGER (oi->state_change);
1747 break;
1748 case OSPFIFAUTHKEY: /* 16 */
1749 *var_len = 0;
1750 return (u_char *) OSPF_IF_PARAM (oi, auth_simple);
1751 break;
1752 case OSPFIFSTATUS: /* 17 */
1753 return SNMP_INTEGER (SNMP_VALID);
1754 break;
1755 case OSPFIFMULTICASTFORWARDING: /* 18 */
1756#define ospf_snmp_multiforward_blocked 1
1757#define ospf_snmp_multiforward_multicast 2
1758#define ospf_snmp_multiforward_unicast 3
1759 return SNMP_INTEGER (ospf_snmp_multiforward_blocked);
1760 break;
1761 case OSPFIFDEMAND: /* 19 */
1762 return SNMP_INTEGER (SNMP_FALSE);
1763 break;
1764 case OSPFIFAUTHTYPE: /* 20 */
1765 if (oi->area)
1766 return SNMP_INTEGER (oi->area->auth_type);
1767 else
1768 return SNMP_INTEGER (0);
1769 break;
1770 default:
1771 return NULL;
1772 break;
1773 }
1774 return NULL;
1775}
1776
1777#define OSPF_SNMP_METRIC_VALUE 1
1778
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001779static struct ospf_interface *
paul718e3742002-12-13 20:15:29 +00001780ospfIfMetricLookup (struct variable *v, oid *name, size_t *length,
1781 struct in_addr *ifaddr, unsigned int *ifindex, int exact)
1782{
paul6c835672004-10-11 11:00:30 +00001783 unsigned int len;
paul718e3742002-12-13 20:15:29 +00001784 int ifaddr_next = 0;
1785 int ifindex_next = 0;
vincent77df1f72005-10-06 07:46:22 +00001786 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001787 oid *offset;
1788 int metric;
1789
1790 if (exact)
1791 {
1792 if (*length != v->namelen + IN_ADDR_SIZE + 1 + 1)
1793 return NULL;
1794
1795 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, ifaddr);
1796 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1797 metric = name[v->namelen + IN_ADDR_SIZE + 1];
1798
1799 if (metric != OSPF_SNMP_METRIC_VALUE)
1800 return NULL;
1801
1802 return ospf_snmp_if_lookup (ifaddr, ifindex);
1803 }
1804 else
1805 {
1806 len = *length - v->namelen;
1807 if (len >= IN_ADDR_SIZE)
1808 len = IN_ADDR_SIZE;
1809 else
1810 ifaddr_next = 1;
1811
1812 oid2in_addr (name + v->namelen, len, ifaddr);
1813
1814 len = *length - v->namelen - IN_ADDR_SIZE;
1815 if (len >= 1)
1816 len = 1;
1817 else
1818 ifindex_next = 1;
1819
1820 if (len == 1)
1821 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1822
vincent77df1f72005-10-06 07:46:22 +00001823 oi = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next,
paul718e3742002-12-13 20:15:29 +00001824 ifindex_next);
vincent77df1f72005-10-06 07:46:22 +00001825 if (oi)
paul718e3742002-12-13 20:15:29 +00001826 {
1827 *length = v->namelen + IN_ADDR_SIZE + 1 + 1;
1828 offset = name + v->namelen;
1829 oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE);
1830 offset += IN_ADDR_SIZE;
1831 *offset = *ifindex;
1832 offset++;
1833 *offset = OSPF_SNMP_METRIC_VALUE;
vincent77df1f72005-10-06 07:46:22 +00001834 return oi;
paul718e3742002-12-13 20:15:29 +00001835 }
1836 }
1837 return NULL;
1838}
1839
1840static u_char *
1841ospfIfMetricEntry (struct variable *v, oid *name, size_t *length, int exact,
1842 size_t *var_len, WriteMethod **write_method)
1843{
1844 /* Currently we support metric 1 only. */
paul718e3742002-12-13 20:15:29 +00001845 unsigned int ifindex;
1846 struct in_addr ifaddr;
1847 struct ospf_interface *oi;
paul020709f2003-04-04 02:44:16 +00001848 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001849
1850 ifindex = 0;
1851 memset (&ifaddr, 0, sizeof (struct in_addr));
1852
1853 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00001854 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00001855 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001856 return NULL;
1857
vincent77df1f72005-10-06 07:46:22 +00001858 oi = ospfIfMetricLookup (v, name, length, &ifaddr, &ifindex, exact);
paul718e3742002-12-13 20:15:29 +00001859 if (oi == NULL)
1860 return NULL;
1861
1862 /* Return the current value of the variable */
1863 switch (v->magic)
1864 {
1865 case OSPFIFMETRICIPADDRESS:
1866 return SNMP_IPADDRESS (ifaddr);
1867 break;
1868 case OSPFIFMETRICADDRESSLESSIF:
1869 return SNMP_INTEGER (ifindex);
1870 break;
1871 case OSPFIFMETRICTOS:
1872 return SNMP_INTEGER (0);
1873 break;
1874 case OSPFIFMETRICVALUE:
1875 return SNMP_INTEGER (OSPF_SNMP_METRIC_VALUE);
1876 break;
1877 case OSPFIFMETRICSTATUS:
1878 return SNMP_INTEGER (1);
1879 break;
1880 default:
1881 return NULL;
1882 break;
1883 }
1884 return NULL;
1885}
1886
1887struct route_table *ospf_snmp_vl_table;
1888
1889void
1890ospf_snmp_vl_add (struct ospf_vl_data *vl_data)
1891{
1892 struct prefix_ls lp;
1893 struct route_node *rn;
1894
1895 memset (&lp, 0, sizeof (struct prefix_ls));
1896 lp.family = 0;
1897 lp.prefixlen = 64;
1898 lp.id = vl_data->vl_area_id;
1899 lp.adv_router = vl_data->vl_peer;
1900
1901 rn = route_node_get (ospf_snmp_vl_table, (struct prefix *) &lp);
1902 rn->info = vl_data;
1903}
1904
1905void
1906ospf_snmp_vl_delete (struct ospf_vl_data *vl_data)
1907{
1908 struct prefix_ls lp;
1909 struct route_node *rn;
1910
1911 memset (&lp, 0, sizeof (struct prefix_ls));
1912 lp.family = 0;
1913 lp.prefixlen = 64;
1914 lp.id = vl_data->vl_area_id;
1915 lp.adv_router = vl_data->vl_peer;
1916
1917 rn = route_node_lookup (ospf_snmp_vl_table, (struct prefix *) &lp);
1918 if (! rn)
1919 return;
1920 rn->info = NULL;
1921 route_unlock_node (rn);
1922 route_unlock_node (rn);
1923}
1924
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001925static struct ospf_vl_data *
paul718e3742002-12-13 20:15:29 +00001926ospf_snmp_vl_lookup (struct in_addr *area_id, struct in_addr *neighbor)
1927{
1928 struct prefix_ls lp;
1929 struct route_node *rn;
1930 struct ospf_vl_data *vl_data;
1931
1932 memset (&lp, 0, sizeof (struct prefix_ls));
1933 lp.family = 0;
1934 lp.prefixlen = 64;
1935 lp.id = *area_id;
1936 lp.adv_router = *neighbor;
1937
1938 rn = route_node_lookup (ospf_snmp_vl_table, (struct prefix *) &lp);
1939 if (rn)
1940 {
1941 vl_data = rn->info;
1942 route_unlock_node (rn);
1943 return vl_data;
1944 }
1945 return NULL;
1946}
1947
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001948static struct ospf_vl_data *
paul718e3742002-12-13 20:15:29 +00001949ospf_snmp_vl_lookup_next (struct in_addr *area_id, struct in_addr *neighbor,
1950 int first)
1951{
1952 struct prefix_ls lp;
1953 struct route_node *rn;
1954 struct ospf_vl_data *vl_data;
1955
1956 memset (&lp, 0, sizeof (struct prefix_ls));
1957 lp.family = 0;
1958 lp.prefixlen = 64;
1959 lp.id = *area_id;
1960 lp.adv_router = *neighbor;
1961
1962 if (first)
1963 rn = route_top (ospf_snmp_vl_table);
1964 else
1965 {
1966 rn = route_node_get (ospf_snmp_vl_table, (struct prefix *) &lp);
1967 rn = route_next (rn);
1968 }
1969
1970 for (; rn; rn = route_next (rn))
1971 if (rn->info)
1972 break;
1973
1974 if (rn && rn->info)
1975 {
1976 vl_data = rn->info;
1977 *area_id = vl_data->vl_area_id;
1978 *neighbor = vl_data->vl_peer;
1979 route_unlock_node (rn);
1980 return vl_data;
1981 }
1982 return NULL;
1983}
1984
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001985static struct ospf_vl_data *
paul718e3742002-12-13 20:15:29 +00001986ospfVirtIfLookup (struct variable *v, oid *name, size_t *length,
1987 struct in_addr *area_id, struct in_addr *neighbor, int exact)
1988{
1989 int first;
paul6c835672004-10-11 11:00:30 +00001990 unsigned int len;
paul718e3742002-12-13 20:15:29 +00001991 struct ospf_vl_data *vl_data;
1992
1993 if (exact)
1994 {
1995 if (*length != v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE)
1996 return NULL;
1997
1998 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, area_id);
1999 oid2in_addr (name + v->namelen + IN_ADDR_SIZE, IN_ADDR_SIZE, neighbor);
2000
2001 return ospf_snmp_vl_lookup (area_id, neighbor);
2002 }
2003 else
2004 {
2005 first = 0;
2006
2007 len = *length - v->namelen;
2008 if (len <= 0)
2009 first = 1;
2010 if (len > IN_ADDR_SIZE)
2011 len = IN_ADDR_SIZE;
2012 oid2in_addr (name + v->namelen, len, area_id);
2013
2014 len = *length - v->namelen - IN_ADDR_SIZE;
2015 if (len > IN_ADDR_SIZE)
2016 len = IN_ADDR_SIZE;
2017 oid2in_addr (name + v->namelen + IN_ADDR_SIZE, len, neighbor);
2018
2019 vl_data = ospf_snmp_vl_lookup_next (area_id, neighbor, first);
2020
2021 if (vl_data)
2022 {
2023 *length = v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE;
2024 oid_copy_addr (name + v->namelen, area_id, IN_ADDR_SIZE);
2025 oid_copy_addr (name + v->namelen + IN_ADDR_SIZE, neighbor,
2026 IN_ADDR_SIZE);
2027 return vl_data;
2028 }
2029 }
2030 return NULL;
2031}
2032
2033static u_char *
2034ospfVirtIfEntry (struct variable *v, oid *name, size_t *length, int exact,
Chris Caputo0be8dfb2009-06-02 18:40:07 +01002035 size_t *var_len, WriteMethod **write_method)
paul718e3742002-12-13 20:15:29 +00002036{
2037 struct ospf_vl_data *vl_data;
2038 struct ospf_interface *oi;
2039 struct in_addr area_id;
2040 struct in_addr neighbor;
2041
2042 memset (&area_id, 0, sizeof (struct in_addr));
2043 memset (&neighbor, 0, sizeof (struct in_addr));
2044
2045 vl_data = ospfVirtIfLookup (v, name, length, &area_id, &neighbor, exact);
2046 if (! vl_data)
2047 return NULL;
2048 oi = vl_data->vl_oi;
2049 if (! oi)
2050 return NULL;
2051
2052 /* Return the current value of the variable */
2053 switch (v->magic)
2054 {
2055 case OSPFVIRTIFAREAID:
2056 return SNMP_IPADDRESS (area_id);
2057 break;
2058 case OSPFVIRTIFNEIGHBOR:
2059 return SNMP_IPADDRESS (neighbor);
2060 break;
2061 case OSPFVIRTIFTRANSITDELAY:
2062 return SNMP_INTEGER (OSPF_IF_PARAM (oi, transmit_delay));
2063 break;
2064 case OSPFVIRTIFRETRANSINTERVAL:
2065 return SNMP_INTEGER (OSPF_IF_PARAM (oi, retransmit_interval));
2066 break;
2067 case OSPFVIRTIFHELLOINTERVAL:
2068 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_hello));
2069 break;
2070 case OSPFVIRTIFRTRDEADINTERVAL:
2071 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_wait));
2072 break;
2073 case OSPFVIRTIFSTATE:
2074 return SNMP_INTEGER (oi->state);
2075 break;
2076 case OSPFVIRTIFEVENTS:
2077 return SNMP_INTEGER (oi->state_change);
2078 break;
2079 case OSPFVIRTIFAUTHKEY:
2080 *var_len = 0;
2081 return (u_char *) OSPF_IF_PARAM (oi, auth_simple);
2082 break;
2083 case OSPFVIRTIFSTATUS:
2084 return SNMP_INTEGER (SNMP_VALID);
2085 break;
2086 case OSPFVIRTIFAUTHTYPE:
2087 if (oi->area)
2088 return SNMP_INTEGER (oi->area->auth_type);
2089 else
2090 return SNMP_INTEGER (0);
2091 break;
2092 default:
2093 return NULL;
2094 break;
2095 }
2096 return NULL;
2097}
2098
Chris Caputo0be8dfb2009-06-02 18:40:07 +01002099static struct ospf_neighbor *
paul68980082003-03-25 05:07:42 +00002100ospf_snmp_nbr_lookup (struct ospf *ospf, struct in_addr *nbr_addr,
2101 unsigned int *ifindex)
paul718e3742002-12-13 20:15:29 +00002102{
paul1eb8ef22005-04-07 07:30:20 +00002103 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002104 struct ospf_interface *oi;
2105 struct ospf_neighbor *nbr;
2106 struct route_node *rn;
2107
paul1eb8ef22005-04-07 07:30:20 +00002108 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002109 {
2110 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2111 if ((nbr = rn->info) != NULL
2112 && nbr != oi->nbr_self
vincent5e4914c2005-09-29 16:34:30 +00002113/* If EXACT match is needed, provide ALL entry found
paul718e3742002-12-13 20:15:29 +00002114 && nbr->state != NSM_Down
vincent5e4914c2005-09-29 16:34:30 +00002115 */
paul718e3742002-12-13 20:15:29 +00002116 && nbr->src.s_addr != 0)
2117 {
2118 if (IPV4_ADDR_SAME (&nbr->src, nbr_addr))
2119 {
2120 route_unlock_node (rn);
2121 return nbr;
2122 }
2123 }
2124 }
2125 return NULL;
2126}
2127
Chris Caputo0be8dfb2009-06-02 18:40:07 +01002128static struct ospf_neighbor *
paul718e3742002-12-13 20:15:29 +00002129ospf_snmp_nbr_lookup_next (struct in_addr *nbr_addr, unsigned int *ifindex,
2130 int first)
2131{
2132 struct listnode *nn;
2133 struct ospf_interface *oi;
2134 struct ospf_neighbor *nbr;
2135 struct route_node *rn;
2136 struct ospf_neighbor *min = NULL;
paul020709f2003-04-04 02:44:16 +00002137 struct ospf *ospf = ospf;
paul718e3742002-12-13 20:15:29 +00002138
paul020709f2003-04-04 02:44:16 +00002139 ospf = ospf_lookup ();
paul1eb8ef22005-04-07 07:30:20 +00002140
2141 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, nn, oi))
paul718e3742002-12-13 20:15:29 +00002142 {
2143 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2144 if ((nbr = rn->info) != NULL
2145 && nbr != oi->nbr_self
2146 && nbr->state != NSM_Down
2147 && nbr->src.s_addr != 0)
2148 {
2149 if (first)
2150 {
2151 if (! min)
2152 min = nbr;
2153 else if (ntohl (nbr->src.s_addr) < ntohl (min->src.s_addr))
2154 min = nbr;
2155 }
2156 else if (ntohl (nbr->src.s_addr) > ntohl (nbr_addr->s_addr))
2157 {
2158 if (! min)
2159 min = nbr;
2160 else if (ntohl (nbr->src.s_addr) < ntohl (min->src.s_addr))
2161 min = nbr;
2162 }
2163 }
2164 }
2165 if (min)
2166 {
2167 *nbr_addr = min->src;
2168 *ifindex = 0;
2169 return min;
2170 }
2171 return NULL;
2172}
2173
Chris Caputo0be8dfb2009-06-02 18:40:07 +01002174static struct ospf_neighbor *
paul718e3742002-12-13 20:15:29 +00002175ospfNbrLookup (struct variable *v, oid *name, size_t *length,
2176 struct in_addr *nbr_addr, unsigned int *ifindex, int exact)
2177{
paul6c835672004-10-11 11:00:30 +00002178 unsigned int len;
paul718e3742002-12-13 20:15:29 +00002179 int first;
2180 struct ospf_neighbor *nbr;
paul020709f2003-04-04 02:44:16 +00002181 struct ospf *ospf;
2182
2183 ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +00002184
hasso1b639042005-03-27 13:32:25 +00002185 if (! ospf)
2186 return NULL;
2187
paul718e3742002-12-13 20:15:29 +00002188 if (exact)
2189 {
2190 if (*length != v->namelen + IN_ADDR_SIZE + 1)
2191 return NULL;
2192
2193 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, nbr_addr);
2194 *ifindex = name[v->namelen + IN_ADDR_SIZE];
2195
paul68980082003-03-25 05:07:42 +00002196 return ospf_snmp_nbr_lookup (ospf, nbr_addr, ifindex);
paul718e3742002-12-13 20:15:29 +00002197 }
2198 else
2199 {
2200 first = 0;
2201 len = *length - v->namelen;
2202
2203 if (len <= 0)
2204 first = 1;
2205
2206 if (len > IN_ADDR_SIZE)
2207 len = IN_ADDR_SIZE;
2208
2209 oid2in_addr (name + v->namelen, len, nbr_addr);
2210
2211 len = *length - v->namelen - IN_ADDR_SIZE;
2212 if (len >= 1)
2213 *ifindex = name[v->namelen + IN_ADDR_SIZE];
2214
2215 nbr = ospf_snmp_nbr_lookup_next (nbr_addr, ifindex, first);
2216
2217 if (nbr)
2218 {
2219 *length = v->namelen + IN_ADDR_SIZE + 1;
2220 oid_copy_addr (name + v->namelen, nbr_addr, IN_ADDR_SIZE);
2221 name[v->namelen + IN_ADDR_SIZE] = *ifindex;
2222 return nbr;
2223 }
2224 }
2225 return NULL;
2226}
2227
Andrew J. Schorrad81f8c2007-03-14 22:05:18 +00002228/* map internal quagga neighbor states to official MIB values:
2229
2230ospfNbrState OBJECT-TYPE
2231 SYNTAX INTEGER {
2232 down (1),
2233 attempt (2),
2234 init (3),
2235 twoWay (4),
2236 exchangeStart (5),
2237 exchange (6),
2238 loading (7),
2239 full (8)
2240 }
2241*/
2242static int32_t
2243ospf_snmp_neighbor_state(u_char nst)
2244{
2245 switch (nst)
2246 {
2247 case NSM_Attempt:
2248 return 2;
2249 case NSM_Init:
2250 return 3;
2251 case NSM_TwoWay:
2252 return 4;
2253 case NSM_ExStart:
2254 return 5;
2255 case NSM_Exchange:
2256 return 6;
2257 case NSM_Loading:
2258 return 7;
2259 case NSM_Full:
2260 return 8;
2261 default:
2262 return 1; /* down */
2263 }
2264}
2265
paul718e3742002-12-13 20:15:29 +00002266static u_char *
2267ospfNbrEntry (struct variable *v, oid *name, size_t *length, int exact,
Chris Caputo0be8dfb2009-06-02 18:40:07 +01002268 size_t *var_len, WriteMethod **write_method)
paul718e3742002-12-13 20:15:29 +00002269{
2270 struct in_addr nbr_addr;
2271 unsigned int ifindex;
2272 struct ospf_neighbor *nbr;
2273 struct ospf_interface *oi;
2274
2275 memset (&nbr_addr, 0, sizeof (struct in_addr));
2276 ifindex = 0;
2277
2278 nbr = ospfNbrLookup (v, name, length, &nbr_addr, &ifindex, exact);
2279 if (! nbr)
2280 return NULL;
2281 oi = nbr->oi;
2282 if (! oi)
2283 return NULL;
2284
2285 /* Return the current value of the variable */
2286 switch (v->magic)
2287 {
2288 case OSPFNBRIPADDR:
2289 return SNMP_IPADDRESS (nbr_addr);
2290 break;
2291 case OSPFNBRADDRESSLESSINDEX:
2292 return SNMP_INTEGER (ifindex);
2293 break;
2294 case OSPFNBRRTRID:
2295 return SNMP_IPADDRESS (nbr->router_id);
2296 break;
2297 case OSPFNBROPTIONS:
2298 return SNMP_INTEGER (oi->nbr_self->options);
2299 break;
2300 case OSPFNBRPRIORITY:
2301 return SNMP_INTEGER (nbr->priority);
2302 break;
2303 case OSPFNBRSTATE:
Andrew J. Schorrad81f8c2007-03-14 22:05:18 +00002304 return SNMP_INTEGER (ospf_snmp_neighbor_state(nbr->state));
paul718e3742002-12-13 20:15:29 +00002305 break;
2306 case OSPFNBREVENTS:
2307 return SNMP_INTEGER (nbr->state_change);
2308 break;
2309 case OSPFNBRLSRETRANSQLEN:
2310 return SNMP_INTEGER (ospf_ls_retransmit_count (nbr));
2311 break;
2312 case OSPFNBMANBRSTATUS:
2313 return SNMP_INTEGER (SNMP_VALID);
2314 break;
2315 case OSPFNBMANBRPERMANENCE:
2316 return SNMP_INTEGER (2);
2317 break;
2318 case OSPFNBRHELLOSUPPRESSED:
2319 return SNMP_INTEGER (SNMP_FALSE);
2320 break;
2321 default:
2322 return NULL;
2323 break;
2324 }
2325 return NULL;
2326}
2327
2328static u_char *
2329ospfVirtNbrEntry (struct variable *v, oid *name, size_t *length, int exact,
Chris Caputo0be8dfb2009-06-02 18:40:07 +01002330 size_t *var_len, WriteMethod **write_method)
paul718e3742002-12-13 20:15:29 +00002331{
2332 struct ospf_vl_data *vl_data;
2333 struct in_addr area_id;
2334 struct in_addr neighbor;
paul020709f2003-04-04 02:44:16 +00002335 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002336
2337 memset (&area_id, 0, sizeof (struct in_addr));
2338 memset (&neighbor, 0, sizeof (struct in_addr));
2339
2340 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00002341 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00002342 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00002343 return NULL;
2344
2345 vl_data = ospfVirtIfLookup (v, name, length, &area_id, &neighbor, exact);
2346 if (! vl_data)
2347 return NULL;
2348
2349 /* Return the current value of the variable */
2350 switch (v->magic)
2351 {
2352 case OSPFVIRTNBRAREA:
2353 return (u_char *) NULL;
2354 break;
2355 case OSPFVIRTNBRRTRID:
2356 return (u_char *) NULL;
2357 break;
2358 case OSPFVIRTNBRIPADDR:
2359 return (u_char *) NULL;
2360 break;
2361 case OSPFVIRTNBROPTIONS:
2362 return (u_char *) NULL;
2363 break;
2364 case OSPFVIRTNBRSTATE:
2365 return (u_char *) NULL;
2366 break;
2367 case OSPFVIRTNBREVENTS:
2368 return (u_char *) NULL;
2369 break;
2370 case OSPFVIRTNBRLSRETRANSQLEN:
2371 return (u_char *) NULL;
2372 break;
2373 case OSPFVIRTNBRHELLOSUPPRESSED:
2374 return (u_char *) NULL;
2375 break;
2376 default:
2377 return NULL;
2378 break;
2379 }
2380 return NULL;
2381}
2382
Chris Caputo0be8dfb2009-06-02 18:40:07 +01002383static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00002384ospfExtLsdbLookup (struct variable *v, oid *name, size_t *length, u_char *type,
2385 struct in_addr *ls_id, struct in_addr *router_id, int exact)
2386{
2387 int first;
2388 oid *offset;
2389 int offsetlen;
2390 u_char lsa_type;
paul6c835672004-10-11 11:00:30 +00002391 unsigned int len;
paul718e3742002-12-13 20:15:29 +00002392 struct ospf_lsa *lsa;
paul020709f2003-04-04 02:44:16 +00002393 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002394
paul020709f2003-04-04 02:44:16 +00002395 ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +00002396 if (exact)
2397 {
2398 if (*length != v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
2399 return NULL;
2400
2401 offset = name + v->namelen;
2402
2403 /* Make it sure given value match to type. */
2404 lsa_type = *offset;
2405 offset++;
2406
2407 if (lsa_type != *type)
2408 return NULL;
2409
2410 /* LS ID. */
2411 oid2in_addr (offset, IN_ADDR_SIZE, ls_id);
2412 offset += IN_ADDR_SIZE;
2413
2414 /* Router ID. */
2415 oid2in_addr (offset, IN_ADDR_SIZE, router_id);
2416
paul68980082003-03-25 05:07:42 +00002417 return ospf_lsdb_lookup_by_id (ospf->lsdb, *type, *ls_id, *router_id);
paul718e3742002-12-13 20:15:29 +00002418 }
2419 else
2420 {
2421 /* Get variable length. */
2422 first = 0;
2423 offset = name + v->namelen;
2424 offsetlen = *length - v->namelen;
2425
2426 /* LSA type value. */
2427 lsa_type = *offset;
2428 offset++;
2429 offsetlen--;
2430
2431 if (offsetlen <= 0 || lsa_type < OSPF_AS_EXTERNAL_LSA)
2432 first = 1;
2433
2434 /* LS ID. */
2435 len = offsetlen;
2436 if (len > IN_ADDR_SIZE)
2437 len = IN_ADDR_SIZE;
2438
2439 oid2in_addr (offset, len, ls_id);
2440
2441 offset += IN_ADDR_SIZE;
2442 offsetlen -= IN_ADDR_SIZE;
2443
2444 /* Router ID. */
2445 len = offsetlen;
2446 if (len > IN_ADDR_SIZE)
2447 len = IN_ADDR_SIZE;
2448
2449 oid2in_addr (offset, len, router_id);
2450
paul68980082003-03-25 05:07:42 +00002451 lsa = ospf_lsdb_lookup_by_id_next (ospf->lsdb, *type, *ls_id,
paul718e3742002-12-13 20:15:29 +00002452 *router_id, first);
2453
2454 if (lsa)
2455 {
2456 /* Fill in length. */
2457 *length = v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE;
2458
2459 /* Fill in value. */
2460 offset = name + v->namelen;
2461
2462 *offset = OSPF_AS_EXTERNAL_LSA;
2463 offset++;
2464 oid_copy_addr (offset, &lsa->data->id, IN_ADDR_SIZE);
2465 offset += IN_ADDR_SIZE;
2466 oid_copy_addr (offset, &lsa->data->adv_router, IN_ADDR_SIZE);
2467
2468 return lsa;
2469 }
2470 }
2471 return NULL;
2472}
2473
2474static u_char *
2475ospfExtLsdbEntry (struct variable *v, oid *name, size_t *length, int exact,
Chris Caputo0be8dfb2009-06-02 18:40:07 +01002476 size_t *var_len, WriteMethod **write_method)
paul718e3742002-12-13 20:15:29 +00002477{
2478 struct ospf_lsa *lsa;
2479 struct lsa_header *lsah;
2480 u_char type;
2481 struct in_addr ls_id;
2482 struct in_addr router_id;
paul020709f2003-04-04 02:44:16 +00002483 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002484
2485 type = OSPF_AS_EXTERNAL_LSA;
2486 memset (&ls_id, 0, sizeof (struct in_addr));
2487 memset (&router_id, 0, sizeof (struct in_addr));
2488
2489 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00002490 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00002491 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00002492 return NULL;
2493
2494 lsa = ospfExtLsdbLookup (v, name, length, &type, &ls_id, &router_id, exact);
2495 if (! lsa)
2496 return NULL;
2497
2498 lsah = lsa->data;
2499
2500 /* Return the current value of the variable */
2501 switch (v->magic)
2502 {
2503 case OSPFEXTLSDBTYPE:
2504 return SNMP_INTEGER (OSPF_AS_EXTERNAL_LSA);
2505 break;
2506 case OSPFEXTLSDBLSID:
2507 return SNMP_IPADDRESS (lsah->id);
2508 break;
2509 case OSPFEXTLSDBROUTERID:
2510 return SNMP_IPADDRESS (lsah->adv_router);
2511 break;
2512 case OSPFEXTLSDBSEQUENCE:
2513 return SNMP_INTEGER (lsah->ls_seqnum);
2514 break;
2515 case OSPFEXTLSDBAGE:
2516 return SNMP_INTEGER (lsah->ls_age);
2517 break;
2518 case OSPFEXTLSDBCHECKSUM:
2519 return SNMP_INTEGER (lsah->checksum);
2520 break;
2521 case OSPFEXTLSDBADVERTISEMENT:
2522 *var_len = ntohs (lsah->length);
2523 return (u_char *) lsah;
2524 break;
2525 default:
2526 return NULL;
2527 break;
2528 }
2529 return NULL;
2530}
2531
2532static u_char *
2533ospfAreaAggregateEntry (struct variable *v, oid *name, size_t *length,
2534 int exact, size_t *var_len, WriteMethod **write_method)
2535{
2536 /* Return the current value of the variable */
2537 switch (v->magic)
2538 {
2539 case OSPFAREAAGGREGATEAREAID:
2540 return (u_char *) NULL;
2541 break;
2542 case OSPFAREAAGGREGATELSDBTYPE:
2543 return (u_char *) NULL;
2544 break;
2545 case OSPFAREAAGGREGATENET:
2546 return (u_char *) NULL;
2547 break;
2548 case OSPFAREAAGGREGATEMASK:
2549 return (u_char *) NULL;
2550 break;
2551 case OSPFAREAAGGREGATESTATUS:
2552 return (u_char *) NULL;
2553 break;
2554 case OSPFAREAAGGREGATEEFFECT:
2555 return (u_char *) NULL;
2556 break;
2557 default:
2558 return NULL;
2559 break;
2560 }
2561 return NULL;
2562}
2563
vincent5e4914c2005-09-29 16:34:30 +00002564/* OSPF Traps. */
2565#define IFSTATECHANGE 16
2566#define VIRTIFSTATECHANGE 1
2567#define NBRSTATECHANGE 2
2568#define VIRTNBRSTATECHANGE 3
2569
2570struct trap_object ospfNbrTrapList[] =
2571{
Vincent Bernatb8cf46b2012-05-25 08:56:44 +02002572 {-2, {1, OSPFROUTERID}},
2573 {3, {10, 1, OSPFNBRIPADDR}},
2574 {3, {10, 1, OSPFNBRRTRID}},
2575 {3, {10, 1, OSPFNBRSTATE}}
vincent5e4914c2005-09-29 16:34:30 +00002576};
2577
2578
2579struct trap_object ospfVirtNbrTrapList[] =
2580{
Vincent Bernatb8cf46b2012-05-25 08:56:44 +02002581 {-2, {1, 1}},
2582 {3, {11, 1, OSPFVIRTNBRAREA}},
2583 {3, {11, 1, OSPFVIRTNBRRTRID}},
2584 {3, {11, 1, OSPFVIRTNBRSTATE}}
vincent5e4914c2005-09-29 16:34:30 +00002585};
2586
2587struct trap_object ospfIfTrapList[] =
2588{
Vincent Bernatb8cf46b2012-05-25 08:56:44 +02002589 {-2, {1, OSPFROUTERID}},
2590 {3, {7, 1, OSPFIFIPADDRESS}},
2591 {3, {7, 1, OSPFADDRESSLESSIF}},
2592 {3, {7, 1, OSPFIFSTATE}}
vincent5e4914c2005-09-29 16:34:30 +00002593};
2594
2595struct trap_object ospfVirtIfTrapList[] =
2596{
Vincent Bernatb8cf46b2012-05-25 08:56:44 +02002597 {-2, {1, OSPFROUTERID}},
2598 {3, {9, 1, OSPFVIRTIFAREAID}},
2599 {3, {9, 1, OSPFVIRTIFNEIGHBOR}},
2600 {3, {9, 1, OSPFVIRTIFSTATE}}
vincent5e4914c2005-09-29 16:34:30 +00002601};
2602
2603void
2604ospfTrapNbrStateChange (struct ospf_neighbor *on)
2605{
2606 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
Andrew J. Schorr9aecfae2006-06-24 20:05:02 +00002607 char msgbuf[16];
vincent5e4914c2005-09-29 16:34:30 +00002608
Andrew J. Schorr9aecfae2006-06-24 20:05:02 +00002609 ospf_nbr_state_message(on, msgbuf, sizeof(msgbuf));
2610 zlog (NULL, LOG_INFO, "ospfTrapNbrStateChange trap sent: %s now %s",
2611 inet_ntoa(on->address.u.prefix4), msgbuf);
vincent5e4914c2005-09-29 16:34:30 +00002612
2613 oid_copy_addr (index, &(on->address.u.prefix4), IN_ADDR_SIZE);
2614 index[IN_ADDR_SIZE] = 0;
2615
Vincent Bernatb7c0d062012-05-25 11:17:01 +02002616 smux_trap (ospf_variables, sizeof ospf_variables / sizeof (struct variable),
2617 ospf_trap_oid, sizeof ospf_trap_oid / sizeof (oid),
2618 ospf_oid, sizeof ospf_oid / sizeof (oid),
vincent5e4914c2005-09-29 16:34:30 +00002619 index, IN_ADDR_SIZE + 1,
2620 ospfNbrTrapList,
2621 sizeof ospfNbrTrapList / sizeof (struct trap_object),
Vincent Bernat4b89e452012-05-24 21:22:01 +02002622 NBRSTATECHANGE);
vincent5e4914c2005-09-29 16:34:30 +00002623}
2624
2625void
2626ospfTrapVirtNbrStateChange (struct ospf_neighbor *on)
2627{
2628 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
2629
2630 zlog (NULL, LOG_INFO, "ospfTrapVirtNbrStateChange trap sent");
2631
2632 oid_copy_addr (index, &(on->address.u.prefix4), IN_ADDR_SIZE);
2633 index[IN_ADDR_SIZE] = 0;
2634
Vincent Bernatb7c0d062012-05-25 11:17:01 +02002635 smux_trap (ospf_variables, sizeof ospf_variables / sizeof (struct variable),
2636 ospf_trap_oid, sizeof ospf_trap_oid / sizeof (oid),
2637 ospf_oid, sizeof ospf_oid / sizeof (oid),
vincent5e4914c2005-09-29 16:34:30 +00002638 index, IN_ADDR_SIZE + 1,
2639 ospfVirtNbrTrapList,
2640 sizeof ospfVirtNbrTrapList / sizeof (struct trap_object),
Vincent Bernat4b89e452012-05-24 21:22:01 +02002641 VIRTNBRSTATECHANGE);
vincent5e4914c2005-09-29 16:34:30 +00002642}
2643
2644void
2645ospfTrapIfStateChange (struct ospf_interface *oi)
2646{
2647 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
2648
Andrew J. Schorr9aecfae2006-06-24 20:05:02 +00002649 zlog (NULL, LOG_INFO, "ospfTrapIfStateChange trap sent: %s now %s",
2650 inet_ntoa(oi->address->u.prefix4),
2651 LOOKUP(ospf_ism_state_msg, oi->state));
vincent5e4914c2005-09-29 16:34:30 +00002652
2653 oid_copy_addr (index, &(oi->address->u.prefix4), IN_ADDR_SIZE);
2654 index[IN_ADDR_SIZE] = 0;
2655
Vincent Bernatb7c0d062012-05-25 11:17:01 +02002656 smux_trap (ospf_variables, sizeof ospf_variables / sizeof (struct variable),
2657 ospf_trap_oid, sizeof ospf_trap_oid / sizeof (oid),
2658 ospf_oid, sizeof ospf_oid / sizeof (oid),
vincent5e4914c2005-09-29 16:34:30 +00002659 index, IN_ADDR_SIZE + 1,
2660 ospfIfTrapList,
2661 sizeof ospfIfTrapList / sizeof (struct trap_object),
Vincent Bernat4b89e452012-05-24 21:22:01 +02002662 IFSTATECHANGE);
vincent5e4914c2005-09-29 16:34:30 +00002663}
2664
2665void
2666ospfTrapVirtIfStateChange (struct ospf_interface *oi)
2667{
2668 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
2669
2670 zlog (NULL, LOG_INFO, "ospfTrapVirtIfStateChange trap sent");
2671
2672 oid_copy_addr (index, &(oi->address->u.prefix4), IN_ADDR_SIZE);
2673 index[IN_ADDR_SIZE] = 0;
2674
Vincent Bernatb7c0d062012-05-25 11:17:01 +02002675 smux_trap (ospf_variables, sizeof ospf_variables / sizeof (struct variable),
2676 ospf_trap_oid, sizeof ospf_trap_oid / sizeof (oid),
2677 ospf_oid, sizeof ospf_oid / sizeof (oid),
vincent5e4914c2005-09-29 16:34:30 +00002678 index, IN_ADDR_SIZE + 1,
2679 ospfVirtIfTrapList,
2680 sizeof ospfVirtIfTrapList / sizeof (struct trap_object),
Vincent Bernat4b89e452012-05-24 21:22:01 +02002681 VIRTIFSTATECHANGE);
vincent5e4914c2005-09-29 16:34:30 +00002682}
paul718e3742002-12-13 20:15:29 +00002683/* Register OSPF2-MIB. */
2684void
2685ospf_snmp_init ()
2686{
2687 ospf_snmp_iflist = list_new ();
2688 ospf_snmp_vl_table = route_table_init ();
hassoc75105a2004-10-13 10:33:26 +00002689 smux_init (om->master);
paul718e3742002-12-13 20:15:29 +00002690 REGISTER_MIB("mibII/ospf", ospf_variables, variable, ospf_oid);
paul718e3742002-12-13 20:15:29 +00002691}
2692#endif /* HAVE_SNMP */