]> git.proxmox.com Git - mirror_frr.git/blame - ospfd/ospf_snmp.c
From: David Watson <dwatson@eecs.umich.edu>
[mirror_frr.git] / ospfd / ospf_snmp.c
CommitLineData
718e3744 1/* 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
07661cb5 27#ifdef HAVE_NETSNMP
28#include <net-snmp/net-snmp-config.h>
29#endif
718e3744 30#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\f
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\f
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\f
496/* The administrative status of OSPF. When OSPF is enbled on at least
497 one interface return 1. */
498int
68980084 499ospf_admin_stat (struct ospf *ospf)
718e3744 500{
501 listnode node;
502 struct ospf_interface *oi;
503
68980084 504 if (ospf == NULL)
718e3744 505 return 0;
506
68980084 507 for (node = listhead (ospf->oiflist); node; nextnode (node))
718e3744 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{
68980084 521 struct ospf *ospf = ospf_top;
522
718e3744 523 /* Check whether the instance identifier is valid */
524 if (smux_header_generic (v, name, length, exact, var_len, write_method)
525 == MATCH_FAILED)
526 return NULL;
527
528 /* Return the current value of the variable */
529 switch (v->magic)
530 {
531 case OSPFROUTERID: /* 1 */
532 /* Router-ID of this OSPF instance. */
68980084 533 if (ospf)
534 return SNMP_IPADDRESS (ospf->router_id);
718e3744 535 else
536 return SNMP_IPADDRESS (ospf_empty_addr);
537 break;
538 case OSPFADMINSTAT: /* 2 */
539 /* The administrative status of OSPF in the router. */
68980084 540 if (ospf_admin_stat (ospf))
718e3744 541 return SNMP_INTEGER (OSPF_STATUS_ENABLED);
542 else
543 return SNMP_INTEGER (OSPF_STATUS_DISABLED);
544 break;
545 case OSPFVERSIONNUMBER: /* 3 */
546 /* OSPF version 2. */
547 return SNMP_INTEGER (OSPF_VERSION);
548 break;
549 case OSPFAREABDRRTRSTATUS: /* 4 */
550 /* Area Border router status. */
68980084 551 if (ospf && CHECK_FLAG (ospf->flags, OSPF_FLAG_ABR))
718e3744 552 return SNMP_INTEGER (SNMP_TRUE);
553 else
554 return SNMP_INTEGER (SNMP_FALSE);
555 break;
556 case OSPFASBDRRTRSTATUS: /* 5 */
557 /* AS Border router status. */
68980084 558 if (ospf && CHECK_FLAG (ospf->flags, OSPF_FLAG_ASBR))
718e3744 559 return SNMP_INTEGER (SNMP_TRUE);
560 else
561 return SNMP_INTEGER (SNMP_FALSE);
562 break;
563 case OSPFEXTERNLSACOUNT: /* 6 */
564 /* External LSA counts. */
68980084 565 if (ospf)
566 return SNMP_INTEGER (ospf_lsdb_count_all (ospf->lsdb));
718e3744 567 else
568 return SNMP_INTEGER (0);
569 break;
570 case OSPFEXTERNLSACKSUMSUM: /* 7 */
571 /* External LSA checksum. */
572 return SNMP_INTEGER (0);
573 break;
574 case OSPFTOSSUPPORT: /* 8 */
575 /* TOS is not supported. */
576 return SNMP_INTEGER (SNMP_FALSE);
577 break;
578 case OSPFORIGINATENEWLSAS: /* 9 */
579 /* The number of new link-state advertisements. */
68980084 580 if (ospf)
581 return SNMP_INTEGER (ospf->lsa_originate_count);
718e3744 582 else
583 return SNMP_INTEGER (0);
584 break;
585 case OSPFRXNEWLSAS: /* 10 */
586 /* The number of link-state advertisements received determined
587 to be new instantiations. */
68980084 588 if (ospf)
589 return SNMP_INTEGER (ospf->rx_lsa_count);
718e3744 590 else
591 return SNMP_INTEGER (0);
592 break;
593 case OSPFEXTLSDBLIMIT: /* 11 */
594 /* There is no limit for the number of non-default
595 AS-external-LSAs. */
596 return SNMP_INTEGER (-1);
597 break;
598 case OSPFMULTICASTEXTENSIONS: /* 12 */
599 /* Multicast Extensions to OSPF is not supported. */
600 return SNMP_INTEGER (0);
601 break;
602 case OSPFEXITOVERFLOWINTERVAL: /* 13 */
603 /* Overflow is not supported. */
604 return SNMP_INTEGER (0);
605 break;
606 case OSPFDEMANDEXTENSIONS: /* 14 */
607 /* Demand routing is not supported. */
608 return SNMP_INTEGER (SNMP_FALSE);
609 break;
610 default:
611 return NULL;
612 }
613 return NULL;
614}
615
616struct ospf_area *
68980084 617ospf_area_lookup_next (struct ospf *ospf, struct in_addr *area_id, int first)
718e3744 618{
619 struct ospf_area *area;
620 listnode node;
621
622 if (! ospf_top)
623 return NULL;
624
625 if (first)
626 {
68980084 627 node = listhead (ospf->areas);
718e3744 628 if (node)
629 {
630 area = getdata (node);
631 *area_id = area->area_id;
632 return area;
633 }
634 return NULL;
635 }
68980084 636 for (node = listhead (ospf->areas); node; nextnode (node))
718e3744 637 {
638 area = getdata (node);
639
640 if (ntohl (area->area_id.s_addr) > ntohl (area_id->s_addr))
641 {
642 *area_id = area->area_id;
643 return area;
644 }
645 }
646 return NULL;
647}
648
649struct ospf_area *
650ospfAreaLookup (struct variable *v, oid name[], size_t *length,
651 struct in_addr *addr, int exact)
652{
68980084 653 struct ospf *ospf = ospf_top;
718e3744 654 struct ospf_area *area;
68980084 655 int len;
718e3744 656
68980084 657 if (ospf == NULL)
718e3744 658 return NULL;
659
660 if (exact)
661 {
662 /* Length is insufficient to lookup OSPF area. */
663 if (*length - v->namelen != sizeof (struct in_addr))
664 return NULL;
665
666 oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr);
667
68980084 668 area = ospf_area_lookup_by_area_id (ospf, *addr);
718e3744 669
670 return area;
671 }
672 else
673 {
674 len = *length - v->namelen;
675 if (len > 4)
676 len = 4;
677
678 oid2in_addr (name + v->namelen, len, addr);
679
68980084 680 area = ospf_area_lookup_next (ospf, addr, len == 0 ? 1 : 0);
718e3744 681
682 if (area == NULL)
683 return NULL;
684
685 oid_copy_addr (name + v->namelen, addr, sizeof (struct in_addr));
686 *length = sizeof (struct in_addr) + v->namelen;
687
688 return area;
689 }
690 return NULL;
691}
692
693static u_char *
694ospfAreaEntry (struct variable *v, oid *name, size_t *length, int exact,
695 size_t *var_len, WriteMethod **write_method)
696{
697 struct ospf_area *area;
698 struct in_addr addr;
699
700 memset (&addr, 0, sizeof (struct in_addr));
701
702 area = ospfAreaLookup (v, name, length, &addr, exact);
703 if (! area)
704 return NULL;
705
706 /* Return the current value of the variable */
707 switch (v->magic)
708 {
709 case OSPFAREAID: /* 1 */
710 return SNMP_IPADDRESS (area->area_id);
711 break;
712 case OSPFAUTHTYPE: /* 2 */
713 return SNMP_INTEGER (area->auth_type);
714 break;
715 case OSPFIMPORTASEXTERN: /* 3 */
716 return SNMP_INTEGER (area->external_routing + 1);
717 break;
718 case OSPFSPFRUNS: /* 4 */
719 return SNMP_INTEGER (area->spf_calculation);
720 break;
721 case OSPFAREABDRRTRCOUNT: /* 5 */
722 return SNMP_INTEGER (area->abr_count);
723 break;
724 case OSPFASBDRRTRCOUNT: /* 6 */
725 return SNMP_INTEGER (area->asbr_count);
726 break;
727 case OSPFAREALSACOUNT: /* 7 */
728 return SNMP_INTEGER (area->lsdb->total);
729 break;
730 case OSPFAREALSACKSUMSUM: /* 8 */
731 return SNMP_INTEGER (0);
732 break;
733 case OSPFAREASUMMARY: /* 9 */
734#define OSPF_noAreaSummary 1
735#define OSPF_sendAreaSummary 2
736 if (area->no_summary)
737 return SNMP_INTEGER (OSPF_noAreaSummary);
738 else
739 return SNMP_INTEGER (OSPF_sendAreaSummary);
740 break;
741 case OSPFAREASTATUS: /* 10 */
742 return SNMP_INTEGER (SNMP_VALID);
743 break;
744 default:
745 return NULL;
746 break;
747 }
748 return NULL;
749}
750
751struct ospf_area *
752ospf_stub_area_lookup_next (struct in_addr *area_id, int first)
753{
754 struct ospf_area *area;
755 listnode node;
756
757 if (! ospf_top)
758 return NULL;
759
760 for (node = listhead (ospf_top->areas); node; nextnode (node))
761 {
762 area = getdata (node);
763
764 if (area->external_routing == OSPF_AREA_STUB)
765 {
766 if (first)
767 {
768 *area_id = area->area_id;
769 return area;
770 }
771 else if (ntohl (area->area_id.s_addr) > ntohl (area_id->s_addr))
772 {
773 *area_id = area->area_id;
774 return area;
775 }
776 }
777 }
778 return NULL;
779}
780
781struct ospf_area *
782ospfStubAreaLookup (struct variable *v, oid name[], size_t *length,
783 struct in_addr *addr, int exact)
784{
68980084 785 struct ospf *ospf = ospf_top;
718e3744 786 struct ospf_area *area;
68980084 787 int len;
718e3744 788
789 if (! ospf_top)
790 return NULL;
791
792 /* Exact lookup. */
793 if (exact)
794 {
795 /* ospfStubAreaID + ospfStubTOS. */
796 if (*length != v->namelen + sizeof (struct in_addr) + 1)
797 return NULL;
798
799 /* Check ospfStubTOS is zero. */
800 if (name[*length - 1] != 0)
801 return NULL;
802
803 oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr);
804
68980084 805 area = ospf_area_lookup_by_area_id (ospf, *addr);
718e3744 806
807 if (area->external_routing == OSPF_AREA_STUB)
808 return area;
809 else
810 return NULL;
811 }
812 else
813 {
814 len = *length - v->namelen;
815 if (len > 4)
816 len = 4;
817
818 oid2in_addr (name + v->namelen, len, addr);
819
820 area = ospf_stub_area_lookup_next (addr, len == 0 ? 1 : 0);
821
822 if (area == NULL)
823 return NULL;
824
825 oid_copy_addr (name + v->namelen, addr, sizeof (struct in_addr));
826 /* Set TOS 0. */
827 name[v->namelen + sizeof (struct in_addr)] = 0;
828 *length = v->namelen + sizeof (struct in_addr) + 1;
829
830 return area;
831 }
832 return NULL;
833}
834
835static u_char *
836ospfStubAreaEntry (struct variable *v, oid *name, size_t *length,
837 int exact, size_t *var_len, WriteMethod **write_method)
838{
839 struct ospf_area *area;
840 struct in_addr addr;
841
842 memset (&addr, 0, sizeof (struct in_addr));
843
844 area = ospfStubAreaLookup (v, name, length, &addr, exact);
845 if (! area)
846 return NULL;
847
848 /* Return the current value of the variable */
849 switch (v->magic)
850 {
851 case OSPFSTUBAREAID: /* 1 */
852 /* OSPF stub area id. */
853 return SNMP_IPADDRESS (area->area_id);
854 break;
855 case OSPFSTUBTOS: /* 2 */
856 /* TOS value is not supported. */
857 return SNMP_INTEGER (0);
858 break;
859 case OSPFSTUBMETRIC: /* 3 */
860 /* Default cost to stub area. */
861 return SNMP_INTEGER (area->default_cost);
862 break;
863 case OSPFSTUBSTATUS: /* 4 */
864 /* Status of the stub area. */
865 return SNMP_INTEGER (SNMP_VALID);
866 break;
867 case OSPFSTUBMETRICTYPE: /* 5 */
868 /* OSPF Metric type. */
869#define OSPF_ospfMetric 1
870#define OSPF_comparableCost 2
871#define OSPF_nonComparable 3
872 return SNMP_INTEGER (OSPF_ospfMetric);
873 break;
874 default:
875 return NULL;
876 break;
877 }
878 return NULL;
879}
880
881struct ospf_lsa *
882lsdb_lookup_next (struct ospf_area *area, u_char *type, int type_next,
883 struct in_addr *ls_id, int ls_id_next,
884 struct in_addr *router_id, int router_id_next)
885{
886 struct ospf_lsa *lsa;
887 int i;
888
889 if (type_next)
890 i = OSPF_MIN_LSA;
891 else
892 i = *type;
893
894 for (; i < OSPF_MAX_LSA; i++)
895 {
896 *type = i;
897
898 lsa = ospf_lsdb_lookup_by_id_next (area->lsdb, *type, *ls_id, *router_id,
899 ls_id_next);
900 if (lsa)
901 return lsa;
902
903 ls_id_next = 1;
904 }
905 return NULL;
906}
907
908struct ospf_lsa *
909ospfLsdbLookup (struct variable *v, oid *name, size_t *length,
910 struct in_addr *area_id, u_char *type,
911 struct in_addr *ls_id, struct in_addr *router_id, int exact)
912{
68980084 913 struct ospf *ospf = ospf_top;
718e3744 914 struct ospf_area *area;
915 struct ospf_lsa *lsa;
916 int len;
917 int type_next;
918 int ls_id_next;
919 int router_id_next;
920 oid *offset;
921 int offsetlen;
922
923#define OSPF_LSDB_ENTRY_OFFSET \
924 (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
925
926 if (exact)
927 {
928 /* Area ID + Type + LS ID + Router ID. */
929 if (*length - v->namelen != OSPF_LSDB_ENTRY_OFFSET)
930 return NULL;
931
932 /* Set OID offset for Area ID. */
933 offset = name + v->namelen;
934
935 /* Lookup area first. */
936 oid2in_addr (offset, IN_ADDR_SIZE, area_id);
68980084 937 area = ospf_area_lookup_by_area_id (ospf, *area_id);
718e3744 938 if (! area)
939 return NULL;
940 offset += IN_ADDR_SIZE;
941
942 /* Type. */
943 *type = *offset;
944 offset++;
945
946 /* LS ID. */
947 oid2in_addr (offset, IN_ADDR_SIZE, ls_id);
948 offset += IN_ADDR_SIZE;
949
950 /* Router ID. */
951 oid2in_addr (offset, IN_ADDR_SIZE, router_id);
952
953 /* Lookup LSDB. */
954 return ospf_lsdb_lookup_by_id (area->lsdb, *type, *ls_id, *router_id);
955 }
956 else
957 {
958 /* Get variable length. */
959 offset = name + v->namelen;
960 offsetlen = *length - v->namelen;
961 len = offsetlen;
962
963 if (len > IN_ADDR_SIZE)
964 len = IN_ADDR_SIZE;
965
966 oid2in_addr (offset, len, area_id);
967
968 /* First we search area. */
969 if (len == IN_ADDR_SIZE)
68980084 970 area = ospf_area_lookup_by_area_id (ospf, *area_id);
718e3744 971 else
68980084 972 area = ospf_area_lookup_next (ospf, area_id, len == 0 ? 1 : 0);
718e3744 973
974 if (area == NULL)
975 return NULL;
976
977 do
978 {
979 /* Next we lookup type. */
980 offset += IN_ADDR_SIZE;
981 offsetlen -= IN_ADDR_SIZE;
982 len = offsetlen;
983
984 if (len <= 0)
985 type_next = 1;
986 else
987 {
988 len = 1;
989 type_next = 0;
990 *type = *offset;
991 }
992
993 /* LS ID. */
994 offset++;
995 offsetlen--;
996 len = offsetlen;
997
998 if (len <= 0)
999 ls_id_next = 1;
1000 else
1001 {
1002 ls_id_next = 0;
1003 if (len > IN_ADDR_SIZE)
1004 len = IN_ADDR_SIZE;
1005
1006 oid2in_addr (offset, len, ls_id);
1007 }
1008
1009 /* Router ID. */
1010 offset += IN_ADDR_SIZE;
1011 offsetlen -= IN_ADDR_SIZE;
1012 len = offsetlen;
1013
1014 if (len <= 0)
1015 router_id_next = 1;
1016 else
1017 {
1018 router_id_next = 0;
1019 if (len > IN_ADDR_SIZE)
1020 len = IN_ADDR_SIZE;
1021
1022 oid2in_addr (offset, len, router_id);
1023 }
1024
1025 lsa = lsdb_lookup_next (area, type, type_next, ls_id, ls_id_next,
1026 router_id, router_id_next);
1027
1028 if (lsa)
1029 {
1030 /* Fill in length. */
1031 *length = v->namelen + OSPF_LSDB_ENTRY_OFFSET;
1032
1033 /* Fill in value. */
1034 offset = name + v->namelen;
1035 oid_copy_addr (offset, area_id, IN_ADDR_SIZE);
1036 offset += IN_ADDR_SIZE;
1037 *offset = lsa->data->type;
1038 offset++;
1039 oid_copy_addr (offset, &lsa->data->id, IN_ADDR_SIZE);
1040 offset += IN_ADDR_SIZE;
1041 oid_copy_addr (offset, &lsa->data->adv_router, IN_ADDR_SIZE);
1042
1043 return lsa;
1044 }
1045 }
68980084 1046 while ((area = ospf_area_lookup_next (ospf, area_id, 0)) != NULL);
718e3744 1047 }
1048 return NULL;
1049}
1050
1051static u_char *
1052ospfLsdbEntry (struct variable *v, oid *name, size_t *length, int exact,
1053 size_t *var_len, WriteMethod **write_method)
1054{
1055 struct ospf_lsa *lsa;
1056 struct lsa_header *lsah;
1057 struct in_addr area_id;
1058 u_char type;
1059 struct in_addr ls_id;
1060 struct in_addr router_id;
1061
1062 /* INDEX { ospfLsdbAreaId, ospfLsdbType,
1063 ospfLsdbLsid, ospfLsdbRouterId } */
1064
1065 memset (&area_id, 0, sizeof (struct in_addr));
1066 type = 0;
1067 memset (&ls_id, 0, sizeof (struct in_addr));
1068 memset (&router_id, 0, sizeof (struct in_addr));
1069
1070 /* Check OSPF instance. */
1071 if (! ospf_top)
1072 return NULL;
1073
1074 lsa = ospfLsdbLookup (v, name, length, &area_id, &type, &ls_id, &router_id,
1075 exact);
1076 if (! lsa)
1077 return NULL;
1078
1079 lsah = lsa->data;
1080
1081 /* Return the current value of the variable */
1082 switch (v->magic)
1083 {
1084 case OSPFLSDBAREAID: /* 1 */
1085 return SNMP_IPADDRESS (lsa->area->area_id);
1086 break;
1087 case OSPFLSDBTYPE: /* 2 */
1088 return SNMP_INTEGER (lsah->type);
1089 break;
1090 case OSPFLSDBLSID: /* 3 */
1091 return SNMP_IPADDRESS (lsah->id);
1092 break;
1093 case OSPFLSDBROUTERID: /* 4 */
1094 return SNMP_IPADDRESS (lsah->adv_router);
1095 break;
1096 case OSPFLSDBSEQUENCE: /* 5 */
1097 return SNMP_INTEGER (lsah->ls_seqnum);
1098 break;
1099 case OSPFLSDBAGE: /* 6 */
1100 return SNMP_INTEGER (lsah->ls_age);
1101 break;
1102 case OSPFLSDBCHECKSUM: /* 7 */
1103 return SNMP_INTEGER (lsah->checksum);
1104 break;
1105 case OSPFLSDBADVERTISEMENT: /* 8 */
1106 *var_len = ntohs (lsah->length);
1107 return (u_char *) lsah;
1108 break;
1109 default:
1110 return NULL;
1111 break;
1112 }
1113 return NULL;
1114}
1115
1116struct ospf_area_range *
1117ospfAreaRangeLookup (struct variable *v, oid *name, size_t *length,
1118 struct in_addr *area_id, struct in_addr *range_net,
1119 int exact)
1120{
1121 oid *offset;
1122 int offsetlen;
1123 int len;
68980084 1124 struct ospf *ospf = ospf_top;
718e3744 1125 struct ospf_area *area;
1126 struct ospf_area_range *range;
1127 struct prefix_ipv4 p;
1128 p.family = AF_INET;
1129 p.prefixlen = IPV4_MAX_BITLEN;
1130
1131 if (exact)
1132 {
1133 /* Area ID + Range Network. */
1134 if (v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE != *length)
1135 return NULL;
1136
1137 /* Set OID offset for Area ID. */
1138 offset = name + v->namelen;
1139
1140 /* Lookup area first. */
1141 oid2in_addr (offset, IN_ADDR_SIZE, area_id);
1142
68980084 1143 area = ospf_area_lookup_by_area_id (ospf, *area_id);
718e3744 1144 if (! area)
1145 return NULL;
1146
1147 offset += IN_ADDR_SIZE;
1148
1149 /* Lookup area range. */
1150 oid2in_addr (offset, IN_ADDR_SIZE, range_net);
1151 p.prefix = *range_net;
1152
1153 return ospf_area_range_lookup (area, &p);
1154 }
1155 else
1156 {
1157 /* Set OID offset for Area ID. */
1158 offset = name + v->namelen;
1159 offsetlen = *length - v->namelen;
1160
1161 len = offsetlen;
1162 if (len > IN_ADDR_SIZE)
1163 len = IN_ADDR_SIZE;
1164
1165 oid2in_addr (offset, len, area_id);
1166
1167 /* First we search area. */
1168 if (len == IN_ADDR_SIZE)
68980084 1169 area = ospf_area_lookup_by_area_id (ospf,*area_id);
718e3744 1170 else
68980084 1171 area = ospf_area_lookup_next (ospf, area_id, len == 0 ? 1 : 0);
718e3744 1172
1173 if (area == NULL)
1174 return NULL;
1175
1176 do
1177 {
1178 offset += IN_ADDR_SIZE;
1179 offsetlen -= IN_ADDR_SIZE;
1180 len = offsetlen;
1181
1182 if (len < 0)
1183 len = 0;
1184 if (len > IN_ADDR_SIZE)
1185 len = IN_ADDR_SIZE;
1186
1187 oid2in_addr (offset, len, range_net);
1188
1189 range = ospf_area_range_lookup_next (area, range_net,
1190 len == 0 ? 1 : 0);
1191
1192 if (range)
1193 {
1194 /* Fill in length. */
1195 *length = v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE;
1196
1197 /* Fill in value. */
1198 offset = name + v->namelen;
1199 oid_copy_addr (offset, area_id, IN_ADDR_SIZE);
1200 offset += IN_ADDR_SIZE;
1201 oid_copy_addr (offset, range_net, IN_ADDR_SIZE);
1202
1203 return range;
1204 }
1205 }
68980084 1206 while ((area = ospf_area_lookup_next (ospf, area_id, 0)) != NULL);
718e3744 1207 }
1208 return NULL;
1209}
1210
1211static u_char *
1212ospfAreaRangeEntry (struct variable *v, oid *name, size_t *length, int exact,
1213 size_t *var_len, WriteMethod **write_method)
1214{
1215 struct ospf_area_range *range;
1216 struct in_addr area_id;
1217 struct in_addr range_net;
1218 struct in_addr mask;
68980084 1219 struct ospf *ospf = ospf_top;
718e3744 1220
1221 /* Check OSPF instance. */
68980084 1222 if (ospf == NULL)
718e3744 1223 return NULL;
1224
1225 memset (&area_id, 0, IN_ADDR_SIZE);
1226 memset (&range_net, 0, IN_ADDR_SIZE);
1227
1228 range = ospfAreaRangeLookup (v, name, length, &area_id, &range_net, exact);
1229 if (! range)
1230 return NULL;
1231
1232 /* Convert prefixlen to network mask format. */
1233 masklen2ip (range->subst_masklen, &mask);
1234
1235 /* Return the current value of the variable */
1236 switch (v->magic)
1237 {
1238 case OSPFAREARANGEAREAID: /* 1 */
1239 return SNMP_IPADDRESS (area_id);
1240 break;
1241 case OSPFAREARANGENET: /* 2 */
1242 return SNMP_IPADDRESS (range_net);
1243 break;
1244 case OSPFAREARANGEMASK: /* 3 */
1245 return SNMP_IPADDRESS (mask);
1246 break;
1247 case OSPFAREARANGESTATUS: /* 4 */
1248 return SNMP_INTEGER (SNMP_VALID);
1249 break;
1250 case OSPFAREARANGEEFFECT: /* 5 */
1251#define OSPF_advertiseMatching 1
1252#define OSPF_doNotAdvertiseMatching 2
1253 return SNMP_INTEGER (OSPF_advertiseMatching);
1254 break;
1255 default:
1256 return NULL;
1257 break;
1258 }
1259 return NULL;
1260}
1261
1262struct ospf_nbr_nbma *
1263ospfHostLookup (struct variable *v, oid *name, size_t *length,
1264 struct in_addr *addr, int exact)
1265{
1266 int len;
1267 struct ospf_nbr_nbma *nbr_nbma;
68980084 1268 struct ospf *ospf = ospf_top;
718e3744 1269
68980084 1270 if (ospf == NULL)
718e3744 1271 return NULL;
1272
1273 if (exact)
1274 {
1275 /* INDEX { ospfHostIpAddress, ospfHostTOS } */
1276 if (*length != v->namelen + IN_ADDR_SIZE + 1)
1277 return NULL;
1278
1279 /* Check ospfHostTOS. */
1280 if (name[*length - 1] != 0)
1281 return NULL;
1282
1283 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, addr);
1284
68980084 1285 nbr_nbma = ospf_nbr_nbma_lookup (ospf, *addr);
718e3744 1286
1287 return nbr_nbma;
1288 }
1289 else
1290 {
1291 len = *length - v->namelen;
1292 if (len > 4)
1293 len = 4;
1294
1295 oid2in_addr (name + v->namelen, len, addr);
1296
68980084 1297 nbr_nbma = ospf_nbr_nbma_lookup_next (ospf, addr, len == 0 ? 1 : 0);
718e3744 1298
1299 if (nbr_nbma == NULL)
1300 return NULL;
1301
1302 oid_copy_addr (name + v->namelen, addr, IN_ADDR_SIZE);
1303
1304 /* Set TOS 0. */
1305 name[v->namelen + IN_ADDR_SIZE] = 0;
1306
1307 *length = v->namelen + IN_ADDR_SIZE + 1;
1308
1309 return nbr_nbma;
1310 }
1311 return NULL;
1312}
1313
1314static u_char *
1315ospfHostEntry (struct variable *v, oid *name, size_t *length, int exact,
1316 size_t *var_len, WriteMethod **write_method)
1317{
1318 struct ospf_nbr_nbma *nbr_nbma;
1319 struct ospf_interface *oi;
1320 struct in_addr addr;
68980084 1321 struct ospf *ospf = ospf_top;
718e3744 1322
1323 /* Check OSPF instance. */
68980084 1324 if (ospf == NULL)
718e3744 1325 return NULL;
1326
1327 memset (&addr, 0, sizeof (struct in_addr));
1328
1329 nbr_nbma = ospfHostLookup (v, name, length, &addr, exact);
1330 if (nbr_nbma == NULL)
1331 return NULL;
1332
1333 oi = nbr_nbma->oi;
1334
1335 /* Return the current value of the variable */
1336 switch (v->magic)
1337 {
1338 case OSPFHOSTIPADDRESS: /* 1 */
1339 return SNMP_IPADDRESS (nbr_nbma->addr);
1340 break;
1341 case OSPFHOSTTOS: /* 2 */
1342 return SNMP_INTEGER (0);
1343 break;
1344 case OSPFHOSTMETRIC: /* 3 */
1345 if (oi)
1346 return SNMP_INTEGER (oi->output_cost);
1347 else
1348 return SNMP_INTEGER (1);
1349 break;
1350 case OSPFHOSTSTATUS: /* 4 */
1351 return SNMP_INTEGER (SNMP_VALID);
1352 break;
1353 case OSPFHOSTAREAID: /* 5 */
1354 if (oi && oi->area)
1355 return SNMP_IPADDRESS (oi->area->area_id);
1356 else
1357 return SNMP_IPADDRESS (ospf_empty_addr);
1358 break;
1359 default:
1360 return NULL;
1361 break;
1362 }
1363 return NULL;
1364}
1365\f
1366struct list *ospf_snmp_iflist;
1367
1368struct ospf_snmp_if
1369{
1370 struct in_addr addr;
1371 unsigned int ifindex;
1372 struct interface *ifp;
1373};
1374
1375struct ospf_snmp_if *
1376ospf_snmp_if_new ()
1377{
1378 struct ospf_snmp_if *osif;
1379
1380 osif = XMALLOC (0, sizeof (struct ospf_snmp_if));
1381 memset (osif, 0, sizeof (struct ospf_snmp_if));
1382 return osif;
1383}
1384
1385void
1386ospf_snmp_if_free (struct ospf_snmp_if *osif)
1387{
1388 XFREE (0, osif);
1389}
1390
1391void
1392ospf_snmp_if_delete (struct interface *ifp)
1393{
1394 struct listnode *nn;
1395 struct ospf_snmp_if *osif;
1396
1397 LIST_LOOP (ospf_snmp_iflist, osif, nn)
1398 {
1399 if (osif->ifp == ifp)
1400 {
1401 list_delete_node (ospf_snmp_iflist, nn);
1402 ospf_snmp_if_free (osif);
1403 return;
1404 }
1405 }
1406}
1407
1408void
1409ospf_snmp_if_update (struct interface *ifp)
1410{
1411 struct listnode *nn;
1412 struct listnode *pn;
1413 struct connected *ifc;
1414 struct prefix *p;
1415 struct ospf_snmp_if *osif;
1416 struct in_addr *addr;
1417 unsigned int ifindex;
1418
1419 ospf_snmp_if_delete (ifp);
1420
1421 p = NULL;
1422 addr = NULL;
1423 ifindex = 0;
1424
1425 /* Lookup first IPv4 address entry. */
1426 LIST_LOOP (ifp->connected, ifc, nn)
1427 {
00df0c1e 1428 if (ifc_pointopoint (ifc))
718e3744 1429 p = ifc->destination;
1430 else
1431 p = ifc->address;
1432
1433 if (p->family == AF_INET)
1434 {
1435 addr = &p->u.prefix4;
1436 break;
1437 }
1438 }
1439 if (! addr)
1440 ifindex = ifp->ifindex;
1441
1442 /* Add interface to the list. */
1443 pn = NULL;
1444 LIST_LOOP (ospf_snmp_iflist, osif, nn)
1445 {
1446 if (addr)
1447 {
1448 if (ntohl (osif->addr.s_addr) > ntohl (addr->s_addr))
1449 break;
1450 }
1451 else
1452 {
1453 /* Unnumbered interface. */
1454 if (osif->addr.s_addr != 0 || osif->ifindex > ifindex)
1455 break;
1456 }
1457 pn = nn;
1458 }
1459
1460 osif = ospf_snmp_if_new ();
1461 if (addr)
1462 osif->addr = *addr;
1463 else
1464 osif->ifindex = ifindex;
1465 osif->ifp = ifp;
1466
1467 listnode_add_after (ospf_snmp_iflist, pn, osif);
1468}
1469
1470struct interface *
1471ospf_snmp_if_lookup (struct in_addr *ifaddr, unsigned int *ifindex)
1472{
1473 struct listnode *nn;
1474 struct ospf_snmp_if *osif;
1475
1476 LIST_LOOP (ospf_snmp_iflist, osif, nn)
1477 {
1478 if (ifaddr->s_addr)
1479 {
1480 if (IPV4_ADDR_SAME (&osif->addr, ifaddr))
1481 return osif->ifp;
1482 }
1483 else
1484 {
1485 if (osif->ifindex == *ifindex)
1486 return osif->ifp;
1487 }
1488 }
1489 return NULL;
1490}
1491
1492struct interface *
1493ospf_snmp_if_lookup_next (struct in_addr *ifaddr, unsigned int *ifindex,
1494 int ifaddr_next, int ifindex_next)
1495{
1496 struct ospf_snmp_if *osif;
1497 struct listnode *nn;
1498
1499 if (ifaddr_next)
1500 {
1501 nn = listhead (ospf_snmp_iflist);
1502 if (nn)
1503 {
1504 osif = getdata (nn);
1505 *ifaddr = osif->addr;
1506 *ifindex = osif->ifindex;
1507 return osif->ifp;
1508 }
1509 return NULL;
1510 }
1511
1512 LIST_LOOP (ospf_snmp_iflist, osif, nn)
1513 {
1514 if (ifaddr->s_addr)
1515 {
1516 if (ntohl (osif->addr.s_addr) > ntohl (ifaddr->s_addr))
1517 {
1518 *ifaddr = osif->addr;
1519 *ifindex = osif->ifindex;
1520 return osif->ifp;
1521 }
1522 }
1523 else
1524 {
1525 if (osif->ifindex > *ifindex || osif->addr.s_addr)
1526 {
1527 *ifaddr = osif->addr;
1528 *ifindex = osif->ifindex;
1529 return osif->ifp;
1530 }
1531 }
1532 }
1533 return NULL;
1534}
1535
1536int
1537ospf_snmp_iftype (struct interface *ifp)
1538{
1539#define ospf_snmp_iftype_broadcast 1
1540#define ospf_snmp_iftype_nbma 2
1541#define ospf_snmp_iftype_pointToPoint 3
1542#define ospf_snmp_iftype_pointToMultipoint 5
1543 if (if_is_broadcast (ifp))
1544 return ospf_snmp_iftype_broadcast;
1545 if (if_is_pointopoint (ifp))
1546 return ospf_snmp_iftype_pointToPoint;
1547 return ospf_snmp_iftype_broadcast;
1548}
1549
1550struct interface *
1551ospfIfLookup (struct variable *v, oid *name, size_t *length,
1552 struct in_addr *ifaddr, unsigned int *ifindex, int exact)
1553{
1554 int len;
1555 int ifaddr_next = 0;
1556 int ifindex_next = 0;
1557 struct interface *ifp;
1558 oid *offset;
1559
1560 if (exact)
1561 {
1562 if (*length != v->namelen + IN_ADDR_SIZE + 1)
1563 return NULL;
1564
1565 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, ifaddr);
1566 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1567
1568 return ospf_snmp_if_lookup (ifaddr, ifindex);
1569 }
1570 else
1571 {
1572 len = *length - v->namelen;
1573 if (len >= IN_ADDR_SIZE)
1574 len = IN_ADDR_SIZE;
1575 if (len <= 0)
1576 ifaddr_next = 1;
1577
1578 oid2in_addr (name + v->namelen, len, ifaddr);
1579
1580 len = *length - v->namelen - IN_ADDR_SIZE;
1581 if (len >= 1)
1582 len = 1;
1583 else
1584 ifindex_next = 1;
1585
1586 if (len == 1)
1587 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1588
1589 ifp = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next,
1590 ifindex_next);
1591 if (ifp)
1592 {
1593 *length = v->namelen + IN_ADDR_SIZE + 1;
1594 offset = name + v->namelen;
1595 oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE);
1596 offset += IN_ADDR_SIZE;
1597 *offset = *ifindex;
1598 return ifp;
1599 }
1600 }
1601 return NULL;
1602}
1603
1604static u_char *
1605ospfIfEntry (struct variable *v, oid *name, size_t *length, int exact,
1606 size_t *var_len, WriteMethod **write_method)
1607{
1608 struct interface *ifp;
1609 unsigned int ifindex;
1610 struct in_addr ifaddr;
1611 struct ospf_interface *oi;
68980084 1612 struct ospf *ospf = ospf_top;
718e3744 1613
1614 ifindex = 0;
1615 memset (&ifaddr, 0, sizeof (struct in_addr));
1616
1617 /* Check OSPF instance. */
68980084 1618 if (ospf == NULL)
718e3744 1619 return NULL;
1620
1621 ifp = ospfIfLookup (v, name, length, &ifaddr, &ifindex, exact);
1622 if (ifp == NULL)
1623 return NULL;
1624
68980084 1625 oi = ospf_if_lookup_by_local_addr (ospf, ifp, ifaddr);
718e3744 1626 if (oi == NULL)
1627 return NULL;
1628
1629 /* Return the current value of the variable */
1630 switch (v->magic)
1631 {
1632 case OSPFIFIPADDRESS: /* 1 */
1633 return SNMP_IPADDRESS (ifaddr);
1634 break;
1635 case OSPFADDRESSLESSIF: /* 2 */
1636 return SNMP_INTEGER (ifindex);
1637 break;
1638 case OSPFIFAREAID: /* 3 */
1639 if (oi->area)
1640 return SNMP_IPADDRESS (oi->area->area_id);
1641 else
1642 return SNMP_IPADDRESS (ospf_empty_addr);
1643 break;
1644 case OSPFIFTYPE: /* 4 */
1645 return SNMP_INTEGER (ospf_snmp_iftype (ifp));
1646 break;
1647 case OSPFIFADMINSTAT: /* 5 */
1648 if (oi)
1649 return SNMP_INTEGER (OSPF_STATUS_ENABLED);
1650 else
1651 return SNMP_INTEGER (OSPF_STATUS_DISABLED);
1652 break;
1653 case OSPFIFRTRPRIORITY: /* 6 */
1654 return SNMP_INTEGER (PRIORITY (oi));
1655 break;
1656 case OSPFIFTRANSITDELAY: /* 7 */
1657 return SNMP_INTEGER (OSPF_IF_PARAM (oi, transmit_delay));
1658 break;
1659 case OSPFIFRETRANSINTERVAL: /* 8 */
1660 return SNMP_INTEGER (OSPF_IF_PARAM (oi, retransmit_interval));
1661 break;
1662 case OSPFIFHELLOINTERVAL: /* 9 */
1663 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_hello));
1664 break;
1665 case OSPFIFRTRDEADINTERVAL: /* 10 */
1666 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_wait));
1667 break;
1668 case OSPFIFPOLLINTERVAL: /* 11 */
1669 return SNMP_INTEGER (OSPF_POLL_INTERVAL_DEFAULT);
1670 break;
1671 case OSPFIFSTATE: /* 12 */
1672 return SNMP_INTEGER (oi->state);
1673 break;
1674 case OSPFIFDESIGNATEDROUTER: /* 13 */
1675 return SNMP_IPADDRESS (DR (oi));
1676 break;
1677 case OSPFIFBACKUPDESIGNATEDROUTER: /* 14 */
1678 return SNMP_IPADDRESS (BDR (oi));
1679 break;
1680 case OSPFIFEVENTS: /* 15 */
1681 return SNMP_INTEGER (oi->state_change);
1682 break;
1683 case OSPFIFAUTHKEY: /* 16 */
1684 *var_len = 0;
1685 return (u_char *) OSPF_IF_PARAM (oi, auth_simple);
1686 break;
1687 case OSPFIFSTATUS: /* 17 */
1688 return SNMP_INTEGER (SNMP_VALID);
1689 break;
1690 case OSPFIFMULTICASTFORWARDING: /* 18 */
1691#define ospf_snmp_multiforward_blocked 1
1692#define ospf_snmp_multiforward_multicast 2
1693#define ospf_snmp_multiforward_unicast 3
1694 return SNMP_INTEGER (ospf_snmp_multiforward_blocked);
1695 break;
1696 case OSPFIFDEMAND: /* 19 */
1697 return SNMP_INTEGER (SNMP_FALSE);
1698 break;
1699 case OSPFIFAUTHTYPE: /* 20 */
1700 if (oi->area)
1701 return SNMP_INTEGER (oi->area->auth_type);
1702 else
1703 return SNMP_INTEGER (0);
1704 break;
1705 default:
1706 return NULL;
1707 break;
1708 }
1709 return NULL;
1710}
1711
1712#define OSPF_SNMP_METRIC_VALUE 1
1713
1714struct interface *
1715ospfIfMetricLookup (struct variable *v, oid *name, size_t *length,
1716 struct in_addr *ifaddr, unsigned int *ifindex, int exact)
1717{
1718 int len;
1719 int ifaddr_next = 0;
1720 int ifindex_next = 0;
1721 struct interface *ifp;
1722 oid *offset;
1723 int metric;
1724
1725 if (exact)
1726 {
1727 if (*length != v->namelen + IN_ADDR_SIZE + 1 + 1)
1728 return NULL;
1729
1730 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, ifaddr);
1731 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1732 metric = name[v->namelen + IN_ADDR_SIZE + 1];
1733
1734 if (metric != OSPF_SNMP_METRIC_VALUE)
1735 return NULL;
1736
1737 return ospf_snmp_if_lookup (ifaddr, ifindex);
1738 }
1739 else
1740 {
1741 len = *length - v->namelen;
1742 if (len >= IN_ADDR_SIZE)
1743 len = IN_ADDR_SIZE;
1744 else
1745 ifaddr_next = 1;
1746
1747 oid2in_addr (name + v->namelen, len, ifaddr);
1748
1749 len = *length - v->namelen - IN_ADDR_SIZE;
1750 if (len >= 1)
1751 len = 1;
1752 else
1753 ifindex_next = 1;
1754
1755 if (len == 1)
1756 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1757
1758 ifp = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next,
1759 ifindex_next);
1760 if (ifp)
1761 {
1762 *length = v->namelen + IN_ADDR_SIZE + 1 + 1;
1763 offset = name + v->namelen;
1764 oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE);
1765 offset += IN_ADDR_SIZE;
1766 *offset = *ifindex;
1767 offset++;
1768 *offset = OSPF_SNMP_METRIC_VALUE;
1769 return ifp;
1770 }
1771 }
1772 return NULL;
1773}
1774
1775static u_char *
1776ospfIfMetricEntry (struct variable *v, oid *name, size_t *length, int exact,
1777 size_t *var_len, WriteMethod **write_method)
1778{
1779 /* Currently we support metric 1 only. */
1780 struct interface *ifp;
1781 unsigned int ifindex;
1782 struct in_addr ifaddr;
1783 struct ospf_interface *oi;
68980084 1784 struct ospf *ospf = ospf_top;
718e3744 1785
1786 ifindex = 0;
1787 memset (&ifaddr, 0, sizeof (struct in_addr));
1788
1789 /* Check OSPF instance. */
68980084 1790 if (ospf == NULL)
718e3744 1791 return NULL;
1792
1793 ifp = ospfIfMetricLookup (v, name, length, &ifaddr, &ifindex, exact);
1794 if (ifp == NULL)
1795 return NULL;
1796
68980084 1797 oi = ospf_if_lookup_by_local_addr (ospf, ifp, ifaddr);
718e3744 1798 if (oi == NULL)
1799 return NULL;
1800
1801 /* Return the current value of the variable */
1802 switch (v->magic)
1803 {
1804 case OSPFIFMETRICIPADDRESS:
1805 return SNMP_IPADDRESS (ifaddr);
1806 break;
1807 case OSPFIFMETRICADDRESSLESSIF:
1808 return SNMP_INTEGER (ifindex);
1809 break;
1810 case OSPFIFMETRICTOS:
1811 return SNMP_INTEGER (0);
1812 break;
1813 case OSPFIFMETRICVALUE:
1814 return SNMP_INTEGER (OSPF_SNMP_METRIC_VALUE);
1815 break;
1816 case OSPFIFMETRICSTATUS:
1817 return SNMP_INTEGER (1);
1818 break;
1819 default:
1820 return NULL;
1821 break;
1822 }
1823 return NULL;
1824}
1825\f
1826struct route_table *ospf_snmp_vl_table;
1827
1828void
1829ospf_snmp_vl_add (struct ospf_vl_data *vl_data)
1830{
1831 struct prefix_ls lp;
1832 struct route_node *rn;
1833
1834 memset (&lp, 0, sizeof (struct prefix_ls));
1835 lp.family = 0;
1836 lp.prefixlen = 64;
1837 lp.id = vl_data->vl_area_id;
1838 lp.adv_router = vl_data->vl_peer;
1839
1840 rn = route_node_get (ospf_snmp_vl_table, (struct prefix *) &lp);
1841 rn->info = vl_data;
1842}
1843
1844void
1845ospf_snmp_vl_delete (struct ospf_vl_data *vl_data)
1846{
1847 struct prefix_ls lp;
1848 struct route_node *rn;
1849
1850 memset (&lp, 0, sizeof (struct prefix_ls));
1851 lp.family = 0;
1852 lp.prefixlen = 64;
1853 lp.id = vl_data->vl_area_id;
1854 lp.adv_router = vl_data->vl_peer;
1855
1856 rn = route_node_lookup (ospf_snmp_vl_table, (struct prefix *) &lp);
1857 if (! rn)
1858 return;
1859 rn->info = NULL;
1860 route_unlock_node (rn);
1861 route_unlock_node (rn);
1862}
1863
1864struct ospf_vl_data *
1865ospf_snmp_vl_lookup (struct in_addr *area_id, struct in_addr *neighbor)
1866{
1867 struct prefix_ls lp;
1868 struct route_node *rn;
1869 struct ospf_vl_data *vl_data;
1870
1871 memset (&lp, 0, sizeof (struct prefix_ls));
1872 lp.family = 0;
1873 lp.prefixlen = 64;
1874 lp.id = *area_id;
1875 lp.adv_router = *neighbor;
1876
1877 rn = route_node_lookup (ospf_snmp_vl_table, (struct prefix *) &lp);
1878 if (rn)
1879 {
1880 vl_data = rn->info;
1881 route_unlock_node (rn);
1882 return vl_data;
1883 }
1884 return NULL;
1885}
1886
1887struct ospf_vl_data *
1888ospf_snmp_vl_lookup_next (struct in_addr *area_id, struct in_addr *neighbor,
1889 int first)
1890{
1891 struct prefix_ls lp;
1892 struct route_node *rn;
1893 struct ospf_vl_data *vl_data;
1894
1895 memset (&lp, 0, sizeof (struct prefix_ls));
1896 lp.family = 0;
1897 lp.prefixlen = 64;
1898 lp.id = *area_id;
1899 lp.adv_router = *neighbor;
1900
1901 if (first)
1902 rn = route_top (ospf_snmp_vl_table);
1903 else
1904 {
1905 rn = route_node_get (ospf_snmp_vl_table, (struct prefix *) &lp);
1906 rn = route_next (rn);
1907 }
1908
1909 for (; rn; rn = route_next (rn))
1910 if (rn->info)
1911 break;
1912
1913 if (rn && rn->info)
1914 {
1915 vl_data = rn->info;
1916 *area_id = vl_data->vl_area_id;
1917 *neighbor = vl_data->vl_peer;
1918 route_unlock_node (rn);
1919 return vl_data;
1920 }
1921 return NULL;
1922}
1923
1924struct ospf_vl_data *
1925ospfVirtIfLookup (struct variable *v, oid *name, size_t *length,
1926 struct in_addr *area_id, struct in_addr *neighbor, int exact)
1927{
1928 int first;
1929 int len;
1930 struct ospf_vl_data *vl_data;
1931
1932 if (exact)
1933 {
1934 if (*length != v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE)
1935 return NULL;
1936
1937 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, area_id);
1938 oid2in_addr (name + v->namelen + IN_ADDR_SIZE, IN_ADDR_SIZE, neighbor);
1939
1940 return ospf_snmp_vl_lookup (area_id, neighbor);
1941 }
1942 else
1943 {
1944 first = 0;
1945
1946 len = *length - v->namelen;
1947 if (len <= 0)
1948 first = 1;
1949 if (len > IN_ADDR_SIZE)
1950 len = IN_ADDR_SIZE;
1951 oid2in_addr (name + v->namelen, len, area_id);
1952
1953 len = *length - v->namelen - IN_ADDR_SIZE;
1954 if (len > IN_ADDR_SIZE)
1955 len = IN_ADDR_SIZE;
1956 oid2in_addr (name + v->namelen + IN_ADDR_SIZE, len, neighbor);
1957
1958 vl_data = ospf_snmp_vl_lookup_next (area_id, neighbor, first);
1959
1960 if (vl_data)
1961 {
1962 *length = v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE;
1963 oid_copy_addr (name + v->namelen, area_id, IN_ADDR_SIZE);
1964 oid_copy_addr (name + v->namelen + IN_ADDR_SIZE, neighbor,
1965 IN_ADDR_SIZE);
1966 return vl_data;
1967 }
1968 }
1969 return NULL;
1970}
1971
1972static u_char *
1973ospfVirtIfEntry (struct variable *v, oid *name, size_t *length, int exact,
1974 size_t *var_len, WriteMethod **write_method)
1975{
1976 struct ospf_vl_data *vl_data;
1977 struct ospf_interface *oi;
1978 struct in_addr area_id;
1979 struct in_addr neighbor;
1980
1981 memset (&area_id, 0, sizeof (struct in_addr));
1982 memset (&neighbor, 0, sizeof (struct in_addr));
1983
1984 vl_data = ospfVirtIfLookup (v, name, length, &area_id, &neighbor, exact);
1985 if (! vl_data)
1986 return NULL;
1987 oi = vl_data->vl_oi;
1988 if (! oi)
1989 return NULL;
1990
1991 /* Return the current value of the variable */
1992 switch (v->magic)
1993 {
1994 case OSPFVIRTIFAREAID:
1995 return SNMP_IPADDRESS (area_id);
1996 break;
1997 case OSPFVIRTIFNEIGHBOR:
1998 return SNMP_IPADDRESS (neighbor);
1999 break;
2000 case OSPFVIRTIFTRANSITDELAY:
2001 return SNMP_INTEGER (OSPF_IF_PARAM (oi, transmit_delay));
2002 break;
2003 case OSPFVIRTIFRETRANSINTERVAL:
2004 return SNMP_INTEGER (OSPF_IF_PARAM (oi, retransmit_interval));
2005 break;
2006 case OSPFVIRTIFHELLOINTERVAL:
2007 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_hello));
2008 break;
2009 case OSPFVIRTIFRTRDEADINTERVAL:
2010 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_wait));
2011 break;
2012 case OSPFVIRTIFSTATE:
2013 return SNMP_INTEGER (oi->state);
2014 break;
2015 case OSPFVIRTIFEVENTS:
2016 return SNMP_INTEGER (oi->state_change);
2017 break;
2018 case OSPFVIRTIFAUTHKEY:
2019 *var_len = 0;
2020 return (u_char *) OSPF_IF_PARAM (oi, auth_simple);
2021 break;
2022 case OSPFVIRTIFSTATUS:
2023 return SNMP_INTEGER (SNMP_VALID);
2024 break;
2025 case OSPFVIRTIFAUTHTYPE:
2026 if (oi->area)
2027 return SNMP_INTEGER (oi->area->auth_type);
2028 else
2029 return SNMP_INTEGER (0);
2030 break;
2031 default:
2032 return NULL;
2033 break;
2034 }
2035 return NULL;
2036}
2037\f
2038struct ospf_neighbor *
68980084 2039ospf_snmp_nbr_lookup (struct ospf *ospf, struct in_addr *nbr_addr,
2040 unsigned int *ifindex)
718e3744 2041{
2042 struct listnode *nn;
2043 struct ospf_interface *oi;
2044 struct ospf_neighbor *nbr;
2045 struct route_node *rn;
2046
68980084 2047 LIST_LOOP (ospf->oiflist, oi, nn)
718e3744 2048 {
2049 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2050 if ((nbr = rn->info) != NULL
2051 && nbr != oi->nbr_self
2052 && nbr->state != NSM_Down
2053 && nbr->src.s_addr != 0)
2054 {
2055 if (IPV4_ADDR_SAME (&nbr->src, nbr_addr))
2056 {
2057 route_unlock_node (rn);
2058 return nbr;
2059 }
2060 }
2061 }
2062 return NULL;
2063}
2064
2065struct ospf_neighbor *
2066ospf_snmp_nbr_lookup_next (struct in_addr *nbr_addr, unsigned int *ifindex,
2067 int first)
2068{
2069 struct listnode *nn;
2070 struct ospf_interface *oi;
2071 struct ospf_neighbor *nbr;
2072 struct route_node *rn;
2073 struct ospf_neighbor *min = NULL;
68980084 2074 struct ospf *ospf = ospf_top;
718e3744 2075
68980084 2076 LIST_LOOP (ospf->oiflist, oi, nn)
718e3744 2077 {
2078 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2079 if ((nbr = rn->info) != NULL
2080 && nbr != oi->nbr_self
2081 && nbr->state != NSM_Down
2082 && nbr->src.s_addr != 0)
2083 {
2084 if (first)
2085 {
2086 if (! min)
2087 min = nbr;
2088 else if (ntohl (nbr->src.s_addr) < ntohl (min->src.s_addr))
2089 min = nbr;
2090 }
2091 else if (ntohl (nbr->src.s_addr) > ntohl (nbr_addr->s_addr))
2092 {
2093 if (! min)
2094 min = nbr;
2095 else if (ntohl (nbr->src.s_addr) < ntohl (min->src.s_addr))
2096 min = nbr;
2097 }
2098 }
2099 }
2100 if (min)
2101 {
2102 *nbr_addr = min->src;
2103 *ifindex = 0;
2104 return min;
2105 }
2106 return NULL;
2107}
2108
2109struct ospf_neighbor *
2110ospfNbrLookup (struct variable *v, oid *name, size_t *length,
2111 struct in_addr *nbr_addr, unsigned int *ifindex, int exact)
2112{
2113 int len;
2114 int first;
2115 struct ospf_neighbor *nbr;
68980084 2116 struct ospf *ospf = ospf_top;
718e3744 2117
2118 if (exact)
2119 {
2120 if (*length != v->namelen + IN_ADDR_SIZE + 1)
2121 return NULL;
2122
2123 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, nbr_addr);
2124 *ifindex = name[v->namelen + IN_ADDR_SIZE];
2125
68980084 2126 return ospf_snmp_nbr_lookup (ospf, nbr_addr, ifindex);
718e3744 2127 }
2128 else
2129 {
2130 first = 0;
2131 len = *length - v->namelen;
2132
2133 if (len <= 0)
2134 first = 1;
2135
2136 if (len > IN_ADDR_SIZE)
2137 len = IN_ADDR_SIZE;
2138
2139 oid2in_addr (name + v->namelen, len, nbr_addr);
2140
2141 len = *length - v->namelen - IN_ADDR_SIZE;
2142 if (len >= 1)
2143 *ifindex = name[v->namelen + IN_ADDR_SIZE];
2144
2145 nbr = ospf_snmp_nbr_lookup_next (nbr_addr, ifindex, first);
2146
2147 if (nbr)
2148 {
2149 *length = v->namelen + IN_ADDR_SIZE + 1;
2150 oid_copy_addr (name + v->namelen, nbr_addr, IN_ADDR_SIZE);
2151 name[v->namelen + IN_ADDR_SIZE] = *ifindex;
2152 return nbr;
2153 }
2154 }
2155 return NULL;
2156}
2157
2158static u_char *
2159ospfNbrEntry (struct variable *v, oid *name, size_t *length, int exact,
2160 size_t *var_len, WriteMethod **write_method)
2161{
2162 struct in_addr nbr_addr;
2163 unsigned int ifindex;
2164 struct ospf_neighbor *nbr;
2165 struct ospf_interface *oi;
2166
2167 memset (&nbr_addr, 0, sizeof (struct in_addr));
2168 ifindex = 0;
2169
2170 nbr = ospfNbrLookup (v, name, length, &nbr_addr, &ifindex, exact);
2171 if (! nbr)
2172 return NULL;
2173 oi = nbr->oi;
2174 if (! oi)
2175 return NULL;
2176
2177 /* Return the current value of the variable */
2178 switch (v->magic)
2179 {
2180 case OSPFNBRIPADDR:
2181 return SNMP_IPADDRESS (nbr_addr);
2182 break;
2183 case OSPFNBRADDRESSLESSINDEX:
2184 return SNMP_INTEGER (ifindex);
2185 break;
2186 case OSPFNBRRTRID:
2187 return SNMP_IPADDRESS (nbr->router_id);
2188 break;
2189 case OSPFNBROPTIONS:
2190 return SNMP_INTEGER (oi->nbr_self->options);
2191 break;
2192 case OSPFNBRPRIORITY:
2193 return SNMP_INTEGER (nbr->priority);
2194 break;
2195 case OSPFNBRSTATE:
2196 return SNMP_INTEGER (nbr->state);
2197 break;
2198 case OSPFNBREVENTS:
2199 return SNMP_INTEGER (nbr->state_change);
2200 break;
2201 case OSPFNBRLSRETRANSQLEN:
2202 return SNMP_INTEGER (ospf_ls_retransmit_count (nbr));
2203 break;
2204 case OSPFNBMANBRSTATUS:
2205 return SNMP_INTEGER (SNMP_VALID);
2206 break;
2207 case OSPFNBMANBRPERMANENCE:
2208 return SNMP_INTEGER (2);
2209 break;
2210 case OSPFNBRHELLOSUPPRESSED:
2211 return SNMP_INTEGER (SNMP_FALSE);
2212 break;
2213 default:
2214 return NULL;
2215 break;
2216 }
2217 return NULL;
2218}
2219\f
2220static u_char *
2221ospfVirtNbrEntry (struct variable *v, oid *name, size_t *length, int exact,
2222 size_t *var_len, WriteMethod **write_method)
2223{
2224 struct ospf_vl_data *vl_data;
2225 struct in_addr area_id;
2226 struct in_addr neighbor;
68980084 2227 struct ospf *ospf = ospf_top;
718e3744 2228
2229 memset (&area_id, 0, sizeof (struct in_addr));
2230 memset (&neighbor, 0, sizeof (struct in_addr));
2231
2232 /* Check OSPF instance. */
68980084 2233 if (ospf == NULL)
718e3744 2234 return NULL;
2235
2236 vl_data = ospfVirtIfLookup (v, name, length, &area_id, &neighbor, exact);
2237 if (! vl_data)
2238 return NULL;
2239
2240 /* Return the current value of the variable */
2241 switch (v->magic)
2242 {
2243 case OSPFVIRTNBRAREA:
2244 return (u_char *) NULL;
2245 break;
2246 case OSPFVIRTNBRRTRID:
2247 return (u_char *) NULL;
2248 break;
2249 case OSPFVIRTNBRIPADDR:
2250 return (u_char *) NULL;
2251 break;
2252 case OSPFVIRTNBROPTIONS:
2253 return (u_char *) NULL;
2254 break;
2255 case OSPFVIRTNBRSTATE:
2256 return (u_char *) NULL;
2257 break;
2258 case OSPFVIRTNBREVENTS:
2259 return (u_char *) NULL;
2260 break;
2261 case OSPFVIRTNBRLSRETRANSQLEN:
2262 return (u_char *) NULL;
2263 break;
2264 case OSPFVIRTNBRHELLOSUPPRESSED:
2265 return (u_char *) NULL;
2266 break;
2267 default:
2268 return NULL;
2269 break;
2270 }
2271 return NULL;
2272}
2273\f
2274struct ospf_lsa *
2275ospfExtLsdbLookup (struct variable *v, oid *name, size_t *length, u_char *type,
2276 struct in_addr *ls_id, struct in_addr *router_id, int exact)
2277{
2278 int first;
2279 oid *offset;
2280 int offsetlen;
2281 u_char lsa_type;
2282 int len;
2283 struct ospf_lsa *lsa;
68980084 2284 struct ospf *ospf = ospf_top;
718e3744 2285
2286 if (exact)
2287 {
2288 if (*length != v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
2289 return NULL;
2290
2291 offset = name + v->namelen;
2292
2293 /* Make it sure given value match to type. */
2294 lsa_type = *offset;
2295 offset++;
2296
2297 if (lsa_type != *type)
2298 return NULL;
2299
2300 /* LS ID. */
2301 oid2in_addr (offset, IN_ADDR_SIZE, ls_id);
2302 offset += IN_ADDR_SIZE;
2303
2304 /* Router ID. */
2305 oid2in_addr (offset, IN_ADDR_SIZE, router_id);
2306
68980084 2307 return ospf_lsdb_lookup_by_id (ospf->lsdb, *type, *ls_id, *router_id);
718e3744 2308 }
2309 else
2310 {
2311 /* Get variable length. */
2312 first = 0;
2313 offset = name + v->namelen;
2314 offsetlen = *length - v->namelen;
2315
2316 /* LSA type value. */
2317 lsa_type = *offset;
2318 offset++;
2319 offsetlen--;
2320
2321 if (offsetlen <= 0 || lsa_type < OSPF_AS_EXTERNAL_LSA)
2322 first = 1;
2323
2324 /* LS ID. */
2325 len = offsetlen;
2326 if (len > IN_ADDR_SIZE)
2327 len = IN_ADDR_SIZE;
2328
2329 oid2in_addr (offset, len, ls_id);
2330
2331 offset += IN_ADDR_SIZE;
2332 offsetlen -= IN_ADDR_SIZE;
2333
2334 /* Router ID. */
2335 len = offsetlen;
2336 if (len > IN_ADDR_SIZE)
2337 len = IN_ADDR_SIZE;
2338
2339 oid2in_addr (offset, len, router_id);
2340
68980084 2341 lsa = ospf_lsdb_lookup_by_id_next (ospf->lsdb, *type, *ls_id,
718e3744 2342 *router_id, first);
2343
2344 if (lsa)
2345 {
2346 /* Fill in length. */
2347 *length = v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE;
2348
2349 /* Fill in value. */
2350 offset = name + v->namelen;
2351
2352 *offset = OSPF_AS_EXTERNAL_LSA;
2353 offset++;
2354 oid_copy_addr (offset, &lsa->data->id, IN_ADDR_SIZE);
2355 offset += IN_ADDR_SIZE;
2356 oid_copy_addr (offset, &lsa->data->adv_router, IN_ADDR_SIZE);
2357
2358 return lsa;
2359 }
2360 }
2361 return NULL;
2362}
2363
2364static u_char *
2365ospfExtLsdbEntry (struct variable *v, oid *name, size_t *length, int exact,
2366 size_t *var_len, WriteMethod **write_method)
2367{
2368 struct ospf_lsa *lsa;
2369 struct lsa_header *lsah;
2370 u_char type;
2371 struct in_addr ls_id;
2372 struct in_addr router_id;
68980084 2373 struct ospf *ospf = ospf_top;
718e3744 2374
2375 type = OSPF_AS_EXTERNAL_LSA;
2376 memset (&ls_id, 0, sizeof (struct in_addr));
2377 memset (&router_id, 0, sizeof (struct in_addr));
2378
2379 /* Check OSPF instance. */
68980084 2380 if (ospf == NULL)
718e3744 2381 return NULL;
2382
2383 lsa = ospfExtLsdbLookup (v, name, length, &type, &ls_id, &router_id, exact);
2384 if (! lsa)
2385 return NULL;
2386
2387 lsah = lsa->data;
2388
2389 /* Return the current value of the variable */
2390 switch (v->magic)
2391 {
2392 case OSPFEXTLSDBTYPE:
2393 return SNMP_INTEGER (OSPF_AS_EXTERNAL_LSA);
2394 break;
2395 case OSPFEXTLSDBLSID:
2396 return SNMP_IPADDRESS (lsah->id);
2397 break;
2398 case OSPFEXTLSDBROUTERID:
2399 return SNMP_IPADDRESS (lsah->adv_router);
2400 break;
2401 case OSPFEXTLSDBSEQUENCE:
2402 return SNMP_INTEGER (lsah->ls_seqnum);
2403 break;
2404 case OSPFEXTLSDBAGE:
2405 return SNMP_INTEGER (lsah->ls_age);
2406 break;
2407 case OSPFEXTLSDBCHECKSUM:
2408 return SNMP_INTEGER (lsah->checksum);
2409 break;
2410 case OSPFEXTLSDBADVERTISEMENT:
2411 *var_len = ntohs (lsah->length);
2412 return (u_char *) lsah;
2413 break;
2414 default:
2415 return NULL;
2416 break;
2417 }
2418 return NULL;
2419}
2420\f
2421static u_char *
2422ospfAreaAggregateEntry (struct variable *v, oid *name, size_t *length,
2423 int exact, size_t *var_len, WriteMethod **write_method)
2424{
2425 /* Return the current value of the variable */
2426 switch (v->magic)
2427 {
2428 case OSPFAREAAGGREGATEAREAID:
2429 return (u_char *) NULL;
2430 break;
2431 case OSPFAREAAGGREGATELSDBTYPE:
2432 return (u_char *) NULL;
2433 break;
2434 case OSPFAREAAGGREGATENET:
2435 return (u_char *) NULL;
2436 break;
2437 case OSPFAREAAGGREGATEMASK:
2438 return (u_char *) NULL;
2439 break;
2440 case OSPFAREAAGGREGATESTATUS:
2441 return (u_char *) NULL;
2442 break;
2443 case OSPFAREAAGGREGATEEFFECT:
2444 return (u_char *) NULL;
2445 break;
2446 default:
2447 return NULL;
2448 break;
2449 }
2450 return NULL;
2451}
2452\f
2453/* Register OSPF2-MIB. */
2454void
2455ospf_snmp_init ()
2456{
2457 ospf_snmp_iflist = list_new ();
2458 ospf_snmp_vl_table = route_table_init ();
2459 smux_init (ospfd_oid, sizeof (ospfd_oid) / sizeof (oid));
2460 REGISTER_MIB("mibII/ospf", ospf_variables, variable, ospf_oid);
2461 smux_start ();
2462}
2463#endif /* HAVE_SNMP */