build: Add QuaggaId to README.NetBSD
[jleu-quagga.git] / ospf6d / ospf6_snmp.c
blob5ac7846d2247701033f8637d6af0bc98abbb0668
1 /* OSPFv3 SNMP support
2 * Copyright (C) 2004 Yasuhiro Ohara
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
22 #include <zebra.h>
24 #ifdef HAVE_SNMP
26 #ifdef HAVE_NETSNMP
27 #include <net-snmp/net-snmp-config.h>
28 #include <net-snmp/net-snmp-includes.h>
29 #else
30 #include <asn1.h>
31 #include <snmp.h>
32 #include <snmp_impl.h>
33 #endif
35 #include "log.h"
36 #include "vty.h"
37 #include "linklist.h"
38 #include "smux.h"
40 #include "ospf6_proto.h"
41 #include "ospf6_lsa.h"
42 #include "ospf6_lsdb.h"
43 #include "ospf6_route.h"
44 #include "ospf6_top.h"
45 #include "ospf6_area.h"
46 #include "ospf6_interface.h"
47 #include "ospf6_message.h"
48 #include "ospf6_neighbor.h"
49 #include "ospf6d.h"
50 #include "ospf6_snmp.h"
52 /* OSPFv3-MIB */
53 #define OSPFv3MIB 1,3,6,1,3,102
55 /* OSPFv3 MIB General Group values. */
56 #define OSPFv3ROUTERID 1
57 #define OSPFv3ADMINSTAT 2
58 #define OSPFv3VERSIONNUMBER 3
59 #define OSPFv3AREABDRRTRSTATUS 4
60 #define OSPFv3ASBDRRTRSTATUS 5
61 #define OSPFv3ASSCOPELSACOUNT 6
62 #define OSPFv3ASSCOPELSACHECKSUMSUM 7
63 #define OSPFv3ORIGINATENEWLSAS 8
64 #define OSPFv3RXNEWLSAS 9
65 #define OSPFv3EXTLSACOUNT 10
66 #define OSPFv3EXTAREALSDBLIMIT 11
67 #define OSPFv3MULTICASTEXTENSIONS 12
68 #define OSPFv3EXITOVERFLOWINTERVAL 13
69 #define OSPFv3DEMANDEXTENSIONS 14
70 #define OSPFv3TRAFFICENGINEERINGSUPPORT 15
71 #define OSPFv3REFERENCEBANDWIDTH 16
72 #define OSPFv3RESTARTSUPPORT 17
73 #define OSPFv3RESTARTINTERVAL 18
74 #define OSPFv3RESTARTSTATUS 19
75 #define OSPFv3RESTARTAGE 20
76 #define OSPFv3RESTARTEXITREASON 21
78 /* OSPFv3 MIB Area Table values. */
79 #define OSPFv3AREAID 1
80 #define OSPFv3IMPORTASEXTERN 2
81 #define OSPFv3AREASPFRUNS 3
82 #define OSPFv3AREABDRRTRCOUNT 4
83 #define OSPFv3AREAASBDRRTRCOUNT 5
84 #define OSPFv3AREASCOPELSACOUNT 6
85 #define OSPFv3AREASCOPELSACKSUMSUM 7
86 #define OSPFv3AREASUMMARY 8
87 #define OSPFv3AREASTATUS 9
88 #define OSPFv3STUBMETRIC 10
89 #define OSPFv3AREANSSATRANSLATORROLE 11
90 #define OSPFv3AREANSSATRANSLATORSTATE 12
91 #define OSPFv3AREANSSATRANSLATORSTABILITYINTERVAL 13
92 #define OSPFv3AREANSSATRANSLATOREVENTS 14
93 #define OSPFv3AREASTUBMETRICTYPE 15
95 /* OSPFv3 MIB Area Lsdb Table values. */
96 #define OSPFv3AREALSDBAREAID 1
97 #define OSPFv3AREALSDBTYPE 2
98 #define OSPFv3AREALSDBROUTERID 3
99 #define OSPFv3AREALSDBLSID 4
100 #define OSPFv3AREALSDBSEQUENCE 5
101 #define OSPFv3AREALSDBAGE 6
102 #define OSPFv3AREALSDBCHECKSUM 7
103 #define OSPFv3AREALSDBADVERTISEMENT 8
104 #define OSPFv3AREALSDBTYPEKNOWN 9
106 /* SYNTAX Status from OSPF-MIB. */
107 #define OSPF_STATUS_ENABLED 1
108 #define OSPF_STATUS_DISABLED 2
110 /* SNMP value hack. */
111 #define COUNTER ASN_COUNTER
112 #define INTEGER ASN_INTEGER
113 #define GAUGE ASN_GAUGE
114 #define TIMETICKS ASN_TIMETICKS
115 #define IPADDRESS ASN_IPADDRESS
116 #define STRING ASN_OCTET_STR
118 /* For return values e.g. SNMP_INTEGER macro */
119 SNMP_LOCAL_VARIABLES
121 static struct in_addr tmp;
122 #define INT32_INADDR(x) \
123 (tmp.s_addr = (x), tmp)
125 /* OSPFv3-MIB instances. */
126 oid ospfv3_oid [] = { OSPFv3MIB };
128 /* empty ID 0.0.0.0 e.g. empty router-id */
129 static struct in_addr ospf6_empty_id = {0};
131 /* Hook functions. */
132 static u_char *ospfv3GeneralGroup (struct variable *, oid *, size_t *,
133 int, size_t *, WriteMethod **);
134 static u_char *ospfv3AreaEntry (struct variable *, oid *, size_t *,
135 int, size_t *, WriteMethod **);
136 static u_char *ospfv3AreaLsdbEntry (struct variable *, oid *, size_t *,
137 int, size_t *, WriteMethod **);
139 struct variable ospfv3_variables[] =
141 /* OSPF general variables */
142 {OSPFv3ROUTERID, IPADDRESS, RWRITE, ospfv3GeneralGroup,
143 3, {1, 1, 1}},
144 {OSPFv3ADMINSTAT, INTEGER, RWRITE, ospfv3GeneralGroup,
145 3, {1, 1, 2}},
146 {OSPFv3VERSIONNUMBER, INTEGER, RONLY, ospfv3GeneralGroup,
147 3, {1, 1, 3}},
148 {OSPFv3AREABDRRTRSTATUS, INTEGER, RONLY, ospfv3GeneralGroup,
149 3, {1, 1, 4}},
150 {OSPFv3ASBDRRTRSTATUS, INTEGER, RWRITE, ospfv3GeneralGroup,
151 3, {1, 1, 5}},
152 {OSPFv3ASSCOPELSACOUNT, GAUGE, RONLY, ospfv3GeneralGroup,
153 3, {1, 1, 6}},
154 {OSPFv3ASSCOPELSACHECKSUMSUM, INTEGER, RONLY, ospfv3GeneralGroup,
155 3, {1, 1, 7}},
156 {OSPFv3ORIGINATENEWLSAS, COUNTER, RONLY, ospfv3GeneralGroup,
157 3, {1, 1, 8}},
158 {OSPFv3RXNEWLSAS, COUNTER, RONLY, ospfv3GeneralGroup,
159 3, {1, 1, 9}},
160 {OSPFv3EXTLSACOUNT, GAUGE, RONLY, ospfv3GeneralGroup,
161 3, {1, 1, 10}},
162 {OSPFv3EXTAREALSDBLIMIT, INTEGER, RWRITE, ospfv3GeneralGroup,
163 3, {1, 1, 11}},
164 {OSPFv3MULTICASTEXTENSIONS, INTEGER, RWRITE, ospfv3GeneralGroup,
165 3, {1, 1, 12}},
166 {OSPFv3EXITOVERFLOWINTERVAL, INTEGER, RWRITE, ospfv3GeneralGroup,
167 3, {1, 1, 13}},
168 {OSPFv3DEMANDEXTENSIONS, INTEGER, RWRITE, ospfv3GeneralGroup,
169 3, {1, 1, 14}},
170 {OSPFv3TRAFFICENGINEERINGSUPPORT, INTEGER, RWRITE, ospfv3GeneralGroup,
171 3, {1, 1, 15}},
172 {OSPFv3REFERENCEBANDWIDTH, INTEGER, RWRITE, ospfv3GeneralGroup,
173 3, {1, 1, 16}},
174 {OSPFv3RESTARTSUPPORT, INTEGER, RWRITE, ospfv3GeneralGroup,
175 3, {1, 1, 17}},
176 {OSPFv3RESTARTINTERVAL, INTEGER, RWRITE, ospfv3GeneralGroup,
177 3, {1, 1, 18}},
178 {OSPFv3RESTARTSTATUS, INTEGER, RONLY, ospfv3GeneralGroup,
179 3, {1, 1, 19}},
180 {OSPFv3RESTARTAGE, INTEGER, RONLY, ospfv3GeneralGroup,
181 3, {1, 1, 20}},
182 {OSPFv3RESTARTEXITREASON, INTEGER, RONLY, ospfv3GeneralGroup,
183 3, {1, 1, 21}},
185 /* OSPFv3 Area Data Structure */
186 {OSPFv3AREAID, IPADDRESS, RONLY, ospfv3AreaEntry,
187 4, {1, 2, 1, 1}},
188 {OSPFv3IMPORTASEXTERN, INTEGER, RWRITE, ospfv3AreaEntry,
189 4, {1, 2, 1, 2}},
190 {OSPFv3AREASPFRUNS, COUNTER, RONLY, ospfv3AreaEntry,
191 4, {1, 2, 1, 3}},
192 {OSPFv3AREABDRRTRCOUNT, GAUGE, RONLY, ospfv3AreaEntry,
193 4, {1, 2, 1, 4}},
194 {OSPFv3AREAASBDRRTRCOUNT, GAUGE, RONLY, ospfv3AreaEntry,
195 4, {1, 2, 1, 5}},
196 {OSPFv3AREASCOPELSACOUNT, GAUGE, RONLY, ospfv3AreaEntry,
197 4, {1, 2, 1, 6}},
198 {OSPFv3AREASCOPELSACKSUMSUM, INTEGER, RONLY, ospfv3AreaEntry,
199 4, {1, 2, 1, 7}},
200 {OSPFv3AREASUMMARY, INTEGER, RWRITE, ospfv3AreaEntry,
201 4, {1, 2, 1, 8}},
202 {OSPFv3AREASTATUS, INTEGER, RWRITE, ospfv3AreaEntry,
203 4, {1, 2, 1, 9}},
204 {OSPFv3STUBMETRIC, INTEGER, RWRITE, ospfv3AreaEntry,
205 4, {1, 2, 1, 10}},
206 {OSPFv3AREANSSATRANSLATORROLE, INTEGER, RWRITE, ospfv3AreaEntry,
207 4, {1, 2, 1, 11}},
208 {OSPFv3AREANSSATRANSLATORSTATE, INTEGER, RONLY, ospfv3AreaEntry,
209 4, {1, 2, 1, 12}},
210 {OSPFv3AREANSSATRANSLATORSTABILITYINTERVAL, INTEGER, RWRITE, ospfv3AreaEntry,
211 4, {1, 2, 1, 13}},
212 {OSPFv3AREANSSATRANSLATOREVENTS, COUNTER, RONLY, ospfv3AreaEntry,
213 4, {1, 2, 1, 14}},
214 {OSPFv3AREASTUBMETRICTYPE, INTEGER, RWRITE, ospfv3AreaEntry,
215 4, {1, 2, 1, 15}},
217 {OSPFv3AREALSDBAREAID, IPADDRESS, RONLY, ospfv3AreaLsdbEntry,
218 4, {1, 4, 1, 1}},
219 {OSPFv3AREALSDBTYPE, GAUGE, RONLY, ospfv3AreaLsdbEntry,
220 4, {1, 4, 1, 2}},
221 {OSPFv3AREALSDBROUTERID, IPADDRESS, RONLY, ospfv3AreaLsdbEntry,
222 4, {1, 4, 1, 3}},
223 {OSPFv3AREALSDBLSID, IPADDRESS, RONLY, ospfv3AreaLsdbEntry,
224 4, {1, 4, 1, 4}},
225 {OSPFv3AREALSDBSEQUENCE, INTEGER, RONLY, ospfv3AreaLsdbEntry,
226 4, {1, 4, 1, 5}},
227 {OSPFv3AREALSDBAGE, INTEGER, RONLY, ospfv3AreaLsdbEntry,
228 4, {1, 4, 1, 6}},
229 {OSPFv3AREALSDBCHECKSUM, INTEGER, RONLY, ospfv3AreaLsdbEntry,
230 4, {1, 4, 1, 7}},
231 {OSPFv3AREALSDBADVERTISEMENT, STRING, RONLY, ospfv3AreaLsdbEntry,
232 4, {1, 4, 1, 8}},
233 {OSPFv3AREALSDBTYPEKNOWN, INTEGER, RONLY, ospfv3AreaLsdbEntry,
234 4, {1, 4, 1, 9}},
238 static u_char *
239 ospfv3GeneralGroup (struct variable *v, oid *name, size_t *length,
240 int exact, size_t *var_len, WriteMethod **write_method)
242 /* Check whether the instance identifier is valid */
243 if (smux_header_generic (v, name, length, exact, var_len, write_method)
244 == MATCH_FAILED)
245 return NULL;
247 /* Return the current value of the variable */
248 switch (v->magic)
250 case OSPFv3ROUTERID: /* 1*/
251 /* Router-ID of this OSPF instance. */
252 if (ospf6)
253 return SNMP_IPADDRESS (INT32_INADDR (ospf6->router_id));
254 else
255 return SNMP_IPADDRESS (ospf6_empty_id);
256 break;
257 case OSPFv3ADMINSTAT: /* 2*/
258 break;
259 case OSPFv3VERSIONNUMBER: /* 3*/
260 break;
261 case OSPFv3AREABDRRTRSTATUS: /* 4*/
262 break;
263 case OSPFv3ASBDRRTRSTATUS: /* 5*/
264 break;
265 case OSPFv3ASSCOPELSACOUNT: /* 6*/
266 break;
267 case OSPFv3ASSCOPELSACHECKSUMSUM: /* 7*/
268 break;
269 case OSPFv3ORIGINATENEWLSAS: /* 8*/
270 break;
271 case OSPFv3RXNEWLSAS: /* 9*/
272 break;
273 case OSPFv3EXTLSACOUNT: /*10*/
274 break;
275 case OSPFv3EXTAREALSDBLIMIT: /*11*/
276 break;
277 case OSPFv3MULTICASTEXTENSIONS: /*12*/
278 break;
279 case OSPFv3EXITOVERFLOWINTERVAL: /*13*/
280 break;
281 case OSPFv3DEMANDEXTENSIONS: /*14*/
282 break;
283 case OSPFv3TRAFFICENGINEERINGSUPPORT: /*15*/
284 break;
285 case OSPFv3REFERENCEBANDWIDTH: /*16*/
286 break;
287 case OSPFv3RESTARTSUPPORT: /*17*/
288 break;
289 case OSPFv3RESTARTINTERVAL: /*18*/
290 break;
291 case OSPFv3RESTARTSTATUS: /*19*/
292 break;
293 case OSPFv3RESTARTAGE: /*20*/
294 break;
295 case OSPFv3RESTARTEXITREASON: /*21*/
296 break;
297 default:
298 return NULL;
300 return NULL;
303 static u_char *
304 ospfv3AreaEntry (struct variable *v, oid *name, size_t *length,
305 int exact, size_t *var_len, WriteMethod **write_method)
307 struct ospf6_area *oa, *area = NULL;
308 u_int32_t area_id = 0;
309 struct listnode *node;
310 unsigned int len;
312 if (ospf6 == NULL)
313 return NULL;
315 len = *length - v->namelen;
316 len = (len >= sizeof (u_int32_t) ? sizeof (u_int32_t) : 0);
317 if (exact && len != sizeof (u_int32_t))
318 return NULL;
319 if (len)
320 oid2in_addr (name + v->namelen, len, (struct in_addr *) &area_id);
322 zlog_debug ("SNMP access by area: %s, exact=%d len=%d length=%lu",
323 inet_ntoa (* (struct in_addr *) &area_id),
324 exact, len, (u_long)*length);
326 for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
328 if (area == NULL)
330 if (len == 0) /* return first area entry */
331 area = oa;
332 else if (exact && ntohl (oa->area_id) == ntohl (area_id))
333 area = oa;
334 else if (ntohl (oa->area_id) > ntohl (area_id))
335 area = oa;
339 if (area == NULL)
340 return NULL;
342 *length = v->namelen + sizeof (u_int32_t);
343 oid_copy_addr (name + v->namelen, (struct in_addr *) &area->area_id,
344 sizeof (u_int32_t));
346 zlog_debug ("SNMP found area: %s, exact=%d len=%d length=%lu",
347 inet_ntoa (* (struct in_addr *) &area->area_id),
348 exact, len, (u_long)*length);
350 switch (v->magic)
352 case OSPFv3AREAID: /* 1*/
353 return SNMP_IPADDRESS (INT32_INADDR (area->area_id));
354 break;
355 case OSPFv3IMPORTASEXTERN: /* 2*/
356 return SNMP_INTEGER (ospf6->external_table->count);
357 break;
358 default:
359 return NULL;
360 break;
362 return NULL;
365 static u_char *
366 ospfv3AreaLsdbEntry (struct variable *v, oid *name, size_t *length,
367 int exact, size_t *var_len, WriteMethod **write_method)
369 struct ospf6_lsa *lsa = NULL;
370 struct in_addr area_id;
371 u_int16_t type;
372 struct in_addr id;
373 struct in_addr adv_router;
374 int len;
375 oid *offset;
376 int offsetlen;
377 char a[16], b[16], c[16];
378 struct ospf6_area *oa;
379 struct listnode *node;
381 memset (&area_id, 0, sizeof (struct in_addr));
382 type = 0;
383 memset (&id, 0, sizeof (struct in_addr));
384 memset (&adv_router, 0, sizeof (struct in_addr));
386 /* Check OSPFv3 instance. */
387 if (ospf6 == NULL)
388 return NULL;
390 /* Get variable length. */
391 offset = name + v->namelen;
392 offsetlen = *length - v->namelen;
394 #define OSPFV3_AREA_LSDB_ENTRY_EXACT_OFFSET \
395 (IN_ADDR_SIZE + 1 + IN_ADDR_SIZE + IN_ADDR_SIZE)
397 if (exact && offsetlen != OSPFV3_AREA_LSDB_ENTRY_EXACT_OFFSET)
398 return NULL;
400 /* Parse area-id */
401 len = (offsetlen < IN_ADDR_SIZE ? offsetlen : IN_ADDR_SIZE);
402 if (len)
403 oid2in_addr (offset, len, &area_id);
404 offset += len;
405 offsetlen -= len;
407 /* Parse type */
408 len = (offsetlen < 1 ? offsetlen : 1);
409 if (len)
410 type = htons (*offset);
411 offset += len;
412 offsetlen -= len;
414 /* Parse Router-ID */
415 len = (offsetlen < IN_ADDR_SIZE ? offsetlen : IN_ADDR_SIZE);
416 if (len)
417 oid2in_addr (offset, len, &adv_router);
418 offset += len;
419 offsetlen -= len;
421 /* Parse LS-ID */
422 len = (offsetlen < IN_ADDR_SIZE ? offsetlen : IN_ADDR_SIZE);
423 if (len)
424 oid2in_addr (offset, len, &id);
425 offset += len;
426 offsetlen -= len;
428 inet_ntop (AF_INET, &area_id, a, sizeof (a));
429 inet_ntop (AF_INET, &adv_router, b, sizeof (b));
430 inet_ntop (AF_INET, &id, c, sizeof (c));
431 zlog_debug ("SNMP access by lsdb: area=%s exact=%d length=%lu magic=%d"
432 " type=%#x adv_router=%s id=%s",
433 a, exact, (u_long)*length, v->magic, ntohs (type), b, c);
435 if (exact)
437 oa = ospf6_area_lookup (area_id.s_addr, ospf6);
438 lsa = ospf6_lsdb_lookup (type, id.s_addr, adv_router.s_addr, oa->lsdb);
440 else
442 for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
444 if (lsa)
445 continue;
446 if (ntohl (oa->area_id) < ntohl (area_id.s_addr))
447 continue;
449 lsa = ospf6_lsdb_lookup_next (type, id.s_addr, adv_router.s_addr,
450 oa->lsdb);
451 if (! lsa)
453 type = 0;
454 memset (&id, 0, sizeof (struct in_addr));
455 memset (&adv_router, 0, sizeof (struct in_addr));
460 if (! lsa)
462 zlog_debug ("SNMP respond: No LSA to return");
463 return NULL;
465 oa = OSPF6_AREA (lsa->lsdb->data);
467 zlog_debug ("SNMP respond: area: %s lsa: %s", oa->name, lsa->name);
469 /* Add Index (AreaId, Type, RouterId, Lsid) */
470 *length = v->namelen + OSPFV3_AREA_LSDB_ENTRY_EXACT_OFFSET;
471 offset = name + v->namelen;
472 oid_copy_addr (offset, (struct in_addr *) &oa->area_id, IN_ADDR_SIZE);
473 offset += IN_ADDR_SIZE;
474 *offset = ntohs (lsa->header->type);
475 offset++;
476 oid_copy_addr (offset, (struct in_addr *) &lsa->header->adv_router,
477 IN_ADDR_SIZE);
478 offset += IN_ADDR_SIZE;
479 oid_copy_addr (offset, (struct in_addr *) &lsa->header->id, IN_ADDR_SIZE);
480 offset += IN_ADDR_SIZE;
482 /* Return the current value of the variable */
483 switch (v->magic)
485 case OSPFv3AREALSDBAREAID: /* 1 */
486 area_id.s_addr = OSPF6_AREA (lsa->lsdb->data)->area_id;
487 return SNMP_IPADDRESS (area_id);
488 break;
489 case OSPFv3AREALSDBTYPE: /* 2 */
490 return SNMP_INTEGER (ntohs (lsa->header->type));
491 break;
492 case OSPFv3AREALSDBROUTERID: /* 3 */
493 adv_router.s_addr = lsa->header->adv_router;
494 return SNMP_IPADDRESS (adv_router);
495 break;
496 case OSPFv3AREALSDBLSID: /* 4 */
497 id.s_addr = lsa->header->id;
498 return SNMP_IPADDRESS (id);
499 break;
500 case OSPFv3AREALSDBSEQUENCE: /* 5 */
501 return SNMP_INTEGER (lsa->header->seqnum);
502 break;
503 case OSPFv3AREALSDBAGE: /* 6 */
504 ospf6_lsa_age_current (lsa);
505 return SNMP_INTEGER (lsa->header->age);
506 break;
507 case OSPFv3AREALSDBCHECKSUM: /* 7 */
508 return SNMP_INTEGER (lsa->header->checksum);
509 break;
510 case OSPFv3AREALSDBADVERTISEMENT: /* 8 */
511 *var_len = ntohs (lsa->header->length);
512 return (u_char *) lsa->header;
513 break;
514 case OSPFv3AREALSDBTYPEKNOWN: /* 9 */
515 return SNMP_INTEGER (OSPF6_LSA_IS_KNOWN (lsa->header->type) ?
516 SNMP_TRUE : SNMP_FALSE);
517 break;
518 default:
519 return NULL;
520 break;
522 return NULL;
526 /* Register OSPFv3-MIB. */
527 void
528 ospf6_snmp_init (struct thread_master *master)
530 smux_init (master);
531 REGISTER_MIB ("OSPFv3MIB", ospfv3_variables, variable, ospfv3_oid);
534 #endif /* HAVE_SNMP */