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