blob: cc4974ce6d32ca42d6db89c46a089e5b8fa685a1 [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"
Chris Caputo0be8dfb2009-06-02 18:40:07 +010056#include "ospfd/ospf_snmp.h"
paul718e3742002-12-13 20:15:29 +000057
58/* OSPF2-MIB. */
59#define OSPF2MIB 1,3,6,1,2,1,14
60
paul718e3742002-12-13 20:15:29 +000061/* OSPF MIB General Group values. */
62#define OSPFROUTERID 1
63#define OSPFADMINSTAT 2
64#define OSPFVERSIONNUMBER 3
65#define OSPFAREABDRRTRSTATUS 4
66#define OSPFASBDRRTRSTATUS 5
67#define OSPFEXTERNLSACOUNT 6
68#define OSPFEXTERNLSACKSUMSUM 7
69#define OSPFTOSSUPPORT 8
70#define OSPFORIGINATENEWLSAS 9
71#define OSPFRXNEWLSAS 10
72#define OSPFEXTLSDBLIMIT 11
73#define OSPFMULTICASTEXTENSIONS 12
74#define OSPFEXITOVERFLOWINTERVAL 13
75#define OSPFDEMANDEXTENSIONS 14
76
77/* OSPF MIB ospfAreaTable. */
78#define OSPFAREAID 1
79#define OSPFAUTHTYPE 2
80#define OSPFIMPORTASEXTERN 3
81#define OSPFSPFRUNS 4
82#define OSPFAREABDRRTRCOUNT 5
83#define OSPFASBDRRTRCOUNT 6
84#define OSPFAREALSACOUNT 7
85#define OSPFAREALSACKSUMSUM 8
86#define OSPFAREASUMMARY 9
87#define OSPFAREASTATUS 10
88
89/* OSPF MIB ospfStubAreaTable. */
90#define OSPFSTUBAREAID 1
91#define OSPFSTUBTOS 2
92#define OSPFSTUBMETRIC 3
93#define OSPFSTUBSTATUS 4
94#define OSPFSTUBMETRICTYPE 5
95
96/* OSPF MIB ospfLsdbTable. */
97#define OSPFLSDBAREAID 1
98#define OSPFLSDBTYPE 2
99#define OSPFLSDBLSID 3
100#define OSPFLSDBROUTERID 4
101#define OSPFLSDBSEQUENCE 5
102#define OSPFLSDBAGE 6
103#define OSPFLSDBCHECKSUM 7
104#define OSPFLSDBADVERTISEMENT 8
105
106/* OSPF MIB ospfAreaRangeTable. */
107#define OSPFAREARANGEAREAID 1
108#define OSPFAREARANGENET 2
109#define OSPFAREARANGEMASK 3
110#define OSPFAREARANGESTATUS 4
111#define OSPFAREARANGEEFFECT 5
112
113/* OSPF MIB ospfHostTable. */
114#define OSPFHOSTIPADDRESS 1
115#define OSPFHOSTTOS 2
116#define OSPFHOSTMETRIC 3
117#define OSPFHOSTSTATUS 4
118#define OSPFHOSTAREAID 5
119
120/* OSPF MIB ospfIfTable. */
121#define OSPFIFIPADDRESS 1
122#define OSPFADDRESSLESSIF 2
123#define OSPFIFAREAID 3
124#define OSPFIFTYPE 4
125#define OSPFIFADMINSTAT 5
126#define OSPFIFRTRPRIORITY 6
127#define OSPFIFTRANSITDELAY 7
128#define OSPFIFRETRANSINTERVAL 8
129#define OSPFIFHELLOINTERVAL 9
130#define OSPFIFRTRDEADINTERVAL 10
131#define OSPFIFPOLLINTERVAL 11
132#define OSPFIFSTATE 12
133#define OSPFIFDESIGNATEDROUTER 13
134#define OSPFIFBACKUPDESIGNATEDROUTER 14
135#define OSPFIFEVENTS 15
136#define OSPFIFAUTHKEY 16
137#define OSPFIFSTATUS 17
138#define OSPFIFMULTICASTFORWARDING 18
139#define OSPFIFDEMAND 19
140#define OSPFIFAUTHTYPE 20
141
142/* OSPF MIB ospfIfMetricTable. */
143#define OSPFIFMETRICIPADDRESS 1
144#define OSPFIFMETRICADDRESSLESSIF 2
145#define OSPFIFMETRICTOS 3
146#define OSPFIFMETRICVALUE 4
147#define OSPFIFMETRICSTATUS 5
148
149/* OSPF MIB ospfVirtIfTable. */
150#define OSPFVIRTIFAREAID 1
151#define OSPFVIRTIFNEIGHBOR 2
152#define OSPFVIRTIFTRANSITDELAY 3
153#define OSPFVIRTIFRETRANSINTERVAL 4
154#define OSPFVIRTIFHELLOINTERVAL 5
155#define OSPFVIRTIFRTRDEADINTERVAL 6
156#define OSPFVIRTIFSTATE 7
157#define OSPFVIRTIFEVENTS 8
158#define OSPFVIRTIFAUTHKEY 9
159#define OSPFVIRTIFSTATUS 10
160#define OSPFVIRTIFAUTHTYPE 11
161
162/* OSPF MIB ospfNbrTable. */
163#define OSPFNBRIPADDR 1
164#define OSPFNBRADDRESSLESSINDEX 2
165#define OSPFNBRRTRID 3
166#define OSPFNBROPTIONS 4
167#define OSPFNBRPRIORITY 5
168#define OSPFNBRSTATE 6
169#define OSPFNBREVENTS 7
170#define OSPFNBRLSRETRANSQLEN 8
171#define OSPFNBMANBRSTATUS 9
172#define OSPFNBMANBRPERMANENCE 10
173#define OSPFNBRHELLOSUPPRESSED 11
174
175/* OSPF MIB ospfVirtNbrTable. */
176#define OSPFVIRTNBRAREA 1
177#define OSPFVIRTNBRRTRID 2
178#define OSPFVIRTNBRIPADDR 3
179#define OSPFVIRTNBROPTIONS 4
180#define OSPFVIRTNBRSTATE 5
181#define OSPFVIRTNBREVENTS 6
182#define OSPFVIRTNBRLSRETRANSQLEN 7
183#define OSPFVIRTNBRHELLOSUPPRESSED 8
184
185/* OSPF MIB ospfExtLsdbTable. */
186#define OSPFEXTLSDBTYPE 1
187#define OSPFEXTLSDBLSID 2
188#define OSPFEXTLSDBROUTERID 3
189#define OSPFEXTLSDBSEQUENCE 4
190#define OSPFEXTLSDBAGE 5
191#define OSPFEXTLSDBCHECKSUM 6
192#define OSPFEXTLSDBADVERTISEMENT 7
193
194/* OSPF MIB ospfAreaAggregateTable. */
195#define OSPFAREAAGGREGATEAREAID 1
196#define OSPFAREAAGGREGATELSDBTYPE 2
197#define OSPFAREAAGGREGATENET 3
198#define OSPFAREAAGGREGATEMASK 4
199#define OSPFAREAAGGREGATESTATUS 5
200#define OSPFAREAAGGREGATEEFFECT 6
201
202/* SYNTAX Status from OSPF-MIB. */
203#define OSPF_STATUS_ENABLED 1
204#define OSPF_STATUS_DISABLED 2
205
206/* SNMP value hack. */
207#define COUNTER ASN_COUNTER
208#define INTEGER ASN_INTEGER
209#define GAUGE ASN_GAUGE
210#define TIMETICKS ASN_TIMETICKS
211#define IPADDRESS ASN_IPADDRESS
212#define STRING ASN_OCTET_STR
213
214/* Declare static local variables for convenience. */
215SNMP_LOCAL_VARIABLES
216
217/* OSPF-MIB instances. */
218oid ospf_oid [] = { OSPF2MIB };
paul718e3742002-12-13 20:15:29 +0000219
220/* IP address 0.0.0.0. */
221static struct in_addr ospf_empty_addr = {0};
222
223/* Hook functions. */
Chris Caputo0be8dfb2009-06-02 18:40:07 +0100224static u_char *ospfGeneralGroup (struct variable *, oid *, size_t *,
225 int, size_t *, WriteMethod **);
226static u_char *ospfAreaEntry (struct variable *, oid *, size_t *, int,
227 size_t *, WriteMethod **);
228static u_char *ospfStubAreaEntry (struct variable *, oid *, size_t *,
229 int, size_t *, WriteMethod **);
230static u_char *ospfLsdbEntry (struct variable *, oid *, size_t *, int,
231 size_t *, WriteMethod **);
232static u_char *ospfAreaRangeEntry (struct variable *, oid *, size_t *, int,
233 size_t *, WriteMethod **);
234static u_char *ospfHostEntry (struct variable *, oid *, size_t *, int,
235 size_t *, WriteMethod **);
236static u_char *ospfIfEntry (struct variable *, oid *, size_t *, int,
237 size_t *, WriteMethod **);
238static u_char *ospfIfMetricEntry (struct variable *, oid *, size_t *, int,
239 size_t *, WriteMethod **);
240static u_char *ospfVirtIfEntry (struct variable *, oid *, size_t *, int,
241 size_t *, WriteMethod **);
242static u_char *ospfNbrEntry (struct variable *, oid *, size_t *, int,
243 size_t *, WriteMethod **);
244static u_char *ospfVirtNbrEntry (struct variable *, oid *, size_t *, int,
245 size_t *, WriteMethod **);
246static u_char *ospfExtLsdbEntry (struct variable *, oid *, size_t *, int,
247 size_t *, WriteMethod **);
248static u_char *ospfAreaAggregateEntry (struct variable *, oid *, size_t *,
249 int, size_t *, WriteMethod **);
paul718e3742002-12-13 20:15:29 +0000250
251struct variable ospf_variables[] =
252{
253 /* OSPF general variables */
254 {OSPFROUTERID, IPADDRESS, RWRITE, ospfGeneralGroup,
255 2, {1, 1}},
256 {OSPFADMINSTAT, INTEGER, RWRITE, ospfGeneralGroup,
257 2, {1, 2}},
258 {OSPFVERSIONNUMBER, INTEGER, RONLY, ospfGeneralGroup,
259 2, {1, 3}},
260 {OSPFAREABDRRTRSTATUS, INTEGER, RONLY, ospfGeneralGroup,
261 2, {1, 4}},
262 {OSPFASBDRRTRSTATUS, INTEGER, RWRITE, ospfGeneralGroup,
263 2, {1, 5}},
264 {OSPFEXTERNLSACOUNT, GAUGE, RONLY, ospfGeneralGroup,
265 2, {1, 6}},
266 {OSPFEXTERNLSACKSUMSUM, INTEGER, RONLY, ospfGeneralGroup,
267 2, {1, 7}},
268 {OSPFTOSSUPPORT, INTEGER, RWRITE, ospfGeneralGroup,
269 2, {1, 8}},
270 {OSPFORIGINATENEWLSAS, COUNTER, RONLY, ospfGeneralGroup,
271 2, {1, 9}},
272 {OSPFRXNEWLSAS, COUNTER, RONLY, ospfGeneralGroup,
273 2, {1, 10}},
274 {OSPFEXTLSDBLIMIT, INTEGER, RWRITE, ospfGeneralGroup,
275 2, {1, 11}},
276 {OSPFMULTICASTEXTENSIONS, INTEGER, RWRITE, ospfGeneralGroup,
277 2, {1, 12}},
278 {OSPFEXITOVERFLOWINTERVAL, INTEGER, RWRITE, ospfGeneralGroup,
279 2, {1, 13}},
280 {OSPFDEMANDEXTENSIONS, INTEGER, RWRITE, ospfGeneralGroup,
281 2, {1, 14}},
282
283 /* OSPF area data structure. */
284 {OSPFAREAID, IPADDRESS, RONLY, ospfAreaEntry,
285 3, {2, 1, 1}},
286 {OSPFAUTHTYPE, INTEGER, RWRITE, ospfAreaEntry,
287 3, {2, 1, 2}},
288 {OSPFIMPORTASEXTERN, INTEGER, RWRITE, ospfAreaEntry,
289 3, {2, 1, 3}},
290 {OSPFSPFRUNS, COUNTER, RONLY, ospfAreaEntry,
291 3, {2, 1, 4}},
292 {OSPFAREABDRRTRCOUNT, GAUGE, RONLY, ospfAreaEntry,
293 3, {2, 1, 5}},
294 {OSPFASBDRRTRCOUNT, GAUGE, RONLY, ospfAreaEntry,
295 3, {2, 1, 6}},
296 {OSPFAREALSACOUNT, GAUGE, RONLY, ospfAreaEntry,
297 3, {2, 1, 7}},
298 {OSPFAREALSACKSUMSUM, INTEGER, RONLY, ospfAreaEntry,
299 3, {2, 1, 8}},
300 {OSPFAREASUMMARY, INTEGER, RWRITE, ospfAreaEntry,
301 3, {2, 1, 9}},
302 {OSPFAREASTATUS, INTEGER, RWRITE, ospfAreaEntry,
303 3, {2, 1, 10}},
304
305 /* OSPF stub area information. */
306 {OSPFSTUBAREAID, IPADDRESS, RONLY, ospfStubAreaEntry,
307 3, {3, 1, 1}},
308 {OSPFSTUBTOS, INTEGER, RONLY, ospfStubAreaEntry,
309 3, {3, 1, 2}},
310 {OSPFSTUBMETRIC, INTEGER, RWRITE, ospfStubAreaEntry,
311 3, {3, 1, 3}},
312 {OSPFSTUBSTATUS, INTEGER, RWRITE, ospfStubAreaEntry,
313 3, {3, 1, 4}},
314 {OSPFSTUBMETRICTYPE, INTEGER, RWRITE, ospfStubAreaEntry,
315 3, {3, 1, 5}},
316
317 /* OSPF link state database. */
318 {OSPFLSDBAREAID, IPADDRESS, RONLY, ospfLsdbEntry,
319 3, {4, 1, 1}},
320 {OSPFLSDBTYPE, INTEGER, RONLY, ospfLsdbEntry,
321 3, {4, 1, 2}},
322 {OSPFLSDBLSID, IPADDRESS, RONLY, ospfLsdbEntry,
323 3, {4, 1, 3}},
324 {OSPFLSDBROUTERID, IPADDRESS, RONLY, ospfLsdbEntry,
325 3, {4, 1, 4}},
326 {OSPFLSDBSEQUENCE, INTEGER, RONLY, ospfLsdbEntry,
327 3, {4, 1, 5}},
328 {OSPFLSDBAGE, INTEGER, RONLY, ospfLsdbEntry,
329 3, {4, 1, 6}},
330 {OSPFLSDBCHECKSUM, INTEGER, RONLY, ospfLsdbEntry,
331 3, {4, 1, 7}},
332 {OSPFLSDBADVERTISEMENT, STRING, RONLY, ospfLsdbEntry,
333 3, {4, 1, 8}},
334
335 /* Area range table. */
336 {OSPFAREARANGEAREAID, IPADDRESS, RONLY, ospfAreaRangeEntry,
337 3, {5, 1, 1}},
338 {OSPFAREARANGENET, IPADDRESS, RONLY, ospfAreaRangeEntry,
339 3, {5, 1, 2}},
340 {OSPFAREARANGEMASK, IPADDRESS, RWRITE, ospfAreaRangeEntry,
341 3, {5, 1, 3}},
342 {OSPFAREARANGESTATUS, INTEGER, RWRITE, ospfAreaRangeEntry,
343 3, {5, 1, 4}},
344 {OSPFAREARANGEEFFECT, INTEGER, RWRITE, ospfAreaRangeEntry,
345 3, {5, 1, 5}},
346
347 /* OSPF host table. */
348 {OSPFHOSTIPADDRESS, IPADDRESS, RONLY, ospfHostEntry,
349 3, {6, 1, 1}},
350 {OSPFHOSTTOS, INTEGER, RONLY, ospfHostEntry,
351 3, {6, 1, 2}},
352 {OSPFHOSTMETRIC, INTEGER, RWRITE, ospfHostEntry,
353 3, {6, 1, 3}},
354 {OSPFHOSTSTATUS, INTEGER, RWRITE, ospfHostEntry,
355 3, {6, 1, 4}},
356 {OSPFHOSTAREAID, IPADDRESS, RONLY, ospfHostEntry,
357 3, {6, 1, 5}},
358
359 /* OSPF interface table. */
360 {OSPFIFIPADDRESS, IPADDRESS, RONLY, ospfIfEntry,
361 3, {7, 1, 1}},
362 {OSPFADDRESSLESSIF, INTEGER, RONLY, ospfIfEntry,
363 3, {7, 1, 2}},
364 {OSPFIFAREAID, IPADDRESS, RWRITE, ospfIfEntry,
365 3, {7, 1, 3}},
366 {OSPFIFTYPE, INTEGER, RWRITE, ospfIfEntry,
367 3, {7, 1, 4}},
368 {OSPFIFADMINSTAT, INTEGER, RWRITE, ospfIfEntry,
369 3, {7, 1, 5}},
370 {OSPFIFRTRPRIORITY, INTEGER, RWRITE, ospfIfEntry,
371 3, {7, 1, 6}},
372 {OSPFIFTRANSITDELAY, INTEGER, RWRITE, ospfIfEntry,
373 3, {7, 1, 7}},
374 {OSPFIFRETRANSINTERVAL, INTEGER, RWRITE, ospfIfEntry,
375 3, {7, 1, 8}},
376 {OSPFIFHELLOINTERVAL, INTEGER, RWRITE, ospfIfEntry,
377 3, {7, 1, 9}},
378 {OSPFIFRTRDEADINTERVAL, INTEGER, RWRITE, ospfIfEntry,
379 3, {7, 1, 10}},
380 {OSPFIFPOLLINTERVAL, INTEGER, RWRITE, ospfIfEntry,
381 3, {7, 1, 11}},
382 {OSPFIFSTATE, INTEGER, RONLY, ospfIfEntry,
383 3, {7, 1, 12}},
384 {OSPFIFDESIGNATEDROUTER, IPADDRESS, RONLY, ospfIfEntry,
385 3, {7, 1, 13}},
386 {OSPFIFBACKUPDESIGNATEDROUTER, IPADDRESS, RONLY, ospfIfEntry,
387 3, {7, 1, 14}},
388 {OSPFIFEVENTS, COUNTER, RONLY, ospfIfEntry,
389 3, {7, 1, 15}},
390 {OSPFIFAUTHKEY, STRING, RWRITE, ospfIfEntry,
391 3, {7, 1, 16}},
392 {OSPFIFSTATUS, INTEGER, RWRITE, ospfIfEntry,
393 3, {7, 1, 17}},
394 {OSPFIFMULTICASTFORWARDING, INTEGER, RWRITE, ospfIfEntry,
395 3, {7, 1, 18}},
396 {OSPFIFDEMAND, INTEGER, RWRITE, ospfIfEntry,
397 3, {7, 1, 19}},
398 {OSPFIFAUTHTYPE, INTEGER, RWRITE, ospfIfEntry,
399 3, {7, 1, 20}},
400
401 /* OSPF interface metric table. */
402 {OSPFIFMETRICIPADDRESS, IPADDRESS, RONLY, ospfIfMetricEntry,
403 3, {8, 1, 1}},
404 {OSPFIFMETRICADDRESSLESSIF, INTEGER, RONLY, ospfIfMetricEntry,
405 3, {8, 1, 2}},
406 {OSPFIFMETRICTOS, INTEGER, RONLY, ospfIfMetricEntry,
407 3, {8, 1, 3}},
408 {OSPFIFMETRICVALUE, INTEGER, RWRITE, ospfIfMetricEntry,
409 3, {8, 1, 4}},
410 {OSPFIFMETRICSTATUS, INTEGER, RWRITE, ospfIfMetricEntry,
411 3, {8, 1, 5}},
412
413 /* OSPF virtual interface table. */
414 {OSPFVIRTIFAREAID, IPADDRESS, RONLY, ospfVirtIfEntry,
415 3, {9, 1, 1}},
416 {OSPFVIRTIFNEIGHBOR, IPADDRESS, RONLY, ospfVirtIfEntry,
417 3, {9, 1, 2}},
418 {OSPFVIRTIFTRANSITDELAY, INTEGER, RWRITE, ospfVirtIfEntry,
419 3, {9, 1, 3}},
420 {OSPFVIRTIFRETRANSINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry,
421 3, {9, 1, 4}},
422 {OSPFVIRTIFHELLOINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry,
423 3, {9, 1, 5}},
424 {OSPFVIRTIFRTRDEADINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry,
425 3, {9, 1, 6}},
426 {OSPFVIRTIFSTATE, INTEGER, RONLY, ospfVirtIfEntry,
427 3, {9, 1, 7}},
428 {OSPFVIRTIFEVENTS, COUNTER, RONLY, ospfVirtIfEntry,
429 3, {9, 1, 8}},
430 {OSPFVIRTIFAUTHKEY, STRING, RWRITE, ospfVirtIfEntry,
431 3, {9, 1, 9}},
432 {OSPFVIRTIFSTATUS, INTEGER, RWRITE, ospfVirtIfEntry,
433 3, {9, 1, 10}},
434 {OSPFVIRTIFAUTHTYPE, INTEGER, RWRITE, ospfVirtIfEntry,
435 3, {9, 1, 11}},
436
437 /* OSPF neighbor table. */
438 {OSPFNBRIPADDR, IPADDRESS, RONLY, ospfNbrEntry,
439 3, {10, 1, 1}},
440 {OSPFNBRADDRESSLESSINDEX, INTEGER, RONLY, ospfNbrEntry,
441 3, {10, 1, 2}},
442 {OSPFNBRRTRID, IPADDRESS, RONLY, ospfNbrEntry,
443 3, {10, 1, 3}},
444 {OSPFNBROPTIONS, INTEGER, RONLY, ospfNbrEntry,
445 3, {10, 1, 4}},
446 {OSPFNBRPRIORITY, INTEGER, RWRITE, ospfNbrEntry,
447 3, {10, 1, 5}},
448 {OSPFNBRSTATE, INTEGER, RONLY, ospfNbrEntry,
449 3, {10, 1, 6}},
450 {OSPFNBREVENTS, COUNTER, RONLY, ospfNbrEntry,
451 3, {10, 1, 7}},
452 {OSPFNBRLSRETRANSQLEN, GAUGE, RONLY, ospfNbrEntry,
453 3, {10, 1, 8}},
454 {OSPFNBMANBRSTATUS, INTEGER, RWRITE, ospfNbrEntry,
455 3, {10, 1, 9}},
456 {OSPFNBMANBRPERMANENCE, INTEGER, RONLY, ospfNbrEntry,
457 3, {10, 1, 10}},
458 {OSPFNBRHELLOSUPPRESSED, INTEGER, RONLY, ospfNbrEntry,
459 3, {10, 1, 11}},
460
461 /* OSPF virtual neighbor table. */
462 {OSPFVIRTNBRAREA, IPADDRESS, RONLY, ospfVirtNbrEntry,
463 3, {11, 1, 1}},
464 {OSPFVIRTNBRRTRID, IPADDRESS, RONLY, ospfVirtNbrEntry,
465 3, {11, 1, 2}},
466 {OSPFVIRTNBRIPADDR, IPADDRESS, RONLY, ospfVirtNbrEntry,
467 3, {11, 1, 3}},
468 {OSPFVIRTNBROPTIONS, INTEGER, RONLY, ospfVirtNbrEntry,
469 3, {11, 1, 4}},
470 {OSPFVIRTNBRSTATE, INTEGER, RONLY, ospfVirtNbrEntry,
471 3, {11, 1, 5}},
472 {OSPFVIRTNBREVENTS, COUNTER, RONLY, ospfVirtNbrEntry,
473 3, {11, 1, 6}},
474 {OSPFVIRTNBRLSRETRANSQLEN, INTEGER, RONLY, ospfVirtNbrEntry,
475 3, {11, 1, 7}},
476 {OSPFVIRTNBRHELLOSUPPRESSED, INTEGER, RONLY, ospfVirtNbrEntry,
477 3, {11, 1, 8}},
478
479 /* OSPF link state database, external. */
480 {OSPFEXTLSDBTYPE, INTEGER, RONLY, ospfExtLsdbEntry,
481 3, {12, 1, 1}},
482 {OSPFEXTLSDBLSID, IPADDRESS, RONLY, ospfExtLsdbEntry,
483 3, {12, 1, 2}},
484 {OSPFEXTLSDBROUTERID, IPADDRESS, RONLY, ospfExtLsdbEntry,
485 3, {12, 1, 3}},
486 {OSPFEXTLSDBSEQUENCE, INTEGER, RONLY, ospfExtLsdbEntry,
487 3, {12, 1, 4}},
488 {OSPFEXTLSDBAGE, INTEGER, RONLY, ospfExtLsdbEntry,
489 3, {12, 1, 5}},
490 {OSPFEXTLSDBCHECKSUM, INTEGER, RONLY, ospfExtLsdbEntry,
491 3, {12, 1, 6}},
492 {OSPFEXTLSDBADVERTISEMENT, STRING, RONLY, ospfExtLsdbEntry,
493 3, {12, 1, 7}},
494
495 /* OSPF area aggregate table. */
496 {OSPFAREAAGGREGATEAREAID, IPADDRESS, RONLY, ospfAreaAggregateEntry,
497 3, {14, 1, 1}},
498 {OSPFAREAAGGREGATELSDBTYPE, INTEGER, RONLY, ospfAreaAggregateEntry,
499 3, {14, 1, 2}},
500 {OSPFAREAAGGREGATENET, IPADDRESS, RONLY, ospfAreaAggregateEntry,
501 3, {14, 1, 3}},
502 {OSPFAREAAGGREGATEMASK, IPADDRESS, RONLY, ospfAreaAggregateEntry,
503 3, {14, 1, 4}},
504 {OSPFAREAAGGREGATESTATUS, INTEGER, RWRITE, ospfAreaAggregateEntry,
505 3, {14, 1, 5}},
506 {OSPFAREAAGGREGATEEFFECT, INTEGER, RWRITE, ospfAreaAggregateEntry,
507 3, {14, 1, 6}}
508};
509
510/* The administrative status of OSPF. When OSPF is enbled on at least
511 one interface return 1. */
Chris Caputo0be8dfb2009-06-02 18:40:07 +0100512static int
paul68980082003-03-25 05:07:42 +0000513ospf_admin_stat (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +0000514{
paulaa20c6f2004-10-07 14:19:36 +0000515 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000516 struct ospf_interface *oi;
517
paul68980082003-03-25 05:07:42 +0000518 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +0000519 return 0;
520
paul1eb8ef22005-04-07 07:30:20 +0000521 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
522 if (oi && oi->address)
523 return 1;
paul718e3742002-12-13 20:15:29 +0000524
paul718e3742002-12-13 20:15:29 +0000525 return 0;
526}
527
528static u_char *
529ospfGeneralGroup (struct variable *v, oid *name, size_t *length,
530 int exact, size_t *var_len, WriteMethod **write_method)
531{
paul020709f2003-04-04 02:44:16 +0000532 struct ospf *ospf;
533
534 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +0000535
paul718e3742002-12-13 20:15:29 +0000536 /* Check whether the instance identifier is valid */
537 if (smux_header_generic (v, name, length, exact, var_len, write_method)
538 == MATCH_FAILED)
539 return NULL;
540
541 /* Return the current value of the variable */
542 switch (v->magic)
543 {
544 case OSPFROUTERID: /* 1 */
545 /* Router-ID of this OSPF instance. */
paul68980082003-03-25 05:07:42 +0000546 if (ospf)
547 return SNMP_IPADDRESS (ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000548 else
549 return SNMP_IPADDRESS (ospf_empty_addr);
550 break;
551 case OSPFADMINSTAT: /* 2 */
552 /* The administrative status of OSPF in the router. */
paul68980082003-03-25 05:07:42 +0000553 if (ospf_admin_stat (ospf))
paul718e3742002-12-13 20:15:29 +0000554 return SNMP_INTEGER (OSPF_STATUS_ENABLED);
555 else
556 return SNMP_INTEGER (OSPF_STATUS_DISABLED);
557 break;
558 case OSPFVERSIONNUMBER: /* 3 */
559 /* OSPF version 2. */
560 return SNMP_INTEGER (OSPF_VERSION);
561 break;
562 case OSPFAREABDRRTRSTATUS: /* 4 */
563 /* Area Border router status. */
paul68980082003-03-25 05:07:42 +0000564 if (ospf && CHECK_FLAG (ospf->flags, OSPF_FLAG_ABR))
paul718e3742002-12-13 20:15:29 +0000565 return SNMP_INTEGER (SNMP_TRUE);
566 else
567 return SNMP_INTEGER (SNMP_FALSE);
568 break;
569 case OSPFASBDRRTRSTATUS: /* 5 */
570 /* AS Border router status. */
paul68980082003-03-25 05:07:42 +0000571 if (ospf && CHECK_FLAG (ospf->flags, OSPF_FLAG_ASBR))
paul718e3742002-12-13 20:15:29 +0000572 return SNMP_INTEGER (SNMP_TRUE);
573 else
574 return SNMP_INTEGER (SNMP_FALSE);
575 break;
576 case OSPFEXTERNLSACOUNT: /* 6 */
577 /* External LSA counts. */
paul68980082003-03-25 05:07:42 +0000578 if (ospf)
579 return SNMP_INTEGER (ospf_lsdb_count_all (ospf->lsdb));
paul718e3742002-12-13 20:15:29 +0000580 else
581 return SNMP_INTEGER (0);
582 break;
583 case OSPFEXTERNLSACKSUMSUM: /* 7 */
584 /* External LSA checksum. */
585 return SNMP_INTEGER (0);
586 break;
587 case OSPFTOSSUPPORT: /* 8 */
588 /* TOS is not supported. */
589 return SNMP_INTEGER (SNMP_FALSE);
590 break;
591 case OSPFORIGINATENEWLSAS: /* 9 */
592 /* The number of new link-state advertisements. */
paul68980082003-03-25 05:07:42 +0000593 if (ospf)
594 return SNMP_INTEGER (ospf->lsa_originate_count);
paul718e3742002-12-13 20:15:29 +0000595 else
596 return SNMP_INTEGER (0);
597 break;
598 case OSPFRXNEWLSAS: /* 10 */
599 /* The number of link-state advertisements received determined
600 to be new instantiations. */
paul68980082003-03-25 05:07:42 +0000601 if (ospf)
602 return SNMP_INTEGER (ospf->rx_lsa_count);
paul718e3742002-12-13 20:15:29 +0000603 else
604 return SNMP_INTEGER (0);
605 break;
606 case OSPFEXTLSDBLIMIT: /* 11 */
607 /* There is no limit for the number of non-default
608 AS-external-LSAs. */
609 return SNMP_INTEGER (-1);
610 break;
611 case OSPFMULTICASTEXTENSIONS: /* 12 */
612 /* Multicast Extensions to OSPF is not supported. */
613 return SNMP_INTEGER (0);
614 break;
615 case OSPFEXITOVERFLOWINTERVAL: /* 13 */
616 /* Overflow is not supported. */
617 return SNMP_INTEGER (0);
618 break;
619 case OSPFDEMANDEXTENSIONS: /* 14 */
620 /* Demand routing is not supported. */
621 return SNMP_INTEGER (SNMP_FALSE);
622 break;
623 default:
624 return NULL;
625 }
626 return NULL;
627}
628
Chris Caputo0be8dfb2009-06-02 18:40:07 +0100629static struct ospf_area *
paul68980082003-03-25 05:07:42 +0000630ospf_area_lookup_next (struct ospf *ospf, struct in_addr *area_id, int first)
paul718e3742002-12-13 20:15:29 +0000631{
632 struct ospf_area *area;
paulaa20c6f2004-10-07 14:19:36 +0000633 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000634
paul020709f2003-04-04 02:44:16 +0000635 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +0000636 return NULL;
637
638 if (first)
639 {
paul68980082003-03-25 05:07:42 +0000640 node = listhead (ospf->areas);
paul718e3742002-12-13 20:15:29 +0000641 if (node)
642 {
paul1eb8ef22005-04-07 07:30:20 +0000643 area = listgetdata (node);
paul718e3742002-12-13 20:15:29 +0000644 *area_id = area->area_id;
645 return area;
646 }
647 return NULL;
648 }
paul1eb8ef22005-04-07 07:30:20 +0000649 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
paul718e3742002-12-13 20:15:29 +0000650 {
paul718e3742002-12-13 20:15:29 +0000651 if (ntohl (area->area_id.s_addr) > ntohl (area_id->s_addr))
652 {
653 *area_id = area->area_id;
654 return area;
655 }
656 }
657 return NULL;
658}
659
Chris Caputo0be8dfb2009-06-02 18:40:07 +0100660static struct ospf_area *
paul718e3742002-12-13 20:15:29 +0000661ospfAreaLookup (struct variable *v, oid name[], size_t *length,
662 struct in_addr *addr, int exact)
663{
paul020709f2003-04-04 02:44:16 +0000664 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000665 struct ospf_area *area;
paul68980082003-03-25 05:07:42 +0000666 int len;
paul718e3742002-12-13 20:15:29 +0000667
paul020709f2003-04-04 02:44:16 +0000668 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +0000669 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +0000670 return NULL;
671
672 if (exact)
673 {
674 /* Length is insufficient to lookup OSPF area. */
675 if (*length - v->namelen != sizeof (struct in_addr))
676 return NULL;
677
678 oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr);
679
paul68980082003-03-25 05:07:42 +0000680 area = ospf_area_lookup_by_area_id (ospf, *addr);
paul718e3742002-12-13 20:15:29 +0000681
682 return area;
683 }
684 else
685 {
686 len = *length - v->namelen;
687 if (len > 4)
688 len = 4;
689
690 oid2in_addr (name + v->namelen, len, addr);
691
paul68980082003-03-25 05:07:42 +0000692 area = ospf_area_lookup_next (ospf, addr, len == 0 ? 1 : 0);
paul718e3742002-12-13 20:15:29 +0000693
694 if (area == NULL)
695 return NULL;
696
697 oid_copy_addr (name + v->namelen, addr, sizeof (struct in_addr));
698 *length = sizeof (struct in_addr) + v->namelen;
699
700 return area;
701 }
702 return NULL;
703}
704
705static u_char *
706ospfAreaEntry (struct variable *v, oid *name, size_t *length, int exact,
707 size_t *var_len, WriteMethod **write_method)
708{
709 struct ospf_area *area;
710 struct in_addr addr;
711
712 memset (&addr, 0, sizeof (struct in_addr));
713
714 area = ospfAreaLookup (v, name, length, &addr, exact);
715 if (! area)
716 return NULL;
717
718 /* Return the current value of the variable */
719 switch (v->magic)
720 {
721 case OSPFAREAID: /* 1 */
722 return SNMP_IPADDRESS (area->area_id);
723 break;
724 case OSPFAUTHTYPE: /* 2 */
725 return SNMP_INTEGER (area->auth_type);
726 break;
727 case OSPFIMPORTASEXTERN: /* 3 */
728 return SNMP_INTEGER (area->external_routing + 1);
729 break;
730 case OSPFSPFRUNS: /* 4 */
731 return SNMP_INTEGER (area->spf_calculation);
732 break;
733 case OSPFAREABDRRTRCOUNT: /* 5 */
734 return SNMP_INTEGER (area->abr_count);
735 break;
736 case OSPFASBDRRTRCOUNT: /* 6 */
737 return SNMP_INTEGER (area->asbr_count);
738 break;
739 case OSPFAREALSACOUNT: /* 7 */
740 return SNMP_INTEGER (area->lsdb->total);
741 break;
742 case OSPFAREALSACKSUMSUM: /* 8 */
743 return SNMP_INTEGER (0);
744 break;
745 case OSPFAREASUMMARY: /* 9 */
746#define OSPF_noAreaSummary 1
747#define OSPF_sendAreaSummary 2
748 if (area->no_summary)
749 return SNMP_INTEGER (OSPF_noAreaSummary);
750 else
751 return SNMP_INTEGER (OSPF_sendAreaSummary);
752 break;
753 case OSPFAREASTATUS: /* 10 */
754 return SNMP_INTEGER (SNMP_VALID);
755 break;
756 default:
757 return NULL;
758 break;
759 }
760 return NULL;
761}
762
Chris Caputo0be8dfb2009-06-02 18:40:07 +0100763static struct ospf_area *
paul718e3742002-12-13 20:15:29 +0000764ospf_stub_area_lookup_next (struct in_addr *area_id, int first)
765{
766 struct ospf_area *area;
paulaa20c6f2004-10-07 14:19:36 +0000767 struct listnode *node;
paul020709f2003-04-04 02:44:16 +0000768 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000769
paul020709f2003-04-04 02:44:16 +0000770 ospf = ospf_lookup ();
771 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +0000772 return NULL;
773
paul1eb8ef22005-04-07 07:30:20 +0000774 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
paul718e3742002-12-13 20:15:29 +0000775 {
paul718e3742002-12-13 20:15:29 +0000776 if (area->external_routing == OSPF_AREA_STUB)
777 {
778 if (first)
779 {
780 *area_id = area->area_id;
781 return area;
782 }
783 else if (ntohl (area->area_id.s_addr) > ntohl (area_id->s_addr))
784 {
785 *area_id = area->area_id;
786 return area;
787 }
788 }
789 }
790 return NULL;
791}
792
Chris Caputo0be8dfb2009-06-02 18:40:07 +0100793static struct ospf_area *
paul718e3742002-12-13 20:15:29 +0000794ospfStubAreaLookup (struct variable *v, oid name[], size_t *length,
795 struct in_addr *addr, int exact)
796{
paul020709f2003-04-04 02:44:16 +0000797 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000798 struct ospf_area *area;
paul68980082003-03-25 05:07:42 +0000799 int len;
paul718e3742002-12-13 20:15:29 +0000800
paul020709f2003-04-04 02:44:16 +0000801 ospf = ospf_lookup ();
802 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +0000803 return NULL;
804
805 /* Exact lookup. */
806 if (exact)
807 {
808 /* ospfStubAreaID + ospfStubTOS. */
809 if (*length != v->namelen + sizeof (struct in_addr) + 1)
810 return NULL;
811
812 /* Check ospfStubTOS is zero. */
813 if (name[*length - 1] != 0)
814 return NULL;
815
816 oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr);
817
paul68980082003-03-25 05:07:42 +0000818 area = ospf_area_lookup_by_area_id (ospf, *addr);
paul718e3742002-12-13 20:15:29 +0000819
820 if (area->external_routing == OSPF_AREA_STUB)
821 return area;
822 else
823 return NULL;
824 }
825 else
826 {
827 len = *length - v->namelen;
828 if (len > 4)
829 len = 4;
830
831 oid2in_addr (name + v->namelen, len, addr);
832
833 area = ospf_stub_area_lookup_next (addr, len == 0 ? 1 : 0);
834
835 if (area == NULL)
836 return NULL;
837
838 oid_copy_addr (name + v->namelen, addr, sizeof (struct in_addr));
839 /* Set TOS 0. */
840 name[v->namelen + sizeof (struct in_addr)] = 0;
841 *length = v->namelen + sizeof (struct in_addr) + 1;
842
843 return area;
844 }
845 return NULL;
846}
847
848static u_char *
849ospfStubAreaEntry (struct variable *v, oid *name, size_t *length,
850 int exact, size_t *var_len, WriteMethod **write_method)
851{
852 struct ospf_area *area;
853 struct in_addr addr;
854
855 memset (&addr, 0, sizeof (struct in_addr));
856
857 area = ospfStubAreaLookup (v, name, length, &addr, exact);
858 if (! area)
859 return NULL;
860
861 /* Return the current value of the variable */
862 switch (v->magic)
863 {
864 case OSPFSTUBAREAID: /* 1 */
865 /* OSPF stub area id. */
866 return SNMP_IPADDRESS (area->area_id);
867 break;
868 case OSPFSTUBTOS: /* 2 */
869 /* TOS value is not supported. */
870 return SNMP_INTEGER (0);
871 break;
872 case OSPFSTUBMETRIC: /* 3 */
873 /* Default cost to stub area. */
874 return SNMP_INTEGER (area->default_cost);
875 break;
876 case OSPFSTUBSTATUS: /* 4 */
877 /* Status of the stub area. */
878 return SNMP_INTEGER (SNMP_VALID);
879 break;
880 case OSPFSTUBMETRICTYPE: /* 5 */
881 /* OSPF Metric type. */
882#define OSPF_ospfMetric 1
883#define OSPF_comparableCost 2
884#define OSPF_nonComparable 3
885 return SNMP_INTEGER (OSPF_ospfMetric);
886 break;
887 default:
888 return NULL;
889 break;
890 }
891 return NULL;
892}
893
Chris Caputo0be8dfb2009-06-02 18:40:07 +0100894static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000895lsdb_lookup_next (struct ospf_area *area, u_char *type, int type_next,
896 struct in_addr *ls_id, int ls_id_next,
897 struct in_addr *router_id, int router_id_next)
898{
899 struct ospf_lsa *lsa;
900 int i;
901
902 if (type_next)
903 i = OSPF_MIN_LSA;
904 else
905 i = *type;
906
vincentba682532005-09-29 13:52:57 +0000907 /* Sanity check, if LSA type unknwon
908 merley skip any LSA */
909 if ((i < OSPF_MIN_LSA) || (i >= OSPF_MAX_LSA))
910 {
911 zlog_debug("Strange request with LSA type %d\n", i);
912 return NULL;
913 }
914
paul718e3742002-12-13 20:15:29 +0000915 for (; i < OSPF_MAX_LSA; i++)
916 {
917 *type = i;
918
919 lsa = ospf_lsdb_lookup_by_id_next (area->lsdb, *type, *ls_id, *router_id,
920 ls_id_next);
921 if (lsa)
922 return lsa;
923
924 ls_id_next = 1;
925 }
926 return NULL;
927}
928
Chris Caputo0be8dfb2009-06-02 18:40:07 +0100929static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000930ospfLsdbLookup (struct variable *v, oid *name, size_t *length,
931 struct in_addr *area_id, u_char *type,
932 struct in_addr *ls_id, struct in_addr *router_id, int exact)
933{
paul020709f2003-04-04 02:44:16 +0000934 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +0000935 struct ospf_area *area;
936 struct ospf_lsa *lsa;
paul6c835672004-10-11 11:00:30 +0000937 unsigned int len;
paul718e3742002-12-13 20:15:29 +0000938 int type_next;
939 int ls_id_next;
940 int router_id_next;
941 oid *offset;
942 int offsetlen;
943
paul020709f2003-04-04 02:44:16 +0000944 ospf = ospf_lookup ();
945
paul718e3742002-12-13 20:15:29 +0000946#define OSPF_LSDB_ENTRY_OFFSET \
947 (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
948
949 if (exact)
950 {
951 /* Area ID + Type + LS ID + Router ID. */
952 if (*length - v->namelen != OSPF_LSDB_ENTRY_OFFSET)
953 return NULL;
954
955 /* Set OID offset for Area ID. */
956 offset = name + v->namelen;
957
958 /* Lookup area first. */
959 oid2in_addr (offset, IN_ADDR_SIZE, area_id);
paul68980082003-03-25 05:07:42 +0000960 area = ospf_area_lookup_by_area_id (ospf, *area_id);
paul718e3742002-12-13 20:15:29 +0000961 if (! area)
962 return NULL;
963 offset += IN_ADDR_SIZE;
964
965 /* Type. */
966 *type = *offset;
967 offset++;
968
969 /* LS ID. */
970 oid2in_addr (offset, IN_ADDR_SIZE, ls_id);
971 offset += IN_ADDR_SIZE;
972
973 /* Router ID. */
974 oid2in_addr (offset, IN_ADDR_SIZE, router_id);
975
976 /* Lookup LSDB. */
977 return ospf_lsdb_lookup_by_id (area->lsdb, *type, *ls_id, *router_id);
978 }
979 else
980 {
981 /* Get variable length. */
982 offset = name + v->namelen;
983 offsetlen = *length - v->namelen;
984 len = offsetlen;
985
986 if (len > IN_ADDR_SIZE)
987 len = IN_ADDR_SIZE;
988
989 oid2in_addr (offset, len, area_id);
990
991 /* First we search area. */
992 if (len == IN_ADDR_SIZE)
paul68980082003-03-25 05:07:42 +0000993 area = ospf_area_lookup_by_area_id (ospf, *area_id);
paul718e3742002-12-13 20:15:29 +0000994 else
paul68980082003-03-25 05:07:42 +0000995 area = ospf_area_lookup_next (ospf, area_id, len == 0 ? 1 : 0);
paul718e3742002-12-13 20:15:29 +0000996
997 if (area == NULL)
998 return NULL;
999
1000 do
1001 {
1002 /* Next we lookup type. */
1003 offset += IN_ADDR_SIZE;
1004 offsetlen -= IN_ADDR_SIZE;
1005 len = offsetlen;
1006
1007 if (len <= 0)
1008 type_next = 1;
1009 else
1010 {
1011 len = 1;
1012 type_next = 0;
1013 *type = *offset;
1014 }
1015
1016 /* LS ID. */
1017 offset++;
1018 offsetlen--;
1019 len = offsetlen;
1020
1021 if (len <= 0)
1022 ls_id_next = 1;
1023 else
1024 {
1025 ls_id_next = 0;
1026 if (len > IN_ADDR_SIZE)
1027 len = IN_ADDR_SIZE;
1028
1029 oid2in_addr (offset, len, ls_id);
1030 }
1031
1032 /* Router ID. */
1033 offset += IN_ADDR_SIZE;
1034 offsetlen -= IN_ADDR_SIZE;
1035 len = offsetlen;
1036
1037 if (len <= 0)
1038 router_id_next = 1;
1039 else
1040 {
1041 router_id_next = 0;
1042 if (len > IN_ADDR_SIZE)
1043 len = IN_ADDR_SIZE;
1044
1045 oid2in_addr (offset, len, router_id);
1046 }
1047
1048 lsa = lsdb_lookup_next (area, type, type_next, ls_id, ls_id_next,
1049 router_id, router_id_next);
1050
1051 if (lsa)
1052 {
1053 /* Fill in length. */
1054 *length = v->namelen + OSPF_LSDB_ENTRY_OFFSET;
1055
1056 /* Fill in value. */
1057 offset = name + v->namelen;
1058 oid_copy_addr (offset, area_id, IN_ADDR_SIZE);
1059 offset += IN_ADDR_SIZE;
1060 *offset = lsa->data->type;
1061 offset++;
1062 oid_copy_addr (offset, &lsa->data->id, IN_ADDR_SIZE);
1063 offset += IN_ADDR_SIZE;
1064 oid_copy_addr (offset, &lsa->data->adv_router, IN_ADDR_SIZE);
1065
1066 return lsa;
1067 }
1068 }
paul68980082003-03-25 05:07:42 +00001069 while ((area = ospf_area_lookup_next (ospf, area_id, 0)) != NULL);
paul718e3742002-12-13 20:15:29 +00001070 }
1071 return NULL;
1072}
1073
1074static u_char *
1075ospfLsdbEntry (struct variable *v, oid *name, size_t *length, int exact,
1076 size_t *var_len, WriteMethod **write_method)
1077{
1078 struct ospf_lsa *lsa;
1079 struct lsa_header *lsah;
1080 struct in_addr area_id;
1081 u_char type;
1082 struct in_addr ls_id;
1083 struct in_addr router_id;
paul020709f2003-04-04 02:44:16 +00001084 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001085
1086 /* INDEX { ospfLsdbAreaId, ospfLsdbType,
1087 ospfLsdbLsid, ospfLsdbRouterId } */
1088
1089 memset (&area_id, 0, sizeof (struct in_addr));
1090 type = 0;
1091 memset (&ls_id, 0, sizeof (struct in_addr));
1092 memset (&router_id, 0, sizeof (struct in_addr));
1093
1094 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00001095 ospf = ospf_lookup ();
1096 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001097 return NULL;
1098
1099 lsa = ospfLsdbLookup (v, name, length, &area_id, &type, &ls_id, &router_id,
1100 exact);
1101 if (! lsa)
1102 return NULL;
1103
1104 lsah = lsa->data;
1105
1106 /* Return the current value of the variable */
1107 switch (v->magic)
1108 {
1109 case OSPFLSDBAREAID: /* 1 */
1110 return SNMP_IPADDRESS (lsa->area->area_id);
1111 break;
1112 case OSPFLSDBTYPE: /* 2 */
1113 return SNMP_INTEGER (lsah->type);
1114 break;
1115 case OSPFLSDBLSID: /* 3 */
1116 return SNMP_IPADDRESS (lsah->id);
1117 break;
1118 case OSPFLSDBROUTERID: /* 4 */
1119 return SNMP_IPADDRESS (lsah->adv_router);
1120 break;
1121 case OSPFLSDBSEQUENCE: /* 5 */
1122 return SNMP_INTEGER (lsah->ls_seqnum);
1123 break;
1124 case OSPFLSDBAGE: /* 6 */
1125 return SNMP_INTEGER (lsah->ls_age);
1126 break;
1127 case OSPFLSDBCHECKSUM: /* 7 */
1128 return SNMP_INTEGER (lsah->checksum);
1129 break;
1130 case OSPFLSDBADVERTISEMENT: /* 8 */
1131 *var_len = ntohs (lsah->length);
1132 return (u_char *) lsah;
1133 break;
1134 default:
1135 return NULL;
1136 break;
1137 }
1138 return NULL;
1139}
1140
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001141static struct ospf_area_range *
paul718e3742002-12-13 20:15:29 +00001142ospfAreaRangeLookup (struct variable *v, oid *name, size_t *length,
1143 struct in_addr *area_id, struct in_addr *range_net,
1144 int exact)
1145{
1146 oid *offset;
1147 int offsetlen;
paul6c835672004-10-11 11:00:30 +00001148 unsigned int len;
paul020709f2003-04-04 02:44:16 +00001149 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001150 struct ospf_area *area;
1151 struct ospf_area_range *range;
1152 struct prefix_ipv4 p;
1153 p.family = AF_INET;
1154 p.prefixlen = IPV4_MAX_BITLEN;
1155
paul020709f2003-04-04 02:44:16 +00001156 ospf = ospf_lookup ();
1157
paul718e3742002-12-13 20:15:29 +00001158 if (exact)
1159 {
1160 /* Area ID + Range Network. */
1161 if (v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE != *length)
1162 return NULL;
1163
1164 /* Set OID offset for Area ID. */
1165 offset = name + v->namelen;
1166
1167 /* Lookup area first. */
1168 oid2in_addr (offset, IN_ADDR_SIZE, area_id);
1169
paul68980082003-03-25 05:07:42 +00001170 area = ospf_area_lookup_by_area_id (ospf, *area_id);
paul718e3742002-12-13 20:15:29 +00001171 if (! area)
1172 return NULL;
1173
1174 offset += IN_ADDR_SIZE;
1175
1176 /* Lookup area range. */
1177 oid2in_addr (offset, IN_ADDR_SIZE, range_net);
1178 p.prefix = *range_net;
1179
1180 return ospf_area_range_lookup (area, &p);
1181 }
1182 else
1183 {
1184 /* Set OID offset for Area ID. */
1185 offset = name + v->namelen;
1186 offsetlen = *length - v->namelen;
1187
1188 len = offsetlen;
1189 if (len > IN_ADDR_SIZE)
1190 len = IN_ADDR_SIZE;
1191
1192 oid2in_addr (offset, len, area_id);
1193
1194 /* First we search area. */
1195 if (len == IN_ADDR_SIZE)
paul68980082003-03-25 05:07:42 +00001196 area = ospf_area_lookup_by_area_id (ospf,*area_id);
paul718e3742002-12-13 20:15:29 +00001197 else
paul68980082003-03-25 05:07:42 +00001198 area = ospf_area_lookup_next (ospf, area_id, len == 0 ? 1 : 0);
paul718e3742002-12-13 20:15:29 +00001199
1200 if (area == NULL)
1201 return NULL;
1202
1203 do
1204 {
1205 offset += IN_ADDR_SIZE;
1206 offsetlen -= IN_ADDR_SIZE;
1207 len = offsetlen;
1208
1209 if (len < 0)
1210 len = 0;
1211 if (len > IN_ADDR_SIZE)
1212 len = IN_ADDR_SIZE;
1213
1214 oid2in_addr (offset, len, range_net);
1215
1216 range = ospf_area_range_lookup_next (area, range_net,
1217 len == 0 ? 1 : 0);
1218
1219 if (range)
1220 {
1221 /* Fill in length. */
1222 *length = v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE;
1223
1224 /* Fill in value. */
1225 offset = name + v->namelen;
1226 oid_copy_addr (offset, area_id, IN_ADDR_SIZE);
1227 offset += IN_ADDR_SIZE;
1228 oid_copy_addr (offset, range_net, IN_ADDR_SIZE);
1229
1230 return range;
1231 }
1232 }
paul68980082003-03-25 05:07:42 +00001233 while ((area = ospf_area_lookup_next (ospf, area_id, 0)) != NULL);
paul718e3742002-12-13 20:15:29 +00001234 }
1235 return NULL;
1236}
1237
1238static u_char *
1239ospfAreaRangeEntry (struct variable *v, oid *name, size_t *length, int exact,
1240 size_t *var_len, WriteMethod **write_method)
1241{
1242 struct ospf_area_range *range;
1243 struct in_addr area_id;
1244 struct in_addr range_net;
1245 struct in_addr mask;
paul020709f2003-04-04 02:44:16 +00001246 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001247
1248 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00001249 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00001250 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001251 return NULL;
1252
1253 memset (&area_id, 0, IN_ADDR_SIZE);
1254 memset (&range_net, 0, IN_ADDR_SIZE);
1255
1256 range = ospfAreaRangeLookup (v, name, length, &area_id, &range_net, exact);
1257 if (! range)
1258 return NULL;
1259
1260 /* Convert prefixlen to network mask format. */
1261 masklen2ip (range->subst_masklen, &mask);
1262
1263 /* Return the current value of the variable */
1264 switch (v->magic)
1265 {
1266 case OSPFAREARANGEAREAID: /* 1 */
1267 return SNMP_IPADDRESS (area_id);
1268 break;
1269 case OSPFAREARANGENET: /* 2 */
1270 return SNMP_IPADDRESS (range_net);
1271 break;
1272 case OSPFAREARANGEMASK: /* 3 */
1273 return SNMP_IPADDRESS (mask);
1274 break;
1275 case OSPFAREARANGESTATUS: /* 4 */
1276 return SNMP_INTEGER (SNMP_VALID);
1277 break;
1278 case OSPFAREARANGEEFFECT: /* 5 */
1279#define OSPF_advertiseMatching 1
1280#define OSPF_doNotAdvertiseMatching 2
1281 return SNMP_INTEGER (OSPF_advertiseMatching);
1282 break;
1283 default:
1284 return NULL;
1285 break;
1286 }
1287 return NULL;
1288}
1289
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001290static struct ospf_nbr_nbma *
paul718e3742002-12-13 20:15:29 +00001291ospfHostLookup (struct variable *v, oid *name, size_t *length,
1292 struct in_addr *addr, int exact)
1293{
1294 int len;
1295 struct ospf_nbr_nbma *nbr_nbma;
paul020709f2003-04-04 02:44:16 +00001296 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001297
paul020709f2003-04-04 02:44:16 +00001298 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00001299 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001300 return NULL;
1301
1302 if (exact)
1303 {
1304 /* INDEX { ospfHostIpAddress, ospfHostTOS } */
1305 if (*length != v->namelen + IN_ADDR_SIZE + 1)
1306 return NULL;
1307
1308 /* Check ospfHostTOS. */
1309 if (name[*length - 1] != 0)
1310 return NULL;
1311
1312 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, addr);
1313
paul68980082003-03-25 05:07:42 +00001314 nbr_nbma = ospf_nbr_nbma_lookup (ospf, *addr);
paul718e3742002-12-13 20:15:29 +00001315
1316 return nbr_nbma;
1317 }
1318 else
1319 {
1320 len = *length - v->namelen;
1321 if (len > 4)
1322 len = 4;
1323
1324 oid2in_addr (name + v->namelen, len, addr);
1325
paul68980082003-03-25 05:07:42 +00001326 nbr_nbma = ospf_nbr_nbma_lookup_next (ospf, addr, len == 0 ? 1 : 0);
paul718e3742002-12-13 20:15:29 +00001327
1328 if (nbr_nbma == NULL)
1329 return NULL;
1330
1331 oid_copy_addr (name + v->namelen, addr, IN_ADDR_SIZE);
1332
1333 /* Set TOS 0. */
1334 name[v->namelen + IN_ADDR_SIZE] = 0;
1335
1336 *length = v->namelen + IN_ADDR_SIZE + 1;
1337
1338 return nbr_nbma;
1339 }
1340 return NULL;
1341}
1342
1343static u_char *
1344ospfHostEntry (struct variable *v, oid *name, size_t *length, int exact,
1345 size_t *var_len, WriteMethod **write_method)
1346{
1347 struct ospf_nbr_nbma *nbr_nbma;
1348 struct ospf_interface *oi;
1349 struct in_addr addr;
paul020709f2003-04-04 02:44:16 +00001350 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001351
1352 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00001353 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00001354 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001355 return NULL;
1356
1357 memset (&addr, 0, sizeof (struct in_addr));
1358
1359 nbr_nbma = ospfHostLookup (v, name, length, &addr, exact);
1360 if (nbr_nbma == NULL)
1361 return NULL;
1362
1363 oi = nbr_nbma->oi;
1364
1365 /* Return the current value of the variable */
1366 switch (v->magic)
1367 {
1368 case OSPFHOSTIPADDRESS: /* 1 */
1369 return SNMP_IPADDRESS (nbr_nbma->addr);
1370 break;
1371 case OSPFHOSTTOS: /* 2 */
1372 return SNMP_INTEGER (0);
1373 break;
1374 case OSPFHOSTMETRIC: /* 3 */
1375 if (oi)
1376 return SNMP_INTEGER (oi->output_cost);
1377 else
1378 return SNMP_INTEGER (1);
1379 break;
1380 case OSPFHOSTSTATUS: /* 4 */
1381 return SNMP_INTEGER (SNMP_VALID);
1382 break;
1383 case OSPFHOSTAREAID: /* 5 */
1384 if (oi && oi->area)
1385 return SNMP_IPADDRESS (oi->area->area_id);
1386 else
1387 return SNMP_IPADDRESS (ospf_empty_addr);
1388 break;
1389 default:
1390 return NULL;
1391 break;
1392 }
1393 return NULL;
1394}
1395
1396struct list *ospf_snmp_iflist;
1397
1398struct ospf_snmp_if
1399{
1400 struct in_addr addr;
1401 unsigned int ifindex;
1402 struct interface *ifp;
1403};
1404
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001405static struct ospf_snmp_if *
Stephen Hemminger66e5cd82009-02-09 10:14:16 -08001406ospf_snmp_if_new (void)
paul718e3742002-12-13 20:15:29 +00001407{
Stephen Hemminger393deb92008-08-18 14:13:29 -07001408 return XCALLOC (0, sizeof (struct ospf_snmp_if));
paul718e3742002-12-13 20:15:29 +00001409}
1410
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001411static void
paul718e3742002-12-13 20:15:29 +00001412ospf_snmp_if_free (struct ospf_snmp_if *osif)
1413{
1414 XFREE (0, osif);
1415}
1416
1417void
1418ospf_snmp_if_delete (struct interface *ifp)
1419{
paul1eb8ef22005-04-07 07:30:20 +00001420 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001421 struct ospf_snmp_if *osif;
1422
paul1eb8ef22005-04-07 07:30:20 +00001423 for (ALL_LIST_ELEMENTS (ospf_snmp_iflist, node, nnode, osif))
paul718e3742002-12-13 20:15:29 +00001424 {
1425 if (osif->ifp == ifp)
1426 {
paul1eb8ef22005-04-07 07:30:20 +00001427 list_delete_node (ospf_snmp_iflist, node);
paul718e3742002-12-13 20:15:29 +00001428 ospf_snmp_if_free (osif);
1429 return;
1430 }
1431 }
1432}
1433
1434void
1435ospf_snmp_if_update (struct interface *ifp)
1436{
paul1eb8ef22005-04-07 07:30:20 +00001437 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001438 struct listnode *pn;
1439 struct connected *ifc;
1440 struct prefix *p;
1441 struct ospf_snmp_if *osif;
1442 struct in_addr *addr;
1443 unsigned int ifindex;
1444
1445 ospf_snmp_if_delete (ifp);
1446
1447 p = NULL;
1448 addr = NULL;
1449 ifindex = 0;
1450
1451 /* Lookup first IPv4 address entry. */
paul1eb8ef22005-04-07 07:30:20 +00001452 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc))
paul718e3742002-12-13 20:15:29 +00001453 {
Andrew J. Schorre4529632006-12-12 19:18:21 +00001454 p = CONNECTED_ID(ifc);
paul718e3742002-12-13 20:15:29 +00001455
1456 if (p->family == AF_INET)
1457 {
1458 addr = &p->u.prefix4;
1459 break;
1460 }
1461 }
1462 if (! addr)
1463 ifindex = ifp->ifindex;
1464
1465 /* Add interface to the list. */
1466 pn = NULL;
paul1eb8ef22005-04-07 07:30:20 +00001467 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, node, osif))
paul718e3742002-12-13 20:15:29 +00001468 {
1469 if (addr)
1470 {
vincent77df1f72005-10-06 07:46:22 +00001471 /* Usual interfaces --> Sort them based on interface IPv4 addresses */
paul718e3742002-12-13 20:15:29 +00001472 if (ntohl (osif->addr.s_addr) > ntohl (addr->s_addr))
1473 break;
1474 }
1475 else
1476 {
vincent77df1f72005-10-06 07:46:22 +00001477 /* Unnumbered interfaces --> Sort them based on interface indexes */
paul718e3742002-12-13 20:15:29 +00001478 if (osif->addr.s_addr != 0 || osif->ifindex > ifindex)
1479 break;
1480 }
paul1eb8ef22005-04-07 07:30:20 +00001481 pn = node;
paul718e3742002-12-13 20:15:29 +00001482 }
1483
1484 osif = ospf_snmp_if_new ();
vincent77df1f72005-10-06 07:46:22 +00001485 if (addr) /* Usual interface */
1486 {
paul718e3742002-12-13 20:15:29 +00001487 osif->addr = *addr;
vincent77df1f72005-10-06 07:46:22 +00001488
1489 /* This field is used for storing ospfAddressLessIf OID value,
1490 * conform to RFC1850 OSPF-MIB specification, it must be 0 for
1491 * usual interface */
1492 osif->ifindex = 0;
1493 }
1494 else /* Unnumbered interface */
paul718e3742002-12-13 20:15:29 +00001495 osif->ifindex = ifindex;
1496 osif->ifp = ifp;
1497
1498 listnode_add_after (ospf_snmp_iflist, pn, osif);
1499}
1500
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001501static int
vincent77df1f72005-10-06 07:46:22 +00001502ospf_snmp_is_if_have_addr (struct interface *ifp)
1503{
vincent77df1f72005-10-06 07:46:22 +00001504 struct listnode *nn;
1505 struct connected *ifc;
1506
1507 /* Is this interface having any connected IPv4 address ? */
1508 for (ALL_LIST_ELEMENTS_RO (ifp->connected, nn, ifc))
1509 {
Andrew J. Schorre4529632006-12-12 19:18:21 +00001510 if (CONNECTED_PREFIX(ifc)->family == AF_INET)
vincent77df1f72005-10-06 07:46:22 +00001511 return 1;
1512 }
1513
1514 return 0;
1515}
1516
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001517static struct ospf_interface *
paul718e3742002-12-13 20:15:29 +00001518ospf_snmp_if_lookup (struct in_addr *ifaddr, unsigned int *ifindex)
1519{
paul1eb8ef22005-04-07 07:30:20 +00001520 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001521 struct ospf_snmp_if *osif;
vincent77df1f72005-10-06 07:46:22 +00001522 struct ospf_interface *oi = NULL;
1523 struct ospf *ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +00001524
paul1eb8ef22005-04-07 07:30:20 +00001525 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, node, osif))
paul718e3742002-12-13 20:15:29 +00001526 {
1527 if (ifaddr->s_addr)
vincent77df1f72005-10-06 07:46:22 +00001528 {
1529 if (IPV4_ADDR_SAME (&osif->addr, ifaddr))
1530 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1531 }
paul718e3742002-12-13 20:15:29 +00001532 else
vincent77df1f72005-10-06 07:46:22 +00001533 {
1534 if (osif->ifindex == *ifindex)
1535 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1536 }
paul718e3742002-12-13 20:15:29 +00001537 }
vincent77df1f72005-10-06 07:46:22 +00001538 return oi;
paul718e3742002-12-13 20:15:29 +00001539}
1540
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001541static struct ospf_interface *
paul718e3742002-12-13 20:15:29 +00001542ospf_snmp_if_lookup_next (struct in_addr *ifaddr, unsigned int *ifindex,
1543 int ifaddr_next, int ifindex_next)
1544{
1545 struct ospf_snmp_if *osif;
1546 struct listnode *nn;
vincent77df1f72005-10-06 07:46:22 +00001547 struct ospf *ospf = ospf_lookup ();
1548 struct ospf_interface *oi = NULL;
paul718e3742002-12-13 20:15:29 +00001549
vincent77df1f72005-10-06 07:46:22 +00001550 if (ospf == NULL)
1551 return NULL;
1552
1553 /* No instance is specified --> Return the first OSPF interface */
paul718e3742002-12-13 20:15:29 +00001554 if (ifaddr_next)
1555 {
vincent77df1f72005-10-06 07:46:22 +00001556 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, nn, osif))
paul718e3742002-12-13 20:15:29 +00001557 {
paul1eb8ef22005-04-07 07:30:20 +00001558 osif = listgetdata (nn);
paul718e3742002-12-13 20:15:29 +00001559 *ifaddr = osif->addr;
1560 *ifindex = osif->ifindex;
vincent77df1f72005-10-06 07:46:22 +00001561 /* Because no instance is specified, we don't care about the kind of
1562 * interface (usual or unnumbered), just returning the first valid
1563 * OSPF interface */
1564 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1565 if (oi)
1566 return (oi);
paul718e3742002-12-13 20:15:29 +00001567 }
1568 return NULL;
1569 }
1570
vincent77df1f72005-10-06 07:46:22 +00001571 /* An instance is specified --> Return the next OSPF interface */
paul1eb8ef22005-04-07 07:30:20 +00001572 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, nn, osif))
paul718e3742002-12-13 20:15:29 +00001573 {
vincent77df1f72005-10-06 07:46:22 +00001574 /* Usual interface */
1575 if (ifaddr->s_addr)
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001576 {
1577 /* The interface must have valid AF_INET connected address */
1578 /* it must have lager IPv4 address value than the lookup entry */
1579 if ((ospf_snmp_is_if_have_addr(osif->ifp)) &&
1580 (ntohl (osif->addr.s_addr) > ntohl (ifaddr->s_addr)))
1581 {
1582 *ifaddr = osif->addr;
1583 *ifindex = osif->ifindex;
vincent77df1f72005-10-06 07:46:22 +00001584
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001585 /* and it must be an OSPF interface */
1586 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1587 if (oi)
1588 return oi;
1589 }
1590 }
vincent77df1f72005-10-06 07:46:22 +00001591 /* Unnumbered interface */
1592 else
1593 /* The interface must NOT have valid AF_INET connected address */
1594 /* it must have lager interface index than the lookup entry */
1595 if ((!ospf_snmp_is_if_have_addr(osif->ifp)) &&
1596 (osif->ifindex > *ifindex))
1597 {
1598 *ifaddr = osif->addr;
1599 *ifindex = osif->ifindex;
1600
1601 /* and it must be an OSPF interface */
1602 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1603 if (oi)
1604 return oi;
1605 }
paul718e3742002-12-13 20:15:29 +00001606 }
1607 return NULL;
1608}
1609
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001610static int
paul718e3742002-12-13 20:15:29 +00001611ospf_snmp_iftype (struct interface *ifp)
1612{
1613#define ospf_snmp_iftype_broadcast 1
1614#define ospf_snmp_iftype_nbma 2
1615#define ospf_snmp_iftype_pointToPoint 3
1616#define ospf_snmp_iftype_pointToMultipoint 5
1617 if (if_is_broadcast (ifp))
1618 return ospf_snmp_iftype_broadcast;
1619 if (if_is_pointopoint (ifp))
1620 return ospf_snmp_iftype_pointToPoint;
1621 return ospf_snmp_iftype_broadcast;
1622}
1623
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001624static struct ospf_interface *
paul718e3742002-12-13 20:15:29 +00001625ospfIfLookup (struct variable *v, oid *name, size_t *length,
1626 struct in_addr *ifaddr, unsigned int *ifindex, int exact)
1627{
paul6c835672004-10-11 11:00:30 +00001628 unsigned int len;
paul718e3742002-12-13 20:15:29 +00001629 int ifaddr_next = 0;
1630 int ifindex_next = 0;
vincent77df1f72005-10-06 07:46:22 +00001631 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001632 oid *offset;
1633
1634 if (exact)
1635 {
1636 if (*length != v->namelen + IN_ADDR_SIZE + 1)
1637 return NULL;
1638
1639 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, ifaddr);
1640 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1641
1642 return ospf_snmp_if_lookup (ifaddr, ifindex);
1643 }
1644 else
1645 {
1646 len = *length - v->namelen;
1647 if (len >= IN_ADDR_SIZE)
1648 len = IN_ADDR_SIZE;
1649 if (len <= 0)
1650 ifaddr_next = 1;
1651
1652 oid2in_addr (name + v->namelen, len, ifaddr);
1653
1654 len = *length - v->namelen - IN_ADDR_SIZE;
1655 if (len >= 1)
1656 len = 1;
1657 else
1658 ifindex_next = 1;
1659
1660 if (len == 1)
1661 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1662
vincent77df1f72005-10-06 07:46:22 +00001663 oi = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next,
paul718e3742002-12-13 20:15:29 +00001664 ifindex_next);
vincent77df1f72005-10-06 07:46:22 +00001665 if (oi)
paul718e3742002-12-13 20:15:29 +00001666 {
1667 *length = v->namelen + IN_ADDR_SIZE + 1;
1668 offset = name + v->namelen;
1669 oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE);
1670 offset += IN_ADDR_SIZE;
1671 *offset = *ifindex;
vincent77df1f72005-10-06 07:46:22 +00001672 return oi;
paul718e3742002-12-13 20:15:29 +00001673 }
1674 }
1675 return NULL;
1676}
1677
1678static u_char *
1679ospfIfEntry (struct variable *v, oid *name, size_t *length, int exact,
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001680 size_t *var_len, WriteMethod **write_method)
paul718e3742002-12-13 20:15:29 +00001681{
paul718e3742002-12-13 20:15:29 +00001682 unsigned int ifindex;
1683 struct in_addr ifaddr;
1684 struct ospf_interface *oi;
paul020709f2003-04-04 02:44:16 +00001685 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001686
1687 ifindex = 0;
1688 memset (&ifaddr, 0, sizeof (struct in_addr));
1689
1690 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00001691 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00001692 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001693 return NULL;
1694
vincent77df1f72005-10-06 07:46:22 +00001695 oi = ospfIfLookup (v, name, length, &ifaddr, &ifindex, exact);
paul718e3742002-12-13 20:15:29 +00001696 if (oi == NULL)
1697 return NULL;
1698
1699 /* Return the current value of the variable */
1700 switch (v->magic)
1701 {
1702 case OSPFIFIPADDRESS: /* 1 */
1703 return SNMP_IPADDRESS (ifaddr);
1704 break;
1705 case OSPFADDRESSLESSIF: /* 2 */
1706 return SNMP_INTEGER (ifindex);
1707 break;
1708 case OSPFIFAREAID: /* 3 */
1709 if (oi->area)
1710 return SNMP_IPADDRESS (oi->area->area_id);
1711 else
1712 return SNMP_IPADDRESS (ospf_empty_addr);
1713 break;
1714 case OSPFIFTYPE: /* 4 */
vincent77df1f72005-10-06 07:46:22 +00001715 return SNMP_INTEGER (ospf_snmp_iftype (oi->ifp));
paul718e3742002-12-13 20:15:29 +00001716 break;
1717 case OSPFIFADMINSTAT: /* 5 */
1718 if (oi)
1719 return SNMP_INTEGER (OSPF_STATUS_ENABLED);
1720 else
1721 return SNMP_INTEGER (OSPF_STATUS_DISABLED);
1722 break;
1723 case OSPFIFRTRPRIORITY: /* 6 */
1724 return SNMP_INTEGER (PRIORITY (oi));
1725 break;
1726 case OSPFIFTRANSITDELAY: /* 7 */
1727 return SNMP_INTEGER (OSPF_IF_PARAM (oi, transmit_delay));
1728 break;
1729 case OSPFIFRETRANSINTERVAL: /* 8 */
1730 return SNMP_INTEGER (OSPF_IF_PARAM (oi, retransmit_interval));
1731 break;
1732 case OSPFIFHELLOINTERVAL: /* 9 */
1733 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_hello));
1734 break;
1735 case OSPFIFRTRDEADINTERVAL: /* 10 */
1736 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_wait));
1737 break;
1738 case OSPFIFPOLLINTERVAL: /* 11 */
1739 return SNMP_INTEGER (OSPF_POLL_INTERVAL_DEFAULT);
1740 break;
1741 case OSPFIFSTATE: /* 12 */
vincentba682532005-09-29 13:52:57 +00001742 return SNMP_INTEGER (ISM_SNMP(oi->state));
paul718e3742002-12-13 20:15:29 +00001743 break;
1744 case OSPFIFDESIGNATEDROUTER: /* 13 */
1745 return SNMP_IPADDRESS (DR (oi));
1746 break;
1747 case OSPFIFBACKUPDESIGNATEDROUTER: /* 14 */
1748 return SNMP_IPADDRESS (BDR (oi));
1749 break;
1750 case OSPFIFEVENTS: /* 15 */
1751 return SNMP_INTEGER (oi->state_change);
1752 break;
1753 case OSPFIFAUTHKEY: /* 16 */
1754 *var_len = 0;
1755 return (u_char *) OSPF_IF_PARAM (oi, auth_simple);
1756 break;
1757 case OSPFIFSTATUS: /* 17 */
1758 return SNMP_INTEGER (SNMP_VALID);
1759 break;
1760 case OSPFIFMULTICASTFORWARDING: /* 18 */
1761#define ospf_snmp_multiforward_blocked 1
1762#define ospf_snmp_multiforward_multicast 2
1763#define ospf_snmp_multiforward_unicast 3
1764 return SNMP_INTEGER (ospf_snmp_multiforward_blocked);
1765 break;
1766 case OSPFIFDEMAND: /* 19 */
1767 return SNMP_INTEGER (SNMP_FALSE);
1768 break;
1769 case OSPFIFAUTHTYPE: /* 20 */
1770 if (oi->area)
1771 return SNMP_INTEGER (oi->area->auth_type);
1772 else
1773 return SNMP_INTEGER (0);
1774 break;
1775 default:
1776 return NULL;
1777 break;
1778 }
1779 return NULL;
1780}
1781
1782#define OSPF_SNMP_METRIC_VALUE 1
1783
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001784static struct ospf_interface *
paul718e3742002-12-13 20:15:29 +00001785ospfIfMetricLookup (struct variable *v, oid *name, size_t *length,
1786 struct in_addr *ifaddr, unsigned int *ifindex, int exact)
1787{
paul6c835672004-10-11 11:00:30 +00001788 unsigned int len;
paul718e3742002-12-13 20:15:29 +00001789 int ifaddr_next = 0;
1790 int ifindex_next = 0;
vincent77df1f72005-10-06 07:46:22 +00001791 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001792 oid *offset;
1793 int metric;
1794
1795 if (exact)
1796 {
1797 if (*length != v->namelen + IN_ADDR_SIZE + 1 + 1)
1798 return NULL;
1799
1800 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, ifaddr);
1801 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1802 metric = name[v->namelen + IN_ADDR_SIZE + 1];
1803
1804 if (metric != OSPF_SNMP_METRIC_VALUE)
1805 return NULL;
1806
1807 return ospf_snmp_if_lookup (ifaddr, ifindex);
1808 }
1809 else
1810 {
1811 len = *length - v->namelen;
1812 if (len >= IN_ADDR_SIZE)
1813 len = IN_ADDR_SIZE;
1814 else
1815 ifaddr_next = 1;
1816
1817 oid2in_addr (name + v->namelen, len, ifaddr);
1818
1819 len = *length - v->namelen - IN_ADDR_SIZE;
1820 if (len >= 1)
1821 len = 1;
1822 else
1823 ifindex_next = 1;
1824
1825 if (len == 1)
1826 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1827
vincent77df1f72005-10-06 07:46:22 +00001828 oi = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next,
paul718e3742002-12-13 20:15:29 +00001829 ifindex_next);
vincent77df1f72005-10-06 07:46:22 +00001830 if (oi)
paul718e3742002-12-13 20:15:29 +00001831 {
1832 *length = v->namelen + IN_ADDR_SIZE + 1 + 1;
1833 offset = name + v->namelen;
1834 oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE);
1835 offset += IN_ADDR_SIZE;
1836 *offset = *ifindex;
1837 offset++;
1838 *offset = OSPF_SNMP_METRIC_VALUE;
vincent77df1f72005-10-06 07:46:22 +00001839 return oi;
paul718e3742002-12-13 20:15:29 +00001840 }
1841 }
1842 return NULL;
1843}
1844
1845static u_char *
1846ospfIfMetricEntry (struct variable *v, oid *name, size_t *length, int exact,
1847 size_t *var_len, WriteMethod **write_method)
1848{
1849 /* Currently we support metric 1 only. */
paul718e3742002-12-13 20:15:29 +00001850 unsigned int ifindex;
1851 struct in_addr ifaddr;
1852 struct ospf_interface *oi;
paul020709f2003-04-04 02:44:16 +00001853 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001854
1855 ifindex = 0;
1856 memset (&ifaddr, 0, sizeof (struct in_addr));
1857
1858 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00001859 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00001860 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00001861 return NULL;
1862
vincent77df1f72005-10-06 07:46:22 +00001863 oi = ospfIfMetricLookup (v, name, length, &ifaddr, &ifindex, exact);
paul718e3742002-12-13 20:15:29 +00001864 if (oi == NULL)
1865 return NULL;
1866
1867 /* Return the current value of the variable */
1868 switch (v->magic)
1869 {
1870 case OSPFIFMETRICIPADDRESS:
1871 return SNMP_IPADDRESS (ifaddr);
1872 break;
1873 case OSPFIFMETRICADDRESSLESSIF:
1874 return SNMP_INTEGER (ifindex);
1875 break;
1876 case OSPFIFMETRICTOS:
1877 return SNMP_INTEGER (0);
1878 break;
1879 case OSPFIFMETRICVALUE:
1880 return SNMP_INTEGER (OSPF_SNMP_METRIC_VALUE);
1881 break;
1882 case OSPFIFMETRICSTATUS:
1883 return SNMP_INTEGER (1);
1884 break;
1885 default:
1886 return NULL;
1887 break;
1888 }
1889 return NULL;
1890}
1891
1892struct route_table *ospf_snmp_vl_table;
1893
1894void
1895ospf_snmp_vl_add (struct ospf_vl_data *vl_data)
1896{
1897 struct prefix_ls lp;
1898 struct route_node *rn;
1899
1900 memset (&lp, 0, sizeof (struct prefix_ls));
1901 lp.family = 0;
1902 lp.prefixlen = 64;
1903 lp.id = vl_data->vl_area_id;
1904 lp.adv_router = vl_data->vl_peer;
1905
1906 rn = route_node_get (ospf_snmp_vl_table, (struct prefix *) &lp);
1907 rn->info = vl_data;
1908}
1909
1910void
1911ospf_snmp_vl_delete (struct ospf_vl_data *vl_data)
1912{
1913 struct prefix_ls lp;
1914 struct route_node *rn;
1915
1916 memset (&lp, 0, sizeof (struct prefix_ls));
1917 lp.family = 0;
1918 lp.prefixlen = 64;
1919 lp.id = vl_data->vl_area_id;
1920 lp.adv_router = vl_data->vl_peer;
1921
1922 rn = route_node_lookup (ospf_snmp_vl_table, (struct prefix *) &lp);
1923 if (! rn)
1924 return;
1925 rn->info = NULL;
1926 route_unlock_node (rn);
1927 route_unlock_node (rn);
1928}
1929
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001930static struct ospf_vl_data *
paul718e3742002-12-13 20:15:29 +00001931ospf_snmp_vl_lookup (struct in_addr *area_id, struct in_addr *neighbor)
1932{
1933 struct prefix_ls lp;
1934 struct route_node *rn;
1935 struct ospf_vl_data *vl_data;
1936
1937 memset (&lp, 0, sizeof (struct prefix_ls));
1938 lp.family = 0;
1939 lp.prefixlen = 64;
1940 lp.id = *area_id;
1941 lp.adv_router = *neighbor;
1942
1943 rn = route_node_lookup (ospf_snmp_vl_table, (struct prefix *) &lp);
1944 if (rn)
1945 {
1946 vl_data = rn->info;
1947 route_unlock_node (rn);
1948 return vl_data;
1949 }
1950 return NULL;
1951}
1952
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001953static struct ospf_vl_data *
paul718e3742002-12-13 20:15:29 +00001954ospf_snmp_vl_lookup_next (struct in_addr *area_id, struct in_addr *neighbor,
1955 int first)
1956{
1957 struct prefix_ls lp;
1958 struct route_node *rn;
1959 struct ospf_vl_data *vl_data;
1960
1961 memset (&lp, 0, sizeof (struct prefix_ls));
1962 lp.family = 0;
1963 lp.prefixlen = 64;
1964 lp.id = *area_id;
1965 lp.adv_router = *neighbor;
1966
1967 if (first)
1968 rn = route_top (ospf_snmp_vl_table);
1969 else
1970 {
1971 rn = route_node_get (ospf_snmp_vl_table, (struct prefix *) &lp);
1972 rn = route_next (rn);
1973 }
1974
1975 for (; rn; rn = route_next (rn))
1976 if (rn->info)
1977 break;
1978
1979 if (rn && rn->info)
1980 {
1981 vl_data = rn->info;
1982 *area_id = vl_data->vl_area_id;
1983 *neighbor = vl_data->vl_peer;
1984 route_unlock_node (rn);
1985 return vl_data;
1986 }
1987 return NULL;
1988}
1989
Chris Caputo0be8dfb2009-06-02 18:40:07 +01001990static struct ospf_vl_data *
paul718e3742002-12-13 20:15:29 +00001991ospfVirtIfLookup (struct variable *v, oid *name, size_t *length,
1992 struct in_addr *area_id, struct in_addr *neighbor, int exact)
1993{
1994 int first;
paul6c835672004-10-11 11:00:30 +00001995 unsigned int len;
paul718e3742002-12-13 20:15:29 +00001996 struct ospf_vl_data *vl_data;
1997
1998 if (exact)
1999 {
2000 if (*length != v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE)
2001 return NULL;
2002
2003 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, area_id);
2004 oid2in_addr (name + v->namelen + IN_ADDR_SIZE, IN_ADDR_SIZE, neighbor);
2005
2006 return ospf_snmp_vl_lookup (area_id, neighbor);
2007 }
2008 else
2009 {
2010 first = 0;
2011
2012 len = *length - v->namelen;
2013 if (len <= 0)
2014 first = 1;
2015 if (len > IN_ADDR_SIZE)
2016 len = IN_ADDR_SIZE;
2017 oid2in_addr (name + v->namelen, len, area_id);
2018
2019 len = *length - v->namelen - IN_ADDR_SIZE;
2020 if (len > IN_ADDR_SIZE)
2021 len = IN_ADDR_SIZE;
2022 oid2in_addr (name + v->namelen + IN_ADDR_SIZE, len, neighbor);
2023
2024 vl_data = ospf_snmp_vl_lookup_next (area_id, neighbor, first);
2025
2026 if (vl_data)
2027 {
2028 *length = v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE;
2029 oid_copy_addr (name + v->namelen, area_id, IN_ADDR_SIZE);
2030 oid_copy_addr (name + v->namelen + IN_ADDR_SIZE, neighbor,
2031 IN_ADDR_SIZE);
2032 return vl_data;
2033 }
2034 }
2035 return NULL;
2036}
2037
2038static u_char *
2039ospfVirtIfEntry (struct variable *v, oid *name, size_t *length, int exact,
Chris Caputo0be8dfb2009-06-02 18:40:07 +01002040 size_t *var_len, WriteMethod **write_method)
paul718e3742002-12-13 20:15:29 +00002041{
2042 struct ospf_vl_data *vl_data;
2043 struct ospf_interface *oi;
2044 struct in_addr area_id;
2045 struct in_addr neighbor;
2046
2047 memset (&area_id, 0, sizeof (struct in_addr));
2048 memset (&neighbor, 0, sizeof (struct in_addr));
2049
2050 vl_data = ospfVirtIfLookup (v, name, length, &area_id, &neighbor, exact);
2051 if (! vl_data)
2052 return NULL;
2053 oi = vl_data->vl_oi;
2054 if (! oi)
2055 return NULL;
2056
2057 /* Return the current value of the variable */
2058 switch (v->magic)
2059 {
2060 case OSPFVIRTIFAREAID:
2061 return SNMP_IPADDRESS (area_id);
2062 break;
2063 case OSPFVIRTIFNEIGHBOR:
2064 return SNMP_IPADDRESS (neighbor);
2065 break;
2066 case OSPFVIRTIFTRANSITDELAY:
2067 return SNMP_INTEGER (OSPF_IF_PARAM (oi, transmit_delay));
2068 break;
2069 case OSPFVIRTIFRETRANSINTERVAL:
2070 return SNMP_INTEGER (OSPF_IF_PARAM (oi, retransmit_interval));
2071 break;
2072 case OSPFVIRTIFHELLOINTERVAL:
2073 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_hello));
2074 break;
2075 case OSPFVIRTIFRTRDEADINTERVAL:
2076 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_wait));
2077 break;
2078 case OSPFVIRTIFSTATE:
2079 return SNMP_INTEGER (oi->state);
2080 break;
2081 case OSPFVIRTIFEVENTS:
2082 return SNMP_INTEGER (oi->state_change);
2083 break;
2084 case OSPFVIRTIFAUTHKEY:
2085 *var_len = 0;
2086 return (u_char *) OSPF_IF_PARAM (oi, auth_simple);
2087 break;
2088 case OSPFVIRTIFSTATUS:
2089 return SNMP_INTEGER (SNMP_VALID);
2090 break;
2091 case OSPFVIRTIFAUTHTYPE:
2092 if (oi->area)
2093 return SNMP_INTEGER (oi->area->auth_type);
2094 else
2095 return SNMP_INTEGER (0);
2096 break;
2097 default:
2098 return NULL;
2099 break;
2100 }
2101 return NULL;
2102}
2103
Chris Caputo0be8dfb2009-06-02 18:40:07 +01002104static struct ospf_neighbor *
paul68980082003-03-25 05:07:42 +00002105ospf_snmp_nbr_lookup (struct ospf *ospf, struct in_addr *nbr_addr,
2106 unsigned int *ifindex)
paul718e3742002-12-13 20:15:29 +00002107{
paul1eb8ef22005-04-07 07:30:20 +00002108 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002109 struct ospf_interface *oi;
2110 struct ospf_neighbor *nbr;
2111 struct route_node *rn;
2112
paul1eb8ef22005-04-07 07:30:20 +00002113 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002114 {
2115 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2116 if ((nbr = rn->info) != NULL
2117 && nbr != oi->nbr_self
vincent5e4914c2005-09-29 16:34:30 +00002118/* If EXACT match is needed, provide ALL entry found
paul718e3742002-12-13 20:15:29 +00002119 && nbr->state != NSM_Down
vincent5e4914c2005-09-29 16:34:30 +00002120 */
paul718e3742002-12-13 20:15:29 +00002121 && nbr->src.s_addr != 0)
2122 {
2123 if (IPV4_ADDR_SAME (&nbr->src, nbr_addr))
2124 {
2125 route_unlock_node (rn);
2126 return nbr;
2127 }
2128 }
2129 }
2130 return NULL;
2131}
2132
Chris Caputo0be8dfb2009-06-02 18:40:07 +01002133static struct ospf_neighbor *
paul718e3742002-12-13 20:15:29 +00002134ospf_snmp_nbr_lookup_next (struct in_addr *nbr_addr, unsigned int *ifindex,
2135 int first)
2136{
2137 struct listnode *nn;
2138 struct ospf_interface *oi;
2139 struct ospf_neighbor *nbr;
2140 struct route_node *rn;
2141 struct ospf_neighbor *min = NULL;
paul020709f2003-04-04 02:44:16 +00002142 struct ospf *ospf = ospf;
paul718e3742002-12-13 20:15:29 +00002143
paul020709f2003-04-04 02:44:16 +00002144 ospf = ospf_lookup ();
paul1eb8ef22005-04-07 07:30:20 +00002145
2146 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, nn, oi))
paul718e3742002-12-13 20:15:29 +00002147 {
2148 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2149 if ((nbr = rn->info) != NULL
2150 && nbr != oi->nbr_self
2151 && nbr->state != NSM_Down
2152 && nbr->src.s_addr != 0)
2153 {
2154 if (first)
2155 {
2156 if (! min)
2157 min = nbr;
2158 else if (ntohl (nbr->src.s_addr) < ntohl (min->src.s_addr))
2159 min = nbr;
2160 }
2161 else if (ntohl (nbr->src.s_addr) > ntohl (nbr_addr->s_addr))
2162 {
2163 if (! min)
2164 min = nbr;
2165 else if (ntohl (nbr->src.s_addr) < ntohl (min->src.s_addr))
2166 min = nbr;
2167 }
2168 }
2169 }
2170 if (min)
2171 {
2172 *nbr_addr = min->src;
2173 *ifindex = 0;
2174 return min;
2175 }
2176 return NULL;
2177}
2178
Chris Caputo0be8dfb2009-06-02 18:40:07 +01002179static struct ospf_neighbor *
paul718e3742002-12-13 20:15:29 +00002180ospfNbrLookup (struct variable *v, oid *name, size_t *length,
2181 struct in_addr *nbr_addr, unsigned int *ifindex, int exact)
2182{
paul6c835672004-10-11 11:00:30 +00002183 unsigned int len;
paul718e3742002-12-13 20:15:29 +00002184 int first;
2185 struct ospf_neighbor *nbr;
paul020709f2003-04-04 02:44:16 +00002186 struct ospf *ospf;
2187
2188 ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +00002189
hasso1b639042005-03-27 13:32:25 +00002190 if (! ospf)
2191 return NULL;
2192
paul718e3742002-12-13 20:15:29 +00002193 if (exact)
2194 {
2195 if (*length != v->namelen + IN_ADDR_SIZE + 1)
2196 return NULL;
2197
2198 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, nbr_addr);
2199 *ifindex = name[v->namelen + IN_ADDR_SIZE];
2200
paul68980082003-03-25 05:07:42 +00002201 return ospf_snmp_nbr_lookup (ospf, nbr_addr, ifindex);
paul718e3742002-12-13 20:15:29 +00002202 }
2203 else
2204 {
2205 first = 0;
2206 len = *length - v->namelen;
2207
2208 if (len <= 0)
2209 first = 1;
2210
2211 if (len > IN_ADDR_SIZE)
2212 len = IN_ADDR_SIZE;
2213
2214 oid2in_addr (name + v->namelen, len, nbr_addr);
2215
2216 len = *length - v->namelen - IN_ADDR_SIZE;
2217 if (len >= 1)
2218 *ifindex = name[v->namelen + IN_ADDR_SIZE];
2219
2220 nbr = ospf_snmp_nbr_lookup_next (nbr_addr, ifindex, first);
2221
2222 if (nbr)
2223 {
2224 *length = v->namelen + IN_ADDR_SIZE + 1;
2225 oid_copy_addr (name + v->namelen, nbr_addr, IN_ADDR_SIZE);
2226 name[v->namelen + IN_ADDR_SIZE] = *ifindex;
2227 return nbr;
2228 }
2229 }
2230 return NULL;
2231}
2232
Andrew J. Schorrad81f8c2007-03-14 22:05:18 +00002233/* map internal quagga neighbor states to official MIB values:
2234
2235ospfNbrState OBJECT-TYPE
2236 SYNTAX INTEGER {
2237 down (1),
2238 attempt (2),
2239 init (3),
2240 twoWay (4),
2241 exchangeStart (5),
2242 exchange (6),
2243 loading (7),
2244 full (8)
2245 }
2246*/
2247static int32_t
2248ospf_snmp_neighbor_state(u_char nst)
2249{
2250 switch (nst)
2251 {
2252 case NSM_Attempt:
2253 return 2;
2254 case NSM_Init:
2255 return 3;
2256 case NSM_TwoWay:
2257 return 4;
2258 case NSM_ExStart:
2259 return 5;
2260 case NSM_Exchange:
2261 return 6;
2262 case NSM_Loading:
2263 return 7;
2264 case NSM_Full:
2265 return 8;
2266 default:
2267 return 1; /* down */
2268 }
2269}
2270
paul718e3742002-12-13 20:15:29 +00002271static u_char *
2272ospfNbrEntry (struct variable *v, oid *name, size_t *length, int exact,
Chris Caputo0be8dfb2009-06-02 18:40:07 +01002273 size_t *var_len, WriteMethod **write_method)
paul718e3742002-12-13 20:15:29 +00002274{
2275 struct in_addr nbr_addr;
2276 unsigned int ifindex;
2277 struct ospf_neighbor *nbr;
2278 struct ospf_interface *oi;
2279
2280 memset (&nbr_addr, 0, sizeof (struct in_addr));
2281 ifindex = 0;
2282
2283 nbr = ospfNbrLookup (v, name, length, &nbr_addr, &ifindex, exact);
2284 if (! nbr)
2285 return NULL;
2286 oi = nbr->oi;
2287 if (! oi)
2288 return NULL;
2289
2290 /* Return the current value of the variable */
2291 switch (v->magic)
2292 {
2293 case OSPFNBRIPADDR:
2294 return SNMP_IPADDRESS (nbr_addr);
2295 break;
2296 case OSPFNBRADDRESSLESSINDEX:
2297 return SNMP_INTEGER (ifindex);
2298 break;
2299 case OSPFNBRRTRID:
2300 return SNMP_IPADDRESS (nbr->router_id);
2301 break;
2302 case OSPFNBROPTIONS:
2303 return SNMP_INTEGER (oi->nbr_self->options);
2304 break;
2305 case OSPFNBRPRIORITY:
2306 return SNMP_INTEGER (nbr->priority);
2307 break;
2308 case OSPFNBRSTATE:
Andrew J. Schorrad81f8c2007-03-14 22:05:18 +00002309 return SNMP_INTEGER (ospf_snmp_neighbor_state(nbr->state));
paul718e3742002-12-13 20:15:29 +00002310 break;
2311 case OSPFNBREVENTS:
2312 return SNMP_INTEGER (nbr->state_change);
2313 break;
2314 case OSPFNBRLSRETRANSQLEN:
2315 return SNMP_INTEGER (ospf_ls_retransmit_count (nbr));
2316 break;
2317 case OSPFNBMANBRSTATUS:
2318 return SNMP_INTEGER (SNMP_VALID);
2319 break;
2320 case OSPFNBMANBRPERMANENCE:
2321 return SNMP_INTEGER (2);
2322 break;
2323 case OSPFNBRHELLOSUPPRESSED:
2324 return SNMP_INTEGER (SNMP_FALSE);
2325 break;
2326 default:
2327 return NULL;
2328 break;
2329 }
2330 return NULL;
2331}
2332
2333static u_char *
2334ospfVirtNbrEntry (struct variable *v, oid *name, size_t *length, int exact,
Chris Caputo0be8dfb2009-06-02 18:40:07 +01002335 size_t *var_len, WriteMethod **write_method)
paul718e3742002-12-13 20:15:29 +00002336{
2337 struct ospf_vl_data *vl_data;
2338 struct in_addr area_id;
2339 struct in_addr neighbor;
paul020709f2003-04-04 02:44:16 +00002340 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002341
2342 memset (&area_id, 0, sizeof (struct in_addr));
2343 memset (&neighbor, 0, sizeof (struct in_addr));
2344
2345 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00002346 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00002347 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00002348 return NULL;
2349
2350 vl_data = ospfVirtIfLookup (v, name, length, &area_id, &neighbor, exact);
2351 if (! vl_data)
2352 return NULL;
2353
2354 /* Return the current value of the variable */
2355 switch (v->magic)
2356 {
2357 case OSPFVIRTNBRAREA:
2358 return (u_char *) NULL;
2359 break;
2360 case OSPFVIRTNBRRTRID:
2361 return (u_char *) NULL;
2362 break;
2363 case OSPFVIRTNBRIPADDR:
2364 return (u_char *) NULL;
2365 break;
2366 case OSPFVIRTNBROPTIONS:
2367 return (u_char *) NULL;
2368 break;
2369 case OSPFVIRTNBRSTATE:
2370 return (u_char *) NULL;
2371 break;
2372 case OSPFVIRTNBREVENTS:
2373 return (u_char *) NULL;
2374 break;
2375 case OSPFVIRTNBRLSRETRANSQLEN:
2376 return (u_char *) NULL;
2377 break;
2378 case OSPFVIRTNBRHELLOSUPPRESSED:
2379 return (u_char *) NULL;
2380 break;
2381 default:
2382 return NULL;
2383 break;
2384 }
2385 return NULL;
2386}
2387
Chris Caputo0be8dfb2009-06-02 18:40:07 +01002388static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00002389ospfExtLsdbLookup (struct variable *v, oid *name, size_t *length, u_char *type,
2390 struct in_addr *ls_id, struct in_addr *router_id, int exact)
2391{
2392 int first;
2393 oid *offset;
2394 int offsetlen;
2395 u_char lsa_type;
paul6c835672004-10-11 11:00:30 +00002396 unsigned int len;
paul718e3742002-12-13 20:15:29 +00002397 struct ospf_lsa *lsa;
paul020709f2003-04-04 02:44:16 +00002398 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002399
paul020709f2003-04-04 02:44:16 +00002400 ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +00002401 if (exact)
2402 {
2403 if (*length != v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
2404 return NULL;
2405
2406 offset = name + v->namelen;
2407
2408 /* Make it sure given value match to type. */
2409 lsa_type = *offset;
2410 offset++;
2411
2412 if (lsa_type != *type)
2413 return NULL;
2414
2415 /* LS ID. */
2416 oid2in_addr (offset, IN_ADDR_SIZE, ls_id);
2417 offset += IN_ADDR_SIZE;
2418
2419 /* Router ID. */
2420 oid2in_addr (offset, IN_ADDR_SIZE, router_id);
2421
paul68980082003-03-25 05:07:42 +00002422 return ospf_lsdb_lookup_by_id (ospf->lsdb, *type, *ls_id, *router_id);
paul718e3742002-12-13 20:15:29 +00002423 }
2424 else
2425 {
2426 /* Get variable length. */
2427 first = 0;
2428 offset = name + v->namelen;
2429 offsetlen = *length - v->namelen;
2430
2431 /* LSA type value. */
2432 lsa_type = *offset;
2433 offset++;
2434 offsetlen--;
2435
2436 if (offsetlen <= 0 || lsa_type < OSPF_AS_EXTERNAL_LSA)
2437 first = 1;
2438
2439 /* LS ID. */
2440 len = offsetlen;
2441 if (len > IN_ADDR_SIZE)
2442 len = IN_ADDR_SIZE;
2443
2444 oid2in_addr (offset, len, ls_id);
2445
2446 offset += IN_ADDR_SIZE;
2447 offsetlen -= IN_ADDR_SIZE;
2448
2449 /* Router ID. */
2450 len = offsetlen;
2451 if (len > IN_ADDR_SIZE)
2452 len = IN_ADDR_SIZE;
2453
2454 oid2in_addr (offset, len, router_id);
2455
paul68980082003-03-25 05:07:42 +00002456 lsa = ospf_lsdb_lookup_by_id_next (ospf->lsdb, *type, *ls_id,
paul718e3742002-12-13 20:15:29 +00002457 *router_id, first);
2458
2459 if (lsa)
2460 {
2461 /* Fill in length. */
2462 *length = v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE;
2463
2464 /* Fill in value. */
2465 offset = name + v->namelen;
2466
2467 *offset = OSPF_AS_EXTERNAL_LSA;
2468 offset++;
2469 oid_copy_addr (offset, &lsa->data->id, IN_ADDR_SIZE);
2470 offset += IN_ADDR_SIZE;
2471 oid_copy_addr (offset, &lsa->data->adv_router, IN_ADDR_SIZE);
2472
2473 return lsa;
2474 }
2475 }
2476 return NULL;
2477}
2478
2479static u_char *
2480ospfExtLsdbEntry (struct variable *v, oid *name, size_t *length, int exact,
Chris Caputo0be8dfb2009-06-02 18:40:07 +01002481 size_t *var_len, WriteMethod **write_method)
paul718e3742002-12-13 20:15:29 +00002482{
2483 struct ospf_lsa *lsa;
2484 struct lsa_header *lsah;
2485 u_char type;
2486 struct in_addr ls_id;
2487 struct in_addr router_id;
paul020709f2003-04-04 02:44:16 +00002488 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002489
2490 type = OSPF_AS_EXTERNAL_LSA;
2491 memset (&ls_id, 0, sizeof (struct in_addr));
2492 memset (&router_id, 0, sizeof (struct in_addr));
2493
2494 /* Check OSPF instance. */
paul020709f2003-04-04 02:44:16 +00002495 ospf = ospf_lookup ();
paul68980082003-03-25 05:07:42 +00002496 if (ospf == NULL)
paul718e3742002-12-13 20:15:29 +00002497 return NULL;
2498
2499 lsa = ospfExtLsdbLookup (v, name, length, &type, &ls_id, &router_id, exact);
2500 if (! lsa)
2501 return NULL;
2502
2503 lsah = lsa->data;
2504
2505 /* Return the current value of the variable */
2506 switch (v->magic)
2507 {
2508 case OSPFEXTLSDBTYPE:
2509 return SNMP_INTEGER (OSPF_AS_EXTERNAL_LSA);
2510 break;
2511 case OSPFEXTLSDBLSID:
2512 return SNMP_IPADDRESS (lsah->id);
2513 break;
2514 case OSPFEXTLSDBROUTERID:
2515 return SNMP_IPADDRESS (lsah->adv_router);
2516 break;
2517 case OSPFEXTLSDBSEQUENCE:
2518 return SNMP_INTEGER (lsah->ls_seqnum);
2519 break;
2520 case OSPFEXTLSDBAGE:
2521 return SNMP_INTEGER (lsah->ls_age);
2522 break;
2523 case OSPFEXTLSDBCHECKSUM:
2524 return SNMP_INTEGER (lsah->checksum);
2525 break;
2526 case OSPFEXTLSDBADVERTISEMENT:
2527 *var_len = ntohs (lsah->length);
2528 return (u_char *) lsah;
2529 break;
2530 default:
2531 return NULL;
2532 break;
2533 }
2534 return NULL;
2535}
2536
2537static u_char *
2538ospfAreaAggregateEntry (struct variable *v, oid *name, size_t *length,
2539 int exact, size_t *var_len, WriteMethod **write_method)
2540{
2541 /* Return the current value of the variable */
2542 switch (v->magic)
2543 {
2544 case OSPFAREAAGGREGATEAREAID:
2545 return (u_char *) NULL;
2546 break;
2547 case OSPFAREAAGGREGATELSDBTYPE:
2548 return (u_char *) NULL;
2549 break;
2550 case OSPFAREAAGGREGATENET:
2551 return (u_char *) NULL;
2552 break;
2553 case OSPFAREAAGGREGATEMASK:
2554 return (u_char *) NULL;
2555 break;
2556 case OSPFAREAAGGREGATESTATUS:
2557 return (u_char *) NULL;
2558 break;
2559 case OSPFAREAAGGREGATEEFFECT:
2560 return (u_char *) NULL;
2561 break;
2562 default:
2563 return NULL;
2564 break;
2565 }
2566 return NULL;
2567}
2568
vincent5e4914c2005-09-29 16:34:30 +00002569/* OSPF Traps. */
2570#define IFSTATECHANGE 16
2571#define VIRTIFSTATECHANGE 1
2572#define NBRSTATECHANGE 2
2573#define VIRTNBRSTATECHANGE 3
2574
2575struct trap_object ospfNbrTrapList[] =
2576{
2577 {ospfGeneralGroup, -2, {1, OSPFROUTERID}},
2578 {ospfNbrEntry, 3, {10, 1, OSPFNBRIPADDR}},
2579 {ospfNbrEntry, 3, {10, 1, OSPFNBRRTRID}},
2580 {ospfNbrEntry, 3, {10, 1, OSPFNBRSTATE}}
2581};
2582
2583
2584struct trap_object ospfVirtNbrTrapList[] =
2585{
2586 {ospfGeneralGroup, -2, {1, 1}},
2587 {ospfVirtNbrEntry, 3, {11, 1, OSPFVIRTNBRAREA}},
2588 {ospfVirtNbrEntry, 3, {11, 1, OSPFVIRTNBRRTRID}},
2589 {ospfVirtNbrEntry, 3, {11, 1, OSPFVIRTNBRSTATE}}
2590};
2591
2592struct trap_object ospfIfTrapList[] =
2593{
2594 {ospfGeneralGroup, -2, {1, OSPFROUTERID}},
2595 {ospfIfEntry, 3, {7, 1, OSPFIFIPADDRESS}},
2596 {ospfIfEntry, 3, {7, 1, OSPFADDRESSLESSIF}},
2597 {ospfIfEntry, 3, {7, 1, OSPFIFSTATE}}
2598};
2599
2600struct trap_object ospfVirtIfTrapList[] =
2601{
2602 {ospfGeneralGroup, -2, {1, OSPFROUTERID}},
2603 {ospfVirtIfEntry, 3, {9, 1, OSPFVIRTIFAREAID}},
2604 {ospfVirtIfEntry, 3, {9, 1, OSPFVIRTIFNEIGHBOR}},
2605 {ospfVirtIfEntry, 3, {9, 1, OSPFVIRTIFSTATE}}
2606};
2607
2608void
2609ospfTrapNbrStateChange (struct ospf_neighbor *on)
2610{
2611 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
Andrew J. Schorr9aecfae2006-06-24 20:05:02 +00002612 char msgbuf[16];
vincent5e4914c2005-09-29 16:34:30 +00002613
Andrew J. Schorr9aecfae2006-06-24 20:05:02 +00002614 ospf_nbr_state_message(on, msgbuf, sizeof(msgbuf));
2615 zlog (NULL, LOG_INFO, "ospfTrapNbrStateChange trap sent: %s now %s",
2616 inet_ntoa(on->address.u.prefix4), msgbuf);
vincent5e4914c2005-09-29 16:34:30 +00002617
2618 oid_copy_addr (index, &(on->address.u.prefix4), IN_ADDR_SIZE);
2619 index[IN_ADDR_SIZE] = 0;
2620
2621 smux_trap (ospf_oid, sizeof ospf_oid / sizeof (oid),
2622 index, IN_ADDR_SIZE + 1,
2623 ospfNbrTrapList,
2624 sizeof ospfNbrTrapList / sizeof (struct trap_object),
2625 time (NULL), NBRSTATECHANGE);
2626}
2627
2628void
2629ospfTrapVirtNbrStateChange (struct ospf_neighbor *on)
2630{
2631 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
2632
2633 zlog (NULL, LOG_INFO, "ospfTrapVirtNbrStateChange trap sent");
2634
2635 oid_copy_addr (index, &(on->address.u.prefix4), IN_ADDR_SIZE);
2636 index[IN_ADDR_SIZE] = 0;
2637
2638 smux_trap (ospf_oid, sizeof ospf_oid / sizeof (oid),
2639 index, IN_ADDR_SIZE + 1,
2640 ospfVirtNbrTrapList,
2641 sizeof ospfVirtNbrTrapList / sizeof (struct trap_object),
2642 time (NULL), VIRTNBRSTATECHANGE);
2643}
2644
2645void
2646ospfTrapIfStateChange (struct ospf_interface *oi)
2647{
2648 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
2649
Andrew J. Schorr9aecfae2006-06-24 20:05:02 +00002650 zlog (NULL, LOG_INFO, "ospfTrapIfStateChange trap sent: %s now %s",
2651 inet_ntoa(oi->address->u.prefix4),
2652 LOOKUP(ospf_ism_state_msg, oi->state));
vincent5e4914c2005-09-29 16:34:30 +00002653
2654 oid_copy_addr (index, &(oi->address->u.prefix4), IN_ADDR_SIZE);
2655 index[IN_ADDR_SIZE] = 0;
2656
2657 smux_trap (ospf_oid, sizeof ospf_oid / sizeof (oid),
2658 index, IN_ADDR_SIZE + 1,
2659 ospfIfTrapList,
2660 sizeof ospfIfTrapList / sizeof (struct trap_object),
2661 time (NULL), IFSTATECHANGE);
2662}
2663
2664void
2665ospfTrapVirtIfStateChange (struct ospf_interface *oi)
2666{
2667 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
2668
2669 zlog (NULL, LOG_INFO, "ospfTrapVirtIfStateChange trap sent");
2670
2671 oid_copy_addr (index, &(oi->address->u.prefix4), IN_ADDR_SIZE);
2672 index[IN_ADDR_SIZE] = 0;
2673
2674 smux_trap (ospf_oid, sizeof ospf_oid / sizeof (oid),
2675 index, IN_ADDR_SIZE + 1,
2676 ospfVirtIfTrapList,
2677 sizeof ospfVirtIfTrapList / sizeof (struct trap_object),
2678 time (NULL), VIRTIFSTATECHANGE);
2679}
paul718e3742002-12-13 20:15:29 +00002680/* Register OSPF2-MIB. */
2681void
2682ospf_snmp_init ()
2683{
2684 ospf_snmp_iflist = list_new ();
2685 ospf_snmp_vl_table = route_table_init ();
hassoc75105a2004-10-13 10:33:26 +00002686 smux_init (om->master);
paul718e3742002-12-13 20:15:29 +00002687 REGISTER_MIB("mibII/ospf", ospf_variables, variable, ospf_oid);
paul718e3742002-12-13 20:15:29 +00002688}
2689#endif /* HAVE_SNMP */