blob: 4f9af315fd88fa36c35d01f3e5155ad6666c2cab [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* OSPFv2 SNMP support
2 * Copyright (C) 2000 IP Infusion Inc.
3 *
4 * Written by Kunihiro Ishiguro <kunihiro@zebra.org>
5 *
6 * This file is part of GNU Zebra.
7 *
8 * GNU Zebra is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2, or (at your option) any
11 * later version.
12 *
13 * GNU Zebra is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with GNU Zebra; see the file COPYING. If not, write to the Free
20 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21 * 02111-1307, USA.
22 */
23
24#include <zebra.h>
25
26#ifdef HAVE_SNMP
paul07661cb2003-03-18 00:03:05 +000027#ifdef HAVE_NETSNMP
28#include <net-snmp/net-snmp-config.h>
29#endif
paul718e3742002-12-13 20:15:29 +000030#include <asn1.h>
31#include <snmp.h>
32#include <snmp_impl.h>
33
34#include "if.h"
35#include "log.h"
36#include "prefix.h"
37#include "table.h"
38#include "command.h"
39#include "memory.h"
40#include "smux.h"
41
42#include "ospfd/ospfd.h"
43#include "ospfd/ospf_interface.h"
44#include "ospfd/ospf_asbr.h"
45#include "ospfd/ospf_lsa.h"
46#include "ospfd/ospf_lsdb.h"
47#include "ospfd/ospf_abr.h"
48#include "ospfd/ospf_neighbor.h"
49#include "ospfd/ospf_nsm.h"
50#include "ospfd/ospf_flood.h"
51
52/* OSPF2-MIB. */
53#define OSPF2MIB 1,3,6,1,2,1,14
54
55/* Zebra enterprise OSPF MIB. This variable is used for register
56 OSPF MIB to SNMP agent under SMUX protocol. */
57#define OSPFDOID 1,3,6,1,4,1,3317,1,2,5
58
59/* OSPF MIB General Group values. */
60#define OSPFROUTERID 1
61#define OSPFADMINSTAT 2
62#define OSPFVERSIONNUMBER 3
63#define OSPFAREABDRRTRSTATUS 4
64#define OSPFASBDRRTRSTATUS 5
65#define OSPFEXTERNLSACOUNT 6
66#define OSPFEXTERNLSACKSUMSUM 7
67#define OSPFTOSSUPPORT 8
68#define OSPFORIGINATENEWLSAS 9
69#define OSPFRXNEWLSAS 10
70#define OSPFEXTLSDBLIMIT 11
71#define OSPFMULTICASTEXTENSIONS 12
72#define OSPFEXITOVERFLOWINTERVAL 13
73#define OSPFDEMANDEXTENSIONS 14
74
75/* OSPF MIB ospfAreaTable. */
76#define OSPFAREAID 1
77#define OSPFAUTHTYPE 2
78#define OSPFIMPORTASEXTERN 3
79#define OSPFSPFRUNS 4
80#define OSPFAREABDRRTRCOUNT 5
81#define OSPFASBDRRTRCOUNT 6
82#define OSPFAREALSACOUNT 7
83#define OSPFAREALSACKSUMSUM 8
84#define OSPFAREASUMMARY 9
85#define OSPFAREASTATUS 10
86
87/* OSPF MIB ospfStubAreaTable. */
88#define OSPFSTUBAREAID 1
89#define OSPFSTUBTOS 2
90#define OSPFSTUBMETRIC 3
91#define OSPFSTUBSTATUS 4
92#define OSPFSTUBMETRICTYPE 5
93
94/* OSPF MIB ospfLsdbTable. */
95#define OSPFLSDBAREAID 1
96#define OSPFLSDBTYPE 2
97#define OSPFLSDBLSID 3
98#define OSPFLSDBROUTERID 4
99#define OSPFLSDBSEQUENCE 5
100#define OSPFLSDBAGE 6
101#define OSPFLSDBCHECKSUM 7
102#define OSPFLSDBADVERTISEMENT 8
103
104/* OSPF MIB ospfAreaRangeTable. */
105#define OSPFAREARANGEAREAID 1
106#define OSPFAREARANGENET 2
107#define OSPFAREARANGEMASK 3
108#define OSPFAREARANGESTATUS 4
109#define OSPFAREARANGEEFFECT 5
110
111/* OSPF MIB ospfHostTable. */
112#define OSPFHOSTIPADDRESS 1
113#define OSPFHOSTTOS 2
114#define OSPFHOSTMETRIC 3
115#define OSPFHOSTSTATUS 4
116#define OSPFHOSTAREAID 5
117
118/* OSPF MIB ospfIfTable. */
119#define OSPFIFIPADDRESS 1
120#define OSPFADDRESSLESSIF 2
121#define OSPFIFAREAID 3
122#define OSPFIFTYPE 4
123#define OSPFIFADMINSTAT 5
124#define OSPFIFRTRPRIORITY 6
125#define OSPFIFTRANSITDELAY 7
126#define OSPFIFRETRANSINTERVAL 8
127#define OSPFIFHELLOINTERVAL 9
128#define OSPFIFRTRDEADINTERVAL 10
129#define OSPFIFPOLLINTERVAL 11
130#define OSPFIFSTATE 12
131#define OSPFIFDESIGNATEDROUTER 13
132#define OSPFIFBACKUPDESIGNATEDROUTER 14
133#define OSPFIFEVENTS 15
134#define OSPFIFAUTHKEY 16
135#define OSPFIFSTATUS 17
136#define OSPFIFMULTICASTFORWARDING 18
137#define OSPFIFDEMAND 19
138#define OSPFIFAUTHTYPE 20
139
140/* OSPF MIB ospfIfMetricTable. */
141#define OSPFIFMETRICIPADDRESS 1
142#define OSPFIFMETRICADDRESSLESSIF 2
143#define OSPFIFMETRICTOS 3
144#define OSPFIFMETRICVALUE 4
145#define OSPFIFMETRICSTATUS 5
146
147/* OSPF MIB ospfVirtIfTable. */
148#define OSPFVIRTIFAREAID 1
149#define OSPFVIRTIFNEIGHBOR 2
150#define OSPFVIRTIFTRANSITDELAY 3
151#define OSPFVIRTIFRETRANSINTERVAL 4
152#define OSPFVIRTIFHELLOINTERVAL 5
153#define OSPFVIRTIFRTRDEADINTERVAL 6
154#define OSPFVIRTIFSTATE 7
155#define OSPFVIRTIFEVENTS 8
156#define OSPFVIRTIFAUTHKEY 9
157#define OSPFVIRTIFSTATUS 10
158#define OSPFVIRTIFAUTHTYPE 11
159
160/* OSPF MIB ospfNbrTable. */
161#define OSPFNBRIPADDR 1
162#define OSPFNBRADDRESSLESSINDEX 2
163#define OSPFNBRRTRID 3
164#define OSPFNBROPTIONS 4
165#define OSPFNBRPRIORITY 5
166#define OSPFNBRSTATE 6
167#define OSPFNBREVENTS 7
168#define OSPFNBRLSRETRANSQLEN 8
169#define OSPFNBMANBRSTATUS 9
170#define OSPFNBMANBRPERMANENCE 10
171#define OSPFNBRHELLOSUPPRESSED 11
172
173/* OSPF MIB ospfVirtNbrTable. */
174#define OSPFVIRTNBRAREA 1
175#define OSPFVIRTNBRRTRID 2
176#define OSPFVIRTNBRIPADDR 3
177#define OSPFVIRTNBROPTIONS 4
178#define OSPFVIRTNBRSTATE 5
179#define OSPFVIRTNBREVENTS 6
180#define OSPFVIRTNBRLSRETRANSQLEN 7
181#define OSPFVIRTNBRHELLOSUPPRESSED 8
182
183/* OSPF MIB ospfExtLsdbTable. */
184#define OSPFEXTLSDBTYPE 1
185#define OSPFEXTLSDBLSID 2
186#define OSPFEXTLSDBROUTERID 3
187#define OSPFEXTLSDBSEQUENCE 4
188#define OSPFEXTLSDBAGE 5
189#define OSPFEXTLSDBCHECKSUM 6
190#define OSPFEXTLSDBADVERTISEMENT 7
191
192/* OSPF MIB ospfAreaAggregateTable. */
193#define OSPFAREAAGGREGATEAREAID 1
194#define OSPFAREAAGGREGATELSDBTYPE 2
195#define OSPFAREAAGGREGATENET 3
196#define OSPFAREAAGGREGATEMASK 4
197#define OSPFAREAAGGREGATESTATUS 5
198#define OSPFAREAAGGREGATEEFFECT 6
199
200/* SYNTAX Status from OSPF-MIB. */
201#define OSPF_STATUS_ENABLED 1
202#define OSPF_STATUS_DISABLED 2
203
204/* SNMP value hack. */
205#define COUNTER ASN_COUNTER
206#define INTEGER ASN_INTEGER
207#define GAUGE ASN_GAUGE
208#define TIMETICKS ASN_TIMETICKS
209#define IPADDRESS ASN_IPADDRESS
210#define STRING ASN_OCTET_STR
211
212/* Declare static local variables for convenience. */
213SNMP_LOCAL_VARIABLES
214
215/* OSPF-MIB instances. */
216oid ospf_oid [] = { OSPF2MIB };
217oid ospfd_oid [] = { OSPFDOID };
218
219/* IP address 0.0.0.0. */
220static struct in_addr ospf_empty_addr = {0};
221
222/* Hook functions. */
223static u_char *ospfGeneralGroup ();
224static u_char *ospfAreaEntry ();
225static u_char *ospfStubAreaEntry ();
226static u_char *ospfLsdbEntry ();
227static u_char *ospfAreaRangeEntry ();
228static u_char *ospfHostEntry ();
229static u_char *ospfIfEntry ();
230static u_char *ospfIfMetricEntry ();
231static u_char *ospfVirtIfEntry ();
232static u_char *ospfNbrEntry ();
233static u_char *ospfVirtNbrEntry ();
234static u_char *ospfExtLsdbEntry ();
235static u_char *ospfAreaAggregateEntry ();
236
237struct variable ospf_variables[] =
238{
239 /* OSPF general variables */
240 {OSPFROUTERID, IPADDRESS, RWRITE, ospfGeneralGroup,
241 2, {1, 1}},
242 {OSPFADMINSTAT, INTEGER, RWRITE, ospfGeneralGroup,
243 2, {1, 2}},
244 {OSPFVERSIONNUMBER, INTEGER, RONLY, ospfGeneralGroup,
245 2, {1, 3}},
246 {OSPFAREABDRRTRSTATUS, INTEGER, RONLY, ospfGeneralGroup,
247 2, {1, 4}},
248 {OSPFASBDRRTRSTATUS, INTEGER, RWRITE, ospfGeneralGroup,
249 2, {1, 5}},
250 {OSPFEXTERNLSACOUNT, GAUGE, RONLY, ospfGeneralGroup,
251 2, {1, 6}},
252 {OSPFEXTERNLSACKSUMSUM, INTEGER, RONLY, ospfGeneralGroup,
253 2, {1, 7}},
254 {OSPFTOSSUPPORT, INTEGER, RWRITE, ospfGeneralGroup,
255 2, {1, 8}},
256 {OSPFORIGINATENEWLSAS, COUNTER, RONLY, ospfGeneralGroup,
257 2, {1, 9}},
258 {OSPFRXNEWLSAS, COUNTER, RONLY, ospfGeneralGroup,
259 2, {1, 10}},
260 {OSPFEXTLSDBLIMIT, INTEGER, RWRITE, ospfGeneralGroup,
261 2, {1, 11}},
262 {OSPFMULTICASTEXTENSIONS, INTEGER, RWRITE, ospfGeneralGroup,
263 2, {1, 12}},
264 {OSPFEXITOVERFLOWINTERVAL, INTEGER, RWRITE, ospfGeneralGroup,
265 2, {1, 13}},
266 {OSPFDEMANDEXTENSIONS, INTEGER, RWRITE, ospfGeneralGroup,
267 2, {1, 14}},
268
269 /* OSPF area data structure. */
270 {OSPFAREAID, IPADDRESS, RONLY, ospfAreaEntry,
271 3, {2, 1, 1}},
272 {OSPFAUTHTYPE, INTEGER, RWRITE, ospfAreaEntry,
273 3, {2, 1, 2}},
274 {OSPFIMPORTASEXTERN, INTEGER, RWRITE, ospfAreaEntry,
275 3, {2, 1, 3}},
276 {OSPFSPFRUNS, COUNTER, RONLY, ospfAreaEntry,
277 3, {2, 1, 4}},
278 {OSPFAREABDRRTRCOUNT, GAUGE, RONLY, ospfAreaEntry,
279 3, {2, 1, 5}},
280 {OSPFASBDRRTRCOUNT, GAUGE, RONLY, ospfAreaEntry,
281 3, {2, 1, 6}},
282 {OSPFAREALSACOUNT, GAUGE, RONLY, ospfAreaEntry,
283 3, {2, 1, 7}},
284 {OSPFAREALSACKSUMSUM, INTEGER, RONLY, ospfAreaEntry,
285 3, {2, 1, 8}},
286 {OSPFAREASUMMARY, INTEGER, RWRITE, ospfAreaEntry,
287 3, {2, 1, 9}},
288 {OSPFAREASTATUS, INTEGER, RWRITE, ospfAreaEntry,
289 3, {2, 1, 10}},
290
291 /* OSPF stub area information. */
292 {OSPFSTUBAREAID, IPADDRESS, RONLY, ospfStubAreaEntry,
293 3, {3, 1, 1}},
294 {OSPFSTUBTOS, INTEGER, RONLY, ospfStubAreaEntry,
295 3, {3, 1, 2}},
296 {OSPFSTUBMETRIC, INTEGER, RWRITE, ospfStubAreaEntry,
297 3, {3, 1, 3}},
298 {OSPFSTUBSTATUS, INTEGER, RWRITE, ospfStubAreaEntry,
299 3, {3, 1, 4}},
300 {OSPFSTUBMETRICTYPE, INTEGER, RWRITE, ospfStubAreaEntry,
301 3, {3, 1, 5}},
302
303 /* OSPF link state database. */
304 {OSPFLSDBAREAID, IPADDRESS, RONLY, ospfLsdbEntry,
305 3, {4, 1, 1}},
306 {OSPFLSDBTYPE, INTEGER, RONLY, ospfLsdbEntry,
307 3, {4, 1, 2}},
308 {OSPFLSDBLSID, IPADDRESS, RONLY, ospfLsdbEntry,
309 3, {4, 1, 3}},
310 {OSPFLSDBROUTERID, IPADDRESS, RONLY, ospfLsdbEntry,
311 3, {4, 1, 4}},
312 {OSPFLSDBSEQUENCE, INTEGER, RONLY, ospfLsdbEntry,
313 3, {4, 1, 5}},
314 {OSPFLSDBAGE, INTEGER, RONLY, ospfLsdbEntry,
315 3, {4, 1, 6}},
316 {OSPFLSDBCHECKSUM, INTEGER, RONLY, ospfLsdbEntry,
317 3, {4, 1, 7}},
318 {OSPFLSDBADVERTISEMENT, STRING, RONLY, ospfLsdbEntry,
319 3, {4, 1, 8}},
320
321 /* Area range table. */
322 {OSPFAREARANGEAREAID, IPADDRESS, RONLY, ospfAreaRangeEntry,
323 3, {5, 1, 1}},
324 {OSPFAREARANGENET, IPADDRESS, RONLY, ospfAreaRangeEntry,
325 3, {5, 1, 2}},
326 {OSPFAREARANGEMASK, IPADDRESS, RWRITE, ospfAreaRangeEntry,
327 3, {5, 1, 3}},
328 {OSPFAREARANGESTATUS, INTEGER, RWRITE, ospfAreaRangeEntry,
329 3, {5, 1, 4}},
330 {OSPFAREARANGEEFFECT, INTEGER, RWRITE, ospfAreaRangeEntry,
331 3, {5, 1, 5}},
332
333 /* OSPF host table. */
334 {OSPFHOSTIPADDRESS, IPADDRESS, RONLY, ospfHostEntry,
335 3, {6, 1, 1}},
336 {OSPFHOSTTOS, INTEGER, RONLY, ospfHostEntry,
337 3, {6, 1, 2}},
338 {OSPFHOSTMETRIC, INTEGER, RWRITE, ospfHostEntry,
339 3, {6, 1, 3}},
340 {OSPFHOSTSTATUS, INTEGER, RWRITE, ospfHostEntry,
341 3, {6, 1, 4}},
342 {OSPFHOSTAREAID, IPADDRESS, RONLY, ospfHostEntry,
343 3, {6, 1, 5}},
344
345 /* OSPF interface table. */
346 {OSPFIFIPADDRESS, IPADDRESS, RONLY, ospfIfEntry,
347 3, {7, 1, 1}},
348 {OSPFADDRESSLESSIF, INTEGER, RONLY, ospfIfEntry,
349 3, {7, 1, 2}},
350 {OSPFIFAREAID, IPADDRESS, RWRITE, ospfIfEntry,
351 3, {7, 1, 3}},
352 {OSPFIFTYPE, INTEGER, RWRITE, ospfIfEntry,
353 3, {7, 1, 4}},
354 {OSPFIFADMINSTAT, INTEGER, RWRITE, ospfIfEntry,
355 3, {7, 1, 5}},
356 {OSPFIFRTRPRIORITY, INTEGER, RWRITE, ospfIfEntry,
357 3, {7, 1, 6}},
358 {OSPFIFTRANSITDELAY, INTEGER, RWRITE, ospfIfEntry,
359 3, {7, 1, 7}},
360 {OSPFIFRETRANSINTERVAL, INTEGER, RWRITE, ospfIfEntry,
361 3, {7, 1, 8}},
362 {OSPFIFHELLOINTERVAL, INTEGER, RWRITE, ospfIfEntry,
363 3, {7, 1, 9}},
364 {OSPFIFRTRDEADINTERVAL, INTEGER, RWRITE, ospfIfEntry,
365 3, {7, 1, 10}},
366 {OSPFIFPOLLINTERVAL, INTEGER, RWRITE, ospfIfEntry,
367 3, {7, 1, 11}},
368 {OSPFIFSTATE, INTEGER, RONLY, ospfIfEntry,
369 3, {7, 1, 12}},
370 {OSPFIFDESIGNATEDROUTER, IPADDRESS, RONLY, ospfIfEntry,
371 3, {7, 1, 13}},
372 {OSPFIFBACKUPDESIGNATEDROUTER, IPADDRESS, RONLY, ospfIfEntry,
373 3, {7, 1, 14}},
374 {OSPFIFEVENTS, COUNTER, RONLY, ospfIfEntry,
375 3, {7, 1, 15}},
376 {OSPFIFAUTHKEY, STRING, RWRITE, ospfIfEntry,
377 3, {7, 1, 16}},
378 {OSPFIFSTATUS, INTEGER, RWRITE, ospfIfEntry,
379 3, {7, 1, 17}},
380 {OSPFIFMULTICASTFORWARDING, INTEGER, RWRITE, ospfIfEntry,
381 3, {7, 1, 18}},
382 {OSPFIFDEMAND, INTEGER, RWRITE, ospfIfEntry,
383 3, {7, 1, 19}},
384 {OSPFIFAUTHTYPE, INTEGER, RWRITE, ospfIfEntry,
385 3, {7, 1, 20}},
386
387 /* OSPF interface metric table. */
388 {OSPFIFMETRICIPADDRESS, IPADDRESS, RONLY, ospfIfMetricEntry,
389 3, {8, 1, 1}},
390 {OSPFIFMETRICADDRESSLESSIF, INTEGER, RONLY, ospfIfMetricEntry,
391 3, {8, 1, 2}},
392 {OSPFIFMETRICTOS, INTEGER, RONLY, ospfIfMetricEntry,
393 3, {8, 1, 3}},
394 {OSPFIFMETRICVALUE, INTEGER, RWRITE, ospfIfMetricEntry,
395 3, {8, 1, 4}},
396 {OSPFIFMETRICSTATUS, INTEGER, RWRITE, ospfIfMetricEntry,
397 3, {8, 1, 5}},
398
399 /* OSPF virtual interface table. */
400 {OSPFVIRTIFAREAID, IPADDRESS, RONLY, ospfVirtIfEntry,
401 3, {9, 1, 1}},
402 {OSPFVIRTIFNEIGHBOR, IPADDRESS, RONLY, ospfVirtIfEntry,
403 3, {9, 1, 2}},
404 {OSPFVIRTIFTRANSITDELAY, INTEGER, RWRITE, ospfVirtIfEntry,
405 3, {9, 1, 3}},
406 {OSPFVIRTIFRETRANSINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry,
407 3, {9, 1, 4}},
408 {OSPFVIRTIFHELLOINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry,
409 3, {9, 1, 5}},
410 {OSPFVIRTIFRTRDEADINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry,
411 3, {9, 1, 6}},
412 {OSPFVIRTIFSTATE, INTEGER, RONLY, ospfVirtIfEntry,
413 3, {9, 1, 7}},
414 {OSPFVIRTIFEVENTS, COUNTER, RONLY, ospfVirtIfEntry,
415 3, {9, 1, 8}},
416 {OSPFVIRTIFAUTHKEY, STRING, RWRITE, ospfVirtIfEntry,
417 3, {9, 1, 9}},
418 {OSPFVIRTIFSTATUS, INTEGER, RWRITE, ospfVirtIfEntry,
419 3, {9, 1, 10}},
420 {OSPFVIRTIFAUTHTYPE, INTEGER, RWRITE, ospfVirtIfEntry,
421 3, {9, 1, 11}},
422
423 /* OSPF neighbor table. */
424 {OSPFNBRIPADDR, IPADDRESS, RONLY, ospfNbrEntry,
425 3, {10, 1, 1}},
426 {OSPFNBRADDRESSLESSINDEX, INTEGER, RONLY, ospfNbrEntry,
427 3, {10, 1, 2}},
428 {OSPFNBRRTRID, IPADDRESS, RONLY, ospfNbrEntry,
429 3, {10, 1, 3}},
430 {OSPFNBROPTIONS, INTEGER, RONLY, ospfNbrEntry,
431 3, {10, 1, 4}},
432 {OSPFNBRPRIORITY, INTEGER, RWRITE, ospfNbrEntry,
433 3, {10, 1, 5}},
434 {OSPFNBRSTATE, INTEGER, RONLY, ospfNbrEntry,
435 3, {10, 1, 6}},
436 {OSPFNBREVENTS, COUNTER, RONLY, ospfNbrEntry,
437 3, {10, 1, 7}},
438 {OSPFNBRLSRETRANSQLEN, GAUGE, RONLY, ospfNbrEntry,
439 3, {10, 1, 8}},
440 {OSPFNBMANBRSTATUS, INTEGER, RWRITE, ospfNbrEntry,
441 3, {10, 1, 9}},
442 {OSPFNBMANBRPERMANENCE, INTEGER, RONLY, ospfNbrEntry,
443 3, {10, 1, 10}},
444 {OSPFNBRHELLOSUPPRESSED, INTEGER, RONLY, ospfNbrEntry,
445 3, {10, 1, 11}},
446
447 /* OSPF virtual neighbor table. */
448 {OSPFVIRTNBRAREA, IPADDRESS, RONLY, ospfVirtNbrEntry,
449 3, {11, 1, 1}},
450 {OSPFVIRTNBRRTRID, IPADDRESS, RONLY, ospfVirtNbrEntry,
451 3, {11, 1, 2}},
452 {OSPFVIRTNBRIPADDR, IPADDRESS, RONLY, ospfVirtNbrEntry,
453 3, {11, 1, 3}},
454 {OSPFVIRTNBROPTIONS, INTEGER, RONLY, ospfVirtNbrEntry,
455 3, {11, 1, 4}},
456 {OSPFVIRTNBRSTATE, INTEGER, RONLY, ospfVirtNbrEntry,
457 3, {11, 1, 5}},
458 {OSPFVIRTNBREVENTS, COUNTER, RONLY, ospfVirtNbrEntry,
459 3, {11, 1, 6}},
460 {OSPFVIRTNBRLSRETRANSQLEN, INTEGER, RONLY, ospfVirtNbrEntry,
461 3, {11, 1, 7}},
462 {OSPFVIRTNBRHELLOSUPPRESSED, INTEGER, RONLY, ospfVirtNbrEntry,
463 3, {11, 1, 8}},
464
465 /* OSPF link state database, external. */
466 {OSPFEXTLSDBTYPE, INTEGER, RONLY, ospfExtLsdbEntry,
467 3, {12, 1, 1}},
468 {OSPFEXTLSDBLSID, IPADDRESS, RONLY, ospfExtLsdbEntry,
469 3, {12, 1, 2}},
470 {OSPFEXTLSDBROUTERID, IPADDRESS, RONLY, ospfExtLsdbEntry,
471 3, {12, 1, 3}},
472 {OSPFEXTLSDBSEQUENCE, INTEGER, RONLY, ospfExtLsdbEntry,
473 3, {12, 1, 4}},
474 {OSPFEXTLSDBAGE, INTEGER, RONLY, ospfExtLsdbEntry,
475 3, {12, 1, 5}},
476 {OSPFEXTLSDBCHECKSUM, INTEGER, RONLY, ospfExtLsdbEntry,
477 3, {12, 1, 6}},
478 {OSPFEXTLSDBADVERTISEMENT, STRING, RONLY, ospfExtLsdbEntry,
479 3, {12, 1, 7}},
480
481 /* OSPF area aggregate table. */
482 {OSPFAREAAGGREGATEAREAID, IPADDRESS, RONLY, ospfAreaAggregateEntry,
483 3, {14, 1, 1}},
484 {OSPFAREAAGGREGATELSDBTYPE, INTEGER, RONLY, ospfAreaAggregateEntry,
485 3, {14, 1, 2}},
486 {OSPFAREAAGGREGATENET, IPADDRESS, RONLY, ospfAreaAggregateEntry,
487 3, {14, 1, 3}},
488 {OSPFAREAAGGREGATEMASK, IPADDRESS, RONLY, ospfAreaAggregateEntry,
489 3, {14, 1, 4}},
490 {OSPFAREAAGGREGATESTATUS, INTEGER, RWRITE, ospfAreaAggregateEntry,
491 3, {14, 1, 5}},
492 {OSPFAREAAGGREGATEEFFECT, INTEGER, RWRITE, ospfAreaAggregateEntry,
493 3, {14, 1, 6}}
494};
495
496/* The administrative status of OSPF. When OSPF is enbled on at least
497 one interface return 1. */
498int
499ospf_admin_stat ()
500{
501 listnode node;
502 struct ospf_interface *oi;
503
504 if (! ospf_top)
505 return 0;
506
507 for (node = listhead (ospf_top->oiflist); node; nextnode (node))
508 {
509 oi = getdata (node);
510
511 if (oi && oi->address)
512 return 1;
513 }
514 return 0;
515}
516
517static u_char *
518ospfGeneralGroup (struct variable *v, oid *name, size_t *length,
519 int exact, size_t *var_len, WriteMethod **write_method)
520{
521 /* Check whether the instance identifier is valid */
522 if (smux_header_generic (v, name, length, exact, var_len, write_method)
523 == MATCH_FAILED)
524 return NULL;
525
526 /* Return the current value of the variable */
527 switch (v->magic)
528 {
529 case OSPFROUTERID: /* 1 */
530 /* Router-ID of this OSPF instance. */
531 if (ospf_top)
532 return SNMP_IPADDRESS (ospf_top->router_id);
533 else
534 return SNMP_IPADDRESS (ospf_empty_addr);
535 break;
536 case OSPFADMINSTAT: /* 2 */
537 /* The administrative status of OSPF in the router. */
538 if (ospf_admin_stat ())
539 return SNMP_INTEGER (OSPF_STATUS_ENABLED);
540 else
541 return SNMP_INTEGER (OSPF_STATUS_DISABLED);
542 break;
543 case OSPFVERSIONNUMBER: /* 3 */
544 /* OSPF version 2. */
545 return SNMP_INTEGER (OSPF_VERSION);
546 break;
547 case OSPFAREABDRRTRSTATUS: /* 4 */
548 /* Area Border router status. */
549 if (ospf_top && CHECK_FLAG (ospf_top->flags, OSPF_FLAG_ABR))
550 return SNMP_INTEGER (SNMP_TRUE);
551 else
552 return SNMP_INTEGER (SNMP_FALSE);
553 break;
554 case OSPFASBDRRTRSTATUS: /* 5 */
555 /* AS Border router status. */
556 if (ospf_top && CHECK_FLAG (ospf_top->flags, OSPF_FLAG_ASBR))
557 return SNMP_INTEGER (SNMP_TRUE);
558 else
559 return SNMP_INTEGER (SNMP_FALSE);
560 break;
561 case OSPFEXTERNLSACOUNT: /* 6 */
562 /* External LSA counts. */
563 if (ospf_top)
564 return SNMP_INTEGER (ospf_lsdb_count_all (ospf_top->lsdb));
565 else
566 return SNMP_INTEGER (0);
567 break;
568 case OSPFEXTERNLSACKSUMSUM: /* 7 */
569 /* External LSA checksum. */
570 return SNMP_INTEGER (0);
571 break;
572 case OSPFTOSSUPPORT: /* 8 */
573 /* TOS is not supported. */
574 return SNMP_INTEGER (SNMP_FALSE);
575 break;
576 case OSPFORIGINATENEWLSAS: /* 9 */
577 /* The number of new link-state advertisements. */
578 if (ospf_top)
579 return SNMP_INTEGER (ospf_top->lsa_originate_count);
580 else
581 return SNMP_INTEGER (0);
582 break;
583 case OSPFRXNEWLSAS: /* 10 */
584 /* The number of link-state advertisements received determined
585 to be new instantiations. */
586 if (ospf_top)
587 return SNMP_INTEGER (ospf_top->rx_lsa_count);
588 else
589 return SNMP_INTEGER (0);
590 break;
591 case OSPFEXTLSDBLIMIT: /* 11 */
592 /* There is no limit for the number of non-default
593 AS-external-LSAs. */
594 return SNMP_INTEGER (-1);
595 break;
596 case OSPFMULTICASTEXTENSIONS: /* 12 */
597 /* Multicast Extensions to OSPF is not supported. */
598 return SNMP_INTEGER (0);
599 break;
600 case OSPFEXITOVERFLOWINTERVAL: /* 13 */
601 /* Overflow is not supported. */
602 return SNMP_INTEGER (0);
603 break;
604 case OSPFDEMANDEXTENSIONS: /* 14 */
605 /* Demand routing is not supported. */
606 return SNMP_INTEGER (SNMP_FALSE);
607 break;
608 default:
609 return NULL;
610 }
611 return NULL;
612}
613
614struct ospf_area *
615ospf_area_lookup_next (struct in_addr *area_id, int first)
616{
617 struct ospf_area *area;
618 listnode node;
619
620 if (! ospf_top)
621 return NULL;
622
623 if (first)
624 {
625 node = listhead (ospf_top->areas);
626 if (node)
627 {
628 area = getdata (node);
629 *area_id = area->area_id;
630 return area;
631 }
632 return NULL;
633 }
634 for (node = listhead (ospf_top->areas); node; nextnode (node))
635 {
636 area = getdata (node);
637
638 if (ntohl (area->area_id.s_addr) > ntohl (area_id->s_addr))
639 {
640 *area_id = area->area_id;
641 return area;
642 }
643 }
644 return NULL;
645}
646
647struct ospf_area *
648ospfAreaLookup (struct variable *v, oid name[], size_t *length,
649 struct in_addr *addr, int exact)
650{
651 int len;
652 struct ospf_area *area;
653
654 if (! ospf_top)
655 return NULL;
656
657 if (exact)
658 {
659 /* Length is insufficient to lookup OSPF area. */
660 if (*length - v->namelen != sizeof (struct in_addr))
661 return NULL;
662
663 oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr);
664
665 area = ospf_area_lookup_by_area_id (*addr);
666
667 return area;
668 }
669 else
670 {
671 len = *length - v->namelen;
672 if (len > 4)
673 len = 4;
674
675 oid2in_addr (name + v->namelen, len, addr);
676
677 area = ospf_area_lookup_next (addr, len == 0 ? 1 : 0);
678
679 if (area == NULL)
680 return NULL;
681
682 oid_copy_addr (name + v->namelen, addr, sizeof (struct in_addr));
683 *length = sizeof (struct in_addr) + v->namelen;
684
685 return area;
686 }
687 return NULL;
688}
689
690static u_char *
691ospfAreaEntry (struct variable *v, oid *name, size_t *length, int exact,
692 size_t *var_len, WriteMethod **write_method)
693{
694 struct ospf_area *area;
695 struct in_addr addr;
696
697 memset (&addr, 0, sizeof (struct in_addr));
698
699 area = ospfAreaLookup (v, name, length, &addr, exact);
700 if (! area)
701 return NULL;
702
703 /* Return the current value of the variable */
704 switch (v->magic)
705 {
706 case OSPFAREAID: /* 1 */
707 return SNMP_IPADDRESS (area->area_id);
708 break;
709 case OSPFAUTHTYPE: /* 2 */
710 return SNMP_INTEGER (area->auth_type);
711 break;
712 case OSPFIMPORTASEXTERN: /* 3 */
713 return SNMP_INTEGER (area->external_routing + 1);
714 break;
715 case OSPFSPFRUNS: /* 4 */
716 return SNMP_INTEGER (area->spf_calculation);
717 break;
718 case OSPFAREABDRRTRCOUNT: /* 5 */
719 return SNMP_INTEGER (area->abr_count);
720 break;
721 case OSPFASBDRRTRCOUNT: /* 6 */
722 return SNMP_INTEGER (area->asbr_count);
723 break;
724 case OSPFAREALSACOUNT: /* 7 */
725 return SNMP_INTEGER (area->lsdb->total);
726 break;
727 case OSPFAREALSACKSUMSUM: /* 8 */
728 return SNMP_INTEGER (0);
729 break;
730 case OSPFAREASUMMARY: /* 9 */
731#define OSPF_noAreaSummary 1
732#define OSPF_sendAreaSummary 2
733 if (area->no_summary)
734 return SNMP_INTEGER (OSPF_noAreaSummary);
735 else
736 return SNMP_INTEGER (OSPF_sendAreaSummary);
737 break;
738 case OSPFAREASTATUS: /* 10 */
739 return SNMP_INTEGER (SNMP_VALID);
740 break;
741 default:
742 return NULL;
743 break;
744 }
745 return NULL;
746}
747
748struct ospf_area *
749ospf_stub_area_lookup_next (struct in_addr *area_id, int first)
750{
751 struct ospf_area *area;
752 listnode node;
753
754 if (! ospf_top)
755 return NULL;
756
757 for (node = listhead (ospf_top->areas); node; nextnode (node))
758 {
759 area = getdata (node);
760
761 if (area->external_routing == OSPF_AREA_STUB)
762 {
763 if (first)
764 {
765 *area_id = area->area_id;
766 return area;
767 }
768 else if (ntohl (area->area_id.s_addr) > ntohl (area_id->s_addr))
769 {
770 *area_id = area->area_id;
771 return area;
772 }
773 }
774 }
775 return NULL;
776}
777
778struct ospf_area *
779ospfStubAreaLookup (struct variable *v, oid name[], size_t *length,
780 struct in_addr *addr, int exact)
781{
782 int len;
783 struct ospf_area *area;
784
785 if (! ospf_top)
786 return NULL;
787
788 /* Exact lookup. */
789 if (exact)
790 {
791 /* ospfStubAreaID + ospfStubTOS. */
792 if (*length != v->namelen + sizeof (struct in_addr) + 1)
793 return NULL;
794
795 /* Check ospfStubTOS is zero. */
796 if (name[*length - 1] != 0)
797 return NULL;
798
799 oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr);
800
801 area = ospf_area_lookup_by_area_id (*addr);
802
803 if (area->external_routing == OSPF_AREA_STUB)
804 return area;
805 else
806 return NULL;
807 }
808 else
809 {
810 len = *length - v->namelen;
811 if (len > 4)
812 len = 4;
813
814 oid2in_addr (name + v->namelen, len, addr);
815
816 area = ospf_stub_area_lookup_next (addr, len == 0 ? 1 : 0);
817
818 if (area == NULL)
819 return NULL;
820
821 oid_copy_addr (name + v->namelen, addr, sizeof (struct in_addr));
822 /* Set TOS 0. */
823 name[v->namelen + sizeof (struct in_addr)] = 0;
824 *length = v->namelen + sizeof (struct in_addr) + 1;
825
826 return area;
827 }
828 return NULL;
829}
830
831static u_char *
832ospfStubAreaEntry (struct variable *v, oid *name, size_t *length,
833 int exact, size_t *var_len, WriteMethod **write_method)
834{
835 struct ospf_area *area;
836 struct in_addr addr;
837
838 memset (&addr, 0, sizeof (struct in_addr));
839
840 area = ospfStubAreaLookup (v, name, length, &addr, exact);
841 if (! area)
842 return NULL;
843
844 /* Return the current value of the variable */
845 switch (v->magic)
846 {
847 case OSPFSTUBAREAID: /* 1 */
848 /* OSPF stub area id. */
849 return SNMP_IPADDRESS (area->area_id);
850 break;
851 case OSPFSTUBTOS: /* 2 */
852 /* TOS value is not supported. */
853 return SNMP_INTEGER (0);
854 break;
855 case OSPFSTUBMETRIC: /* 3 */
856 /* Default cost to stub area. */
857 return SNMP_INTEGER (area->default_cost);
858 break;
859 case OSPFSTUBSTATUS: /* 4 */
860 /* Status of the stub area. */
861 return SNMP_INTEGER (SNMP_VALID);
862 break;
863 case OSPFSTUBMETRICTYPE: /* 5 */
864 /* OSPF Metric type. */
865#define OSPF_ospfMetric 1
866#define OSPF_comparableCost 2
867#define OSPF_nonComparable 3
868 return SNMP_INTEGER (OSPF_ospfMetric);
869 break;
870 default:
871 return NULL;
872 break;
873 }
874 return NULL;
875}
876
877struct ospf_lsa *
878lsdb_lookup_next (struct ospf_area *area, u_char *type, int type_next,
879 struct in_addr *ls_id, int ls_id_next,
880 struct in_addr *router_id, int router_id_next)
881{
882 struct ospf_lsa *lsa;
883 int i;
884
885 if (type_next)
886 i = OSPF_MIN_LSA;
887 else
888 i = *type;
889
890 for (; i < OSPF_MAX_LSA; i++)
891 {
892 *type = i;
893
894 lsa = ospf_lsdb_lookup_by_id_next (area->lsdb, *type, *ls_id, *router_id,
895 ls_id_next);
896 if (lsa)
897 return lsa;
898
899 ls_id_next = 1;
900 }
901 return NULL;
902}
903
904struct ospf_lsa *
905ospfLsdbLookup (struct variable *v, oid *name, size_t *length,
906 struct in_addr *area_id, u_char *type,
907 struct in_addr *ls_id, struct in_addr *router_id, int exact)
908{
909 struct ospf_area *area;
910 struct ospf_lsa *lsa;
911 int len;
912 int type_next;
913 int ls_id_next;
914 int router_id_next;
915 oid *offset;
916 int offsetlen;
917
918#define OSPF_LSDB_ENTRY_OFFSET \
919 (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
920
921 if (exact)
922 {
923 /* Area ID + Type + LS ID + Router ID. */
924 if (*length - v->namelen != OSPF_LSDB_ENTRY_OFFSET)
925 return NULL;
926
927 /* Set OID offset for Area ID. */
928 offset = name + v->namelen;
929
930 /* Lookup area first. */
931 oid2in_addr (offset, IN_ADDR_SIZE, area_id);
932 area = ospf_area_lookup_by_area_id (*area_id);
933 if (! area)
934 return NULL;
935 offset += IN_ADDR_SIZE;
936
937 /* Type. */
938 *type = *offset;
939 offset++;
940
941 /* LS ID. */
942 oid2in_addr (offset, IN_ADDR_SIZE, ls_id);
943 offset += IN_ADDR_SIZE;
944
945 /* Router ID. */
946 oid2in_addr (offset, IN_ADDR_SIZE, router_id);
947
948 /* Lookup LSDB. */
949 return ospf_lsdb_lookup_by_id (area->lsdb, *type, *ls_id, *router_id);
950 }
951 else
952 {
953 /* Get variable length. */
954 offset = name + v->namelen;
955 offsetlen = *length - v->namelen;
956 len = offsetlen;
957
958 if (len > IN_ADDR_SIZE)
959 len = IN_ADDR_SIZE;
960
961 oid2in_addr (offset, len, area_id);
962
963 /* First we search area. */
964 if (len == IN_ADDR_SIZE)
965 area = ospf_area_lookup_by_area_id (*area_id);
966 else
967 area = ospf_area_lookup_next (area_id, len == 0 ? 1 : 0);
968
969 if (area == NULL)
970 return NULL;
971
972 do
973 {
974 /* Next we lookup type. */
975 offset += IN_ADDR_SIZE;
976 offsetlen -= IN_ADDR_SIZE;
977 len = offsetlen;
978
979 if (len <= 0)
980 type_next = 1;
981 else
982 {
983 len = 1;
984 type_next = 0;
985 *type = *offset;
986 }
987
988 /* LS ID. */
989 offset++;
990 offsetlen--;
991 len = offsetlen;
992
993 if (len <= 0)
994 ls_id_next = 1;
995 else
996 {
997 ls_id_next = 0;
998 if (len > IN_ADDR_SIZE)
999 len = IN_ADDR_SIZE;
1000
1001 oid2in_addr (offset, len, ls_id);
1002 }
1003
1004 /* Router ID. */
1005 offset += IN_ADDR_SIZE;
1006 offsetlen -= IN_ADDR_SIZE;
1007 len = offsetlen;
1008
1009 if (len <= 0)
1010 router_id_next = 1;
1011 else
1012 {
1013 router_id_next = 0;
1014 if (len > IN_ADDR_SIZE)
1015 len = IN_ADDR_SIZE;
1016
1017 oid2in_addr (offset, len, router_id);
1018 }
1019
1020 lsa = lsdb_lookup_next (area, type, type_next, ls_id, ls_id_next,
1021 router_id, router_id_next);
1022
1023 if (lsa)
1024 {
1025 /* Fill in length. */
1026 *length = v->namelen + OSPF_LSDB_ENTRY_OFFSET;
1027
1028 /* Fill in value. */
1029 offset = name + v->namelen;
1030 oid_copy_addr (offset, area_id, IN_ADDR_SIZE);
1031 offset += IN_ADDR_SIZE;
1032 *offset = lsa->data->type;
1033 offset++;
1034 oid_copy_addr (offset, &lsa->data->id, IN_ADDR_SIZE);
1035 offset += IN_ADDR_SIZE;
1036 oid_copy_addr (offset, &lsa->data->adv_router, IN_ADDR_SIZE);
1037
1038 return lsa;
1039 }
1040 }
1041 while ((area = ospf_area_lookup_next (area_id, 0)) != NULL);
1042 }
1043 return NULL;
1044}
1045
1046static u_char *
1047ospfLsdbEntry (struct variable *v, oid *name, size_t *length, int exact,
1048 size_t *var_len, WriteMethod **write_method)
1049{
1050 struct ospf_lsa *lsa;
1051 struct lsa_header *lsah;
1052 struct in_addr area_id;
1053 u_char type;
1054 struct in_addr ls_id;
1055 struct in_addr router_id;
1056
1057 /* INDEX { ospfLsdbAreaId, ospfLsdbType,
1058 ospfLsdbLsid, ospfLsdbRouterId } */
1059
1060 memset (&area_id, 0, sizeof (struct in_addr));
1061 type = 0;
1062 memset (&ls_id, 0, sizeof (struct in_addr));
1063 memset (&router_id, 0, sizeof (struct in_addr));
1064
1065 /* Check OSPF instance. */
1066 if (! ospf_top)
1067 return NULL;
1068
1069 lsa = ospfLsdbLookup (v, name, length, &area_id, &type, &ls_id, &router_id,
1070 exact);
1071 if (! lsa)
1072 return NULL;
1073
1074 lsah = lsa->data;
1075
1076 /* Return the current value of the variable */
1077 switch (v->magic)
1078 {
1079 case OSPFLSDBAREAID: /* 1 */
1080 return SNMP_IPADDRESS (lsa->area->area_id);
1081 break;
1082 case OSPFLSDBTYPE: /* 2 */
1083 return SNMP_INTEGER (lsah->type);
1084 break;
1085 case OSPFLSDBLSID: /* 3 */
1086 return SNMP_IPADDRESS (lsah->id);
1087 break;
1088 case OSPFLSDBROUTERID: /* 4 */
1089 return SNMP_IPADDRESS (lsah->adv_router);
1090 break;
1091 case OSPFLSDBSEQUENCE: /* 5 */
1092 return SNMP_INTEGER (lsah->ls_seqnum);
1093 break;
1094 case OSPFLSDBAGE: /* 6 */
1095 return SNMP_INTEGER (lsah->ls_age);
1096 break;
1097 case OSPFLSDBCHECKSUM: /* 7 */
1098 return SNMP_INTEGER (lsah->checksum);
1099 break;
1100 case OSPFLSDBADVERTISEMENT: /* 8 */
1101 *var_len = ntohs (lsah->length);
1102 return (u_char *) lsah;
1103 break;
1104 default:
1105 return NULL;
1106 break;
1107 }
1108 return NULL;
1109}
1110
1111struct ospf_area_range *
1112ospfAreaRangeLookup (struct variable *v, oid *name, size_t *length,
1113 struct in_addr *area_id, struct in_addr *range_net,
1114 int exact)
1115{
1116 oid *offset;
1117 int offsetlen;
1118 int len;
1119 struct ospf_area *area;
1120 struct ospf_area_range *range;
1121 struct prefix_ipv4 p;
1122 p.family = AF_INET;
1123 p.prefixlen = IPV4_MAX_BITLEN;
1124
1125 if (exact)
1126 {
1127 /* Area ID + Range Network. */
1128 if (v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE != *length)
1129 return NULL;
1130
1131 /* Set OID offset for Area ID. */
1132 offset = name + v->namelen;
1133
1134 /* Lookup area first. */
1135 oid2in_addr (offset, IN_ADDR_SIZE, area_id);
1136
1137 area = ospf_area_lookup_by_area_id (*area_id);
1138 if (! area)
1139 return NULL;
1140
1141 offset += IN_ADDR_SIZE;
1142
1143 /* Lookup area range. */
1144 oid2in_addr (offset, IN_ADDR_SIZE, range_net);
1145 p.prefix = *range_net;
1146
1147 return ospf_area_range_lookup (area, &p);
1148 }
1149 else
1150 {
1151 /* Set OID offset for Area ID. */
1152 offset = name + v->namelen;
1153 offsetlen = *length - v->namelen;
1154
1155 len = offsetlen;
1156 if (len > IN_ADDR_SIZE)
1157 len = IN_ADDR_SIZE;
1158
1159 oid2in_addr (offset, len, area_id);
1160
1161 /* First we search area. */
1162 if (len == IN_ADDR_SIZE)
1163 area = ospf_area_lookup_by_area_id (*area_id);
1164 else
1165 area = ospf_area_lookup_next (area_id, len == 0 ? 1 : 0);
1166
1167 if (area == NULL)
1168 return NULL;
1169
1170 do
1171 {
1172 offset += IN_ADDR_SIZE;
1173 offsetlen -= IN_ADDR_SIZE;
1174 len = offsetlen;
1175
1176 if (len < 0)
1177 len = 0;
1178 if (len > IN_ADDR_SIZE)
1179 len = IN_ADDR_SIZE;
1180
1181 oid2in_addr (offset, len, range_net);
1182
1183 range = ospf_area_range_lookup_next (area, range_net,
1184 len == 0 ? 1 : 0);
1185
1186 if (range)
1187 {
1188 /* Fill in length. */
1189 *length = v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE;
1190
1191 /* Fill in value. */
1192 offset = name + v->namelen;
1193 oid_copy_addr (offset, area_id, IN_ADDR_SIZE);
1194 offset += IN_ADDR_SIZE;
1195 oid_copy_addr (offset, range_net, IN_ADDR_SIZE);
1196
1197 return range;
1198 }
1199 }
1200 while ((area = ospf_area_lookup_next (area_id, 0)) != NULL);
1201 }
1202 return NULL;
1203}
1204
1205static u_char *
1206ospfAreaRangeEntry (struct variable *v, oid *name, size_t *length, int exact,
1207 size_t *var_len, WriteMethod **write_method)
1208{
1209 struct ospf_area_range *range;
1210 struct in_addr area_id;
1211 struct in_addr range_net;
1212 struct in_addr mask;
1213
1214 /* Check OSPF instance. */
1215 if (! ospf_top)
1216 return NULL;
1217
1218 memset (&area_id, 0, IN_ADDR_SIZE);
1219 memset (&range_net, 0, IN_ADDR_SIZE);
1220
1221 range = ospfAreaRangeLookup (v, name, length, &area_id, &range_net, exact);
1222 if (! range)
1223 return NULL;
1224
1225 /* Convert prefixlen to network mask format. */
1226 masklen2ip (range->subst_masklen, &mask);
1227
1228 /* Return the current value of the variable */
1229 switch (v->magic)
1230 {
1231 case OSPFAREARANGEAREAID: /* 1 */
1232 return SNMP_IPADDRESS (area_id);
1233 break;
1234 case OSPFAREARANGENET: /* 2 */
1235 return SNMP_IPADDRESS (range_net);
1236 break;
1237 case OSPFAREARANGEMASK: /* 3 */
1238 return SNMP_IPADDRESS (mask);
1239 break;
1240 case OSPFAREARANGESTATUS: /* 4 */
1241 return SNMP_INTEGER (SNMP_VALID);
1242 break;
1243 case OSPFAREARANGEEFFECT: /* 5 */
1244#define OSPF_advertiseMatching 1
1245#define OSPF_doNotAdvertiseMatching 2
1246 return SNMP_INTEGER (OSPF_advertiseMatching);
1247 break;
1248 default:
1249 return NULL;
1250 break;
1251 }
1252 return NULL;
1253}
1254
1255struct ospf_nbr_nbma *
1256ospfHostLookup (struct variable *v, oid *name, size_t *length,
1257 struct in_addr *addr, int exact)
1258{
1259 int len;
1260 struct ospf_nbr_nbma *nbr_nbma;
1261
1262 if (! ospf_top)
1263 return NULL;
1264
1265 if (exact)
1266 {
1267 /* INDEX { ospfHostIpAddress, ospfHostTOS } */
1268 if (*length != v->namelen + IN_ADDR_SIZE + 1)
1269 return NULL;
1270
1271 /* Check ospfHostTOS. */
1272 if (name[*length - 1] != 0)
1273 return NULL;
1274
1275 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, addr);
1276
1277 nbr_nbma = ospf_nbr_nbma_lookup (ospf_top, *addr);
1278
1279 return nbr_nbma;
1280 }
1281 else
1282 {
1283 len = *length - v->namelen;
1284 if (len > 4)
1285 len = 4;
1286
1287 oid2in_addr (name + v->namelen, len, addr);
1288
1289 nbr_nbma = ospf_nbr_nbma_lookup_next (addr, len == 0 ? 1 : 0);
1290
1291 if (nbr_nbma == NULL)
1292 return NULL;
1293
1294 oid_copy_addr (name + v->namelen, addr, IN_ADDR_SIZE);
1295
1296 /* Set TOS 0. */
1297 name[v->namelen + IN_ADDR_SIZE] = 0;
1298
1299 *length = v->namelen + IN_ADDR_SIZE + 1;
1300
1301 return nbr_nbma;
1302 }
1303 return NULL;
1304}
1305
1306static u_char *
1307ospfHostEntry (struct variable *v, oid *name, size_t *length, int exact,
1308 size_t *var_len, WriteMethod **write_method)
1309{
1310 struct ospf_nbr_nbma *nbr_nbma;
1311 struct ospf_interface *oi;
1312 struct in_addr addr;
1313
1314 /* Check OSPF instance. */
1315 if (! ospf_top)
1316 return NULL;
1317
1318 memset (&addr, 0, sizeof (struct in_addr));
1319
1320 nbr_nbma = ospfHostLookup (v, name, length, &addr, exact);
1321 if (nbr_nbma == NULL)
1322 return NULL;
1323
1324 oi = nbr_nbma->oi;
1325
1326 /* Return the current value of the variable */
1327 switch (v->magic)
1328 {
1329 case OSPFHOSTIPADDRESS: /* 1 */
1330 return SNMP_IPADDRESS (nbr_nbma->addr);
1331 break;
1332 case OSPFHOSTTOS: /* 2 */
1333 return SNMP_INTEGER (0);
1334 break;
1335 case OSPFHOSTMETRIC: /* 3 */
1336 if (oi)
1337 return SNMP_INTEGER (oi->output_cost);
1338 else
1339 return SNMP_INTEGER (1);
1340 break;
1341 case OSPFHOSTSTATUS: /* 4 */
1342 return SNMP_INTEGER (SNMP_VALID);
1343 break;
1344 case OSPFHOSTAREAID: /* 5 */
1345 if (oi && oi->area)
1346 return SNMP_IPADDRESS (oi->area->area_id);
1347 else
1348 return SNMP_IPADDRESS (ospf_empty_addr);
1349 break;
1350 default:
1351 return NULL;
1352 break;
1353 }
1354 return NULL;
1355}
1356
1357struct list *ospf_snmp_iflist;
1358
1359struct ospf_snmp_if
1360{
1361 struct in_addr addr;
1362 unsigned int ifindex;
1363 struct interface *ifp;
1364};
1365
1366struct ospf_snmp_if *
1367ospf_snmp_if_new ()
1368{
1369 struct ospf_snmp_if *osif;
1370
1371 osif = XMALLOC (0, sizeof (struct ospf_snmp_if));
1372 memset (osif, 0, sizeof (struct ospf_snmp_if));
1373 return osif;
1374}
1375
1376void
1377ospf_snmp_if_free (struct ospf_snmp_if *osif)
1378{
1379 XFREE (0, osif);
1380}
1381
1382void
1383ospf_snmp_if_delete (struct interface *ifp)
1384{
1385 struct listnode *nn;
1386 struct ospf_snmp_if *osif;
1387
1388 LIST_LOOP (ospf_snmp_iflist, osif, nn)
1389 {
1390 if (osif->ifp == ifp)
1391 {
1392 list_delete_node (ospf_snmp_iflist, nn);
1393 ospf_snmp_if_free (osif);
1394 return;
1395 }
1396 }
1397}
1398
1399void
1400ospf_snmp_if_update (struct interface *ifp)
1401{
1402 struct listnode *nn;
1403 struct listnode *pn;
1404 struct connected *ifc;
1405 struct prefix *p;
1406 struct ospf_snmp_if *osif;
1407 struct in_addr *addr;
1408 unsigned int ifindex;
1409
1410 ospf_snmp_if_delete (ifp);
1411
1412 p = NULL;
1413 addr = NULL;
1414 ifindex = 0;
1415
1416 /* Lookup first IPv4 address entry. */
1417 LIST_LOOP (ifp->connected, ifc, nn)
1418 {
paul00df0c12002-12-13 21:07:36 +00001419 if (ifc_pointopoint (ifc))
paul718e3742002-12-13 20:15:29 +00001420 p = ifc->destination;
1421 else
1422 p = ifc->address;
1423
1424 if (p->family == AF_INET)
1425 {
1426 addr = &p->u.prefix4;
1427 break;
1428 }
1429 }
1430 if (! addr)
1431 ifindex = ifp->ifindex;
1432
1433 /* Add interface to the list. */
1434 pn = NULL;
1435 LIST_LOOP (ospf_snmp_iflist, osif, nn)
1436 {
1437 if (addr)
1438 {
1439 if (ntohl (osif->addr.s_addr) > ntohl (addr->s_addr))
1440 break;
1441 }
1442 else
1443 {
1444 /* Unnumbered interface. */
1445 if (osif->addr.s_addr != 0 || osif->ifindex > ifindex)
1446 break;
1447 }
1448 pn = nn;
1449 }
1450
1451 osif = ospf_snmp_if_new ();
1452 if (addr)
1453 osif->addr = *addr;
1454 else
1455 osif->ifindex = ifindex;
1456 osif->ifp = ifp;
1457
1458 listnode_add_after (ospf_snmp_iflist, pn, osif);
1459}
1460
1461struct interface *
1462ospf_snmp_if_lookup (struct in_addr *ifaddr, unsigned int *ifindex)
1463{
1464 struct listnode *nn;
1465 struct ospf_snmp_if *osif;
1466
1467 LIST_LOOP (ospf_snmp_iflist, osif, nn)
1468 {
1469 if (ifaddr->s_addr)
1470 {
1471 if (IPV4_ADDR_SAME (&osif->addr, ifaddr))
1472 return osif->ifp;
1473 }
1474 else
1475 {
1476 if (osif->ifindex == *ifindex)
1477 return osif->ifp;
1478 }
1479 }
1480 return NULL;
1481}
1482
1483struct interface *
1484ospf_snmp_if_lookup_next (struct in_addr *ifaddr, unsigned int *ifindex,
1485 int ifaddr_next, int ifindex_next)
1486{
1487 struct ospf_snmp_if *osif;
1488 struct listnode *nn;
1489
1490 if (ifaddr_next)
1491 {
1492 nn = listhead (ospf_snmp_iflist);
1493 if (nn)
1494 {
1495 osif = getdata (nn);
1496 *ifaddr = osif->addr;
1497 *ifindex = osif->ifindex;
1498 return osif->ifp;
1499 }
1500 return NULL;
1501 }
1502
1503 LIST_LOOP (ospf_snmp_iflist, osif, nn)
1504 {
1505 if (ifaddr->s_addr)
1506 {
1507 if (ntohl (osif->addr.s_addr) > ntohl (ifaddr->s_addr))
1508 {
1509 *ifaddr = osif->addr;
1510 *ifindex = osif->ifindex;
1511 return osif->ifp;
1512 }
1513 }
1514 else
1515 {
1516 if (osif->ifindex > *ifindex || osif->addr.s_addr)
1517 {
1518 *ifaddr = osif->addr;
1519 *ifindex = osif->ifindex;
1520 return osif->ifp;
1521 }
1522 }
1523 }
1524 return NULL;
1525}
1526
1527int
1528ospf_snmp_iftype (struct interface *ifp)
1529{
1530#define ospf_snmp_iftype_broadcast 1
1531#define ospf_snmp_iftype_nbma 2
1532#define ospf_snmp_iftype_pointToPoint 3
1533#define ospf_snmp_iftype_pointToMultipoint 5
1534 if (if_is_broadcast (ifp))
1535 return ospf_snmp_iftype_broadcast;
1536 if (if_is_pointopoint (ifp))
1537 return ospf_snmp_iftype_pointToPoint;
1538 return ospf_snmp_iftype_broadcast;
1539}
1540
1541struct interface *
1542ospfIfLookup (struct variable *v, oid *name, size_t *length,
1543 struct in_addr *ifaddr, unsigned int *ifindex, int exact)
1544{
1545 int len;
1546 int ifaddr_next = 0;
1547 int ifindex_next = 0;
1548 struct interface *ifp;
1549 oid *offset;
1550
1551 if (exact)
1552 {
1553 if (*length != v->namelen + IN_ADDR_SIZE + 1)
1554 return NULL;
1555
1556 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, ifaddr);
1557 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1558
1559 return ospf_snmp_if_lookup (ifaddr, ifindex);
1560 }
1561 else
1562 {
1563 len = *length - v->namelen;
1564 if (len >= IN_ADDR_SIZE)
1565 len = IN_ADDR_SIZE;
1566 if (len <= 0)
1567 ifaddr_next = 1;
1568
1569 oid2in_addr (name + v->namelen, len, ifaddr);
1570
1571 len = *length - v->namelen - IN_ADDR_SIZE;
1572 if (len >= 1)
1573 len = 1;
1574 else
1575 ifindex_next = 1;
1576
1577 if (len == 1)
1578 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1579
1580 ifp = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next,
1581 ifindex_next);
1582 if (ifp)
1583 {
1584 *length = v->namelen + IN_ADDR_SIZE + 1;
1585 offset = name + v->namelen;
1586 oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE);
1587 offset += IN_ADDR_SIZE;
1588 *offset = *ifindex;
1589 return ifp;
1590 }
1591 }
1592 return NULL;
1593}
1594
1595static u_char *
1596ospfIfEntry (struct variable *v, oid *name, size_t *length, int exact,
1597 size_t *var_len, WriteMethod **write_method)
1598{
1599 struct interface *ifp;
1600 unsigned int ifindex;
1601 struct in_addr ifaddr;
1602 struct ospf_interface *oi;
1603
1604 ifindex = 0;
1605 memset (&ifaddr, 0, sizeof (struct in_addr));
1606
1607 /* Check OSPF instance. */
1608 if (! ospf_top)
1609 return NULL;
1610
1611 ifp = ospfIfLookup (v, name, length, &ifaddr, &ifindex, exact);
1612 if (ifp == NULL)
1613 return NULL;
1614
1615 oi = ospf_if_lookup_by_local_addr (ifp, ifaddr);
1616 if (oi == NULL)
1617 return NULL;
1618
1619 /* Return the current value of the variable */
1620 switch (v->magic)
1621 {
1622 case OSPFIFIPADDRESS: /* 1 */
1623 return SNMP_IPADDRESS (ifaddr);
1624 break;
1625 case OSPFADDRESSLESSIF: /* 2 */
1626 return SNMP_INTEGER (ifindex);
1627 break;
1628 case OSPFIFAREAID: /* 3 */
1629 if (oi->area)
1630 return SNMP_IPADDRESS (oi->area->area_id);
1631 else
1632 return SNMP_IPADDRESS (ospf_empty_addr);
1633 break;
1634 case OSPFIFTYPE: /* 4 */
1635 return SNMP_INTEGER (ospf_snmp_iftype (ifp));
1636 break;
1637 case OSPFIFADMINSTAT: /* 5 */
1638 if (oi)
1639 return SNMP_INTEGER (OSPF_STATUS_ENABLED);
1640 else
1641 return SNMP_INTEGER (OSPF_STATUS_DISABLED);
1642 break;
1643 case OSPFIFRTRPRIORITY: /* 6 */
1644 return SNMP_INTEGER (PRIORITY (oi));
1645 break;
1646 case OSPFIFTRANSITDELAY: /* 7 */
1647 return SNMP_INTEGER (OSPF_IF_PARAM (oi, transmit_delay));
1648 break;
1649 case OSPFIFRETRANSINTERVAL: /* 8 */
1650 return SNMP_INTEGER (OSPF_IF_PARAM (oi, retransmit_interval));
1651 break;
1652 case OSPFIFHELLOINTERVAL: /* 9 */
1653 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_hello));
1654 break;
1655 case OSPFIFRTRDEADINTERVAL: /* 10 */
1656 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_wait));
1657 break;
1658 case OSPFIFPOLLINTERVAL: /* 11 */
1659 return SNMP_INTEGER (OSPF_POLL_INTERVAL_DEFAULT);
1660 break;
1661 case OSPFIFSTATE: /* 12 */
1662 return SNMP_INTEGER (oi->state);
1663 break;
1664 case OSPFIFDESIGNATEDROUTER: /* 13 */
1665 return SNMP_IPADDRESS (DR (oi));
1666 break;
1667 case OSPFIFBACKUPDESIGNATEDROUTER: /* 14 */
1668 return SNMP_IPADDRESS (BDR (oi));
1669 break;
1670 case OSPFIFEVENTS: /* 15 */
1671 return SNMP_INTEGER (oi->state_change);
1672 break;
1673 case OSPFIFAUTHKEY: /* 16 */
1674 *var_len = 0;
1675 return (u_char *) OSPF_IF_PARAM (oi, auth_simple);
1676 break;
1677 case OSPFIFSTATUS: /* 17 */
1678 return SNMP_INTEGER (SNMP_VALID);
1679 break;
1680 case OSPFIFMULTICASTFORWARDING: /* 18 */
1681#define ospf_snmp_multiforward_blocked 1
1682#define ospf_snmp_multiforward_multicast 2
1683#define ospf_snmp_multiforward_unicast 3
1684 return SNMP_INTEGER (ospf_snmp_multiforward_blocked);
1685 break;
1686 case OSPFIFDEMAND: /* 19 */
1687 return SNMP_INTEGER (SNMP_FALSE);
1688 break;
1689 case OSPFIFAUTHTYPE: /* 20 */
1690 if (oi->area)
1691 return SNMP_INTEGER (oi->area->auth_type);
1692 else
1693 return SNMP_INTEGER (0);
1694 break;
1695 default:
1696 return NULL;
1697 break;
1698 }
1699 return NULL;
1700}
1701
1702#define OSPF_SNMP_METRIC_VALUE 1
1703
1704struct interface *
1705ospfIfMetricLookup (struct variable *v, oid *name, size_t *length,
1706 struct in_addr *ifaddr, unsigned int *ifindex, int exact)
1707{
1708 int len;
1709 int ifaddr_next = 0;
1710 int ifindex_next = 0;
1711 struct interface *ifp;
1712 oid *offset;
1713 int metric;
1714
1715 if (exact)
1716 {
1717 if (*length != v->namelen + IN_ADDR_SIZE + 1 + 1)
1718 return NULL;
1719
1720 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, ifaddr);
1721 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1722 metric = name[v->namelen + IN_ADDR_SIZE + 1];
1723
1724 if (metric != OSPF_SNMP_METRIC_VALUE)
1725 return NULL;
1726
1727 return ospf_snmp_if_lookup (ifaddr, ifindex);
1728 }
1729 else
1730 {
1731 len = *length - v->namelen;
1732 if (len >= IN_ADDR_SIZE)
1733 len = IN_ADDR_SIZE;
1734 else
1735 ifaddr_next = 1;
1736
1737 oid2in_addr (name + v->namelen, len, ifaddr);
1738
1739 len = *length - v->namelen - IN_ADDR_SIZE;
1740 if (len >= 1)
1741 len = 1;
1742 else
1743 ifindex_next = 1;
1744
1745 if (len == 1)
1746 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1747
1748 ifp = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next,
1749 ifindex_next);
1750 if (ifp)
1751 {
1752 *length = v->namelen + IN_ADDR_SIZE + 1 + 1;
1753 offset = name + v->namelen;
1754 oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE);
1755 offset += IN_ADDR_SIZE;
1756 *offset = *ifindex;
1757 offset++;
1758 *offset = OSPF_SNMP_METRIC_VALUE;
1759 return ifp;
1760 }
1761 }
1762 return NULL;
1763}
1764
1765static u_char *
1766ospfIfMetricEntry (struct variable *v, oid *name, size_t *length, int exact,
1767 size_t *var_len, WriteMethod **write_method)
1768{
1769 /* Currently we support metric 1 only. */
1770 struct interface *ifp;
1771 unsigned int ifindex;
1772 struct in_addr ifaddr;
1773 struct ospf_interface *oi;
1774
1775 ifindex = 0;
1776 memset (&ifaddr, 0, sizeof (struct in_addr));
1777
1778 /* Check OSPF instance. */
1779 if (! ospf_top)
1780 return NULL;
1781
1782 ifp = ospfIfMetricLookup (v, name, length, &ifaddr, &ifindex, exact);
1783 if (ifp == NULL)
1784 return NULL;
1785
1786 oi = ospf_if_lookup_by_local_addr (ifp, ifaddr);
1787 if (oi == NULL)
1788 return NULL;
1789
1790 /* Return the current value of the variable */
1791 switch (v->magic)
1792 {
1793 case OSPFIFMETRICIPADDRESS:
1794 return SNMP_IPADDRESS (ifaddr);
1795 break;
1796 case OSPFIFMETRICADDRESSLESSIF:
1797 return SNMP_INTEGER (ifindex);
1798 break;
1799 case OSPFIFMETRICTOS:
1800 return SNMP_INTEGER (0);
1801 break;
1802 case OSPFIFMETRICVALUE:
1803 return SNMP_INTEGER (OSPF_SNMP_METRIC_VALUE);
1804 break;
1805 case OSPFIFMETRICSTATUS:
1806 return SNMP_INTEGER (1);
1807 break;
1808 default:
1809 return NULL;
1810 break;
1811 }
1812 return NULL;
1813}
1814
1815struct route_table *ospf_snmp_vl_table;
1816
1817void
1818ospf_snmp_vl_add (struct ospf_vl_data *vl_data)
1819{
1820 struct prefix_ls lp;
1821 struct route_node *rn;
1822
1823 memset (&lp, 0, sizeof (struct prefix_ls));
1824 lp.family = 0;
1825 lp.prefixlen = 64;
1826 lp.id = vl_data->vl_area_id;
1827 lp.adv_router = vl_data->vl_peer;
1828
1829 rn = route_node_get (ospf_snmp_vl_table, (struct prefix *) &lp);
1830 rn->info = vl_data;
1831}
1832
1833void
1834ospf_snmp_vl_delete (struct ospf_vl_data *vl_data)
1835{
1836 struct prefix_ls lp;
1837 struct route_node *rn;
1838
1839 memset (&lp, 0, sizeof (struct prefix_ls));
1840 lp.family = 0;
1841 lp.prefixlen = 64;
1842 lp.id = vl_data->vl_area_id;
1843 lp.adv_router = vl_data->vl_peer;
1844
1845 rn = route_node_lookup (ospf_snmp_vl_table, (struct prefix *) &lp);
1846 if (! rn)
1847 return;
1848 rn->info = NULL;
1849 route_unlock_node (rn);
1850 route_unlock_node (rn);
1851}
1852
1853struct ospf_vl_data *
1854ospf_snmp_vl_lookup (struct in_addr *area_id, struct in_addr *neighbor)
1855{
1856 struct prefix_ls lp;
1857 struct route_node *rn;
1858 struct ospf_vl_data *vl_data;
1859
1860 memset (&lp, 0, sizeof (struct prefix_ls));
1861 lp.family = 0;
1862 lp.prefixlen = 64;
1863 lp.id = *area_id;
1864 lp.adv_router = *neighbor;
1865
1866 rn = route_node_lookup (ospf_snmp_vl_table, (struct prefix *) &lp);
1867 if (rn)
1868 {
1869 vl_data = rn->info;
1870 route_unlock_node (rn);
1871 return vl_data;
1872 }
1873 return NULL;
1874}
1875
1876struct ospf_vl_data *
1877ospf_snmp_vl_lookup_next (struct in_addr *area_id, struct in_addr *neighbor,
1878 int first)
1879{
1880 struct prefix_ls lp;
1881 struct route_node *rn;
1882 struct ospf_vl_data *vl_data;
1883
1884 memset (&lp, 0, sizeof (struct prefix_ls));
1885 lp.family = 0;
1886 lp.prefixlen = 64;
1887 lp.id = *area_id;
1888 lp.adv_router = *neighbor;
1889
1890 if (first)
1891 rn = route_top (ospf_snmp_vl_table);
1892 else
1893 {
1894 rn = route_node_get (ospf_snmp_vl_table, (struct prefix *) &lp);
1895 rn = route_next (rn);
1896 }
1897
1898 for (; rn; rn = route_next (rn))
1899 if (rn->info)
1900 break;
1901
1902 if (rn && rn->info)
1903 {
1904 vl_data = rn->info;
1905 *area_id = vl_data->vl_area_id;
1906 *neighbor = vl_data->vl_peer;
1907 route_unlock_node (rn);
1908 return vl_data;
1909 }
1910 return NULL;
1911}
1912
1913struct ospf_vl_data *
1914ospfVirtIfLookup (struct variable *v, oid *name, size_t *length,
1915 struct in_addr *area_id, struct in_addr *neighbor, int exact)
1916{
1917 int first;
1918 int len;
1919 struct ospf_vl_data *vl_data;
1920
1921 if (exact)
1922 {
1923 if (*length != v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE)
1924 return NULL;
1925
1926 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, area_id);
1927 oid2in_addr (name + v->namelen + IN_ADDR_SIZE, IN_ADDR_SIZE, neighbor);
1928
1929 return ospf_snmp_vl_lookup (area_id, neighbor);
1930 }
1931 else
1932 {
1933 first = 0;
1934
1935 len = *length - v->namelen;
1936 if (len <= 0)
1937 first = 1;
1938 if (len > IN_ADDR_SIZE)
1939 len = IN_ADDR_SIZE;
1940 oid2in_addr (name + v->namelen, len, area_id);
1941
1942 len = *length - v->namelen - IN_ADDR_SIZE;
1943 if (len > IN_ADDR_SIZE)
1944 len = IN_ADDR_SIZE;
1945 oid2in_addr (name + v->namelen + IN_ADDR_SIZE, len, neighbor);
1946
1947 vl_data = ospf_snmp_vl_lookup_next (area_id, neighbor, first);
1948
1949 if (vl_data)
1950 {
1951 *length = v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE;
1952 oid_copy_addr (name + v->namelen, area_id, IN_ADDR_SIZE);
1953 oid_copy_addr (name + v->namelen + IN_ADDR_SIZE, neighbor,
1954 IN_ADDR_SIZE);
1955 return vl_data;
1956 }
1957 }
1958 return NULL;
1959}
1960
1961static u_char *
1962ospfVirtIfEntry (struct variable *v, oid *name, size_t *length, int exact,
1963 size_t *var_len, WriteMethod **write_method)
1964{
1965 struct ospf_vl_data *vl_data;
1966 struct ospf_interface *oi;
1967 struct in_addr area_id;
1968 struct in_addr neighbor;
1969
1970 memset (&area_id, 0, sizeof (struct in_addr));
1971 memset (&neighbor, 0, sizeof (struct in_addr));
1972
1973 vl_data = ospfVirtIfLookup (v, name, length, &area_id, &neighbor, exact);
1974 if (! vl_data)
1975 return NULL;
1976 oi = vl_data->vl_oi;
1977 if (! oi)
1978 return NULL;
1979
1980 /* Return the current value of the variable */
1981 switch (v->magic)
1982 {
1983 case OSPFVIRTIFAREAID:
1984 return SNMP_IPADDRESS (area_id);
1985 break;
1986 case OSPFVIRTIFNEIGHBOR:
1987 return SNMP_IPADDRESS (neighbor);
1988 break;
1989 case OSPFVIRTIFTRANSITDELAY:
1990 return SNMP_INTEGER (OSPF_IF_PARAM (oi, transmit_delay));
1991 break;
1992 case OSPFVIRTIFRETRANSINTERVAL:
1993 return SNMP_INTEGER (OSPF_IF_PARAM (oi, retransmit_interval));
1994 break;
1995 case OSPFVIRTIFHELLOINTERVAL:
1996 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_hello));
1997 break;
1998 case OSPFVIRTIFRTRDEADINTERVAL:
1999 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_wait));
2000 break;
2001 case OSPFVIRTIFSTATE:
2002 return SNMP_INTEGER (oi->state);
2003 break;
2004 case OSPFVIRTIFEVENTS:
2005 return SNMP_INTEGER (oi->state_change);
2006 break;
2007 case OSPFVIRTIFAUTHKEY:
2008 *var_len = 0;
2009 return (u_char *) OSPF_IF_PARAM (oi, auth_simple);
2010 break;
2011 case OSPFVIRTIFSTATUS:
2012 return SNMP_INTEGER (SNMP_VALID);
2013 break;
2014 case OSPFVIRTIFAUTHTYPE:
2015 if (oi->area)
2016 return SNMP_INTEGER (oi->area->auth_type);
2017 else
2018 return SNMP_INTEGER (0);
2019 break;
2020 default:
2021 return NULL;
2022 break;
2023 }
2024 return NULL;
2025}
2026
2027struct ospf_neighbor *
2028ospf_snmp_nbr_lookup (struct in_addr *nbr_addr, unsigned int *ifindex)
2029{
2030 struct listnode *nn;
2031 struct ospf_interface *oi;
2032 struct ospf_neighbor *nbr;
2033 struct route_node *rn;
2034
2035 LIST_LOOP (ospf_top->oiflist, oi, nn)
2036 {
2037 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2038 if ((nbr = rn->info) != NULL
2039 && nbr != oi->nbr_self
2040 && nbr->state != NSM_Down
2041 && nbr->src.s_addr != 0)
2042 {
2043 if (IPV4_ADDR_SAME (&nbr->src, nbr_addr))
2044 {
2045 route_unlock_node (rn);
2046 return nbr;
2047 }
2048 }
2049 }
2050 return NULL;
2051}
2052
2053struct ospf_neighbor *
2054ospf_snmp_nbr_lookup_next (struct in_addr *nbr_addr, unsigned int *ifindex,
2055 int first)
2056{
2057 struct listnode *nn;
2058 struct ospf_interface *oi;
2059 struct ospf_neighbor *nbr;
2060 struct route_node *rn;
2061 struct ospf_neighbor *min = NULL;
2062
2063 LIST_LOOP (ospf_top->oiflist, oi, nn)
2064 {
2065 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2066 if ((nbr = rn->info) != NULL
2067 && nbr != oi->nbr_self
2068 && nbr->state != NSM_Down
2069 && nbr->src.s_addr != 0)
2070 {
2071 if (first)
2072 {
2073 if (! min)
2074 min = nbr;
2075 else if (ntohl (nbr->src.s_addr) < ntohl (min->src.s_addr))
2076 min = nbr;
2077 }
2078 else if (ntohl (nbr->src.s_addr) > ntohl (nbr_addr->s_addr))
2079 {
2080 if (! min)
2081 min = nbr;
2082 else if (ntohl (nbr->src.s_addr) < ntohl (min->src.s_addr))
2083 min = nbr;
2084 }
2085 }
2086 }
2087 if (min)
2088 {
2089 *nbr_addr = min->src;
2090 *ifindex = 0;
2091 return min;
2092 }
2093 return NULL;
2094}
2095
2096struct ospf_neighbor *
2097ospfNbrLookup (struct variable *v, oid *name, size_t *length,
2098 struct in_addr *nbr_addr, unsigned int *ifindex, int exact)
2099{
2100 int len;
2101 int first;
2102 struct ospf_neighbor *nbr;
2103
2104 if (exact)
2105 {
2106 if (*length != v->namelen + IN_ADDR_SIZE + 1)
2107 return NULL;
2108
2109 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, nbr_addr);
2110 *ifindex = name[v->namelen + IN_ADDR_SIZE];
2111
2112 return ospf_snmp_nbr_lookup (nbr_addr, ifindex);
2113 }
2114 else
2115 {
2116 first = 0;
2117 len = *length - v->namelen;
2118
2119 if (len <= 0)
2120 first = 1;
2121
2122 if (len > IN_ADDR_SIZE)
2123 len = IN_ADDR_SIZE;
2124
2125 oid2in_addr (name + v->namelen, len, nbr_addr);
2126
2127 len = *length - v->namelen - IN_ADDR_SIZE;
2128 if (len >= 1)
2129 *ifindex = name[v->namelen + IN_ADDR_SIZE];
2130
2131 nbr = ospf_snmp_nbr_lookup_next (nbr_addr, ifindex, first);
2132
2133 if (nbr)
2134 {
2135 *length = v->namelen + IN_ADDR_SIZE + 1;
2136 oid_copy_addr (name + v->namelen, nbr_addr, IN_ADDR_SIZE);
2137 name[v->namelen + IN_ADDR_SIZE] = *ifindex;
2138 return nbr;
2139 }
2140 }
2141 return NULL;
2142}
2143
2144static u_char *
2145ospfNbrEntry (struct variable *v, oid *name, size_t *length, int exact,
2146 size_t *var_len, WriteMethod **write_method)
2147{
2148 struct in_addr nbr_addr;
2149 unsigned int ifindex;
2150 struct ospf_neighbor *nbr;
2151 struct ospf_interface *oi;
2152
2153 memset (&nbr_addr, 0, sizeof (struct in_addr));
2154 ifindex = 0;
2155
2156 nbr = ospfNbrLookup (v, name, length, &nbr_addr, &ifindex, exact);
2157 if (! nbr)
2158 return NULL;
2159 oi = nbr->oi;
2160 if (! oi)
2161 return NULL;
2162
2163 /* Return the current value of the variable */
2164 switch (v->magic)
2165 {
2166 case OSPFNBRIPADDR:
2167 return SNMP_IPADDRESS (nbr_addr);
2168 break;
2169 case OSPFNBRADDRESSLESSINDEX:
2170 return SNMP_INTEGER (ifindex);
2171 break;
2172 case OSPFNBRRTRID:
2173 return SNMP_IPADDRESS (nbr->router_id);
2174 break;
2175 case OSPFNBROPTIONS:
2176 return SNMP_INTEGER (oi->nbr_self->options);
2177 break;
2178 case OSPFNBRPRIORITY:
2179 return SNMP_INTEGER (nbr->priority);
2180 break;
2181 case OSPFNBRSTATE:
2182 return SNMP_INTEGER (nbr->state);
2183 break;
2184 case OSPFNBREVENTS:
2185 return SNMP_INTEGER (nbr->state_change);
2186 break;
2187 case OSPFNBRLSRETRANSQLEN:
2188 return SNMP_INTEGER (ospf_ls_retransmit_count (nbr));
2189 break;
2190 case OSPFNBMANBRSTATUS:
2191 return SNMP_INTEGER (SNMP_VALID);
2192 break;
2193 case OSPFNBMANBRPERMANENCE:
2194 return SNMP_INTEGER (2);
2195 break;
2196 case OSPFNBRHELLOSUPPRESSED:
2197 return SNMP_INTEGER (SNMP_FALSE);
2198 break;
2199 default:
2200 return NULL;
2201 break;
2202 }
2203 return NULL;
2204}
2205
2206static u_char *
2207ospfVirtNbrEntry (struct variable *v, oid *name, size_t *length, int exact,
2208 size_t *var_len, WriteMethod **write_method)
2209{
2210 struct ospf_vl_data *vl_data;
2211 struct in_addr area_id;
2212 struct in_addr neighbor;
2213
2214 memset (&area_id, 0, sizeof (struct in_addr));
2215 memset (&neighbor, 0, sizeof (struct in_addr));
2216
2217 /* Check OSPF instance. */
2218 if (! ospf_top)
2219 return NULL;
2220
2221 vl_data = ospfVirtIfLookup (v, name, length, &area_id, &neighbor, exact);
2222 if (! vl_data)
2223 return NULL;
2224
2225 /* Return the current value of the variable */
2226 switch (v->magic)
2227 {
2228 case OSPFVIRTNBRAREA:
2229 return (u_char *) NULL;
2230 break;
2231 case OSPFVIRTNBRRTRID:
2232 return (u_char *) NULL;
2233 break;
2234 case OSPFVIRTNBRIPADDR:
2235 return (u_char *) NULL;
2236 break;
2237 case OSPFVIRTNBROPTIONS:
2238 return (u_char *) NULL;
2239 break;
2240 case OSPFVIRTNBRSTATE:
2241 return (u_char *) NULL;
2242 break;
2243 case OSPFVIRTNBREVENTS:
2244 return (u_char *) NULL;
2245 break;
2246 case OSPFVIRTNBRLSRETRANSQLEN:
2247 return (u_char *) NULL;
2248 break;
2249 case OSPFVIRTNBRHELLOSUPPRESSED:
2250 return (u_char *) NULL;
2251 break;
2252 default:
2253 return NULL;
2254 break;
2255 }
2256 return NULL;
2257}
2258
2259struct ospf_lsa *
2260ospfExtLsdbLookup (struct variable *v, oid *name, size_t *length, u_char *type,
2261 struct in_addr *ls_id, struct in_addr *router_id, int exact)
2262{
2263 int first;
2264 oid *offset;
2265 int offsetlen;
2266 u_char lsa_type;
2267 int len;
2268 struct ospf_lsa *lsa;
2269
2270 if (exact)
2271 {
2272 if (*length != v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
2273 return NULL;
2274
2275 offset = name + v->namelen;
2276
2277 /* Make it sure given value match to type. */
2278 lsa_type = *offset;
2279 offset++;
2280
2281 if (lsa_type != *type)
2282 return NULL;
2283
2284 /* LS ID. */
2285 oid2in_addr (offset, IN_ADDR_SIZE, ls_id);
2286 offset += IN_ADDR_SIZE;
2287
2288 /* Router ID. */
2289 oid2in_addr (offset, IN_ADDR_SIZE, router_id);
2290
2291 return ospf_lsdb_lookup_by_id (ospf_top->lsdb, *type, *ls_id, *router_id);
2292 }
2293 else
2294 {
2295 /* Get variable length. */
2296 first = 0;
2297 offset = name + v->namelen;
2298 offsetlen = *length - v->namelen;
2299
2300 /* LSA type value. */
2301 lsa_type = *offset;
2302 offset++;
2303 offsetlen--;
2304
2305 if (offsetlen <= 0 || lsa_type < OSPF_AS_EXTERNAL_LSA)
2306 first = 1;
2307
2308 /* LS ID. */
2309 len = offsetlen;
2310 if (len > IN_ADDR_SIZE)
2311 len = IN_ADDR_SIZE;
2312
2313 oid2in_addr (offset, len, ls_id);
2314
2315 offset += IN_ADDR_SIZE;
2316 offsetlen -= IN_ADDR_SIZE;
2317
2318 /* Router ID. */
2319 len = offsetlen;
2320 if (len > IN_ADDR_SIZE)
2321 len = IN_ADDR_SIZE;
2322
2323 oid2in_addr (offset, len, router_id);
2324
2325 lsa = ospf_lsdb_lookup_by_id_next (ospf_top->lsdb, *type, *ls_id,
2326 *router_id, first);
2327
2328 if (lsa)
2329 {
2330 /* Fill in length. */
2331 *length = v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE;
2332
2333 /* Fill in value. */
2334 offset = name + v->namelen;
2335
2336 *offset = OSPF_AS_EXTERNAL_LSA;
2337 offset++;
2338 oid_copy_addr (offset, &lsa->data->id, IN_ADDR_SIZE);
2339 offset += IN_ADDR_SIZE;
2340 oid_copy_addr (offset, &lsa->data->adv_router, IN_ADDR_SIZE);
2341
2342 return lsa;
2343 }
2344 }
2345 return NULL;
2346}
2347
2348static u_char *
2349ospfExtLsdbEntry (struct variable *v, oid *name, size_t *length, int exact,
2350 size_t *var_len, WriteMethod **write_method)
2351{
2352 struct ospf_lsa *lsa;
2353 struct lsa_header *lsah;
2354 u_char type;
2355 struct in_addr ls_id;
2356 struct in_addr router_id;
2357
2358 type = OSPF_AS_EXTERNAL_LSA;
2359 memset (&ls_id, 0, sizeof (struct in_addr));
2360 memset (&router_id, 0, sizeof (struct in_addr));
2361
2362 /* Check OSPF instance. */
2363 if (! ospf_top)
2364 return NULL;
2365
2366 lsa = ospfExtLsdbLookup (v, name, length, &type, &ls_id, &router_id, exact);
2367 if (! lsa)
2368 return NULL;
2369
2370 lsah = lsa->data;
2371
2372 /* Return the current value of the variable */
2373 switch (v->magic)
2374 {
2375 case OSPFEXTLSDBTYPE:
2376 return SNMP_INTEGER (OSPF_AS_EXTERNAL_LSA);
2377 break;
2378 case OSPFEXTLSDBLSID:
2379 return SNMP_IPADDRESS (lsah->id);
2380 break;
2381 case OSPFEXTLSDBROUTERID:
2382 return SNMP_IPADDRESS (lsah->adv_router);
2383 break;
2384 case OSPFEXTLSDBSEQUENCE:
2385 return SNMP_INTEGER (lsah->ls_seqnum);
2386 break;
2387 case OSPFEXTLSDBAGE:
2388 return SNMP_INTEGER (lsah->ls_age);
2389 break;
2390 case OSPFEXTLSDBCHECKSUM:
2391 return SNMP_INTEGER (lsah->checksum);
2392 break;
2393 case OSPFEXTLSDBADVERTISEMENT:
2394 *var_len = ntohs (lsah->length);
2395 return (u_char *) lsah;
2396 break;
2397 default:
2398 return NULL;
2399 break;
2400 }
2401 return NULL;
2402}
2403
2404static u_char *
2405ospfAreaAggregateEntry (struct variable *v, oid *name, size_t *length,
2406 int exact, size_t *var_len, WriteMethod **write_method)
2407{
2408 /* Return the current value of the variable */
2409 switch (v->magic)
2410 {
2411 case OSPFAREAAGGREGATEAREAID:
2412 return (u_char *) NULL;
2413 break;
2414 case OSPFAREAAGGREGATELSDBTYPE:
2415 return (u_char *) NULL;
2416 break;
2417 case OSPFAREAAGGREGATENET:
2418 return (u_char *) NULL;
2419 break;
2420 case OSPFAREAAGGREGATEMASK:
2421 return (u_char *) NULL;
2422 break;
2423 case OSPFAREAAGGREGATESTATUS:
2424 return (u_char *) NULL;
2425 break;
2426 case OSPFAREAAGGREGATEEFFECT:
2427 return (u_char *) NULL;
2428 break;
2429 default:
2430 return NULL;
2431 break;
2432 }
2433 return NULL;
2434}
2435
2436/* Register OSPF2-MIB. */
2437void
2438ospf_snmp_init ()
2439{
2440 ospf_snmp_iflist = list_new ();
2441 ospf_snmp_vl_table = route_table_init ();
2442 smux_init (ospfd_oid, sizeof (ospfd_oid) / sizeof (oid));
2443 REGISTER_MIB("mibII/ospf", ospf_variables, variable, ospf_oid);
2444 smux_start ();
2445}
2446#endif /* HAVE_SNMP */