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