%% %% %CopyrightBegin% %% %% Copyright Ericsson AB 1996-2010. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. %% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. %% %% %CopyrightEnd% %% -module(snmp_standard_mib). %%%----------------------------------------------------------------- %%% This module implements the configure- and reinit-functions %%% for the STANDARD-MIB and SNMPv2-MIB. %%%----------------------------------------------------------------- -include("snmp_types.hrl"). -include("STANDARD-MIB.hrl"). -define(VMODULE,"STANDARD-MIB"). -include("snmp_verbosity.hrl"). -define(enabled, 1). -define(disabled, 2). %% External exports %% Avoid warning for local function error/1 clashing with autoimported BIF. -compile({no_auto_import,[error/1]}). -export([configure/1, reconfigure/1, reset/0, sys_up_time/0, sys_up_time/1, snmp_enable_authen_traps/1, snmp_enable_authen_traps/2, sys_object_id/1, sys_object_id/2, sys_or_table/3, variable_func/1, variable_func/2, inc/1, inc/2]). -export([sysDescr/1, sysContact/1, sysName/1, sysLocation/1, sysServices/1, sysUpTime/1, snmpEnableAuthenTraps/1, sysObjectID/1, snmpInPkts/1, snmpOutPkts/1, snmpInBadVersions/1, snmpInBadCommunityNames/1, snmpInBadCommunityUses/1, snmpInASNParseErrs/1, snmpInTooBigs/1, snmpInNoSuchNames/1, snmpInBadValues/1, snmpInReadOnlys/1, snmpInGenErrs/1, snmpInTotalReqVars/1, snmpInTotalSetVars/1, snmpInGetRequests/1, snmpInSetRequests/1, snmpInGetNexts/1, snmpInGetResponses/1, snmpInTraps/1, snmpOutTooBigs/1, snmpOutNoSuchNames/1, snmpOutBadValues/1, snmpOutGenErrs/1, snmpOutGetRequests/1, snmpOutSetRequests/1, snmpOutGetNexts/1, snmpOutGetResponses/1, snmpOutTraps/1]). -export([dummy/1, snmp_set_serial_no/1, snmp_set_serial_no/2]). -export([add_agent_caps/2, del_agent_caps/1, get_agent_caps/0]). -export([check_standard/1]). %%----------------------------------------------------------------- %% Func: configure/1 %% Args: Dir is the directory with trailing dir_separator where %% the configuration files can be found. %% Purpose: Reads the config-files for the standard mib, and %% inserts the data. Persistent data that is already %% present is *not* changed! (use reconfigure for that) %% Returns: ok %% Fails: exit(configuration_error) %%----------------------------------------------------------------- configure(Dir) -> case (catch do_configure(Dir)) of ok -> ok; {error, Reason} -> ?vinfo("configure error: ~p", [Reason]), config_err("configure failed: ~p", [Reason]), exit(configuration_error); Error -> ?vinfo("configure failed: ~p", [Error]), config_err("configure failed: ~p", [Error]), exit(configuration_error) end. do_configure(Dir) -> case snmpa_agent:get_agent_mib_storage() of mnesia -> ok; _ -> Standard = read_standard(Dir), lists:map(fun maybe_create_persistent_var/1, Standard) end, snmpa_local_db:variable_set({next_sys_or_index, volatile}, 1), %% sysORTable is always volatile snmp_generic:table_func(new, {sysORTable, volatile}), ok. %%----------------------------------------------------------------- %% Func: reconfigure/1 %% Args: Dir is the directory with trailing dir_separator where %% the configuration files can be found. %% Purpose: Reads the config-files for the standard mib, and %% inserts the data. Persistent data that is already %% present is deleted. Makes sure the config file %% data is used. %% Returns: ok %% Fails: exit(configuration_error) %%----------------------------------------------------------------- reconfigure(Dir) -> set_sname(), case (catch do_reconfigure(Dir)) of ok -> ok; {error, Reason} -> ?vinfo("reconfigure error: ~p", [Reason]), config_err("reconfigure failed: ~p", [Reason]), exit(configuration_error); Error -> ?vinfo("reconfigure failed: ~p", [Error]), config_err("reconfigure failed: ~p", [Error]), exit(configuration_error) end. do_reconfigure(Dir) -> Standard = read_standard(Dir), lists:map(fun create_persistent_var/1, Standard), snmpa_local_db:variable_set({next_sys_or_index, volatile}, 1), snmp_generic:table_func(new, {sysORTable, volatile}), ok. %%----------------------------------------------------------------- %% Func: read_standard/1 %% Args: Dir is the directory with trailing dir_separator where %% the configuration files can be found. %% Purpose: Reads th standard configuration file. %% Returns: A list of standard variables %% Fails: If an error occurs, the process will die with Reason %% configuration_error. %%----------------------------------------------------------------- read_standard(Dir) -> ?vdebug("check standard config file",[]), Gen = fun(_) -> ok end, Filter = fun(Standard) -> sort_standard(Standard) end, Check = fun(Entry) -> check_standard(Entry) end, [Standard] = snmp_conf:read_files(Dir, [{Gen, Filter, Check, "standard.conf"}]), Standard. %%----------------------------------------------------------------- %% Make sure that each mandatory standard attribute is present, and %% provide default values for the other non-present attributes. %%----------------------------------------------------------------- sort_standard(L) -> Mand = [{sysContact, {value, ""}}, {sysDescr, {value, ""}}, {sysLocation, {value, ""}}, {sysName, {value, ""}}, {sysObjectID, mandatory}, {sysServices, mandatory}, {snmpEnableAuthenTraps, mandatory}], {ok, L2} = snmp_conf:check_mandatory(L, Mand), lists:keysort(1, L2). %%----------------------------------------------------------------- %% Standard %% {Name, Value}. %%----------------------------------------------------------------- check_standard({sysDescr, Value}) -> snmp_conf:check_string(Value); check_standard({sysObjectID, Value}) -> snmp_conf:check_oid(Value); check_standard({sysContact, Value}) -> snmp_conf:check_string(Value); check_standard({sysName, Value}) -> snmp_conf:check_string(Value); check_standard({sysLocation, Value}) -> snmp_conf:check_string(Value); check_standard({sysServices, Value}) -> snmp_conf:check_integer(Value); check_standard({snmpEnableAuthenTraps, Value}) -> Atoms = [{enabled, ?snmpEnableAuthenTraps_enabled}, {disabled, ?snmpEnableAuthenTraps_disabled}], {ok, Val} = snmp_conf:check_atom(Value, Atoms), {ok, {snmpEnableAuthenTraps, Val}}; check_standard({Attrib, _Value}) -> error({unknown_attribute, Attrib}); check_standard(X) -> error({invalid_standard_specification, X}). %%----------------------------------------------------------------- %% Func: reset/0 %% Purpose: Resets all counters (sets them to 0). %%----------------------------------------------------------------- reset() -> snmpa_mpd:reset(). maybe_create_persistent_var({Var, Val}) -> VarDB = db(Var), case snmp_generic:variable_get(VarDB) of {value, _} -> ok; _ -> snmp_generic:variable_set(VarDB, Val) end. create_persistent_var({Var, Val}) -> snmp_generic:variable_set(db(Var), Val). variable_func(_Op) -> ok. variable_func(get, Name) -> [{_, Val}] = ets:lookup(snmp_agent_table, Name), {value, Val}. %%----------------------------------------------------------------- %% inc(VariableName) increments the variable (Counter) in %% the local mib. (e.g. snmpInPkts) %%----------------------------------------------------------------- inc(Name) -> inc(Name, 1). inc(Name, N) -> ets:update_counter(snmp_agent_table, Name, N). sysDescr(print) -> VarAndValue = [{sysDescr, sysDescr(get)}], snmpa_mib_lib:print_variables(VarAndValue); sysDescr(get) -> VarDB = db(sysDescr), snmp_generic:variable_get(VarDB). sysContact(print) -> VarAndValue = [{sysContact, sysContact(get)}], snmpa_mib_lib:print_variables(VarAndValue); sysContact(get) -> VarDB = db(sysContact), snmp_generic:variable_get(VarDB). sysName(print) -> VarAndValue = [{sysName, sysName(get)}], snmpa_mib_lib:print_variables(VarAndValue); sysName(get) -> VarDB = db(sysName), snmp_generic:variable_get(VarDB). sysLocation(print) -> VarAndValue = [{sysLocation, sysLocation(get)}], snmpa_mib_lib:print_variables(VarAndValue); sysLocation(get) -> VarDB = db(sysLocation), snmp_generic:variable_get(VarDB). sysServices(print) -> VarAndValue = [{sysServices, sysServices(get)}], snmpa_mib_lib:print_variables(VarAndValue); sysServices(get) -> VarDB = db(sysServices), snmp_generic:variable_get(VarDB). snmpInPkts(print) -> gen_counter(print, snmpInPkts); snmpInPkts(get) -> gen_counter(get, snmpInPkts). snmpOutPkts(print) -> gen_counter(print, snmpOutPkts); snmpOutPkts(get) -> gen_counter(get, snmpOutPkts). snmpInASNParseErrs(print) -> gen_counter(print, snmpInASNParseErrs); snmpInASNParseErrs(get) -> gen_counter(get, snmpInASNParseErrs). snmpInBadCommunityNames(print) -> gen_counter(print, snmpInBadCommunityNames); snmpInBadCommunityNames(get) -> gen_counter(get, snmpInBadCommunityNames). snmpInBadCommunityUses(print) -> gen_counter(print, snmpInBadCommunityUses); snmpInBadCommunityUses(get) -> gen_counter(get, snmpInBadCommunityUses). snmpInBadVersions(print) -> gen_counter(print, snmpInBadVersions); snmpInBadVersions(get) -> gen_counter(get, snmpInBadVersions). snmpInTooBigs(print) -> gen_counter(print, snmpInTooBigs); snmpInTooBigs(get) -> gen_counter(get, snmpInTooBigs). snmpInNoSuchNames(print) -> gen_counter(print, snmpInNoSuchNames); snmpInNoSuchNames(get) -> gen_counter(get, snmpInNoSuchNames). snmpInBadValues(print) -> gen_counter(print, snmpInBadValues); snmpInBadValues(get) -> gen_counter(get, snmpInBadValues). snmpInReadOnlys(print) -> gen_counter(print, snmpInReadOnlys); snmpInReadOnlys(get) -> gen_counter(get, snmpInReadOnlys). snmpInGenErrs(print) -> gen_counter(print, snmpInGenErrs); snmpInGenErrs(get) -> gen_counter(get, snmpInGenErrs). snmpInTotalReqVars(print) -> gen_counter(print, snmpInTotalReqVars); snmpInTotalReqVars(get) -> gen_counter(get, snmpInTotalReqVars). snmpInTotalSetVars(print) -> gen_counter(print, snmpInTotalSetVars); snmpInTotalSetVars(get) -> gen_counter(get, snmpInTotalSetVars). snmpInGetRequests(print) -> gen_counter(print, snmpInGetRequests); snmpInGetRequests(get) -> gen_counter(get, snmpInGetRequests). snmpInSetRequests(print) -> gen_counter(print, snmpInSetRequests); snmpInSetRequests(get) -> gen_counter(get, snmpInSetRequests). snmpInGetNexts(print) -> gen_counter(print, snmpInGetNexts); snmpInGetNexts(get) -> gen_counter(get, snmpInGetNexts). snmpInGetResponses(print) -> gen_counter(print, snmpInGetResponses); snmpInGetResponses(get) -> gen_counter(get, snmpInGetResponses). snmpInTraps(print) -> gen_counter(print, snmpInTraps); snmpInTraps(get) -> gen_counter(get, snmpInTraps). snmpOutTooBigs(print) -> gen_counter(print, snmpOutTooBigs); snmpOutTooBigs(get) -> gen_counter(get, snmpOutTooBigs). snmpOutNoSuchNames(print) -> gen_counter(print, snmpOutNoSuchNames); snmpOutNoSuchNames(get) -> gen_counter(get, snmpOutNoSuchNames). snmpOutBadValues(print) -> gen_counter(print, snmpOutBadValues); snmpOutBadValues(get) -> gen_counter(get, snmpOutBadValues). snmpOutGenErrs(print) -> gen_counter(print, snmpOutGenErrs); snmpOutGenErrs(get) -> gen_counter(get, snmpOutGenErrs). snmpOutGetRequests(print) -> gen_counter(print, snmpOutGetRequests); snmpOutGetRequests(get) -> gen_counter(get, snmpOutGetRequests). snmpOutSetRequests(print) -> gen_counter(print, snmpOutSetRequests); snmpOutSetRequests(get) -> gen_counter(get, snmpOutSetRequests). snmpOutGetNexts(print) -> gen_counter(print, snmpOutGetNexts); snmpOutGetNexts(get) -> gen_counter(get, snmpOutGetNexts). snmpOutGetResponses(print) -> gen_counter(print, snmpOutGetResponses); snmpOutGetResponses(get) -> gen_counter(get, snmpOutGetResponses). snmpOutTraps(print) -> gen_counter(print, snmpOutTraps); snmpOutTraps(get) -> gen_counter(get, snmpOutTraps). gen_counter(print, Counter) -> Val = gen_counter(get, Counter), VarAndValue = [{Counter, Val}], snmpa_mib_lib:print_variables(VarAndValue); gen_counter(get, Counter) -> variable_func(get, Counter). %%----------------------------------------------------------------- %% This is the instrumentation function for sysUpTime. %%----------------------------------------------------------------- sysUpTime(print) -> sys_up_time(print); sysUpTime(get) -> sys_up_time(get). sys_up_time() -> snmpa:sys_up_time(). sys_up_time(print) -> VarAndValue = [{sysUpTime, sys_up_time(get)}], snmpa_mib_lib:print_variables(VarAndValue); sys_up_time(get) -> {value, snmpa:sys_up_time()}. %%----------------------------------------------------------------- %% This is the instrumentation function for snmpEnableAuthenTraps %%----------------------------------------------------------------- snmpEnableAuthenTraps(print) -> snmp_enable_authen_traps(print); snmpEnableAuthenTraps(get) -> snmp_enable_authen_traps(get). snmp_enable_authen_traps(print) -> VarAndValue = [{snmpEnableAuthenTraps, snmp_enable_authen_traps(get)}], snmpa_mib_lib:print_variables(VarAndValue); snmp_enable_authen_traps(new) -> snmp_generic:variable_func(new, db(snmpEnableAuthenTraps)); snmp_enable_authen_traps(delete) -> ok; snmp_enable_authen_traps(get) -> snmp_generic:variable_func(get, db(snmpEnableAuthenTraps)). snmp_enable_authen_traps(set, NewVal) -> snmp_generic:variable_func(set, NewVal, db(snmpEnableAuthenTraps)). %%----------------------------------------------------------------- %% This is the instrumentation function for sysObjectID %%----------------------------------------------------------------- sysObjectID(print) -> sys_object_id(print); sysObjectID(get) -> sys_object_id(get). sys_object_id(print) -> VarAndValue = [{sysObjectID, sys_object_id(get)}], snmpa_mib_lib:print_variables(VarAndValue); sys_object_id(new) -> snmp_generic:variable_func(new, db(sysObjectID)); sys_object_id(delete) -> ok; sys_object_id(get) -> snmp_generic:variable_func(get, db(sysObjectID)). sys_object_id(set, NewVal) -> snmp_generic:variable_func(set, NewVal, db(sysObjectID)). %%----------------------------------------------------------------- %% This is a dummy instrumentation function for objects like %% snmpTrapOID, that is accessible-for-notify, with different %% values each time. This function will only be called with %% new/delete. %%----------------------------------------------------------------- dummy(_Op) -> ok. %%----------------------------------------------------------------- %% This is the instrumentation function for snmpSetSerialNo. %% It is always volatile. %%----------------------------------------------------------------- snmp_set_serial_no(new) -> snmp_generic:variable_func(new, {snmpSetSerialNo, volatile}), {A1,A2,A3} = erlang:now(), random:seed(A1,A2,A3), Val = random:uniform(2147483648) - 1, snmp_generic:variable_func(set, Val, {snmpSetSerialNo, volatile}); snmp_set_serial_no(delete) -> ok; snmp_set_serial_no(get) -> snmp_generic:variable_func(get, {snmpSetSerialNo, volatile}). snmp_set_serial_no(is_set_ok, NewVal) -> case snmp_generic:variable_func(get, {snmpSetSerialNo, volatile}) of {value, NewVal} -> noError; _ -> inconsistentValue end; snmp_set_serial_no(set, NewVal) -> snmp_generic:variable_func(set, (NewVal + 1) rem 2147483648, {snmpSetSerialNo, volatile}). %%----------------------------------------------------------------- %% This is the instrumentation function for sysOrTable %%----------------------------------------------------------------- sys_or_table(Op, RowIndex, Cols) -> snmp_generic:table_func(Op, RowIndex, Cols, {sysORTable, volatile}). add_agent_caps(Oid, Descr) when is_list(Oid) andalso is_list(Descr) -> {value, Next} = snmpa_local_db:variable_get({next_sys_or_index, volatile}), snmpa_local_db:variable_set({next_sys_or_index, volatile}, Next+1), SysUpTime = sys_up_time(), Row = {Next, Oid, Descr, SysUpTime}, snmpa_local_db:table_create_row({sysORTable, volatile}, [Next], Row), snmpa_local_db:variable_set({sysORLastChange, volatile}, SysUpTime), Next. del_agent_caps(Index) -> snmpa_local_db:table_delete_row({sysORTable, volatile}, [Index]), snmpa_local_db:variable_set({sysORLastChange, volatile}, sys_up_time()). get_agent_caps() -> snmpa_local_db:match({sysORTable, volatile}, {'$1', '$2', '$3', '$4'}). db(Var) -> snmpa_agent:db(Var). %% ----- set_sname() -> set_sname(get(sname)). set_sname(undefined) -> put(sname,conf); set_sname(_) -> %% Keep it, if already set. ok. error(Reason) -> throw({error, Reason}). config_err(F, A) -> snmpa_error:config_err("[STANDARD-MIB]: " ++ F, A).