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