1%% 2%% %CopyrightBegin% 3%% 4%% Copyright Ericsson AB 1996-2019. All Rights Reserved. 5%% 6%% Licensed under the Apache License, Version 2.0 (the "License"); 7%% you may not use this file except in compliance with the License. 8%% You may obtain a copy of the License at 9%% 10%% http://www.apache.org/licenses/LICENSE-2.0 11%% 12%% Unless required by applicable law or agreed to in writing, software 13%% distributed under the License is distributed on an "AS IS" BASIS, 14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15%% See the License for the specific language governing permissions and 16%% limitations under the License. 17%% 18%% %CopyrightEnd% 19%% 20-module(snmp_standard_mib). 21 22%%%----------------------------------------------------------------- 23%%% This module implements the configure- and reinit-functions 24%%% for the STANDARD-MIB and SNMPv2-MIB. 25%%%----------------------------------------------------------------- 26 27-include("snmp_types.hrl"). 28-include("STANDARD-MIB.hrl"). 29 30-include("snmpa_internal.hrl"). 31-define(VMODULE,"STANDARD-MIB"). 32-include("snmp_verbosity.hrl"). 33 34-define(enabled, 1). 35-define(disabled, 2). 36 37%% External exports 38%% Avoid warning for local function error/1 clashing with autoimported BIF. 39-compile({no_auto_import,[error/1]}). 40-export([configure/1, reconfigure/1, reset/0, sys_up_time/0, sys_up_time/1, 41 snmp_enable_authen_traps/1, snmp_enable_authen_traps/2, 42 sys_object_id/1, sys_object_id/2, sys_or_table/3, 43 variable_func/1, variable_func/2, 44 inc/1, inc/2]). 45-export([sysDescr/1, sysContact/1, sysName/1, sysLocation/1, 46 sysServices/1, sysUpTime/1, snmpEnableAuthenTraps/1, 47 sysObjectID/1, 48 snmpInPkts/1, snmpOutPkts/1, 49 snmpInBadVersions/1, 50 snmpInBadCommunityNames/1, snmpInBadCommunityUses/1, 51 snmpInASNParseErrs/1, 52 snmpInTooBigs/1, 53 snmpInNoSuchNames/1, snmpInBadValues/1, 54 snmpInReadOnlys/1, snmpInGenErrs/1, 55 snmpInTotalReqVars/1, snmpInTotalSetVars/1, 56 snmpInGetRequests/1, snmpInSetRequests/1, 57 snmpInGetNexts/1, 58 snmpInGetResponses/1, snmpInTraps/1, 59 snmpOutTooBigs/1, 60 snmpOutNoSuchNames/1, 61 snmpOutBadValues/1, 62 snmpOutGenErrs/1, 63 snmpOutGetRequests/1, snmpOutSetRequests/1, 64 snmpOutGetNexts/1, 65 snmpOutGetResponses/1, 66 snmpOutTraps/1]). 67-export([dummy/1, snmp_set_serial_no/1, snmp_set_serial_no/2]). 68-export([add_agent_caps/2, del_agent_caps/1, get_agent_caps/0]). 69-export([check_standard/1]). 70 71 72%%----------------------------------------------------------------- 73%% Func: configure/1 74%% Args: Dir is the directory with trailing dir_separator where 75%% the configuration files can be found. 76%% Purpose: Reads the config-files for the standard mib, and 77%% inserts the data. Persistent data that is already 78%% present is *not* changed! (use reconfigure for that) 79%% Returns: ok 80%% Fails: exit(configuration_error) 81%%----------------------------------------------------------------- 82configure(Dir) -> 83 case (catch do_configure(Dir)) of 84 ok -> 85 ok; 86 {error, Reason} -> 87 ?vinfo("configure error: ~p", [Reason]), 88 config_err("configure failed: ~p", [Reason]), 89 exit(configuration_error); 90 Error -> 91 ?vinfo("configure failed: ~p", [Error]), 92 config_err("configure failed: ~p", [Error]), 93 exit(configuration_error) 94 end. 95 96do_configure(Dir) -> 97 case snmpa_agent:get_agent_mib_storage() of 98 mnesia -> 99 ok; 100 _ -> 101 Standard = read_standard(Dir), 102 lists:map(fun maybe_create_persistent_var/1, Standard) 103 end, 104 snmpa_local_db:variable_set({next_sys_or_index, volatile}, 1), 105 %% sysORTable is always volatile 106 snmp_generic:table_func(new, {sysORTable, volatile}), 107 ok. 108 109 110%%----------------------------------------------------------------- 111%% Func: reconfigure/1 112%% Args: Dir is the directory with trailing dir_separator where 113%% the configuration files can be found. 114%% Purpose: Reads the config-files for the standard mib, and 115%% inserts the data. Persistent data that is already 116%% present is deleted. Makes sure the config file 117%% data is used. 118%% Returns: ok 119%% Fails: exit(configuration_error) 120%%----------------------------------------------------------------- 121reconfigure(Dir) -> 122 set_sname(), 123 case (catch do_reconfigure(Dir)) of 124 ok -> 125 ok; 126 {error, Reason} -> 127 ?vinfo("reconfigure error: ~p", [Reason]), 128 config_err("reconfigure failed: ~p", [Reason]), 129 exit(configuration_error); 130 Error -> 131 ?vinfo("reconfigure failed: ~p", [Error]), 132 config_err("reconfigure failed: ~p", [Error]), 133 exit(configuration_error) 134 end. 135 136do_reconfigure(Dir) -> 137 Standard = read_standard(Dir), 138 lists:map(fun create_persistent_var/1, Standard), 139 snmpa_local_db:variable_set({next_sys_or_index, volatile}, 1), 140 snmp_generic:table_func(new, {sysORTable, volatile}), 141 ok. 142 143 144%%----------------------------------------------------------------- 145%% Func: read_standard/1 146%% Args: Dir is the directory with trailing dir_separator where 147%% the configuration files can be found. 148%% Purpose: Reads the standard configuration file. 149%% Returns: A list of standard variables 150%% Fails: If an error occurs, the process will die with Reason 151%% configuration_error. 152%% This file is mandatory, as it contains mandatory 153%% config options for which there are no default values. 154%%----------------------------------------------------------------- 155read_standard(Dir) -> 156 ?vdebug("check standard config file",[]), 157 FileName = "standard.conf", 158 Gen = 159 fun (D, Reason) -> 160 throw( 161 {error, 162 {failed_reading_config_file, 163 D, FileName, list_dir(Dir), Reason}}) 164 end, 165 Order = fun snmp_conf:no_order/2, 166 Check = fun (Entry, State) -> {check_standard(Entry), State} end, 167 Filter = fun sort_standard/1, 168 [Standard] = 169 snmp_conf:read_files(Dir, [{FileName, Gen, Order, Check, Filter}]), 170 Standard. 171 172list_dir(Dir) -> 173 case file:list_dir(Dir) of 174 {ok, Files} -> 175 Files; 176 Error -> 177 Error 178 end. 179 180 181%%----------------------------------------------------------------- 182%% Make sure that each mandatory standard attribute is present, and 183%% provide default values for the other non-present attributes. 184%%----------------------------------------------------------------- 185sort_standard(L) -> 186 Mand = [{sysContact, {value, ""}}, 187 {sysDescr, {value, ""}}, 188 {sysLocation, {value, ""}}, 189 {sysName, {value, ""}}, 190 {sysObjectID, mandatory}, 191 {sysServices, mandatory}, 192 {snmpEnableAuthenTraps, mandatory}], 193 {ok, L2} = snmp_conf:check_mandatory(L, Mand), 194 lists:keysort(1, L2). 195 196 197%%----------------------------------------------------------------- 198%% Standard 199%% {Name, Value}. 200%%----------------------------------------------------------------- 201check_standard({sysDescr, Value}) -> snmp_conf:check_string(Value); 202check_standard({sysObjectID, Value}) -> snmp_conf:check_oid(Value); 203check_standard({sysContact, Value}) -> snmp_conf:check_string(Value); 204check_standard({sysName, Value}) -> snmp_conf:check_string(Value); 205check_standard({sysLocation, Value}) -> snmp_conf:check_string(Value); 206check_standard({sysServices, Value}) -> snmp_conf:check_integer(Value); 207check_standard({snmpEnableAuthenTraps, Value}) -> 208 Atoms = [{enabled, ?snmpEnableAuthenTraps_enabled}, 209 {disabled, ?snmpEnableAuthenTraps_disabled}], 210 {ok, Val} = snmp_conf:check_atom(Value, Atoms), 211 {ok, {snmpEnableAuthenTraps, Val}}; 212check_standard({Attrib, _Value}) -> error({unknown_attribute, Attrib}); 213check_standard(X) -> error({invalid_standard_specification, X}). 214 215 216%%----------------------------------------------------------------- 217%% Func: reset/0 218%% Purpose: Resets all counters (sets them to 0). 219%%----------------------------------------------------------------- 220reset() -> 221 snmpa_mpd:reset(). 222 223maybe_create_persistent_var({Var, Val}) -> 224 VarDB = db(Var), 225 case snmp_generic:variable_get(VarDB) of 226 {value, _} -> ok; 227 _ -> snmp_generic:variable_set(VarDB, Val) 228 end. 229 230create_persistent_var({Var, Val}) -> 231 snmp_generic:variable_set(db(Var), Val). 232 233variable_func(_Op) -> ok. 234 235variable_func(get, Name) -> 236 [{_, Val}] = ets:lookup(snmp_agent_table, Name), 237 {value, Val}. 238 239 240%%----------------------------------------------------------------- 241%% inc(VariableName) increments the variable (Counter) in 242%% the local mib. (e.g. snmpInPkts) 243%%----------------------------------------------------------------- 244inc(Name) -> inc(Name, 1). 245inc(Name, N) -> ets:update_counter(snmp_agent_table, Name, N). 246 247 248sysDescr(print) -> 249 VarAndValue = [{sysDescr, sysDescr(get)}], 250 snmpa_mib_lib:print_variables(VarAndValue); 251 252sysDescr(get) -> 253 VarDB = db(sysDescr), 254 snmp_generic:variable_get(VarDB). 255 256 257sysContact(print) -> 258 VarAndValue = [{sysContact, sysContact(get)}], 259 snmpa_mib_lib:print_variables(VarAndValue); 260 261sysContact(get) -> 262 VarDB = db(sysContact), 263 snmp_generic:variable_get(VarDB). 264 265 266sysName(print) -> 267 VarAndValue = [{sysName, sysName(get)}], 268 snmpa_mib_lib:print_variables(VarAndValue); 269 270sysName(get) -> 271 VarDB = db(sysName), 272 snmp_generic:variable_get(VarDB). 273 274 275sysLocation(print) -> 276 VarAndValue = [{sysLocation, sysLocation(get)}], 277 snmpa_mib_lib:print_variables(VarAndValue); 278 279sysLocation(get) -> 280 VarDB = db(sysLocation), 281 snmp_generic:variable_get(VarDB). 282 283 284sysServices(print) -> 285 VarAndValue = [{sysServices, sysServices(get)}], 286 snmpa_mib_lib:print_variables(VarAndValue); 287 288sysServices(get) -> 289 VarDB = db(sysServices), 290 snmp_generic:variable_get(VarDB). 291 292 293snmpInPkts(print) -> 294 gen_counter(print, snmpInPkts); 295snmpInPkts(get) -> 296 gen_counter(get, snmpInPkts). 297 298 299snmpOutPkts(print) -> 300 gen_counter(print, snmpOutPkts); 301snmpOutPkts(get) -> 302 gen_counter(get, snmpOutPkts). 303 304 305snmpInASNParseErrs(print) -> 306 gen_counter(print, snmpInASNParseErrs); 307snmpInASNParseErrs(get) -> 308 gen_counter(get, snmpInASNParseErrs). 309 310 311snmpInBadCommunityNames(print) -> 312 gen_counter(print, snmpInBadCommunityNames); 313snmpInBadCommunityNames(get) -> 314 gen_counter(get, snmpInBadCommunityNames). 315 316 317snmpInBadCommunityUses(print) -> 318 gen_counter(print, snmpInBadCommunityUses); 319 320snmpInBadCommunityUses(get) -> 321 gen_counter(get, snmpInBadCommunityUses). 322 323 324snmpInBadVersions(print) -> 325 gen_counter(print, snmpInBadVersions); 326snmpInBadVersions(get) -> 327 gen_counter(get, snmpInBadVersions). 328 329 330snmpInTooBigs(print) -> 331 gen_counter(print, snmpInTooBigs); 332snmpInTooBigs(get) -> 333 gen_counter(get, snmpInTooBigs). 334 335 336snmpInNoSuchNames(print) -> 337 gen_counter(print, snmpInNoSuchNames); 338snmpInNoSuchNames(get) -> 339 gen_counter(get, snmpInNoSuchNames). 340 341 342snmpInBadValues(print) -> 343 gen_counter(print, snmpInBadValues); 344snmpInBadValues(get) -> 345 gen_counter(get, snmpInBadValues). 346 347 348snmpInReadOnlys(print) -> 349 gen_counter(print, snmpInReadOnlys); 350snmpInReadOnlys(get) -> 351 gen_counter(get, snmpInReadOnlys). 352 353 354snmpInGenErrs(print) -> 355 gen_counter(print, snmpInGenErrs); 356snmpInGenErrs(get) -> 357 gen_counter(get, snmpInGenErrs). 358 359 360snmpInTotalReqVars(print) -> 361 gen_counter(print, snmpInTotalReqVars); 362snmpInTotalReqVars(get) -> 363 gen_counter(get, snmpInTotalReqVars). 364 365 366snmpInTotalSetVars(print) -> 367 gen_counter(print, snmpInTotalSetVars); 368snmpInTotalSetVars(get) -> 369 gen_counter(get, snmpInTotalSetVars). 370 371 372snmpInGetRequests(print) -> 373 gen_counter(print, snmpInGetRequests); 374snmpInGetRequests(get) -> 375 gen_counter(get, snmpInGetRequests). 376 377 378snmpInSetRequests(print) -> 379 gen_counter(print, snmpInSetRequests); 380snmpInSetRequests(get) -> 381 gen_counter(get, snmpInSetRequests). 382 383 384snmpInGetNexts(print) -> 385 gen_counter(print, snmpInGetNexts); 386snmpInGetNexts(get) -> 387 gen_counter(get, snmpInGetNexts). 388 389 390snmpInGetResponses(print) -> 391 gen_counter(print, snmpInGetResponses); 392snmpInGetResponses(get) -> 393 gen_counter(get, snmpInGetResponses). 394 395 396snmpInTraps(print) -> 397 gen_counter(print, snmpInTraps); 398snmpInTraps(get) -> 399 gen_counter(get, snmpInTraps). 400 401 402snmpOutTooBigs(print) -> 403 gen_counter(print, snmpOutTooBigs); 404snmpOutTooBigs(get) -> 405 gen_counter(get, snmpOutTooBigs). 406 407 408snmpOutNoSuchNames(print) -> 409 gen_counter(print, snmpOutNoSuchNames); 410snmpOutNoSuchNames(get) -> 411 gen_counter(get, snmpOutNoSuchNames). 412 413 414snmpOutBadValues(print) -> 415 gen_counter(print, snmpOutBadValues); 416snmpOutBadValues(get) -> 417 gen_counter(get, snmpOutBadValues). 418 419 420snmpOutGenErrs(print) -> 421 gen_counter(print, snmpOutGenErrs); 422snmpOutGenErrs(get) -> 423 gen_counter(get, snmpOutGenErrs). 424 425 426snmpOutGetRequests(print) -> 427 gen_counter(print, snmpOutGetRequests); 428snmpOutGetRequests(get) -> 429 gen_counter(get, snmpOutGetRequests). 430 431 432snmpOutSetRequests(print) -> 433 gen_counter(print, snmpOutSetRequests); 434snmpOutSetRequests(get) -> 435 gen_counter(get, snmpOutSetRequests). 436 437 438snmpOutGetNexts(print) -> 439 gen_counter(print, snmpOutGetNexts); 440snmpOutGetNexts(get) -> 441 gen_counter(get, snmpOutGetNexts). 442 443 444snmpOutGetResponses(print) -> 445 gen_counter(print, snmpOutGetResponses); 446snmpOutGetResponses(get) -> 447 gen_counter(get, snmpOutGetResponses). 448 449 450snmpOutTraps(print) -> 451 gen_counter(print, snmpOutTraps); 452snmpOutTraps(get) -> 453 gen_counter(get, snmpOutTraps). 454 455 456gen_counter(print, Counter) -> 457 Val = gen_counter(get, Counter), 458 VarAndValue = [{Counter, Val}], 459 snmpa_mib_lib:print_variables(VarAndValue); 460 461gen_counter(get, Counter) -> 462 variable_func(get, Counter). 463 464 465%%----------------------------------------------------------------- 466%% This is the instrumentation function for sysUpTime. 467%%----------------------------------------------------------------- 468sysUpTime(print) -> 469 sys_up_time(print); 470sysUpTime(get) -> 471 sys_up_time(get). 472 473sys_up_time() -> 474 snmpa:sys_up_time(). 475 476sys_up_time(print) -> 477 VarAndValue = [{sysUpTime, sys_up_time(get)}], 478 snmpa_mib_lib:print_variables(VarAndValue); 479 480sys_up_time(get) -> 481 {value, snmpa:sys_up_time()}. 482 483 484%%----------------------------------------------------------------- 485%% This is the instrumentation function for snmpEnableAuthenTraps 486%%----------------------------------------------------------------- 487 488snmpEnableAuthenTraps(print) -> 489 snmp_enable_authen_traps(print); 490snmpEnableAuthenTraps(get) -> 491 snmp_enable_authen_traps(get). 492 493 494snmp_enable_authen_traps(print) -> 495 VarAndValue = [{snmpEnableAuthenTraps, snmp_enable_authen_traps(get)}], 496 snmpa_mib_lib:print_variables(VarAndValue); 497 498snmp_enable_authen_traps(new) -> 499 snmp_generic:variable_func(new, db(snmpEnableAuthenTraps)); 500 501snmp_enable_authen_traps(delete) -> 502 ok; 503 504snmp_enable_authen_traps(get) -> 505 snmp_generic:variable_func(get, db(snmpEnableAuthenTraps)). 506 507snmp_enable_authen_traps(set, NewVal) -> 508 snmp_generic:variable_func(set, NewVal, db(snmpEnableAuthenTraps)). 509 510 511%%----------------------------------------------------------------- 512%% This is the instrumentation function for sysObjectID 513%%----------------------------------------------------------------- 514sysObjectID(print) -> 515 sys_object_id(print); 516sysObjectID(get) -> 517 sys_object_id(get). 518 519sys_object_id(print) -> 520 VarAndValue = [{sysObjectID, sys_object_id(get)}], 521 snmpa_mib_lib:print_variables(VarAndValue); 522 523sys_object_id(new) -> 524 snmp_generic:variable_func(new, db(sysObjectID)); 525 526sys_object_id(delete) -> 527 ok; 528 529sys_object_id(get) -> 530 snmp_generic:variable_func(get, db(sysObjectID)). 531 532sys_object_id(set, NewVal) -> 533 snmp_generic:variable_func(set, NewVal, db(sysObjectID)). 534 535 536%%----------------------------------------------------------------- 537%% This is a dummy instrumentation function for objects like 538%% snmpTrapOID, that is accessible-for-notify, with different 539%% values each time. This function will only be called with 540%% new/delete. 541%%----------------------------------------------------------------- 542dummy(_Op) -> ok. 543 544 545%%----------------------------------------------------------------- 546%% This is the instrumentation function for snmpSetSerialNo. 547%% It is always volatile. 548%%----------------------------------------------------------------- 549snmp_set_serial_no(new) -> 550 snmp_generic:variable_func(new, {snmpSetSerialNo, volatile}), 551 ?SNMP_RAND_SEED(), 552 %% rand:seed(exrop, 553 %% {erlang:phash2([node()]), 554 %% erlang:monotonic_time(), 555 %% erlang:unique_integer()}), 556 Val = rand:uniform(2147483648) - 1, 557 snmp_generic:variable_func(set, Val, {snmpSetSerialNo, volatile}); 558 559snmp_set_serial_no(delete) -> 560 ok; 561 562snmp_set_serial_no(get) -> 563 snmp_generic:variable_func(get, {snmpSetSerialNo, volatile}). 564 565snmp_set_serial_no(is_set_ok, NewVal) -> 566 case snmp_generic:variable_func(get, {snmpSetSerialNo, volatile}) of 567 {value, NewVal} -> noError; 568 _ -> inconsistentValue 569 end; 570snmp_set_serial_no(set, NewVal) -> 571 snmp_generic:variable_func(set, (NewVal + 1) rem 2147483648, 572 {snmpSetSerialNo, volatile}). 573 574 575%%----------------------------------------------------------------- 576%% This is the instrumentation function for sysOrTable 577%%----------------------------------------------------------------- 578sys_or_table(Op, RowIndex, Cols) -> 579 snmp_generic:table_func(Op, RowIndex, Cols, {sysORTable, volatile}). 580 581add_agent_caps(Oid, Descr) when is_list(Oid) andalso is_list(Descr) -> 582 {value, Next} = snmpa_local_db:variable_get({next_sys_or_index, volatile}), 583 snmpa_local_db:variable_set({next_sys_or_index, volatile}, Next+1), 584 SysUpTime = sys_up_time(), 585 Row = {Next, Oid, Descr, SysUpTime}, 586 snmpa_local_db:table_create_row({sysORTable, volatile}, [Next], Row), 587 snmpa_local_db:variable_set({sysORLastChange, volatile}, SysUpTime), 588 Next. 589 590del_agent_caps(Index) -> 591 snmpa_local_db:table_delete_row({sysORTable, volatile}, [Index]), 592 snmpa_local_db:variable_set({sysORLastChange, volatile}, sys_up_time()). 593 594get_agent_caps() -> 595 snmpa_local_db:match({sysORTable, volatile}, {'$1', '$2', '$3', '$4'}). 596 597 598db(Var) -> snmpa_agent:db(Var). 599 600 601%% ----- 602 603set_sname() -> 604 set_sname(get(sname)). 605 606set_sname(undefined) -> 607 put(sname,conf); 608set_sname(_) -> %% Keep it, if already set. 609 ok. 610 611error(Reason) -> 612 throw({error, Reason}). 613 614config_err(F, A) -> 615 snmpa_error:config_err("[STANDARD-MIB] " ++ F, A). 616