+ note the meta-queue in NEWS
[jleu-quagga.git] / ospfd / ospf_snmp.c
blob6e972605f1f61533dabba974a53b820d9178f851
1 /* OSPFv2 SNMP support
2 * Copyright (C) 2005 6WIND <alain.ritoux@6wind.com>
3 * Copyright (C) 2000 IP Infusion Inc.
5 * Written by Kunihiro Ishiguro <kunihiro@zebra.org>
7 * This file is part of GNU Zebra.
9 * GNU Zebra is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2, or (at your option) any
12 * later version.
14 * GNU Zebra is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with GNU Zebra; see the file COPYING. If not, write to the Free
21 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22 * 02111-1307, USA.
25 #include <zebra.h>
27 #ifdef HAVE_SNMP
28 #ifdef HAVE_NETSNMP
29 #include <net-snmp/net-snmp-config.h>
30 #endif
31 #include <asn1.h>
32 #include <snmp.h>
33 #include <snmp_impl.h>
35 #include "if.h"
36 #include "log.h"
37 #include "prefix.h"
38 #include "table.h"
39 #include "command.h"
40 #include "memory.h"
41 #include "smux.h"
43 #include "ospfd/ospfd.h"
44 #include "ospfd/ospf_interface.h"
45 #include "ospfd/ospf_asbr.h"
46 #include "ospfd/ospf_lsa.h"
47 #include "ospfd/ospf_lsdb.h"
48 #include "ospfd/ospf_abr.h"
49 #include "ospfd/ospf_neighbor.h"
50 #include "ospfd/ospf_nsm.h"
51 #include "ospfd/ospf_flood.h"
52 #include "ospfd/ospf_ism.h"
53 #include "ospfd/ospf_dump.h"
55 /* OSPF2-MIB. */
56 #define OSPF2MIB 1,3,6,1,2,1,14
58 /* OSPF MIB General Group values. */
59 #define OSPFROUTERID 1
60 #define OSPFADMINSTAT 2
61 #define OSPFVERSIONNUMBER 3
62 #define OSPFAREABDRRTRSTATUS 4
63 #define OSPFASBDRRTRSTATUS 5
64 #define OSPFEXTERNLSACOUNT 6
65 #define OSPFEXTERNLSACKSUMSUM 7
66 #define OSPFTOSSUPPORT 8
67 #define OSPFORIGINATENEWLSAS 9
68 #define OSPFRXNEWLSAS 10
69 #define OSPFEXTLSDBLIMIT 11
70 #define OSPFMULTICASTEXTENSIONS 12
71 #define OSPFEXITOVERFLOWINTERVAL 13
72 #define OSPFDEMANDEXTENSIONS 14
74 /* OSPF MIB ospfAreaTable. */
75 #define OSPFAREAID 1
76 #define OSPFAUTHTYPE 2
77 #define OSPFIMPORTASEXTERN 3
78 #define OSPFSPFRUNS 4
79 #define OSPFAREABDRRTRCOUNT 5
80 #define OSPFASBDRRTRCOUNT 6
81 #define OSPFAREALSACOUNT 7
82 #define OSPFAREALSACKSUMSUM 8
83 #define OSPFAREASUMMARY 9
84 #define OSPFAREASTATUS 10
86 /* OSPF MIB ospfStubAreaTable. */
87 #define OSPFSTUBAREAID 1
88 #define OSPFSTUBTOS 2
89 #define OSPFSTUBMETRIC 3
90 #define OSPFSTUBSTATUS 4
91 #define OSPFSTUBMETRICTYPE 5
93 /* OSPF MIB ospfLsdbTable. */
94 #define OSPFLSDBAREAID 1
95 #define OSPFLSDBTYPE 2
96 #define OSPFLSDBLSID 3
97 #define OSPFLSDBROUTERID 4
98 #define OSPFLSDBSEQUENCE 5
99 #define OSPFLSDBAGE 6
100 #define OSPFLSDBCHECKSUM 7
101 #define OSPFLSDBADVERTISEMENT 8
103 /* OSPF MIB ospfAreaRangeTable. */
104 #define OSPFAREARANGEAREAID 1
105 #define OSPFAREARANGENET 2
106 #define OSPFAREARANGEMASK 3
107 #define OSPFAREARANGESTATUS 4
108 #define OSPFAREARANGEEFFECT 5
110 /* OSPF MIB ospfHostTable. */
111 #define OSPFHOSTIPADDRESS 1
112 #define OSPFHOSTTOS 2
113 #define OSPFHOSTMETRIC 3
114 #define OSPFHOSTSTATUS 4
115 #define OSPFHOSTAREAID 5
117 /* OSPF MIB ospfIfTable. */
118 #define OSPFIFIPADDRESS 1
119 #define OSPFADDRESSLESSIF 2
120 #define OSPFIFAREAID 3
121 #define OSPFIFTYPE 4
122 #define OSPFIFADMINSTAT 5
123 #define OSPFIFRTRPRIORITY 6
124 #define OSPFIFTRANSITDELAY 7
125 #define OSPFIFRETRANSINTERVAL 8
126 #define OSPFIFHELLOINTERVAL 9
127 #define OSPFIFRTRDEADINTERVAL 10
128 #define OSPFIFPOLLINTERVAL 11
129 #define OSPFIFSTATE 12
130 #define OSPFIFDESIGNATEDROUTER 13
131 #define OSPFIFBACKUPDESIGNATEDROUTER 14
132 #define OSPFIFEVENTS 15
133 #define OSPFIFAUTHKEY 16
134 #define OSPFIFSTATUS 17
135 #define OSPFIFMULTICASTFORWARDING 18
136 #define OSPFIFDEMAND 19
137 #define OSPFIFAUTHTYPE 20
139 /* OSPF MIB ospfIfMetricTable. */
140 #define OSPFIFMETRICIPADDRESS 1
141 #define OSPFIFMETRICADDRESSLESSIF 2
142 #define OSPFIFMETRICTOS 3
143 #define OSPFIFMETRICVALUE 4
144 #define OSPFIFMETRICSTATUS 5
146 /* OSPF MIB ospfVirtIfTable. */
147 #define OSPFVIRTIFAREAID 1
148 #define OSPFVIRTIFNEIGHBOR 2
149 #define OSPFVIRTIFTRANSITDELAY 3
150 #define OSPFVIRTIFRETRANSINTERVAL 4
151 #define OSPFVIRTIFHELLOINTERVAL 5
152 #define OSPFVIRTIFRTRDEADINTERVAL 6
153 #define OSPFVIRTIFSTATE 7
154 #define OSPFVIRTIFEVENTS 8
155 #define OSPFVIRTIFAUTHKEY 9
156 #define OSPFVIRTIFSTATUS 10
157 #define OSPFVIRTIFAUTHTYPE 11
159 /* OSPF MIB ospfNbrTable. */
160 #define OSPFNBRIPADDR 1
161 #define OSPFNBRADDRESSLESSINDEX 2
162 #define OSPFNBRRTRID 3
163 #define OSPFNBROPTIONS 4
164 #define OSPFNBRPRIORITY 5
165 #define OSPFNBRSTATE 6
166 #define OSPFNBREVENTS 7
167 #define OSPFNBRLSRETRANSQLEN 8
168 #define OSPFNBMANBRSTATUS 9
169 #define OSPFNBMANBRPERMANENCE 10
170 #define OSPFNBRHELLOSUPPRESSED 11
172 /* OSPF MIB ospfVirtNbrTable. */
173 #define OSPFVIRTNBRAREA 1
174 #define OSPFVIRTNBRRTRID 2
175 #define OSPFVIRTNBRIPADDR 3
176 #define OSPFVIRTNBROPTIONS 4
177 #define OSPFVIRTNBRSTATE 5
178 #define OSPFVIRTNBREVENTS 6
179 #define OSPFVIRTNBRLSRETRANSQLEN 7
180 #define OSPFVIRTNBRHELLOSUPPRESSED 8
182 /* OSPF MIB ospfExtLsdbTable. */
183 #define OSPFEXTLSDBTYPE 1
184 #define OSPFEXTLSDBLSID 2
185 #define OSPFEXTLSDBROUTERID 3
186 #define OSPFEXTLSDBSEQUENCE 4
187 #define OSPFEXTLSDBAGE 5
188 #define OSPFEXTLSDBCHECKSUM 6
189 #define OSPFEXTLSDBADVERTISEMENT 7
191 /* OSPF MIB ospfAreaAggregateTable. */
192 #define OSPFAREAAGGREGATEAREAID 1
193 #define OSPFAREAAGGREGATELSDBTYPE 2
194 #define OSPFAREAAGGREGATENET 3
195 #define OSPFAREAAGGREGATEMASK 4
196 #define OSPFAREAAGGREGATESTATUS 5
197 #define OSPFAREAAGGREGATEEFFECT 6
199 /* SYNTAX Status from OSPF-MIB. */
200 #define OSPF_STATUS_ENABLED 1
201 #define OSPF_STATUS_DISABLED 2
203 /* SNMP value hack. */
204 #define COUNTER ASN_COUNTER
205 #define INTEGER ASN_INTEGER
206 #define GAUGE ASN_GAUGE
207 #define TIMETICKS ASN_TIMETICKS
208 #define IPADDRESS ASN_IPADDRESS
209 #define STRING ASN_OCTET_STR
211 /* Declare static local variables for convenience. */
212 SNMP_LOCAL_VARIABLES
214 /* OSPF-MIB instances. */
215 oid ospf_oid [] = { OSPF2MIB };
217 /* IP address 0.0.0.0. */
218 static struct in_addr ospf_empty_addr = {0};
220 /* Hook functions. */
221 static u_char *ospfGeneralGroup ();
222 static u_char *ospfAreaEntry ();
223 static u_char *ospfStubAreaEntry ();
224 static u_char *ospfLsdbEntry ();
225 static u_char *ospfAreaRangeEntry ();
226 static u_char *ospfHostEntry ();
227 static u_char *ospfIfEntry ();
228 static u_char *ospfIfMetricEntry ();
229 static u_char *ospfVirtIfEntry ();
230 static u_char *ospfNbrEntry ();
231 static u_char *ospfVirtNbrEntry ();
232 static u_char *ospfExtLsdbEntry ();
233 static u_char *ospfAreaAggregateEntry ();
235 struct variable ospf_variables[] =
237 /* OSPF general variables */
238 {OSPFROUTERID, IPADDRESS, RWRITE, ospfGeneralGroup,
239 2, {1, 1}},
240 {OSPFADMINSTAT, INTEGER, RWRITE, ospfGeneralGroup,
241 2, {1, 2}},
242 {OSPFVERSIONNUMBER, INTEGER, RONLY, ospfGeneralGroup,
243 2, {1, 3}},
244 {OSPFAREABDRRTRSTATUS, INTEGER, RONLY, ospfGeneralGroup,
245 2, {1, 4}},
246 {OSPFASBDRRTRSTATUS, INTEGER, RWRITE, ospfGeneralGroup,
247 2, {1, 5}},
248 {OSPFEXTERNLSACOUNT, GAUGE, RONLY, ospfGeneralGroup,
249 2, {1, 6}},
250 {OSPFEXTERNLSACKSUMSUM, INTEGER, RONLY, ospfGeneralGroup,
251 2, {1, 7}},
252 {OSPFTOSSUPPORT, INTEGER, RWRITE, ospfGeneralGroup,
253 2, {1, 8}},
254 {OSPFORIGINATENEWLSAS, COUNTER, RONLY, ospfGeneralGroup,
255 2, {1, 9}},
256 {OSPFRXNEWLSAS, COUNTER, RONLY, ospfGeneralGroup,
257 2, {1, 10}},
258 {OSPFEXTLSDBLIMIT, INTEGER, RWRITE, ospfGeneralGroup,
259 2, {1, 11}},
260 {OSPFMULTICASTEXTENSIONS, INTEGER, RWRITE, ospfGeneralGroup,
261 2, {1, 12}},
262 {OSPFEXITOVERFLOWINTERVAL, INTEGER, RWRITE, ospfGeneralGroup,
263 2, {1, 13}},
264 {OSPFDEMANDEXTENSIONS, INTEGER, RWRITE, ospfGeneralGroup,
265 2, {1, 14}},
267 /* OSPF area data structure. */
268 {OSPFAREAID, IPADDRESS, RONLY, ospfAreaEntry,
269 3, {2, 1, 1}},
270 {OSPFAUTHTYPE, INTEGER, RWRITE, ospfAreaEntry,
271 3, {2, 1, 2}},
272 {OSPFIMPORTASEXTERN, INTEGER, RWRITE, ospfAreaEntry,
273 3, {2, 1, 3}},
274 {OSPFSPFRUNS, COUNTER, RONLY, ospfAreaEntry,
275 3, {2, 1, 4}},
276 {OSPFAREABDRRTRCOUNT, GAUGE, RONLY, ospfAreaEntry,
277 3, {2, 1, 5}},
278 {OSPFASBDRRTRCOUNT, GAUGE, RONLY, ospfAreaEntry,
279 3, {2, 1, 6}},
280 {OSPFAREALSACOUNT, GAUGE, RONLY, ospfAreaEntry,
281 3, {2, 1, 7}},
282 {OSPFAREALSACKSUMSUM, INTEGER, RONLY, ospfAreaEntry,
283 3, {2, 1, 8}},
284 {OSPFAREASUMMARY, INTEGER, RWRITE, ospfAreaEntry,
285 3, {2, 1, 9}},
286 {OSPFAREASTATUS, INTEGER, RWRITE, ospfAreaEntry,
287 3, {2, 1, 10}},
289 /* OSPF stub area information. */
290 {OSPFSTUBAREAID, IPADDRESS, RONLY, ospfStubAreaEntry,
291 3, {3, 1, 1}},
292 {OSPFSTUBTOS, INTEGER, RONLY, ospfStubAreaEntry,
293 3, {3, 1, 2}},
294 {OSPFSTUBMETRIC, INTEGER, RWRITE, ospfStubAreaEntry,
295 3, {3, 1, 3}},
296 {OSPFSTUBSTATUS, INTEGER, RWRITE, ospfStubAreaEntry,
297 3, {3, 1, 4}},
298 {OSPFSTUBMETRICTYPE, INTEGER, RWRITE, ospfStubAreaEntry,
299 3, {3, 1, 5}},
301 /* OSPF link state database. */
302 {OSPFLSDBAREAID, IPADDRESS, RONLY, ospfLsdbEntry,
303 3, {4, 1, 1}},
304 {OSPFLSDBTYPE, INTEGER, RONLY, ospfLsdbEntry,
305 3, {4, 1, 2}},
306 {OSPFLSDBLSID, IPADDRESS, RONLY, ospfLsdbEntry,
307 3, {4, 1, 3}},
308 {OSPFLSDBROUTERID, IPADDRESS, RONLY, ospfLsdbEntry,
309 3, {4, 1, 4}},
310 {OSPFLSDBSEQUENCE, INTEGER, RONLY, ospfLsdbEntry,
311 3, {4, 1, 5}},
312 {OSPFLSDBAGE, INTEGER, RONLY, ospfLsdbEntry,
313 3, {4, 1, 6}},
314 {OSPFLSDBCHECKSUM, INTEGER, RONLY, ospfLsdbEntry,
315 3, {4, 1, 7}},
316 {OSPFLSDBADVERTISEMENT, STRING, RONLY, ospfLsdbEntry,
317 3, {4, 1, 8}},
319 /* Area range table. */
320 {OSPFAREARANGEAREAID, IPADDRESS, RONLY, ospfAreaRangeEntry,
321 3, {5, 1, 1}},
322 {OSPFAREARANGENET, IPADDRESS, RONLY, ospfAreaRangeEntry,
323 3, {5, 1, 2}},
324 {OSPFAREARANGEMASK, IPADDRESS, RWRITE, ospfAreaRangeEntry,
325 3, {5, 1, 3}},
326 {OSPFAREARANGESTATUS, INTEGER, RWRITE, ospfAreaRangeEntry,
327 3, {5, 1, 4}},
328 {OSPFAREARANGEEFFECT, INTEGER, RWRITE, ospfAreaRangeEntry,
329 3, {5, 1, 5}},
331 /* OSPF host table. */
332 {OSPFHOSTIPADDRESS, IPADDRESS, RONLY, ospfHostEntry,
333 3, {6, 1, 1}},
334 {OSPFHOSTTOS, INTEGER, RONLY, ospfHostEntry,
335 3, {6, 1, 2}},
336 {OSPFHOSTMETRIC, INTEGER, RWRITE, ospfHostEntry,
337 3, {6, 1, 3}},
338 {OSPFHOSTSTATUS, INTEGER, RWRITE, ospfHostEntry,
339 3, {6, 1, 4}},
340 {OSPFHOSTAREAID, IPADDRESS, RONLY, ospfHostEntry,
341 3, {6, 1, 5}},
343 /* OSPF interface table. */
344 {OSPFIFIPADDRESS, IPADDRESS, RONLY, ospfIfEntry,
345 3, {7, 1, 1}},
346 {OSPFADDRESSLESSIF, INTEGER, RONLY, ospfIfEntry,
347 3, {7, 1, 2}},
348 {OSPFIFAREAID, IPADDRESS, RWRITE, ospfIfEntry,
349 3, {7, 1, 3}},
350 {OSPFIFTYPE, INTEGER, RWRITE, ospfIfEntry,
351 3, {7, 1, 4}},
352 {OSPFIFADMINSTAT, INTEGER, RWRITE, ospfIfEntry,
353 3, {7, 1, 5}},
354 {OSPFIFRTRPRIORITY, INTEGER, RWRITE, ospfIfEntry,
355 3, {7, 1, 6}},
356 {OSPFIFTRANSITDELAY, INTEGER, RWRITE, ospfIfEntry,
357 3, {7, 1, 7}},
358 {OSPFIFRETRANSINTERVAL, INTEGER, RWRITE, ospfIfEntry,
359 3, {7, 1, 8}},
360 {OSPFIFHELLOINTERVAL, INTEGER, RWRITE, ospfIfEntry,
361 3, {7, 1, 9}},
362 {OSPFIFRTRDEADINTERVAL, INTEGER, RWRITE, ospfIfEntry,
363 3, {7, 1, 10}},
364 {OSPFIFPOLLINTERVAL, INTEGER, RWRITE, ospfIfEntry,
365 3, {7, 1, 11}},
366 {OSPFIFSTATE, INTEGER, RONLY, ospfIfEntry,
367 3, {7, 1, 12}},
368 {OSPFIFDESIGNATEDROUTER, IPADDRESS, RONLY, ospfIfEntry,
369 3, {7, 1, 13}},
370 {OSPFIFBACKUPDESIGNATEDROUTER, IPADDRESS, RONLY, ospfIfEntry,
371 3, {7, 1, 14}},
372 {OSPFIFEVENTS, COUNTER, RONLY, ospfIfEntry,
373 3, {7, 1, 15}},
374 {OSPFIFAUTHKEY, STRING, RWRITE, ospfIfEntry,
375 3, {7, 1, 16}},
376 {OSPFIFSTATUS, INTEGER, RWRITE, ospfIfEntry,
377 3, {7, 1, 17}},
378 {OSPFIFMULTICASTFORWARDING, INTEGER, RWRITE, ospfIfEntry,
379 3, {7, 1, 18}},
380 {OSPFIFDEMAND, INTEGER, RWRITE, ospfIfEntry,
381 3, {7, 1, 19}},
382 {OSPFIFAUTHTYPE, INTEGER, RWRITE, ospfIfEntry,
383 3, {7, 1, 20}},
385 /* OSPF interface metric table. */
386 {OSPFIFMETRICIPADDRESS, IPADDRESS, RONLY, ospfIfMetricEntry,
387 3, {8, 1, 1}},
388 {OSPFIFMETRICADDRESSLESSIF, INTEGER, RONLY, ospfIfMetricEntry,
389 3, {8, 1, 2}},
390 {OSPFIFMETRICTOS, INTEGER, RONLY, ospfIfMetricEntry,
391 3, {8, 1, 3}},
392 {OSPFIFMETRICVALUE, INTEGER, RWRITE, ospfIfMetricEntry,
393 3, {8, 1, 4}},
394 {OSPFIFMETRICSTATUS, INTEGER, RWRITE, ospfIfMetricEntry,
395 3, {8, 1, 5}},
397 /* OSPF virtual interface table. */
398 {OSPFVIRTIFAREAID, IPADDRESS, RONLY, ospfVirtIfEntry,
399 3, {9, 1, 1}},
400 {OSPFVIRTIFNEIGHBOR, IPADDRESS, RONLY, ospfVirtIfEntry,
401 3, {9, 1, 2}},
402 {OSPFVIRTIFTRANSITDELAY, INTEGER, RWRITE, ospfVirtIfEntry,
403 3, {9, 1, 3}},
404 {OSPFVIRTIFRETRANSINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry,
405 3, {9, 1, 4}},
406 {OSPFVIRTIFHELLOINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry,
407 3, {9, 1, 5}},
408 {OSPFVIRTIFRTRDEADINTERVAL, INTEGER, RWRITE, ospfVirtIfEntry,
409 3, {9, 1, 6}},
410 {OSPFVIRTIFSTATE, INTEGER, RONLY, ospfVirtIfEntry,
411 3, {9, 1, 7}},
412 {OSPFVIRTIFEVENTS, COUNTER, RONLY, ospfVirtIfEntry,
413 3, {9, 1, 8}},
414 {OSPFVIRTIFAUTHKEY, STRING, RWRITE, ospfVirtIfEntry,
415 3, {9, 1, 9}},
416 {OSPFVIRTIFSTATUS, INTEGER, RWRITE, ospfVirtIfEntry,
417 3, {9, 1, 10}},
418 {OSPFVIRTIFAUTHTYPE, INTEGER, RWRITE, ospfVirtIfEntry,
419 3, {9, 1, 11}},
421 /* OSPF neighbor table. */
422 {OSPFNBRIPADDR, IPADDRESS, RONLY, ospfNbrEntry,
423 3, {10, 1, 1}},
424 {OSPFNBRADDRESSLESSINDEX, INTEGER, RONLY, ospfNbrEntry,
425 3, {10, 1, 2}},
426 {OSPFNBRRTRID, IPADDRESS, RONLY, ospfNbrEntry,
427 3, {10, 1, 3}},
428 {OSPFNBROPTIONS, INTEGER, RONLY, ospfNbrEntry,
429 3, {10, 1, 4}},
430 {OSPFNBRPRIORITY, INTEGER, RWRITE, ospfNbrEntry,
431 3, {10, 1, 5}},
432 {OSPFNBRSTATE, INTEGER, RONLY, ospfNbrEntry,
433 3, {10, 1, 6}},
434 {OSPFNBREVENTS, COUNTER, RONLY, ospfNbrEntry,
435 3, {10, 1, 7}},
436 {OSPFNBRLSRETRANSQLEN, GAUGE, RONLY, ospfNbrEntry,
437 3, {10, 1, 8}},
438 {OSPFNBMANBRSTATUS, INTEGER, RWRITE, ospfNbrEntry,
439 3, {10, 1, 9}},
440 {OSPFNBMANBRPERMANENCE, INTEGER, RONLY, ospfNbrEntry,
441 3, {10, 1, 10}},
442 {OSPFNBRHELLOSUPPRESSED, INTEGER, RONLY, ospfNbrEntry,
443 3, {10, 1, 11}},
445 /* OSPF virtual neighbor table. */
446 {OSPFVIRTNBRAREA, IPADDRESS, RONLY, ospfVirtNbrEntry,
447 3, {11, 1, 1}},
448 {OSPFVIRTNBRRTRID, IPADDRESS, RONLY, ospfVirtNbrEntry,
449 3, {11, 1, 2}},
450 {OSPFVIRTNBRIPADDR, IPADDRESS, RONLY, ospfVirtNbrEntry,
451 3, {11, 1, 3}},
452 {OSPFVIRTNBROPTIONS, INTEGER, RONLY, ospfVirtNbrEntry,
453 3, {11, 1, 4}},
454 {OSPFVIRTNBRSTATE, INTEGER, RONLY, ospfVirtNbrEntry,
455 3, {11, 1, 5}},
456 {OSPFVIRTNBREVENTS, COUNTER, RONLY, ospfVirtNbrEntry,
457 3, {11, 1, 6}},
458 {OSPFVIRTNBRLSRETRANSQLEN, INTEGER, RONLY, ospfVirtNbrEntry,
459 3, {11, 1, 7}},
460 {OSPFVIRTNBRHELLOSUPPRESSED, INTEGER, RONLY, ospfVirtNbrEntry,
461 3, {11, 1, 8}},
463 /* OSPF link state database, external. */
464 {OSPFEXTLSDBTYPE, INTEGER, RONLY, ospfExtLsdbEntry,
465 3, {12, 1, 1}},
466 {OSPFEXTLSDBLSID, IPADDRESS, RONLY, ospfExtLsdbEntry,
467 3, {12, 1, 2}},
468 {OSPFEXTLSDBROUTERID, IPADDRESS, RONLY, ospfExtLsdbEntry,
469 3, {12, 1, 3}},
470 {OSPFEXTLSDBSEQUENCE, INTEGER, RONLY, ospfExtLsdbEntry,
471 3, {12, 1, 4}},
472 {OSPFEXTLSDBAGE, INTEGER, RONLY, ospfExtLsdbEntry,
473 3, {12, 1, 5}},
474 {OSPFEXTLSDBCHECKSUM, INTEGER, RONLY, ospfExtLsdbEntry,
475 3, {12, 1, 6}},
476 {OSPFEXTLSDBADVERTISEMENT, STRING, RONLY, ospfExtLsdbEntry,
477 3, {12, 1, 7}},
479 /* OSPF area aggregate table. */
480 {OSPFAREAAGGREGATEAREAID, IPADDRESS, RONLY, ospfAreaAggregateEntry,
481 3, {14, 1, 1}},
482 {OSPFAREAAGGREGATELSDBTYPE, INTEGER, RONLY, ospfAreaAggregateEntry,
483 3, {14, 1, 2}},
484 {OSPFAREAAGGREGATENET, IPADDRESS, RONLY, ospfAreaAggregateEntry,
485 3, {14, 1, 3}},
486 {OSPFAREAAGGREGATEMASK, IPADDRESS, RONLY, ospfAreaAggregateEntry,
487 3, {14, 1, 4}},
488 {OSPFAREAAGGREGATESTATUS, INTEGER, RWRITE, ospfAreaAggregateEntry,
489 3, {14, 1, 5}},
490 {OSPFAREAAGGREGATEEFFECT, INTEGER, RWRITE, ospfAreaAggregateEntry,
491 3, {14, 1, 6}}
494 /* The administrative status of OSPF. When OSPF is enbled on at least
495 one interface return 1. */
497 ospf_admin_stat (struct ospf *ospf)
499 struct listnode *node;
500 struct ospf_interface *oi;
502 if (ospf == NULL)
503 return 0;
505 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
506 if (oi && oi->address)
507 return 1;
509 return 0;
512 static u_char *
513 ospfGeneralGroup (struct variable *v, oid *name, size_t *length,
514 int exact, size_t *var_len, WriteMethod **write_method)
516 struct ospf *ospf;
518 ospf = ospf_lookup ();
520 /* Check whether the instance identifier is valid */
521 if (smux_header_generic (v, name, length, exact, var_len, write_method)
522 == MATCH_FAILED)
523 return NULL;
525 /* Return the current value of the variable */
526 switch (v->magic)
528 case OSPFROUTERID: /* 1 */
529 /* Router-ID of this OSPF instance. */
530 if (ospf)
531 return SNMP_IPADDRESS (ospf->router_id);
532 else
533 return SNMP_IPADDRESS (ospf_empty_addr);
534 break;
535 case OSPFADMINSTAT: /* 2 */
536 /* The administrative status of OSPF in the router. */
537 if (ospf_admin_stat (ospf))
538 return SNMP_INTEGER (OSPF_STATUS_ENABLED);
539 else
540 return SNMP_INTEGER (OSPF_STATUS_DISABLED);
541 break;
542 case OSPFVERSIONNUMBER: /* 3 */
543 /* OSPF version 2. */
544 return SNMP_INTEGER (OSPF_VERSION);
545 break;
546 case OSPFAREABDRRTRSTATUS: /* 4 */
547 /* Area Border router status. */
548 if (ospf && CHECK_FLAG (ospf->flags, OSPF_FLAG_ABR))
549 return SNMP_INTEGER (SNMP_TRUE);
550 else
551 return SNMP_INTEGER (SNMP_FALSE);
552 break;
553 case OSPFASBDRRTRSTATUS: /* 5 */
554 /* AS Border router status. */
555 if (ospf && CHECK_FLAG (ospf->flags, OSPF_FLAG_ASBR))
556 return SNMP_INTEGER (SNMP_TRUE);
557 else
558 return SNMP_INTEGER (SNMP_FALSE);
559 break;
560 case OSPFEXTERNLSACOUNT: /* 6 */
561 /* External LSA counts. */
562 if (ospf)
563 return SNMP_INTEGER (ospf_lsdb_count_all (ospf->lsdb));
564 else
565 return SNMP_INTEGER (0);
566 break;
567 case OSPFEXTERNLSACKSUMSUM: /* 7 */
568 /* External LSA checksum. */
569 return SNMP_INTEGER (0);
570 break;
571 case OSPFTOSSUPPORT: /* 8 */
572 /* TOS is not supported. */
573 return SNMP_INTEGER (SNMP_FALSE);
574 break;
575 case OSPFORIGINATENEWLSAS: /* 9 */
576 /* The number of new link-state advertisements. */
577 if (ospf)
578 return SNMP_INTEGER (ospf->lsa_originate_count);
579 else
580 return SNMP_INTEGER (0);
581 break;
582 case OSPFRXNEWLSAS: /* 10 */
583 /* The number of link-state advertisements received determined
584 to be new instantiations. */
585 if (ospf)
586 return SNMP_INTEGER (ospf->rx_lsa_count);
587 else
588 return SNMP_INTEGER (0);
589 break;
590 case OSPFEXTLSDBLIMIT: /* 11 */
591 /* There is no limit for the number of non-default
592 AS-external-LSAs. */
593 return SNMP_INTEGER (-1);
594 break;
595 case OSPFMULTICASTEXTENSIONS: /* 12 */
596 /* Multicast Extensions to OSPF is not supported. */
597 return SNMP_INTEGER (0);
598 break;
599 case OSPFEXITOVERFLOWINTERVAL: /* 13 */
600 /* Overflow is not supported. */
601 return SNMP_INTEGER (0);
602 break;
603 case OSPFDEMANDEXTENSIONS: /* 14 */
604 /* Demand routing is not supported. */
605 return SNMP_INTEGER (SNMP_FALSE);
606 break;
607 default:
608 return NULL;
610 return NULL;
613 struct ospf_area *
614 ospf_area_lookup_next (struct ospf *ospf, struct in_addr *area_id, int first)
616 struct ospf_area *area;
617 struct listnode *node;
619 if (ospf == NULL)
620 return NULL;
622 if (first)
624 node = listhead (ospf->areas);
625 if (node)
627 area = listgetdata (node);
628 *area_id = area->area_id;
629 return area;
631 return NULL;
633 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
635 if (ntohl (area->area_id.s_addr) > ntohl (area_id->s_addr))
637 *area_id = area->area_id;
638 return area;
641 return NULL;
644 struct ospf_area *
645 ospfAreaLookup (struct variable *v, oid name[], size_t *length,
646 struct in_addr *addr, int exact)
648 struct ospf *ospf;
649 struct ospf_area *area;
650 int len;
652 ospf = ospf_lookup ();
653 if (ospf == NULL)
654 return NULL;
656 if (exact)
658 /* Length is insufficient to lookup OSPF area. */
659 if (*length - v->namelen != sizeof (struct in_addr))
660 return NULL;
662 oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr);
664 area = ospf_area_lookup_by_area_id (ospf, *addr);
666 return area;
668 else
670 len = *length - v->namelen;
671 if (len > 4)
672 len = 4;
674 oid2in_addr (name + v->namelen, len, addr);
676 area = ospf_area_lookup_next (ospf, addr, len == 0 ? 1 : 0);
678 if (area == NULL)
679 return NULL;
681 oid_copy_addr (name + v->namelen, addr, sizeof (struct in_addr));
682 *length = sizeof (struct in_addr) + v->namelen;
684 return area;
686 return NULL;
689 static u_char *
690 ospfAreaEntry (struct variable *v, oid *name, size_t *length, int exact,
691 size_t *var_len, WriteMethod **write_method)
693 struct ospf_area *area;
694 struct in_addr addr;
696 memset (&addr, 0, sizeof (struct in_addr));
698 area = ospfAreaLookup (v, name, length, &addr, exact);
699 if (! area)
700 return NULL;
702 /* Return the current value of the variable */
703 switch (v->magic)
705 case OSPFAREAID: /* 1 */
706 return SNMP_IPADDRESS (area->area_id);
707 break;
708 case OSPFAUTHTYPE: /* 2 */
709 return SNMP_INTEGER (area->auth_type);
710 break;
711 case OSPFIMPORTASEXTERN: /* 3 */
712 return SNMP_INTEGER (area->external_routing + 1);
713 break;
714 case OSPFSPFRUNS: /* 4 */
715 return SNMP_INTEGER (area->spf_calculation);
716 break;
717 case OSPFAREABDRRTRCOUNT: /* 5 */
718 return SNMP_INTEGER (area->abr_count);
719 break;
720 case OSPFASBDRRTRCOUNT: /* 6 */
721 return SNMP_INTEGER (area->asbr_count);
722 break;
723 case OSPFAREALSACOUNT: /* 7 */
724 return SNMP_INTEGER (area->lsdb->total);
725 break;
726 case OSPFAREALSACKSUMSUM: /* 8 */
727 return SNMP_INTEGER (0);
728 break;
729 case OSPFAREASUMMARY: /* 9 */
730 #define OSPF_noAreaSummary 1
731 #define OSPF_sendAreaSummary 2
732 if (area->no_summary)
733 return SNMP_INTEGER (OSPF_noAreaSummary);
734 else
735 return SNMP_INTEGER (OSPF_sendAreaSummary);
736 break;
737 case OSPFAREASTATUS: /* 10 */
738 return SNMP_INTEGER (SNMP_VALID);
739 break;
740 default:
741 return NULL;
742 break;
744 return NULL;
747 struct ospf_area *
748 ospf_stub_area_lookup_next (struct in_addr *area_id, int first)
750 struct ospf_area *area;
751 struct listnode *node;
752 struct ospf *ospf;
754 ospf = ospf_lookup ();
755 if (ospf == NULL)
756 return NULL;
758 for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
760 if (area->external_routing == OSPF_AREA_STUB)
762 if (first)
764 *area_id = area->area_id;
765 return area;
767 else if (ntohl (area->area_id.s_addr) > ntohl (area_id->s_addr))
769 *area_id = area->area_id;
770 return area;
774 return NULL;
777 struct ospf_area *
778 ospfStubAreaLookup (struct variable *v, oid name[], size_t *length,
779 struct in_addr *addr, int exact)
781 struct ospf *ospf;
782 struct ospf_area *area;
783 int len;
785 ospf = ospf_lookup ();
786 if (ospf == NULL)
787 return NULL;
789 /* Exact lookup. */
790 if (exact)
792 /* ospfStubAreaID + ospfStubTOS. */
793 if (*length != v->namelen + sizeof (struct in_addr) + 1)
794 return NULL;
796 /* Check ospfStubTOS is zero. */
797 if (name[*length - 1] != 0)
798 return NULL;
800 oid2in_addr (name + v->namelen, sizeof (struct in_addr), addr);
802 area = ospf_area_lookup_by_area_id (ospf, *addr);
804 if (area->external_routing == OSPF_AREA_STUB)
805 return area;
806 else
807 return NULL;
809 else
811 len = *length - v->namelen;
812 if (len > 4)
813 len = 4;
815 oid2in_addr (name + v->namelen, len, addr);
817 area = ospf_stub_area_lookup_next (addr, len == 0 ? 1 : 0);
819 if (area == NULL)
820 return NULL;
822 oid_copy_addr (name + v->namelen, addr, sizeof (struct in_addr));
823 /* Set TOS 0. */
824 name[v->namelen + sizeof (struct in_addr)] = 0;
825 *length = v->namelen + sizeof (struct in_addr) + 1;
827 return area;
829 return NULL;
832 static u_char *
833 ospfStubAreaEntry (struct variable *v, oid *name, size_t *length,
834 int exact, size_t *var_len, WriteMethod **write_method)
836 struct ospf_area *area;
837 struct in_addr addr;
839 memset (&addr, 0, sizeof (struct in_addr));
841 area = ospfStubAreaLookup (v, name, length, &addr, exact);
842 if (! area)
843 return NULL;
845 /* Return the current value of the variable */
846 switch (v->magic)
848 case OSPFSTUBAREAID: /* 1 */
849 /* OSPF stub area id. */
850 return SNMP_IPADDRESS (area->area_id);
851 break;
852 case OSPFSTUBTOS: /* 2 */
853 /* TOS value is not supported. */
854 return SNMP_INTEGER (0);
855 break;
856 case OSPFSTUBMETRIC: /* 3 */
857 /* Default cost to stub area. */
858 return SNMP_INTEGER (area->default_cost);
859 break;
860 case OSPFSTUBSTATUS: /* 4 */
861 /* Status of the stub area. */
862 return SNMP_INTEGER (SNMP_VALID);
863 break;
864 case OSPFSTUBMETRICTYPE: /* 5 */
865 /* OSPF Metric type. */
866 #define OSPF_ospfMetric 1
867 #define OSPF_comparableCost 2
868 #define OSPF_nonComparable 3
869 return SNMP_INTEGER (OSPF_ospfMetric);
870 break;
871 default:
872 return NULL;
873 break;
875 return NULL;
878 struct ospf_lsa *
879 lsdb_lookup_next (struct ospf_area *area, u_char *type, int type_next,
880 struct in_addr *ls_id, int ls_id_next,
881 struct in_addr *router_id, int router_id_next)
883 struct ospf_lsa *lsa;
884 int i;
886 if (type_next)
887 i = OSPF_MIN_LSA;
888 else
889 i = *type;
891 /* Sanity check, if LSA type unknwon
892 merley skip any LSA */
893 if ((i < OSPF_MIN_LSA) || (i >= OSPF_MAX_LSA))
895 zlog_debug("Strange request with LSA type %d\n", i);
896 return NULL;
899 for (; i < OSPF_MAX_LSA; i++)
901 *type = i;
903 lsa = ospf_lsdb_lookup_by_id_next (area->lsdb, *type, *ls_id, *router_id,
904 ls_id_next);
905 if (lsa)
906 return lsa;
908 ls_id_next = 1;
910 return NULL;
913 struct ospf_lsa *
914 ospfLsdbLookup (struct variable *v, oid *name, size_t *length,
915 struct in_addr *area_id, u_char *type,
916 struct in_addr *ls_id, struct in_addr *router_id, int exact)
918 struct ospf *ospf;
919 struct ospf_area *area;
920 struct ospf_lsa *lsa;
921 unsigned int len;
922 int type_next;
923 int ls_id_next;
924 int router_id_next;
925 oid *offset;
926 int offsetlen;
928 ospf = ospf_lookup ();
930 #define OSPF_LSDB_ENTRY_OFFSET \
931 (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
933 if (exact)
935 /* Area ID + Type + LS ID + Router ID. */
936 if (*length - v->namelen != OSPF_LSDB_ENTRY_OFFSET)
937 return NULL;
939 /* Set OID offset for Area ID. */
940 offset = name + v->namelen;
942 /* Lookup area first. */
943 oid2in_addr (offset, IN_ADDR_SIZE, area_id);
944 area = ospf_area_lookup_by_area_id (ospf, *area_id);
945 if (! area)
946 return NULL;
947 offset += IN_ADDR_SIZE;
949 /* Type. */
950 *type = *offset;
951 offset++;
953 /* LS ID. */
954 oid2in_addr (offset, IN_ADDR_SIZE, ls_id);
955 offset += IN_ADDR_SIZE;
957 /* Router ID. */
958 oid2in_addr (offset, IN_ADDR_SIZE, router_id);
960 /* Lookup LSDB. */
961 return ospf_lsdb_lookup_by_id (area->lsdb, *type, *ls_id, *router_id);
963 else
965 /* Get variable length. */
966 offset = name + v->namelen;
967 offsetlen = *length - v->namelen;
968 len = offsetlen;
970 if (len > IN_ADDR_SIZE)
971 len = IN_ADDR_SIZE;
973 oid2in_addr (offset, len, area_id);
975 /* First we search area. */
976 if (len == IN_ADDR_SIZE)
977 area = ospf_area_lookup_by_area_id (ospf, *area_id);
978 else
979 area = ospf_area_lookup_next (ospf, area_id, len == 0 ? 1 : 0);
981 if (area == NULL)
982 return NULL;
986 /* Next we lookup type. */
987 offset += IN_ADDR_SIZE;
988 offsetlen -= IN_ADDR_SIZE;
989 len = offsetlen;
991 if (len <= 0)
992 type_next = 1;
993 else
995 len = 1;
996 type_next = 0;
997 *type = *offset;
1000 /* LS ID. */
1001 offset++;
1002 offsetlen--;
1003 len = offsetlen;
1005 if (len <= 0)
1006 ls_id_next = 1;
1007 else
1009 ls_id_next = 0;
1010 if (len > IN_ADDR_SIZE)
1011 len = IN_ADDR_SIZE;
1013 oid2in_addr (offset, len, ls_id);
1016 /* Router ID. */
1017 offset += IN_ADDR_SIZE;
1018 offsetlen -= IN_ADDR_SIZE;
1019 len = offsetlen;
1021 if (len <= 0)
1022 router_id_next = 1;
1023 else
1025 router_id_next = 0;
1026 if (len > IN_ADDR_SIZE)
1027 len = IN_ADDR_SIZE;
1029 oid2in_addr (offset, len, router_id);
1032 lsa = lsdb_lookup_next (area, type, type_next, ls_id, ls_id_next,
1033 router_id, router_id_next);
1035 if (lsa)
1037 /* Fill in length. */
1038 *length = v->namelen + OSPF_LSDB_ENTRY_OFFSET;
1040 /* Fill in value. */
1041 offset = name + v->namelen;
1042 oid_copy_addr (offset, area_id, IN_ADDR_SIZE);
1043 offset += IN_ADDR_SIZE;
1044 *offset = lsa->data->type;
1045 offset++;
1046 oid_copy_addr (offset, &lsa->data->id, IN_ADDR_SIZE);
1047 offset += IN_ADDR_SIZE;
1048 oid_copy_addr (offset, &lsa->data->adv_router, IN_ADDR_SIZE);
1050 return lsa;
1053 while ((area = ospf_area_lookup_next (ospf, area_id, 0)) != NULL);
1055 return NULL;
1058 static u_char *
1059 ospfLsdbEntry (struct variable *v, oid *name, size_t *length, int exact,
1060 size_t *var_len, WriteMethod **write_method)
1062 struct ospf_lsa *lsa;
1063 struct lsa_header *lsah;
1064 struct in_addr area_id;
1065 u_char type;
1066 struct in_addr ls_id;
1067 struct in_addr router_id;
1068 struct ospf *ospf;
1070 /* INDEX { ospfLsdbAreaId, ospfLsdbType,
1071 ospfLsdbLsid, ospfLsdbRouterId } */
1073 memset (&area_id, 0, sizeof (struct in_addr));
1074 type = 0;
1075 memset (&ls_id, 0, sizeof (struct in_addr));
1076 memset (&router_id, 0, sizeof (struct in_addr));
1078 /* Check OSPF instance. */
1079 ospf = ospf_lookup ();
1080 if (ospf == NULL)
1081 return NULL;
1083 lsa = ospfLsdbLookup (v, name, length, &area_id, &type, &ls_id, &router_id,
1084 exact);
1085 if (! lsa)
1086 return NULL;
1088 lsah = lsa->data;
1090 /* Return the current value of the variable */
1091 switch (v->magic)
1093 case OSPFLSDBAREAID: /* 1 */
1094 return SNMP_IPADDRESS (lsa->area->area_id);
1095 break;
1096 case OSPFLSDBTYPE: /* 2 */
1097 return SNMP_INTEGER (lsah->type);
1098 break;
1099 case OSPFLSDBLSID: /* 3 */
1100 return SNMP_IPADDRESS (lsah->id);
1101 break;
1102 case OSPFLSDBROUTERID: /* 4 */
1103 return SNMP_IPADDRESS (lsah->adv_router);
1104 break;
1105 case OSPFLSDBSEQUENCE: /* 5 */
1106 return SNMP_INTEGER (lsah->ls_seqnum);
1107 break;
1108 case OSPFLSDBAGE: /* 6 */
1109 return SNMP_INTEGER (lsah->ls_age);
1110 break;
1111 case OSPFLSDBCHECKSUM: /* 7 */
1112 return SNMP_INTEGER (lsah->checksum);
1113 break;
1114 case OSPFLSDBADVERTISEMENT: /* 8 */
1115 *var_len = ntohs (lsah->length);
1116 return (u_char *) lsah;
1117 break;
1118 default:
1119 return NULL;
1120 break;
1122 return NULL;
1125 struct ospf_area_range *
1126 ospfAreaRangeLookup (struct variable *v, oid *name, size_t *length,
1127 struct in_addr *area_id, struct in_addr *range_net,
1128 int exact)
1130 oid *offset;
1131 int offsetlen;
1132 unsigned int len;
1133 struct ospf *ospf;
1134 struct ospf_area *area;
1135 struct ospf_area_range *range;
1136 struct prefix_ipv4 p;
1137 p.family = AF_INET;
1138 p.prefixlen = IPV4_MAX_BITLEN;
1140 ospf = ospf_lookup ();
1142 if (exact)
1144 /* Area ID + Range Network. */
1145 if (v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE != *length)
1146 return NULL;
1148 /* Set OID offset for Area ID. */
1149 offset = name + v->namelen;
1151 /* Lookup area first. */
1152 oid2in_addr (offset, IN_ADDR_SIZE, area_id);
1154 area = ospf_area_lookup_by_area_id (ospf, *area_id);
1155 if (! area)
1156 return NULL;
1158 offset += IN_ADDR_SIZE;
1160 /* Lookup area range. */
1161 oid2in_addr (offset, IN_ADDR_SIZE, range_net);
1162 p.prefix = *range_net;
1164 return ospf_area_range_lookup (area, &p);
1166 else
1168 /* Set OID offset for Area ID. */
1169 offset = name + v->namelen;
1170 offsetlen = *length - v->namelen;
1172 len = offsetlen;
1173 if (len > IN_ADDR_SIZE)
1174 len = IN_ADDR_SIZE;
1176 oid2in_addr (offset, len, area_id);
1178 /* First we search area. */
1179 if (len == IN_ADDR_SIZE)
1180 area = ospf_area_lookup_by_area_id (ospf,*area_id);
1181 else
1182 area = ospf_area_lookup_next (ospf, area_id, len == 0 ? 1 : 0);
1184 if (area == NULL)
1185 return NULL;
1189 offset += IN_ADDR_SIZE;
1190 offsetlen -= IN_ADDR_SIZE;
1191 len = offsetlen;
1193 if (len < 0)
1194 len = 0;
1195 if (len > IN_ADDR_SIZE)
1196 len = IN_ADDR_SIZE;
1198 oid2in_addr (offset, len, range_net);
1200 range = ospf_area_range_lookup_next (area, range_net,
1201 len == 0 ? 1 : 0);
1203 if (range)
1205 /* Fill in length. */
1206 *length = v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE;
1208 /* Fill in value. */
1209 offset = name + v->namelen;
1210 oid_copy_addr (offset, area_id, IN_ADDR_SIZE);
1211 offset += IN_ADDR_SIZE;
1212 oid_copy_addr (offset, range_net, IN_ADDR_SIZE);
1214 return range;
1217 while ((area = ospf_area_lookup_next (ospf, area_id, 0)) != NULL);
1219 return NULL;
1222 static u_char *
1223 ospfAreaRangeEntry (struct variable *v, oid *name, size_t *length, int exact,
1224 size_t *var_len, WriteMethod **write_method)
1226 struct ospf_area_range *range;
1227 struct in_addr area_id;
1228 struct in_addr range_net;
1229 struct in_addr mask;
1230 struct ospf *ospf;
1232 /* Check OSPF instance. */
1233 ospf = ospf_lookup ();
1234 if (ospf == NULL)
1235 return NULL;
1237 memset (&area_id, 0, IN_ADDR_SIZE);
1238 memset (&range_net, 0, IN_ADDR_SIZE);
1240 range = ospfAreaRangeLookup (v, name, length, &area_id, &range_net, exact);
1241 if (! range)
1242 return NULL;
1244 /* Convert prefixlen to network mask format. */
1245 masklen2ip (range->subst_masklen, &mask);
1247 /* Return the current value of the variable */
1248 switch (v->magic)
1250 case OSPFAREARANGEAREAID: /* 1 */
1251 return SNMP_IPADDRESS (area_id);
1252 break;
1253 case OSPFAREARANGENET: /* 2 */
1254 return SNMP_IPADDRESS (range_net);
1255 break;
1256 case OSPFAREARANGEMASK: /* 3 */
1257 return SNMP_IPADDRESS (mask);
1258 break;
1259 case OSPFAREARANGESTATUS: /* 4 */
1260 return SNMP_INTEGER (SNMP_VALID);
1261 break;
1262 case OSPFAREARANGEEFFECT: /* 5 */
1263 #define OSPF_advertiseMatching 1
1264 #define OSPF_doNotAdvertiseMatching 2
1265 return SNMP_INTEGER (OSPF_advertiseMatching);
1266 break;
1267 default:
1268 return NULL;
1269 break;
1271 return NULL;
1274 struct ospf_nbr_nbma *
1275 ospfHostLookup (struct variable *v, oid *name, size_t *length,
1276 struct in_addr *addr, int exact)
1278 int len;
1279 struct ospf_nbr_nbma *nbr_nbma;
1280 struct ospf *ospf;
1282 ospf = ospf_lookup ();
1283 if (ospf == NULL)
1284 return NULL;
1286 if (exact)
1288 /* INDEX { ospfHostIpAddress, ospfHostTOS } */
1289 if (*length != v->namelen + IN_ADDR_SIZE + 1)
1290 return NULL;
1292 /* Check ospfHostTOS. */
1293 if (name[*length - 1] != 0)
1294 return NULL;
1296 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, addr);
1298 nbr_nbma = ospf_nbr_nbma_lookup (ospf, *addr);
1300 return nbr_nbma;
1302 else
1304 len = *length - v->namelen;
1305 if (len > 4)
1306 len = 4;
1308 oid2in_addr (name + v->namelen, len, addr);
1310 nbr_nbma = ospf_nbr_nbma_lookup_next (ospf, addr, len == 0 ? 1 : 0);
1312 if (nbr_nbma == NULL)
1313 return NULL;
1315 oid_copy_addr (name + v->namelen, addr, IN_ADDR_SIZE);
1317 /* Set TOS 0. */
1318 name[v->namelen + IN_ADDR_SIZE] = 0;
1320 *length = v->namelen + IN_ADDR_SIZE + 1;
1322 return nbr_nbma;
1324 return NULL;
1327 static u_char *
1328 ospfHostEntry (struct variable *v, oid *name, size_t *length, int exact,
1329 size_t *var_len, WriteMethod **write_method)
1331 struct ospf_nbr_nbma *nbr_nbma;
1332 struct ospf_interface *oi;
1333 struct in_addr addr;
1334 struct ospf *ospf;
1336 /* Check OSPF instance. */
1337 ospf = ospf_lookup ();
1338 if (ospf == NULL)
1339 return NULL;
1341 memset (&addr, 0, sizeof (struct in_addr));
1343 nbr_nbma = ospfHostLookup (v, name, length, &addr, exact);
1344 if (nbr_nbma == NULL)
1345 return NULL;
1347 oi = nbr_nbma->oi;
1349 /* Return the current value of the variable */
1350 switch (v->magic)
1352 case OSPFHOSTIPADDRESS: /* 1 */
1353 return SNMP_IPADDRESS (nbr_nbma->addr);
1354 break;
1355 case OSPFHOSTTOS: /* 2 */
1356 return SNMP_INTEGER (0);
1357 break;
1358 case OSPFHOSTMETRIC: /* 3 */
1359 if (oi)
1360 return SNMP_INTEGER (oi->output_cost);
1361 else
1362 return SNMP_INTEGER (1);
1363 break;
1364 case OSPFHOSTSTATUS: /* 4 */
1365 return SNMP_INTEGER (SNMP_VALID);
1366 break;
1367 case OSPFHOSTAREAID: /* 5 */
1368 if (oi && oi->area)
1369 return SNMP_IPADDRESS (oi->area->area_id);
1370 else
1371 return SNMP_IPADDRESS (ospf_empty_addr);
1372 break;
1373 default:
1374 return NULL;
1375 break;
1377 return NULL;
1380 struct list *ospf_snmp_iflist;
1382 struct ospf_snmp_if
1384 struct in_addr addr;
1385 unsigned int ifindex;
1386 struct interface *ifp;
1389 struct ospf_snmp_if *
1390 ospf_snmp_if_new ()
1392 struct ospf_snmp_if *osif;
1394 osif = XMALLOC (0, sizeof (struct ospf_snmp_if));
1395 memset (osif, 0, sizeof (struct ospf_snmp_if));
1396 return osif;
1399 void
1400 ospf_snmp_if_free (struct ospf_snmp_if *osif)
1402 XFREE (0, osif);
1405 void
1406 ospf_snmp_if_delete (struct interface *ifp)
1408 struct listnode *node, *nnode;
1409 struct ospf_snmp_if *osif;
1411 for (ALL_LIST_ELEMENTS (ospf_snmp_iflist, node, nnode, osif))
1413 if (osif->ifp == ifp)
1415 list_delete_node (ospf_snmp_iflist, node);
1416 ospf_snmp_if_free (osif);
1417 return;
1422 void
1423 ospf_snmp_if_update (struct interface *ifp)
1425 struct listnode *node;
1426 struct listnode *pn;
1427 struct connected *ifc;
1428 struct prefix *p;
1429 struct ospf_snmp_if *osif;
1430 struct in_addr *addr;
1431 unsigned int ifindex;
1433 ospf_snmp_if_delete (ifp);
1435 p = NULL;
1436 addr = NULL;
1437 ifindex = 0;
1439 /* Lookup first IPv4 address entry. */
1440 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc))
1442 p = CONNECTED_ID(ifc);
1444 if (p->family == AF_INET)
1446 addr = &p->u.prefix4;
1447 break;
1450 if (! addr)
1451 ifindex = ifp->ifindex;
1453 /* Add interface to the list. */
1454 pn = NULL;
1455 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, node, osif))
1457 if (addr)
1459 /* Usual interfaces --> Sort them based on interface IPv4 addresses */
1460 if (ntohl (osif->addr.s_addr) > ntohl (addr->s_addr))
1461 break;
1463 else
1465 /* Unnumbered interfaces --> Sort them based on interface indexes */
1466 if (osif->addr.s_addr != 0 || osif->ifindex > ifindex)
1467 break;
1469 pn = node;
1472 osif = ospf_snmp_if_new ();
1473 if (addr) /* Usual interface */
1475 osif->addr = *addr;
1477 /* This field is used for storing ospfAddressLessIf OID value,
1478 * conform to RFC1850 OSPF-MIB specification, it must be 0 for
1479 * usual interface */
1480 osif->ifindex = 0;
1482 else /* Unnumbered interface */
1483 osif->ifindex = ifindex;
1484 osif->ifp = ifp;
1486 listnode_add_after (ospf_snmp_iflist, pn, osif);
1490 ospf_snmp_is_if_have_addr (struct interface *ifp)
1492 struct listnode *nn;
1493 struct connected *ifc;
1495 /* Is this interface having any connected IPv4 address ? */
1496 for (ALL_LIST_ELEMENTS_RO (ifp->connected, nn, ifc))
1498 if (CONNECTED_PREFIX(ifc)->family == AF_INET)
1499 return 1;
1502 return 0;
1505 struct ospf_interface *
1506 ospf_snmp_if_lookup (struct in_addr *ifaddr, unsigned int *ifindex)
1508 struct listnode *node;
1509 struct ospf_snmp_if *osif;
1510 struct ospf_interface *oi = NULL;
1511 struct ospf *ospf = ospf_lookup ();
1513 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, node, osif))
1515 if (ifaddr->s_addr)
1517 if (IPV4_ADDR_SAME (&osif->addr, ifaddr))
1518 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1520 else
1522 if (osif->ifindex == *ifindex)
1523 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1526 return oi;
1529 struct ospf_interface *
1530 ospf_snmp_if_lookup_next (struct in_addr *ifaddr, unsigned int *ifindex,
1531 int ifaddr_next, int ifindex_next)
1533 struct ospf_snmp_if *osif;
1534 struct listnode *nn;
1535 struct ospf *ospf = ospf_lookup ();
1536 struct ospf_interface *oi = NULL;
1538 if (ospf == NULL)
1539 return NULL;
1541 /* No instance is specified --> Return the first OSPF interface */
1542 if (ifaddr_next)
1544 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, nn, osif))
1546 osif = listgetdata (nn);
1547 *ifaddr = osif->addr;
1548 *ifindex = osif->ifindex;
1549 /* Because no instance is specified, we don't care about the kind of
1550 * interface (usual or unnumbered), just returning the first valid
1551 * OSPF interface */
1552 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1553 if (oi)
1554 return (oi);
1556 return NULL;
1559 /* An instance is specified --> Return the next OSPF interface */
1560 for (ALL_LIST_ELEMENTS_RO (ospf_snmp_iflist, nn, osif))
1562 /* Usual interface */
1563 if (ifaddr->s_addr)
1564 /* The interface must have valid AF_INET connected address */
1565 /* it must have lager IPv4 address value than the lookup entry */
1566 if ((ospf_snmp_is_if_have_addr(osif->ifp)) &&
1567 (ntohl (osif->addr.s_addr) > ntohl (ifaddr->s_addr)))
1569 *ifaddr = osif->addr;
1570 *ifindex = osif->ifindex;
1572 /* and it must be an OSPF interface */
1573 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1574 if (oi)
1575 return oi;
1577 /* Unnumbered interface */
1578 else
1579 /* The interface must NOT have valid AF_INET connected address */
1580 /* it must have lager interface index than the lookup entry */
1581 if ((!ospf_snmp_is_if_have_addr(osif->ifp)) &&
1582 (osif->ifindex > *ifindex))
1584 *ifaddr = osif->addr;
1585 *ifindex = osif->ifindex;
1587 /* and it must be an OSPF interface */
1588 oi = ospf_if_lookup_by_local_addr (ospf, osif->ifp, *ifaddr);
1589 if (oi)
1590 return oi;
1593 return NULL;
1597 ospf_snmp_iftype (struct interface *ifp)
1599 #define ospf_snmp_iftype_broadcast 1
1600 #define ospf_snmp_iftype_nbma 2
1601 #define ospf_snmp_iftype_pointToPoint 3
1602 #define ospf_snmp_iftype_pointToMultipoint 5
1603 if (if_is_broadcast (ifp))
1604 return ospf_snmp_iftype_broadcast;
1605 if (if_is_pointopoint (ifp))
1606 return ospf_snmp_iftype_pointToPoint;
1607 return ospf_snmp_iftype_broadcast;
1610 struct ospf_interface *
1611 ospfIfLookup (struct variable *v, oid *name, size_t *length,
1612 struct in_addr *ifaddr, unsigned int *ifindex, int exact)
1614 unsigned int len;
1615 int ifaddr_next = 0;
1616 int ifindex_next = 0;
1617 struct ospf_interface *oi;
1618 oid *offset;
1620 if (exact)
1622 if (*length != v->namelen + IN_ADDR_SIZE + 1)
1623 return NULL;
1625 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, ifaddr);
1626 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1628 return ospf_snmp_if_lookup (ifaddr, ifindex);
1630 else
1632 len = *length - v->namelen;
1633 if (len >= IN_ADDR_SIZE)
1634 len = IN_ADDR_SIZE;
1635 if (len <= 0)
1636 ifaddr_next = 1;
1638 oid2in_addr (name + v->namelen, len, ifaddr);
1640 len = *length - v->namelen - IN_ADDR_SIZE;
1641 if (len >= 1)
1642 len = 1;
1643 else
1644 ifindex_next = 1;
1646 if (len == 1)
1647 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1649 oi = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next,
1650 ifindex_next);
1651 if (oi)
1653 *length = v->namelen + IN_ADDR_SIZE + 1;
1654 offset = name + v->namelen;
1655 oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE);
1656 offset += IN_ADDR_SIZE;
1657 *offset = *ifindex;
1658 return oi;
1661 return NULL;
1664 static u_char *
1665 ospfIfEntry (struct variable *v, oid *name, size_t *length, int exact,
1666 size_t *var_len, WriteMethod **write_method)
1668 unsigned int ifindex;
1669 struct in_addr ifaddr;
1670 struct ospf_interface *oi;
1671 struct ospf *ospf;
1673 ifindex = 0;
1674 memset (&ifaddr, 0, sizeof (struct in_addr));
1676 /* Check OSPF instance. */
1677 ospf = ospf_lookup ();
1678 if (ospf == NULL)
1679 return NULL;
1681 oi = ospfIfLookup (v, name, length, &ifaddr, &ifindex, exact);
1682 if (oi == NULL)
1683 return NULL;
1685 /* Return the current value of the variable */
1686 switch (v->magic)
1688 case OSPFIFIPADDRESS: /* 1 */
1689 return SNMP_IPADDRESS (ifaddr);
1690 break;
1691 case OSPFADDRESSLESSIF: /* 2 */
1692 return SNMP_INTEGER (ifindex);
1693 break;
1694 case OSPFIFAREAID: /* 3 */
1695 if (oi->area)
1696 return SNMP_IPADDRESS (oi->area->area_id);
1697 else
1698 return SNMP_IPADDRESS (ospf_empty_addr);
1699 break;
1700 case OSPFIFTYPE: /* 4 */
1701 return SNMP_INTEGER (ospf_snmp_iftype (oi->ifp));
1702 break;
1703 case OSPFIFADMINSTAT: /* 5 */
1704 if (oi)
1705 return SNMP_INTEGER (OSPF_STATUS_ENABLED);
1706 else
1707 return SNMP_INTEGER (OSPF_STATUS_DISABLED);
1708 break;
1709 case OSPFIFRTRPRIORITY: /* 6 */
1710 return SNMP_INTEGER (PRIORITY (oi));
1711 break;
1712 case OSPFIFTRANSITDELAY: /* 7 */
1713 return SNMP_INTEGER (OSPF_IF_PARAM (oi, transmit_delay));
1714 break;
1715 case OSPFIFRETRANSINTERVAL: /* 8 */
1716 return SNMP_INTEGER (OSPF_IF_PARAM (oi, retransmit_interval));
1717 break;
1718 case OSPFIFHELLOINTERVAL: /* 9 */
1719 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_hello));
1720 break;
1721 case OSPFIFRTRDEADINTERVAL: /* 10 */
1722 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_wait));
1723 break;
1724 case OSPFIFPOLLINTERVAL: /* 11 */
1725 return SNMP_INTEGER (OSPF_POLL_INTERVAL_DEFAULT);
1726 break;
1727 case OSPFIFSTATE: /* 12 */
1728 return SNMP_INTEGER (ISM_SNMP(oi->state));
1729 break;
1730 case OSPFIFDESIGNATEDROUTER: /* 13 */
1731 return SNMP_IPADDRESS (DR (oi));
1732 break;
1733 case OSPFIFBACKUPDESIGNATEDROUTER: /* 14 */
1734 return SNMP_IPADDRESS (BDR (oi));
1735 break;
1736 case OSPFIFEVENTS: /* 15 */
1737 return SNMP_INTEGER (oi->state_change);
1738 break;
1739 case OSPFIFAUTHKEY: /* 16 */
1740 *var_len = 0;
1741 return (u_char *) OSPF_IF_PARAM (oi, auth_simple);
1742 break;
1743 case OSPFIFSTATUS: /* 17 */
1744 return SNMP_INTEGER (SNMP_VALID);
1745 break;
1746 case OSPFIFMULTICASTFORWARDING: /* 18 */
1747 #define ospf_snmp_multiforward_blocked 1
1748 #define ospf_snmp_multiforward_multicast 2
1749 #define ospf_snmp_multiforward_unicast 3
1750 return SNMP_INTEGER (ospf_snmp_multiforward_blocked);
1751 break;
1752 case OSPFIFDEMAND: /* 19 */
1753 return SNMP_INTEGER (SNMP_FALSE);
1754 break;
1755 case OSPFIFAUTHTYPE: /* 20 */
1756 if (oi->area)
1757 return SNMP_INTEGER (oi->area->auth_type);
1758 else
1759 return SNMP_INTEGER (0);
1760 break;
1761 default:
1762 return NULL;
1763 break;
1765 return NULL;
1768 #define OSPF_SNMP_METRIC_VALUE 1
1770 struct ospf_interface *
1771 ospfIfMetricLookup (struct variable *v, oid *name, size_t *length,
1772 struct in_addr *ifaddr, unsigned int *ifindex, int exact)
1774 unsigned int len;
1775 int ifaddr_next = 0;
1776 int ifindex_next = 0;
1777 struct ospf_interface *oi;
1778 oid *offset;
1779 int metric;
1781 if (exact)
1783 if (*length != v->namelen + IN_ADDR_SIZE + 1 + 1)
1784 return NULL;
1786 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, ifaddr);
1787 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1788 metric = name[v->namelen + IN_ADDR_SIZE + 1];
1790 if (metric != OSPF_SNMP_METRIC_VALUE)
1791 return NULL;
1793 return ospf_snmp_if_lookup (ifaddr, ifindex);
1795 else
1797 len = *length - v->namelen;
1798 if (len >= IN_ADDR_SIZE)
1799 len = IN_ADDR_SIZE;
1800 else
1801 ifaddr_next = 1;
1803 oid2in_addr (name + v->namelen, len, ifaddr);
1805 len = *length - v->namelen - IN_ADDR_SIZE;
1806 if (len >= 1)
1807 len = 1;
1808 else
1809 ifindex_next = 1;
1811 if (len == 1)
1812 *ifindex = name[v->namelen + IN_ADDR_SIZE];
1814 oi = ospf_snmp_if_lookup_next (ifaddr, ifindex, ifaddr_next,
1815 ifindex_next);
1816 if (oi)
1818 *length = v->namelen + IN_ADDR_SIZE + 1 + 1;
1819 offset = name + v->namelen;
1820 oid_copy_addr (offset, ifaddr, IN_ADDR_SIZE);
1821 offset += IN_ADDR_SIZE;
1822 *offset = *ifindex;
1823 offset++;
1824 *offset = OSPF_SNMP_METRIC_VALUE;
1825 return oi;
1828 return NULL;
1831 static u_char *
1832 ospfIfMetricEntry (struct variable *v, oid *name, size_t *length, int exact,
1833 size_t *var_len, WriteMethod **write_method)
1835 /* Currently we support metric 1 only. */
1836 unsigned int ifindex;
1837 struct in_addr ifaddr;
1838 struct ospf_interface *oi;
1839 struct ospf *ospf;
1841 ifindex = 0;
1842 memset (&ifaddr, 0, sizeof (struct in_addr));
1844 /* Check OSPF instance. */
1845 ospf = ospf_lookup ();
1846 if (ospf == NULL)
1847 return NULL;
1849 oi = ospfIfMetricLookup (v, name, length, &ifaddr, &ifindex, exact);
1850 if (oi == NULL)
1851 return NULL;
1853 /* Return the current value of the variable */
1854 switch (v->magic)
1856 case OSPFIFMETRICIPADDRESS:
1857 return SNMP_IPADDRESS (ifaddr);
1858 break;
1859 case OSPFIFMETRICADDRESSLESSIF:
1860 return SNMP_INTEGER (ifindex);
1861 break;
1862 case OSPFIFMETRICTOS:
1863 return SNMP_INTEGER (0);
1864 break;
1865 case OSPFIFMETRICVALUE:
1866 return SNMP_INTEGER (OSPF_SNMP_METRIC_VALUE);
1867 break;
1868 case OSPFIFMETRICSTATUS:
1869 return SNMP_INTEGER (1);
1870 break;
1871 default:
1872 return NULL;
1873 break;
1875 return NULL;
1878 struct route_table *ospf_snmp_vl_table;
1880 void
1881 ospf_snmp_vl_add (struct ospf_vl_data *vl_data)
1883 struct prefix_ls lp;
1884 struct route_node *rn;
1886 memset (&lp, 0, sizeof (struct prefix_ls));
1887 lp.family = 0;
1888 lp.prefixlen = 64;
1889 lp.id = vl_data->vl_area_id;
1890 lp.adv_router = vl_data->vl_peer;
1892 rn = route_node_get (ospf_snmp_vl_table, (struct prefix *) &lp);
1893 rn->info = vl_data;
1896 void
1897 ospf_snmp_vl_delete (struct ospf_vl_data *vl_data)
1899 struct prefix_ls lp;
1900 struct route_node *rn;
1902 memset (&lp, 0, sizeof (struct prefix_ls));
1903 lp.family = 0;
1904 lp.prefixlen = 64;
1905 lp.id = vl_data->vl_area_id;
1906 lp.adv_router = vl_data->vl_peer;
1908 rn = route_node_lookup (ospf_snmp_vl_table, (struct prefix *) &lp);
1909 if (! rn)
1910 return;
1911 rn->info = NULL;
1912 route_unlock_node (rn);
1913 route_unlock_node (rn);
1916 struct ospf_vl_data *
1917 ospf_snmp_vl_lookup (struct in_addr *area_id, struct in_addr *neighbor)
1919 struct prefix_ls lp;
1920 struct route_node *rn;
1921 struct ospf_vl_data *vl_data;
1923 memset (&lp, 0, sizeof (struct prefix_ls));
1924 lp.family = 0;
1925 lp.prefixlen = 64;
1926 lp.id = *area_id;
1927 lp.adv_router = *neighbor;
1929 rn = route_node_lookup (ospf_snmp_vl_table, (struct prefix *) &lp);
1930 if (rn)
1932 vl_data = rn->info;
1933 route_unlock_node (rn);
1934 return vl_data;
1936 return NULL;
1939 struct ospf_vl_data *
1940 ospf_snmp_vl_lookup_next (struct in_addr *area_id, struct in_addr *neighbor,
1941 int first)
1943 struct prefix_ls lp;
1944 struct route_node *rn;
1945 struct ospf_vl_data *vl_data;
1947 memset (&lp, 0, sizeof (struct prefix_ls));
1948 lp.family = 0;
1949 lp.prefixlen = 64;
1950 lp.id = *area_id;
1951 lp.adv_router = *neighbor;
1953 if (first)
1954 rn = route_top (ospf_snmp_vl_table);
1955 else
1957 rn = route_node_get (ospf_snmp_vl_table, (struct prefix *) &lp);
1958 rn = route_next (rn);
1961 for (; rn; rn = route_next (rn))
1962 if (rn->info)
1963 break;
1965 if (rn && rn->info)
1967 vl_data = rn->info;
1968 *area_id = vl_data->vl_area_id;
1969 *neighbor = vl_data->vl_peer;
1970 route_unlock_node (rn);
1971 return vl_data;
1973 return NULL;
1976 struct ospf_vl_data *
1977 ospfVirtIfLookup (struct variable *v, oid *name, size_t *length,
1978 struct in_addr *area_id, struct in_addr *neighbor, int exact)
1980 int first;
1981 unsigned int len;
1982 struct ospf_vl_data *vl_data;
1984 if (exact)
1986 if (*length != v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE)
1987 return NULL;
1989 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, area_id);
1990 oid2in_addr (name + v->namelen + IN_ADDR_SIZE, IN_ADDR_SIZE, neighbor);
1992 return ospf_snmp_vl_lookup (area_id, neighbor);
1994 else
1996 first = 0;
1998 len = *length - v->namelen;
1999 if (len <= 0)
2000 first = 1;
2001 if (len > IN_ADDR_SIZE)
2002 len = IN_ADDR_SIZE;
2003 oid2in_addr (name + v->namelen, len, area_id);
2005 len = *length - v->namelen - IN_ADDR_SIZE;
2006 if (len > IN_ADDR_SIZE)
2007 len = IN_ADDR_SIZE;
2008 oid2in_addr (name + v->namelen + IN_ADDR_SIZE, len, neighbor);
2010 vl_data = ospf_snmp_vl_lookup_next (area_id, neighbor, first);
2012 if (vl_data)
2014 *length = v->namelen + IN_ADDR_SIZE + IN_ADDR_SIZE;
2015 oid_copy_addr (name + v->namelen, area_id, IN_ADDR_SIZE);
2016 oid_copy_addr (name + v->namelen + IN_ADDR_SIZE, neighbor,
2017 IN_ADDR_SIZE);
2018 return vl_data;
2021 return NULL;
2024 static u_char *
2025 ospfVirtIfEntry (struct variable *v, oid *name, size_t *length, int exact,
2026 size_t *var_len, WriteMethod **write_method)
2028 struct ospf_vl_data *vl_data;
2029 struct ospf_interface *oi;
2030 struct in_addr area_id;
2031 struct in_addr neighbor;
2033 memset (&area_id, 0, sizeof (struct in_addr));
2034 memset (&neighbor, 0, sizeof (struct in_addr));
2036 vl_data = ospfVirtIfLookup (v, name, length, &area_id, &neighbor, exact);
2037 if (! vl_data)
2038 return NULL;
2039 oi = vl_data->vl_oi;
2040 if (! oi)
2041 return NULL;
2043 /* Return the current value of the variable */
2044 switch (v->magic)
2046 case OSPFVIRTIFAREAID:
2047 return SNMP_IPADDRESS (area_id);
2048 break;
2049 case OSPFVIRTIFNEIGHBOR:
2050 return SNMP_IPADDRESS (neighbor);
2051 break;
2052 case OSPFVIRTIFTRANSITDELAY:
2053 return SNMP_INTEGER (OSPF_IF_PARAM (oi, transmit_delay));
2054 break;
2055 case OSPFVIRTIFRETRANSINTERVAL:
2056 return SNMP_INTEGER (OSPF_IF_PARAM (oi, retransmit_interval));
2057 break;
2058 case OSPFVIRTIFHELLOINTERVAL:
2059 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_hello));
2060 break;
2061 case OSPFVIRTIFRTRDEADINTERVAL:
2062 return SNMP_INTEGER (OSPF_IF_PARAM (oi, v_wait));
2063 break;
2064 case OSPFVIRTIFSTATE:
2065 return SNMP_INTEGER (oi->state);
2066 break;
2067 case OSPFVIRTIFEVENTS:
2068 return SNMP_INTEGER (oi->state_change);
2069 break;
2070 case OSPFVIRTIFAUTHKEY:
2071 *var_len = 0;
2072 return (u_char *) OSPF_IF_PARAM (oi, auth_simple);
2073 break;
2074 case OSPFVIRTIFSTATUS:
2075 return SNMP_INTEGER (SNMP_VALID);
2076 break;
2077 case OSPFVIRTIFAUTHTYPE:
2078 if (oi->area)
2079 return SNMP_INTEGER (oi->area->auth_type);
2080 else
2081 return SNMP_INTEGER (0);
2082 break;
2083 default:
2084 return NULL;
2085 break;
2087 return NULL;
2090 struct ospf_neighbor *
2091 ospf_snmp_nbr_lookup (struct ospf *ospf, struct in_addr *nbr_addr,
2092 unsigned int *ifindex)
2094 struct listnode *node, *nnode;
2095 struct ospf_interface *oi;
2096 struct ospf_neighbor *nbr;
2097 struct route_node *rn;
2099 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
2101 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2102 if ((nbr = rn->info) != NULL
2103 && nbr != oi->nbr_self
2104 /* If EXACT match is needed, provide ALL entry found
2105 && nbr->state != NSM_Down
2107 && nbr->src.s_addr != 0)
2109 if (IPV4_ADDR_SAME (&nbr->src, nbr_addr))
2111 route_unlock_node (rn);
2112 return nbr;
2116 return NULL;
2119 struct ospf_neighbor *
2120 ospf_snmp_nbr_lookup_next (struct in_addr *nbr_addr, unsigned int *ifindex,
2121 int first)
2123 struct listnode *nn;
2124 struct ospf_interface *oi;
2125 struct ospf_neighbor *nbr;
2126 struct route_node *rn;
2127 struct ospf_neighbor *min = NULL;
2128 struct ospf *ospf = ospf;
2130 ospf = ospf_lookup ();
2132 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, nn, oi))
2134 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2135 if ((nbr = rn->info) != NULL
2136 && nbr != oi->nbr_self
2137 && nbr->state != NSM_Down
2138 && nbr->src.s_addr != 0)
2140 if (first)
2142 if (! min)
2143 min = nbr;
2144 else if (ntohl (nbr->src.s_addr) < ntohl (min->src.s_addr))
2145 min = nbr;
2147 else if (ntohl (nbr->src.s_addr) > ntohl (nbr_addr->s_addr))
2149 if (! min)
2150 min = nbr;
2151 else if (ntohl (nbr->src.s_addr) < ntohl (min->src.s_addr))
2152 min = nbr;
2156 if (min)
2158 *nbr_addr = min->src;
2159 *ifindex = 0;
2160 return min;
2162 return NULL;
2165 struct ospf_neighbor *
2166 ospfNbrLookup (struct variable *v, oid *name, size_t *length,
2167 struct in_addr *nbr_addr, unsigned int *ifindex, int exact)
2169 unsigned int len;
2170 int first;
2171 struct ospf_neighbor *nbr;
2172 struct ospf *ospf;
2174 ospf = ospf_lookup ();
2176 if (! ospf)
2177 return NULL;
2179 if (exact)
2181 if (*length != v->namelen + IN_ADDR_SIZE + 1)
2182 return NULL;
2184 oid2in_addr (name + v->namelen, IN_ADDR_SIZE, nbr_addr);
2185 *ifindex = name[v->namelen + IN_ADDR_SIZE];
2187 return ospf_snmp_nbr_lookup (ospf, nbr_addr, ifindex);
2189 else
2191 first = 0;
2192 len = *length - v->namelen;
2194 if (len <= 0)
2195 first = 1;
2197 if (len > IN_ADDR_SIZE)
2198 len = IN_ADDR_SIZE;
2200 oid2in_addr (name + v->namelen, len, nbr_addr);
2202 len = *length - v->namelen - IN_ADDR_SIZE;
2203 if (len >= 1)
2204 *ifindex = name[v->namelen + IN_ADDR_SIZE];
2206 nbr = ospf_snmp_nbr_lookup_next (nbr_addr, ifindex, first);
2208 if (nbr)
2210 *length = v->namelen + IN_ADDR_SIZE + 1;
2211 oid_copy_addr (name + v->namelen, nbr_addr, IN_ADDR_SIZE);
2212 name[v->namelen + IN_ADDR_SIZE] = *ifindex;
2213 return nbr;
2216 return NULL;
2219 /* map internal quagga neighbor states to official MIB values:
2221 ospfNbrState OBJECT-TYPE
2222 SYNTAX INTEGER {
2223 down (1),
2224 attempt (2),
2225 init (3),
2226 twoWay (4),
2227 exchangeStart (5),
2228 exchange (6),
2229 loading (7),
2230 full (8)
2233 static int32_t
2234 ospf_snmp_neighbor_state(u_char nst)
2236 switch (nst)
2238 case NSM_Attempt:
2239 return 2;
2240 case NSM_Init:
2241 return 3;
2242 case NSM_TwoWay:
2243 return 4;
2244 case NSM_ExStart:
2245 return 5;
2246 case NSM_Exchange:
2247 return 6;
2248 case NSM_Loading:
2249 return 7;
2250 case NSM_Full:
2251 return 8;
2252 default:
2253 return 1; /* down */
2257 static u_char *
2258 ospfNbrEntry (struct variable *v, oid *name, size_t *length, int exact,
2259 size_t *var_len, WriteMethod **write_method)
2261 struct in_addr nbr_addr;
2262 unsigned int ifindex;
2263 struct ospf_neighbor *nbr;
2264 struct ospf_interface *oi;
2266 memset (&nbr_addr, 0, sizeof (struct in_addr));
2267 ifindex = 0;
2269 nbr = ospfNbrLookup (v, name, length, &nbr_addr, &ifindex, exact);
2270 if (! nbr)
2271 return NULL;
2272 oi = nbr->oi;
2273 if (! oi)
2274 return NULL;
2276 /* Return the current value of the variable */
2277 switch (v->magic)
2279 case OSPFNBRIPADDR:
2280 return SNMP_IPADDRESS (nbr_addr);
2281 break;
2282 case OSPFNBRADDRESSLESSINDEX:
2283 return SNMP_INTEGER (ifindex);
2284 break;
2285 case OSPFNBRRTRID:
2286 return SNMP_IPADDRESS (nbr->router_id);
2287 break;
2288 case OSPFNBROPTIONS:
2289 return SNMP_INTEGER (oi->nbr_self->options);
2290 break;
2291 case OSPFNBRPRIORITY:
2292 return SNMP_INTEGER (nbr->priority);
2293 break;
2294 case OSPFNBRSTATE:
2295 return SNMP_INTEGER (ospf_snmp_neighbor_state(nbr->state));
2296 break;
2297 case OSPFNBREVENTS:
2298 return SNMP_INTEGER (nbr->state_change);
2299 break;
2300 case OSPFNBRLSRETRANSQLEN:
2301 return SNMP_INTEGER (ospf_ls_retransmit_count (nbr));
2302 break;
2303 case OSPFNBMANBRSTATUS:
2304 return SNMP_INTEGER (SNMP_VALID);
2305 break;
2306 case OSPFNBMANBRPERMANENCE:
2307 return SNMP_INTEGER (2);
2308 break;
2309 case OSPFNBRHELLOSUPPRESSED:
2310 return SNMP_INTEGER (SNMP_FALSE);
2311 break;
2312 default:
2313 return NULL;
2314 break;
2316 return NULL;
2319 static u_char *
2320 ospfVirtNbrEntry (struct variable *v, oid *name, size_t *length, int exact,
2321 size_t *var_len, WriteMethod **write_method)
2323 struct ospf_vl_data *vl_data;
2324 struct in_addr area_id;
2325 struct in_addr neighbor;
2326 struct ospf *ospf;
2328 memset (&area_id, 0, sizeof (struct in_addr));
2329 memset (&neighbor, 0, sizeof (struct in_addr));
2331 /* Check OSPF instance. */
2332 ospf = ospf_lookup ();
2333 if (ospf == NULL)
2334 return NULL;
2336 vl_data = ospfVirtIfLookup (v, name, length, &area_id, &neighbor, exact);
2337 if (! vl_data)
2338 return NULL;
2340 /* Return the current value of the variable */
2341 switch (v->magic)
2343 case OSPFVIRTNBRAREA:
2344 return (u_char *) NULL;
2345 break;
2346 case OSPFVIRTNBRRTRID:
2347 return (u_char *) NULL;
2348 break;
2349 case OSPFVIRTNBRIPADDR:
2350 return (u_char *) NULL;
2351 break;
2352 case OSPFVIRTNBROPTIONS:
2353 return (u_char *) NULL;
2354 break;
2355 case OSPFVIRTNBRSTATE:
2356 return (u_char *) NULL;
2357 break;
2358 case OSPFVIRTNBREVENTS:
2359 return (u_char *) NULL;
2360 break;
2361 case OSPFVIRTNBRLSRETRANSQLEN:
2362 return (u_char *) NULL;
2363 break;
2364 case OSPFVIRTNBRHELLOSUPPRESSED:
2365 return (u_char *) NULL;
2366 break;
2367 default:
2368 return NULL;
2369 break;
2371 return NULL;
2374 struct ospf_lsa *
2375 ospfExtLsdbLookup (struct variable *v, oid *name, size_t *length, u_char *type,
2376 struct in_addr *ls_id, struct in_addr *router_id, int exact)
2378 int first;
2379 oid *offset;
2380 int offsetlen;
2381 u_char lsa_type;
2382 unsigned int len;
2383 struct ospf_lsa *lsa;
2384 struct ospf *ospf;
2386 ospf = ospf_lookup ();
2387 if (exact)
2389 if (*length != v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
2390 return NULL;
2392 offset = name + v->namelen;
2394 /* Make it sure given value match to type. */
2395 lsa_type = *offset;
2396 offset++;
2398 if (lsa_type != *type)
2399 return NULL;
2401 /* LS ID. */
2402 oid2in_addr (offset, IN_ADDR_SIZE, ls_id);
2403 offset += IN_ADDR_SIZE;
2405 /* Router ID. */
2406 oid2in_addr (offset, IN_ADDR_SIZE, router_id);
2408 return ospf_lsdb_lookup_by_id (ospf->lsdb, *type, *ls_id, *router_id);
2410 else
2412 /* Get variable length. */
2413 first = 0;
2414 offset = name + v->namelen;
2415 offsetlen = *length - v->namelen;
2417 /* LSA type value. */
2418 lsa_type = *offset;
2419 offset++;
2420 offsetlen--;
2422 if (offsetlen <= 0 || lsa_type < OSPF_AS_EXTERNAL_LSA)
2423 first = 1;
2425 /* LS ID. */
2426 len = offsetlen;
2427 if (len > IN_ADDR_SIZE)
2428 len = IN_ADDR_SIZE;
2430 oid2in_addr (offset, len, ls_id);
2432 offset += IN_ADDR_SIZE;
2433 offsetlen -= IN_ADDR_SIZE;
2435 /* Router ID. */
2436 len = offsetlen;
2437 if (len > IN_ADDR_SIZE)
2438 len = IN_ADDR_SIZE;
2440 oid2in_addr (offset, len, router_id);
2442 lsa = ospf_lsdb_lookup_by_id_next (ospf->lsdb, *type, *ls_id,
2443 *router_id, first);
2445 if (lsa)
2447 /* Fill in length. */
2448 *length = v->namelen + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE;
2450 /* Fill in value. */
2451 offset = name + v->namelen;
2453 *offset = OSPF_AS_EXTERNAL_LSA;
2454 offset++;
2455 oid_copy_addr (offset, &lsa->data->id, IN_ADDR_SIZE);
2456 offset += IN_ADDR_SIZE;
2457 oid_copy_addr (offset, &lsa->data->adv_router, IN_ADDR_SIZE);
2459 return lsa;
2462 return NULL;
2465 static u_char *
2466 ospfExtLsdbEntry (struct variable *v, oid *name, size_t *length, int exact,
2467 size_t *var_len, WriteMethod **write_method)
2469 struct ospf_lsa *lsa;
2470 struct lsa_header *lsah;
2471 u_char type;
2472 struct in_addr ls_id;
2473 struct in_addr router_id;
2474 struct ospf *ospf;
2476 type = OSPF_AS_EXTERNAL_LSA;
2477 memset (&ls_id, 0, sizeof (struct in_addr));
2478 memset (&router_id, 0, sizeof (struct in_addr));
2480 /* Check OSPF instance. */
2481 ospf = ospf_lookup ();
2482 if (ospf == NULL)
2483 return NULL;
2485 lsa = ospfExtLsdbLookup (v, name, length, &type, &ls_id, &router_id, exact);
2486 if (! lsa)
2487 return NULL;
2489 lsah = lsa->data;
2491 /* Return the current value of the variable */
2492 switch (v->magic)
2494 case OSPFEXTLSDBTYPE:
2495 return SNMP_INTEGER (OSPF_AS_EXTERNAL_LSA);
2496 break;
2497 case OSPFEXTLSDBLSID:
2498 return SNMP_IPADDRESS (lsah->id);
2499 break;
2500 case OSPFEXTLSDBROUTERID:
2501 return SNMP_IPADDRESS (lsah->adv_router);
2502 break;
2503 case OSPFEXTLSDBSEQUENCE:
2504 return SNMP_INTEGER (lsah->ls_seqnum);
2505 break;
2506 case OSPFEXTLSDBAGE:
2507 return SNMP_INTEGER (lsah->ls_age);
2508 break;
2509 case OSPFEXTLSDBCHECKSUM:
2510 return SNMP_INTEGER (lsah->checksum);
2511 break;
2512 case OSPFEXTLSDBADVERTISEMENT:
2513 *var_len = ntohs (lsah->length);
2514 return (u_char *) lsah;
2515 break;
2516 default:
2517 return NULL;
2518 break;
2520 return NULL;
2523 static u_char *
2524 ospfAreaAggregateEntry (struct variable *v, oid *name, size_t *length,
2525 int exact, size_t *var_len, WriteMethod **write_method)
2527 /* Return the current value of the variable */
2528 switch (v->magic)
2530 case OSPFAREAAGGREGATEAREAID:
2531 return (u_char *) NULL;
2532 break;
2533 case OSPFAREAAGGREGATELSDBTYPE:
2534 return (u_char *) NULL;
2535 break;
2536 case OSPFAREAAGGREGATENET:
2537 return (u_char *) NULL;
2538 break;
2539 case OSPFAREAAGGREGATEMASK:
2540 return (u_char *) NULL;
2541 break;
2542 case OSPFAREAAGGREGATESTATUS:
2543 return (u_char *) NULL;
2544 break;
2545 case OSPFAREAAGGREGATEEFFECT:
2546 return (u_char *) NULL;
2547 break;
2548 default:
2549 return NULL;
2550 break;
2552 return NULL;
2555 /* OSPF Traps. */
2556 #define IFSTATECHANGE 16
2557 #define VIRTIFSTATECHANGE 1
2558 #define NBRSTATECHANGE 2
2559 #define VIRTNBRSTATECHANGE 3
2561 struct trap_object ospfNbrTrapList[] =
2563 {ospfGeneralGroup, -2, {1, OSPFROUTERID}},
2564 {ospfNbrEntry, 3, {10, 1, OSPFNBRIPADDR}},
2565 {ospfNbrEntry, 3, {10, 1, OSPFNBRRTRID}},
2566 {ospfNbrEntry, 3, {10, 1, OSPFNBRSTATE}}
2570 struct trap_object ospfVirtNbrTrapList[] =
2572 {ospfGeneralGroup, -2, {1, 1}},
2573 {ospfVirtNbrEntry, 3, {11, 1, OSPFVIRTNBRAREA}},
2574 {ospfVirtNbrEntry, 3, {11, 1, OSPFVIRTNBRRTRID}},
2575 {ospfVirtNbrEntry, 3, {11, 1, OSPFVIRTNBRSTATE}}
2578 struct trap_object ospfIfTrapList[] =
2580 {ospfGeneralGroup, -2, {1, OSPFROUTERID}},
2581 {ospfIfEntry, 3, {7, 1, OSPFIFIPADDRESS}},
2582 {ospfIfEntry, 3, {7, 1, OSPFADDRESSLESSIF}},
2583 {ospfIfEntry, 3, {7, 1, OSPFIFSTATE}}
2586 struct trap_object ospfVirtIfTrapList[] =
2588 {ospfGeneralGroup, -2, {1, OSPFROUTERID}},
2589 {ospfVirtIfEntry, 3, {9, 1, OSPFVIRTIFAREAID}},
2590 {ospfVirtIfEntry, 3, {9, 1, OSPFVIRTIFNEIGHBOR}},
2591 {ospfVirtIfEntry, 3, {9, 1, OSPFVIRTIFSTATE}}
2594 void
2595 ospfTrapNbrStateChange (struct ospf_neighbor *on)
2597 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
2598 char msgbuf[16];
2600 ospf_nbr_state_message(on, msgbuf, sizeof(msgbuf));
2601 zlog (NULL, LOG_INFO, "ospfTrapNbrStateChange trap sent: %s now %s",
2602 inet_ntoa(on->address.u.prefix4), msgbuf);
2604 oid_copy_addr (index, &(on->address.u.prefix4), IN_ADDR_SIZE);
2605 index[IN_ADDR_SIZE] = 0;
2607 smux_trap (ospf_oid, sizeof ospf_oid / sizeof (oid),
2608 index, IN_ADDR_SIZE + 1,
2609 ospfNbrTrapList,
2610 sizeof ospfNbrTrapList / sizeof (struct trap_object),
2611 time (NULL), NBRSTATECHANGE);
2614 void
2615 ospfTrapVirtNbrStateChange (struct ospf_neighbor *on)
2617 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
2619 zlog (NULL, LOG_INFO, "ospfTrapVirtNbrStateChange trap sent");
2621 oid_copy_addr (index, &(on->address.u.prefix4), IN_ADDR_SIZE);
2622 index[IN_ADDR_SIZE] = 0;
2624 smux_trap (ospf_oid, sizeof ospf_oid / sizeof (oid),
2625 index, IN_ADDR_SIZE + 1,
2626 ospfVirtNbrTrapList,
2627 sizeof ospfVirtNbrTrapList / sizeof (struct trap_object),
2628 time (NULL), VIRTNBRSTATECHANGE);
2631 void
2632 ospfTrapIfStateChange (struct ospf_interface *oi)
2634 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
2636 zlog (NULL, LOG_INFO, "ospfTrapIfStateChange trap sent: %s now %s",
2637 inet_ntoa(oi->address->u.prefix4),
2638 LOOKUP(ospf_ism_state_msg, oi->state));
2640 oid_copy_addr (index, &(oi->address->u.prefix4), IN_ADDR_SIZE);
2641 index[IN_ADDR_SIZE] = 0;
2643 smux_trap (ospf_oid, sizeof ospf_oid / sizeof (oid),
2644 index, IN_ADDR_SIZE + 1,
2645 ospfIfTrapList,
2646 sizeof ospfIfTrapList / sizeof (struct trap_object),
2647 time (NULL), IFSTATECHANGE);
2650 void
2651 ospfTrapVirtIfStateChange (struct ospf_interface *oi)
2653 oid index[sizeof (oid) * (IN_ADDR_SIZE + 1)];
2655 zlog (NULL, LOG_INFO, "ospfTrapVirtIfStateChange trap sent");
2657 oid_copy_addr (index, &(oi->address->u.prefix4), IN_ADDR_SIZE);
2658 index[IN_ADDR_SIZE] = 0;
2660 smux_trap (ospf_oid, sizeof ospf_oid / sizeof (oid),
2661 index, IN_ADDR_SIZE + 1,
2662 ospfVirtIfTrapList,
2663 sizeof ospfVirtIfTrapList / sizeof (struct trap_object),
2664 time (NULL), VIRTIFSTATECHANGE);
2666 /* Register OSPF2-MIB. */
2667 void
2668 ospf_snmp_init ()
2670 ospf_snmp_iflist = list_new ();
2671 ospf_snmp_vl_table = route_table_init ();
2672 smux_init (om->master);
2673 REGISTER_MIB("mibII/ospf", ospf_variables, variable, ospf_oid);
2675 #endif /* HAVE_SNMP */