%% %% %CopyrightBegin% %% %% Copyright Ericsson AB 1998-2011. 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_target_mib). %% Avoid warning for local function error/1 clashing with autoimported BIF. -compile({no_auto_import,[error/1]}). -export([configure/1, reconfigure/1, snmpTargetSpinLock/1, snmpTargetSpinLock/2, snmpTargetAddrTable/1, snmpTargetAddrTable/3, snmpTargetParamsTable/1, snmpTargetParamsTable/3, get_target_addrs/0, get_target_engine_id/1, set_target_engine_id/2, is_valid_tag/3, get/3, table_next/2]). -export([add_addr/10, add_addr/11, delete_addr/1, add_params/5, delete_params/1]). -export([check_target_addr/1, check_target_params/1]). -export([default_domain/0]). -include_lib("snmp/include/snmp_types.hrl"). -include_lib("snmp/include/snmp_tables.hrl"). -include_lib("snmp/include/SNMP-TARGET-MIB.hrl"). -include_lib("snmp/include/SNMPv2-TC.hrl"). -include_lib("snmp/include/SNMPv2-TM.hrl"). -include_lib("snmp/include/SNMP-FRAMEWORK-MIB.hrl"). -include_lib("snmp/include/TRANSPORT-ADDRESS-MIB.hrl"). -define(VMODULE,"TARGET-MIB"). -include("snmp_verbosity.hrl"). %% Column not accessible via SNMP - needed when the agent sends informs -define(snmpTargetAddrEngineId, 10). %% Extra comlumns for the augmented table snmpTargetAddrExtTable -define(snmpTargetAddrTMask, 11). -define(snmpTargetAddrMMS, 12). -ifdef(snmp_extended_verbosity). -define(vt(F,A), ?vtrace(F, A)). -else. -define(vt(_F, _A), ok). -endif. %%----------------------------------------------------------------- default_domain() -> snmpUDPDomain. %%----------------------------------------------------------------- %% Func: configure/1 %% Args: Dir is the directory where the configuration files are found. %% Purpose: If the tables doesn't exist, this function reads %% the config-files for the target tables, and %% inserts the data. This means that the data in the tables %% survive a reboot. However, the StorageType column is %% checked for each row. If volatile, the row is deleted. %% Returns: ok %% Fails: exit(configuration_error) %%----------------------------------------------------------------- configure(Dir) -> set_sname(), case db(snmpTargetParamsTable) of {_, mnesia} -> ?vdebug("tables in mnesia: init vars & cleanup",[]), init_vars(), gc_tabs(); TabDb -> case snmpa_local_db:table_exists(TabDb) of true -> ?vdebug("tables already exist: init vars & cleanup",[]), init_vars(), gc_tabs(); false -> ?vdebug("no tables: reconfigure",[]), reconfigure(Dir) end end. %%----------------------------------------------------------------- %% Func: reconfigure/1 %% Args: Dir is the directory where the configuration files are found. %% Purpose: Reads the config-files for the target tables, and %% inserts the data. Makes sure that all old data in %% the tables are deleted, and the new data inserted. %% This function makes sure that all (and only) %% config-file-data are in the tables. %% 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) -> ?vdebug("read target configuration files",[]), {Addrs, Params} = read_target_config_files(Dir), ?vdebug("initiate tables",[]), init_tabs(Addrs, Params), ?vdebug("initiate vars",[]), init_vars(), ?vdebug("invalidate cache for notification mib",[]), snmp_notification_mib:invalidate_cache(), ok. read_target_config_files(Dir) -> ?vdebug("check target address config file",[]), TAGen = fun(_D) -> ok end, TAFilter = fun(Addr) -> Addr end, TACheck = fun(Entry) -> check_target_addr(Entry) end, TPGen = fun(_D) -> ok end, TPFilter = fun(Params) -> Params end, TPCheck = fun(Entry) -> check_target_params(Entry) end, [Addrs, Params] = snmp_conf:read_files(Dir, [{TAGen, TAFilter, TACheck, "target_addr.conf"}, {TPGen, TPFilter, TPCheck, "target_params.conf"}]), {Addrs, Params}. %%----------------------------------------------------------------- %% TargetAddr %% {Name, Ip, Udp, Timeout, RetryCount, TagList, Params, EngineId, %% TMask, MMS} %%----------------------------------------------------------------- check_target_addr({Name, Domain, Ip, Udp, Timeout, RetryCount, TagList, Params, EngineId, TMask, MMS}) -> ?vtrace("check target address with:" "~n Name: ~s" "~n Domain: ~p" "~n Ip: ~p" "~n Udp: ~p" "~n Timeout: ~p" "~n RetryCount: ~p" "~n TagList: ~p" "~n Params: ~p" "~n EngineId: ~p" "~n TMask: ~p" "~n MMS: ~p", [Name, Domain, Ip, Udp, Timeout, RetryCount, TagList, Params, EngineId, TMask, MMS]), snmp_conf:check_string(Name,{gt,0}), snmp_conf:check_domain(Domain), snmp_conf:check_ip(Domain, Ip), snmp_conf:check_integer(Udp, {gt, 0}), snmp_conf:check_integer(Timeout, {gte, 0}), snmp_conf:check_integer(RetryCount, {gte,0}), snmp_conf:check_string(TagList), snmp_conf:check_string(Params), check_engine_id(EngineId), TAddress = snmp_conf:mk_taddress(Domain, Ip, Udp), TDomain = snmp_conf:mk_tdomain(Domain), check_tmask(TDomain, TMask, TAddress), snmp_conf:check_packet_size(MMS), ?vtrace("check target address done",[]), Addr = {Name, TDomain, TAddress, Timeout, RetryCount, TagList, Params, ?'StorageType_nonVolatile', ?'RowStatus_active', EngineId, TMask, MMS}, % Values for Augmenting table in SNMP-COMMUNITY-MIB {ok, Addr}; check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList, Params, EngineId, TMask, MMS}) -> Domain = default_domain(), check_target_addr({Name, Domain, Ip, Udp, Timeout, RetryCount, TagList, Params, EngineId, TMask, MMS}); check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList, Params, EngineId}) -> check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList, Params, EngineId, [], 2048}); %% Use dummy engine id if the old style is found check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList, Params}) -> check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList, Params, "dummy", [], 2048}); %% Use dummy engine id if the old style is found check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList, Params, TMask, MMS}) -> check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList, Params, "dummy", TMask, MMS}); check_target_addr(X) -> error({invalid_target_addr, X}). check_engine_id(discovery) -> ok; check_engine_id(EngineId) -> snmp_conf:check_string(EngineId). check_tmask(_TDomain, [], _TAddress) -> ok; check_tmask(TDomain, TMask, TAddress) when length(TMask) =:= length(TAddress) -> snmp_conf:check_taddress(TDomain, TMask); check_tmask(_TDomain, TMask, _TAddr) -> throw({error, {invalid_tmask, TMask}}). %%----------------------------------------------------------------- %% TargetParams %% {Name, MPModel, SecurityModel, SecurityName, SecurityLevel} %%----------------------------------------------------------------- check_target_params({Name, MPModel, SecModel, SecName, SecLevel}) -> snmp_conf:check_string(Name,{gt,0}), {ok, MP} = snmp_conf:check_atom(MPModel, [{v1, ?MP_V1}, {v2c, ?MP_V2C}, {v3, ?MP_V3}]), {ok, SecM} = snmp_conf:check_sec_model(SecModel, [any]), snmp_conf:check_string(SecName), {ok, SecL} = snmp_conf:check_sec_level(SecLevel), Params = {Name, MP, SecM, SecName, SecL, ?'StorageType_nonVolatile', ?'RowStatus_active'}, {ok, Params}; check_target_params(X) -> error({invalid_target_params, X}). %% maybe_create_table(Name) -> %% case snmpa_local_db:table_exists(db(Name)) of %% true -> ok; %% _ -> snmpa_local_db:table_create(db(Name)) %% end. init_tabs(Addrs, Params) -> ?vdebug("create target address table",[]), AddrDB = db(snmpTargetAddrTable), snmpa_local_db:table_delete(AddrDB), snmpa_local_db:table_create(AddrDB), init_addr_table(Addrs), ?vdebug("create target params table",[]), ParmDB = db(snmpTargetParamsTable), snmpa_local_db:table_delete(ParmDB), snmpa_local_db:table_create(ParmDB), init_params_table(Params). init_addr_table([Row | T]) -> Key = element(1, Row), snmpa_local_db:table_create_row(db(snmpTargetAddrTable), Key, Row), init_addr_table(T); init_addr_table([]) -> true. init_params_table([Row | T]) -> Key = element(1, Row), snmpa_local_db:table_create_row(db(snmpTargetParamsTable), Key, Row), init_params_table(T); init_params_table([]) -> true. table_cre_row(Tab, Key, Row) -> snmpa_mib_lib:table_cre_row(db(Tab), Key, Row). table_del_row(Tab, Key) -> snmpa_mib_lib:table_del_row(db(Tab), Key). add_addr(Name, Ip, Port, Timeout, Retry, TagList, Params, EngineId, TMask, MMS) -> Domain = default_domain(), add_addr(Name, Domain, Ip, Port, Timeout, Retry, TagList, Params, EngineId, TMask, MMS). add_addr(Name, Domain, Ip, Port, Timeout, Retry, TagList, Params, EngineId, TMask, MMS) -> Addr = {Name, Domain, Ip, Port, Timeout, Retry, TagList, Params, EngineId, TMask, MMS}, case (catch check_target_addr(Addr)) of {ok, Row} -> Key = element(1, Row), case table_cre_row(snmpTargetAddrTable, Key, Row) of true -> {ok, Key}; false -> {error, create_failed} end; {error, Reason} -> {error, Reason}; Error -> {error, Error} end. delete_addr(Key) -> case table_del_row(snmpTargetAddrTable, Key) of true -> ok; false -> {error, delete_failed} end. add_params(Name, MPModel, SecModel, SecName, SecLevel) -> Params = {Name, MPModel, SecModel, SecName, SecLevel}, case (catch check_target_params(Params)) of {ok, Row} -> Key = element(1, Row), case table_cre_row(snmpTargetParamsTable, Key, Row) of true -> {ok, Key}; false -> {create_failed} end; {error, Reason} -> {error, Reason}; Error -> {error, Error} end. delete_params(Key) -> case table_del_row(snmpTargetParamsTable, Key) of true -> ok; false -> {error, delete_failed} end. gc_tabs() -> AddrDB = db(snmpTargetAddrTable), AddrSTC = stc(snmpTargetAddrTable), AddrFOI = foi(snmpTargetAddrTable), snmpa_mib_lib:gc_tab(AddrDB, AddrSTC, AddrFOI), ParmDB = db(snmpTargetParamsTable), ParmSTC = stc(snmpTargetParamsTable), ParmFOI = foi(snmpTargetParamsTable), snmpa_mib_lib:gc_tab(ParmDB, ParmSTC, ParmFOI), ok. %%----------------------------------------------------------------- %% Counter functions %%----------------------------------------------------------------- init_vars() -> ?vtrace("initiate vars",[]), lists:map(fun maybe_create_var/1, vars()). maybe_create_var(Var) -> case ets:lookup(snmp_agent_table, Var) of [_] -> ok; _ -> init_var(Var) end. init_var(Var) -> ets:insert(snmp_agent_table, {Var, 0}). vars() -> [ snmpUnavailableContexts, snmpUnknownContexts ]. %%----------------------------------------------------------------- %% API functions %%----------------------------------------------------------------- is_valid_tag("", _TDomain, _TAddress) -> true; is_valid_tag(Tag, TDomain, TAddress) -> is_valid_tag(TDomain, TAddress, Tag, []). is_valid_tag(TDomain, TAddress, Tag, Key) -> ?vtrace("is_valid_tag -> entry with" "~n TDomain: ~p" "~n TAddress: ~p" "~n Tag: ~p" "~n Key: ~p", [TDomain, TAddress, Tag, Key]), case table_next(snmpTargetAddrTable, Key) of endOfTable -> ?vtrace("is_valid_tag -> endOfTable", []), false; NextKey -> ?vtrace("is_valid_tag -> next key found" "~n NextKey: ~p", [NextKey]), case get(snmpTargetAddrTable, NextKey, [?snmpTargetAddrTDomain, ?snmpTargetAddrTAddress, ?snmpTargetAddrTagList, ?snmpTargetAddrTMask]) of [{value, TDomain}, % must match exactly {value, TAddress}, % RFC2576: chapters 5.2.1 & 5.3 {value, TagList}, {value, []}] -> ?vtrace("is_valid_tag -> found with exact match" "~n TagList: ~p", [TagList]), case snmp_misc:is_tag_member(Tag, TagList) of true -> ?vtrace("is_valid_tag -> exact: " "tag IS member of taglist", []), true; false -> ?vtrace("is_valid_tag -> exact: " "tag is NOT member of taglist", []), is_valid_tag(TDomain, TAddress, Tag, NextKey) end; [{value, TDomain}, % must match exactly {value, TAddress2}, {value, TagList}, {value, TMask}] when TMask =/= [] -> ?vtrace("is_valid_tag -> found with exact match" "~n TagList: ~p" "~n TMask: ~p", [TagList, TMask]), case snmp_misc:is_tmask_match(TAddress, TAddress2, TMask) of true -> ?vtrace("is_valid_tag -> " "tmask match - now check tag member", []), case snmp_misc:is_tag_member(Tag, TagList) of true -> ?vtrace("is_valid_tag -> masked: " "tag IS member of taglist", []), true; false -> ?vtrace("is_valid_tag -> masked: " "tag is NOT member of taglist",[]), is_valid_tag(TDomain, TAddress, Tag, NextKey) end; false -> ?vtrace("is_valid_tag -> tmask NO match", []), is_valid_tag(TDomain, TAddress, Tag, NextKey) end; _ -> ?vtrace("is_valid_tag -> not found - try next", []), is_valid_tag(TDomain, TAddress, Tag, NextKey) end end. %% TargAddrs = %% [{TagList, TargetAddr, TargetAddrName, TargetParams, Timeout, Retry}] %% TargetAddr = {TDomain, TAddr}; e.g. {?snmpUDPDomain, IpAndUdpPortAsList} get_target_addrs() -> get_target_addrs([], db(snmpTargetAddrTable), []). get_target_addrs(Key, {Tab, _} = TabDb, Acc) -> ?vt("get_target_addrs -> entry with" "~n Key: ~p", [Key]), case table_next(Tab, Key) of endOfTable -> ?vt("get_target_addrs -> endOfTable when" "~n Acc: ~p", [Acc]), Acc; NextKey -> ?vt("get_target_addrs -> next ok: " "~n NextKey: ~p", [NextKey]), case get_target_addr(TabDb, NextKey) of {ok, Targ} -> get_target_addrs(NextKey, TabDb, [Targ| Acc]); {error, Reason} -> ?vlog("failed getting target address: " "~n Reason: ~p", [Reason]), get_target_addrs(NextKey, TabDb, Acc) end end. get_target_addr({Tab, mnesia}, Key) -> case mnesia:snmp_get_row(Tab, Key) of {ok, #snmpTargetAddrTable{ snmpTargetAddrTDomain = TDomain, snmpTargetAddrTAddress = TAddress, snmpTargetAddrTimeout = Timeout, snmpTargetAddrRetryCount = RetryCount, snmpTargetAddrTagList = TagList, snmpTargetAddrParams = Params, snmpTargetAddrRowStatus = ?'RowStatus_active'}} -> case get_target_params(Params) of undefined -> config_err("Failed retreiving target params [~p]" "~n for ~p [~p]", [Params, Key, TAddress]), {error, {not_found, {target_params, Key, Params}}}; TargetParams -> Targ = {TagList, {TDomain, TAddress}, Key, TargetParams, Timeout, RetryCount}, {ok, Targ} end; _ -> {error, {not_found, {target_addr, Key}}} end; get_target_addr(TabDb, Key) -> case snmpa_local_db:table_get_row(TabDb, Key) of {_Key, TDomain, TAddress, Timeout, RetryCount, TagList, Params, _Storage, ?'RowStatus_active', _TargetEngineId,_TMask,_MMS} -> case get_target_params(Params) of undefined -> config_err("Failed retreiving target params [~p]" "~n for target ~p [~p]", [Params, Key, TAddress]), {error, {not_found, {target_params, Key, Params}}}; TargetParams -> Targ = {TagList, {TDomain, TAddress}, Key, TargetParams, Timeout, RetryCount}, {ok, Targ} end; _ -> {error, {not_found, {target_addr, Key}}} end. get_target_params(Params) -> case snmpTargetParamsTable(get, Params, [?snmpTargetParamsMPModel, ?snmpTargetParamsSecurityModel, ?snmpTargetParamsSecurityName, ?snmpTargetParamsSecurityLevel, ?snmpTargetParamsRowStatus]) of [{value, MpModel}, {value, SecModel}, {value, SecName}, {value, SecLevel}, {value, ?'RowStatus_active'}] -> {MpModel, SecModel, SecName, SecLevel}; _ -> undefined end. get_target_engine_id(TargetAddrName) -> case db(snmpTargetAddrTable) of {_, mnesia} -> case mnesia:snmp_get_row(snmpTargetAddrTable, TargetAddrName) of {ok, T} -> {ok, T#snmpTargetAddrTable.snmpTargetAddrEngineId}; _ -> undefined end; TabDb -> case snmpa_local_db:table_get_element(TabDb, TargetAddrName, ?snmpTargetAddrEngineId) of {value, Val} -> {ok, Val}; _ -> undefined end end. set_target_engine_id(TargetAddrName, EngineId) -> snmp_generic:table_set_elements(db(snmpTargetAddrTable), TargetAddrName, [{?snmpTargetAddrEngineId, EngineId}]). %%----------------------------------------------------------------- %% Instrumentation Functions %%----------------------------------------------------------------- snmpTargetSpinLock(print) -> VarAndValue = [{snmpTargetSpinLock, snmpTargetSpinLock(get)}], snmpa_mib_lib:print_variables(VarAndValue); snmpTargetSpinLock(new) -> snmp_generic:variable_func(new, {snmpTargetSpinLock, volatile}), {A1,A2,A3} = erlang:now(), random:seed(A1,A2,A3), Val = random:uniform(2147483648) - 1, snmp_generic:variable_func(set, Val, {snmpTargetSpinLock, volatile}); snmpTargetSpinLock(delete) -> ok; snmpTargetSpinLock(get) -> snmp_generic:variable_func(get, {snmpTargetSpinLock, volatile}). snmpTargetSpinLock(is_set_ok, NewVal) -> case snmp_generic:variable_func(get, {snmpTargetSpinLock, volatile}) of {value, NewVal} -> noError; _ -> inconsistentValue end; snmpTargetSpinLock(set, NewVal) -> snmp_generic:variable_func(set, (NewVal + 1) rem 2147483648, {snmpTargetSpinLock, volatile}). %% Op = print - Used for debugging purposes snmpTargetAddrTable(print) -> Table = snmpTargetAddrTable, DB = db(Table), FOI = foi(Table), PrintRow = fun(Prefix, Row) -> lists:flatten( io_lib:format("~sName: ~p" "~n~sTDomain: ~p (~w)" "~n~sTAddress: ~p (~s)" "~n~sTimeout: ~p" "~n~sRetryCount: ~p" "~n~sTagList: ~p" "~n~sParams: ~p" "~n~sStorageType: ~p (~w)" "~n~sStatus: ~p (~w)" "~n~s[NonAcc] EngineID: ~p" "~n~s[Ext] TMask: ~p" "~n~s[Ext] MMS: ~p", [Prefix, element(?snmpTargetAddrName, Row), Prefix, element(?snmpTargetAddrTDomain, Row), case element(?snmpTargetAddrTDomain, Row) of ?snmpUDPDomain -> snmpUDPDomain; ?transportDomainUdpIpv4 -> transportDomainUdpIpv4; ?transportDomainUdpIpv6 -> transportDomainUdpIpv6; _ -> undefined end, Prefix, element(?snmpTargetAddrTAddress, Row), case element(?snmpTargetAddrTAddress, Row) of [A,B,C,D,U1,U2] -> lists:flatten( io_lib:format("~w.~w.~w.~w:~w", [A, B, C, D, U1 bsl 8 + U2])); _ -> "-" end, Prefix, element(?snmpTargetAddrTimeout, Row), Prefix, element(?snmpTargetAddrRetryCount, Row), Prefix, element(?snmpTargetAddrTagList, Row), Prefix, element(?snmpTargetAddrParams, Row), Prefix, element(?snmpTargetAddrStorageType, Row), case element(?snmpTargetAddrStorageType, Row) of ?'snmpTargetAddrStorageType_readOnly' -> readOnly; ?'snmpTargetAddrStorageType_permanent' -> permanent; ?'snmpTargetAddrStorageType_nonVolatile' -> nonVolatile; ?'snmpTargetAddrStorageType_volatile' -> volatile; ?'snmpTargetAddrStorageType_other' -> other; _ -> undefined end, Prefix, element(?snmpTargetAddrRowStatus, Row), case element(?snmpTargetAddrRowStatus, Row) of ?'snmpTargetAddrRowStatus_destroy' -> destroy; ?'snmpTargetAddrRowStatus_createAndWait' -> createAndWait; ?'snmpTargetAddrRowStatus_createAndGo' -> createAndGo; ?'snmpTargetAddrRowStatus_notReady' -> notReady; ?'snmpTargetAddrRowStatus_notInService' -> notInService; ?'snmpTargetAddrRowStatus_active' -> active; _ -> undefined end, Prefix, element(?snmpTargetAddrEngineId, Row), Prefix, element(?snmpTargetAddrTMask, Row), Prefix, element(?snmpTargetAddrMMS, Row)])) end, snmpa_mib_lib:print_table(Table, DB, FOI, PrintRow); %% Op == new | delete snmpTargetAddrTable(Op) -> snmp_generic:table_func(Op, db(snmpTargetAddrTable)). %% Op == get | is_set_ok | set | get_next snmpTargetAddrTable(get, RowIndex, Cols) -> get(snmpTargetAddrTable, RowIndex, Cols); snmpTargetAddrTable(get_next, RowIndex, Cols) -> next(snmpTargetAddrTable, RowIndex, Cols); snmpTargetAddrTable(set, RowIndex, Cols0) -> %% BMK BMK case (catch verify_targetAddrTable_cols(Cols0)) of {ok, Cols} -> snmp_notification_mib:invalidate_cache(), %% Add columns for augmenting table snmpTargetAddrExtTable and for %% target engine ID. Target engine ID is set to "". The function %% get_target_engine_id will return "" unless a value is set using %% set_target_engine_id. If it is "" Informs can't be sent to the %% target. NCols = Cols ++ [{?snmpTargetAddrEngineId, ""}, {?snmpTargetAddrTMask, []}, {?snmpTargetAddrMMS, 2048}], Db = db(snmpTargetAddrTable), snmp_generic:table_func(set, RowIndex, NCols, Db); Error -> Error end; snmpTargetAddrTable(is_set_ok, RowIndex, Cols0) -> case (catch verify_targetAddrTable_cols(Cols0)) of {ok, Cols} -> %% Add columns for augmenting table snmpTargetAddrExtTable and for %% target engine ID. Target engine ID is set to "". The function %% get_target_engine_id will return "" unless a value is set using %% set_target_engine_id. If it is "" Informs can't be sent to the %% target. NCols = Cols ++ [{?snmpTargetAddrEngineId, ""}, {?snmpTargetAddrTMask, []}, {?snmpTargetAddrMMS, 2048}], Db = db(snmpTargetAddrTable), snmp_generic:table_func(is_set_ok, RowIndex, NCols, Db); Error -> Error end; snmpTargetAddrTable(Op, Arg1, Arg2) -> Db = db(snmpTargetAddrTable), snmp_generic:table_func(Op, Arg1, Arg2, Db). verify_targetAddrTable_cols(Cols) -> ValidCols0 = verify_targetAddrTable_cols(Cols, []), %% Make a last pass to verify TDomain and TAddress. ValidCols0. verify_targetAddrTable_cols([], Cols) -> {ok, lists:reverse(Cols)}; verify_targetAddrTable_cols([{Col, Val0}|Cols], ValidCols) -> Val = verify_targetAddrTable_col(Col, Val0, ValidCols), verify_targetAddrTable_cols(Cols, [{Col, Val}|ValidCols]). verify_targetAddrTable_col(?snmpTargetAddrName, Name, _) -> case (catch snmp_conf:check_string(Name)) of ok -> Name; _ -> wrongValue(?snmpTargetAddrName) end; verify_targetAddrTable_col(?snmpTargetAddrTDomain, TDomain, _) -> case (catch snmp_conf:check_tdomain(TDomain)) of ok -> TDomain; _ -> wrongValue(?snmpTargetAddrTDomain) end; %% In order to (properly) validate the TAddress, %% the TDomain must already have been validated %% (the format of TAddress depends on TDomain). verify_targetAddrTable_col(?snmpTargetAddrTAddress, TAddress, ValidCols) -> case lists:keysearch(?snmpTargetAddrTDomain, 1, ValidCols) of {value, {?snmpTargetAddrTDomain, TDomain}} -> case (catch snmp_conf:check_taddress(TDomain, TAddress)) of ok -> TAddress; _ -> wrongValue(?snmpTargetAddrTAddress) end; false -> %% The user did not provide us with a TDomain, which %% must mean that he/she intends to use the old domain. TDomain = snmp_conf:mk_tdomain(default_domain()), case (catch snmp_conf:check_taddress(TDomain, TAddress)) of ok -> TAddress; _ -> wrongValue(?snmpTargetAddrTAddress) end end; verify_targetAddrTable_col(?snmpTargetAddrTimeout, Timeout, _) -> case (catch snmp_conf:check_integer(Timeout)) of ok when Timeout >= 0 -> Timeout; _ -> wrongValue(?snmpTargetAddrTimeout) end; verify_targetAddrTable_col(?snmpTargetAddrRetryCount, Retry, _) -> case (catch snmp_conf:check_integer(Retry)) of ok when Retry >= 0 -> Retry; _ -> wrongValue(?snmpTargetAddrRetryCount) end; verify_targetAddrTable_col(?snmpTargetAddrTagList, TagList, _) -> case (catch snmp_conf:check_string(TagList)) of ok -> TagList; _ -> wrongValue(?snmpTargetAddrTagList) end; verify_targetAddrTable_col(?snmpTargetAddrParams, Params, _) -> case (catch snmp_conf:check_string(Params)) of ok -> Params; _ -> wrongValue(?snmpTargetAddrParams) end; verify_targetAddrTable_col(_, Val, _) -> Val. %% Op = print - Used for debugging purposes snmpTargetParamsTable(print) -> Table = snmpTargetParamsTable, DB = db(Table), FOI = foi(Table), PrintRow = fun(Prefix, Row) -> lists:flatten( io_lib:format("~sName: ~p" "~n~sMPModel: ~p (~w)" "~n~sSecurityModel: ~p (~w)" "~n~sSecurityName: ~p" "~n~sSecurityLevel: ~p (~w)" "~n~sStorageType: ~p (~w)" "~n~sStatus: ~p (~w)", [Prefix, element(?snmpTargetParamsName, Row), Prefix, element(?snmpTargetParamsMPModel, Row), case element(?snmpTargetParamsMPModel, Row) of ?MP_V1 -> v1; ?MP_V2C -> v2c; ?MP_V3 -> v3; _ -> undefined end, Prefix, element(?snmpTargetParamsSecurityModel, Row), case element(?snmpTargetParamsSecurityModel, Row) of ?SEC_ANY -> any; ?SEC_V1 -> v1; ?SEC_V2C -> v2c; ?SEC_USM -> usm; _ -> undefined end, Prefix, element(?snmpTargetParamsSecurityName, Row), Prefix, element(?snmpTargetParamsSecurityLevel, Row), case element(?snmpTargetParamsSecurityLevel, Row) of ?'SnmpSecurityLevel_noAuthNoPriv' -> noAuthNoPriv; ?'SnmpSecurityLevel_authNoPriv' -> authNoPriv; ?'SnmpSecurityLevel_authPriv' -> authPriv; _ -> undefined end, Prefix, element(?snmpTargetParamsStorageType, Row), case element(?snmpTargetParamsStorageType, Row) of ?'snmpTargetParamsStorageType_readOnly' -> readOnly; ?'snmpTargetParamsStorageType_permanent' -> permanent; ?'snmpTargetParamsStorageType_nonVolatile' -> nonVolatile; ?'snmpTargetParamsStorageType_volatile' -> volatile; ?'snmpTargetParamsStorageType_other' -> other; _ -> undefined end, Prefix, element(?snmpTargetParamsRowStatus, Row), case element(?snmpTargetParamsRowStatus, Row) of ?'snmpTargetParamsRowStatus_destroy' -> destroy; ?'snmpTargetParamsRowStatus_createAndWait' -> createAndWait; ?'snmpTargetParamsRowStatus_createAndGo' -> createAndGo; ?'snmpTargetParamsRowStatus_notReady' -> notReady; ?'snmpTargetParamsRowStatus_notInService' -> notInService; ?'snmpTargetParamsRowStatus_active' -> active; _ -> undefined end])) end, snmpa_mib_lib:print_table(Table, DB, FOI, PrintRow); %% Op == new | delete snmpTargetParamsTable(Op) -> snmp_generic:table_func(Op, db(snmpTargetParamsTable)). %% Op == get | is_set_ok | set | get_next snmpTargetParamsTable(get, RowIndex, Cols) -> %% BMK BMK BMK get(snmpTargetParamsTable, RowIndex, Cols); snmpTargetParamsTable(get_next, RowIndex, Cols) -> %% BMK BMK BMK next(snmpTargetParamsTable, RowIndex, Cols); snmpTargetParamsTable(set, RowIndex, Cols0) -> %% BMK BMK BMK case (catch verify_snmpTargetParamsTable_cols(Cols0, [])) of {ok, Cols} -> snmp_notification_mib:invalidate_cache(), snmp_generic:table_func(set, RowIndex, Cols, db(snmpTargetParamsTable)); Error -> Error end; snmpTargetParamsTable(Op, Arg1, Arg2) -> snmp_generic:table_func(Op, Arg1, Arg2, db(snmpTargetParamsTable)). verify_snmpTargetParamsTable_cols([], Cols) -> {ok, lists:reverse(Cols)}; verify_snmpTargetParamsTable_cols([{Col, Val0}|Cols], Acc) -> Val = verify_snmpTargetParamsTable_col(Col, Val0), verify_snmpTargetParamsTable_cols(Cols, [{Col, Val}|Acc]). verify_snmpTargetParamsTable_col(?snmpTargetParamsName, Name) -> case (catch snmp_conf:check_string(Name)) of ok -> Name; _ -> wrongValue(?snmpTargetParamsName) end; verify_snmpTargetParamsTable_col(?snmpTargetParamsMPModel, Model) -> case Model of v1 -> ?MP_V1; v2c -> ?MP_V2C; v3 -> ?MP_V3; ?MP_V1 -> ?MP_V1; ?MP_V2C -> ?MP_V2C; ?MP_V3 -> ?MP_V3; _ -> wrongValue(?snmpTargetParamsMPModel) end; verify_snmpTargetParamsTable_col(?snmpTargetParamsSecurityModel, Model) -> case Model of v1 -> ?SEC_V1; v2c -> ?SEC_V2C; usm -> ?SEC_USM; ?SEC_V1 -> ?SEC_V1; ?SEC_V2C -> ?SEC_V2C; ?SEC_USM -> ?SEC_USM; _ -> wrongValue(?snmpTargetParamsSecurityModel) end; verify_snmpTargetParamsTable_col(?snmpTargetParamsSecurityName, Name) -> case (catch snmp_conf:check_string(Name)) of ok -> Name; _ -> wrongValue(?snmpTargetParamsSecurityName) end; verify_snmpTargetParamsTable_col(?snmpTargetParamsSecurityLevel, Level) -> case Level of noAuthNoPriv -> 1; authNoPriv -> 2; authPriv -> 3; 1 -> 1; 2 -> 2; 3 -> 3; _ -> wrongValue(?snmpTargetParamsSecurityLevel) end; verify_snmpTargetParamsTable_col(_, Val) -> Val. db(X) -> snmpa_agent:db(X). fa(snmpTargetAddrTable) -> ?snmpTargetAddrTDomain; fa(snmpTargetParamsTable) -> ?snmpTargetParamsMPModel. foi(snmpTargetAddrTable) -> ?snmpTargetAddrName; foi(snmpTargetParamsTable) -> ?snmpTargetParamsName. noc(snmpTargetAddrTable) -> 9; noc(snmpTargetParamsTable) -> 7. stc(snmpTargetAddrTable) -> ?snmpTargetAddrStorageType; stc(snmpTargetParamsTable) -> ?snmpTargetParamsStorageType. next(Name, RowIndex, Cols) -> snmp_generic:handle_table_next(db(Name), RowIndex, Cols, fa(Name), foi(Name), noc(Name)). table_next(Name, RestOid) -> snmp_generic:table_next(db(Name), RestOid). get(Name, RowIndex, Cols) -> snmp_generic:handle_table_get(db(Name), RowIndex, Cols, foi(Name)). wrongValue(V) -> throw({wrongValue, V}). %% ----- 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("[TARGET-MIB]: " ++ F, A).