%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 1998-2014. 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 and parameter config file(s)",[]),
TAName = "target_addr.conf",
TACheck = fun (Entry, State) -> {check_target_addr(Entry), State} end,
TPName = "target_params.conf",
TPCheck = fun (Entry, State) -> {check_target_params(Entry), State} end,
NoGen = fun snmp_conf:no_gen/2,
NoOrder = fun snmp_conf:no_order/2,
NoFilter = fun snmp_conf:no_filter/1,
[Addrs, Params] =
snmp_conf:read_files(
Dir,
[{TAName, NoGen, NoOrder, TACheck, NoFilter},
{TPName, NoGen, NoOrder, TPCheck, NoFilter}]),
{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}) -> % Arity 11
Address = {Ip, Udp},
check_target_addr(
Name, Domain, Address, Timeout, RetryCount, TagList, Params,
EngineId, TMask, MMS);
check_target_addr(
{Name, Domain, Address, Timeout, RetryCount, TagList, Params,
EngineId, TMask, MMS}) % Arity 10
when is_atom(Domain) ->
check_target_addr(
Name, Domain, Address, Timeout, RetryCount, TagList, Params,
EngineId, TMask, MMS);
check_target_addr(
{Name, Ip, Udp, Timeout, RetryCount, TagList, Params,
EngineId, TMask, MMS}) -> % Arity 10
Domain = default_domain(),
Address = {Ip, Udp},
check_target_addr(
Name, Domain, Address, Timeout, RetryCount, TagList, Params,
EngineId, TMask, MMS);
check_target_addr(
{Name, Domain, Address, Timeout, RetryCount, TagList, Params,
EngineId}) % Arity 8
when is_atom(Domain) ->
check_target_addr(
Name, Domain, Address, Timeout, RetryCount, TagList, Params,
EngineId);
check_target_addr(
{Name, Ip, Udp, Timeout, RetryCount, TagList, Params,
EngineId}) -> % Arity 8
Domain = default_domain(),
Address = {Ip, Udp},
check_target_addr(
Name, Domain, Address, Timeout, RetryCount, TagList, Params,
EngineId);
%% Use dummy engine id if the old style is found
check_target_addr(
{Name, Domain, Address, Timeout, RetryCount, TagList, Params}) % Arity 7
when is_atom(Domain) ->
check_target_addr(
Name, Domain, Address, Timeout, RetryCount, TagList, Params);
check_target_addr(
{Name, Ip, Udp, Timeout, RetryCount, TagList, Params}) -> % Arity 7
Domain = default_domain(),
Address = {Ip, Udp},
check_target_addr(
Name, Domain, Address, Timeout, RetryCount, TagList, Params);
%% Use dummy engine id if the old style is found
check_target_addr(
{Name, Domain, Address, Timeout, RetryCount, TagList, Params,
TMask, MMS}) % Arity 9
when is_atom(Domain) ->
check_target_addr(
Name, Domain, Address, Timeout, RetryCount, TagList, Params, TMask, MMS);
check_target_addr(
{Name, Ip, Udp, Timeout, RetryCount, TagList, Params,
TMask, MMS}) -> % Arity 9
Domain = default_domain(),
Address = {Ip, Udp},
check_target_addr(
Name, Domain, Address, Timeout, RetryCount, TagList, Params, TMask, MMS);
check_target_addr(X) ->
error({invalid_target_addr, X}).
check_target_addr(
Name, Domain, Address, Timeout, RetryCount, TagList, Params) -> % Arity 7
check_target_addr(
Name, Domain, Address, Timeout, RetryCount, TagList, Params,
"dummy").
%%
check_target_addr(
Name, Domain, Address, Timeout, RetryCount, TagList, Params,
EngineId) -> % Arity 8
check_target_addr(
Name, Domain, Address, Timeout, RetryCount, TagList, Params,
EngineId, [], 2048).
%%
check_target_addr(
Name, Domain, Address, Timeout, RetryCount, TagList, Params,
TMask, MMS) -> % Arity 9
check_target_addr(
Name, Domain, Address, Timeout, RetryCount, TagList, Params,
"dummy", TMask, MMS).
%%
check_target_addr(
Name, Domain, Address, Timeout, RetryCount, TagList, Params,
EngineId, Mask, MMS) -> % Arity 10
?vtrace("check target address with:"
"~n Name: ~s"
"~n Domain: ~p"
"~n Address: ~p"
"~n Timeout: ~p"
"~n RetryCount: ~p"
"~n TagList: ~p"
"~n Params: ~p"
"~n EngineId: ~p"
"~n Mask: ~p"
"~n MMS: ~p",
[Name, Domain, Address,
Timeout, RetryCount,
TagList, Params, EngineId, Mask, MMS]),
snmp_conf:check_string(Name,{gt,0}),
snmp_conf:check_domain(Domain),
snmp_conf:check_address(Domain, Address),
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),
check_mask(Domain, Mask),
TDomain = snmp_conf:mk_tdomain(Domain),
TAddress = snmp_conf:mk_taddress(Domain, Address),
TMask = snmp_conf:mk_taddress(Domain, Mask),
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_engine_id(discovery) ->
ok;
check_engine_id(EngineId) ->
snmp_conf:check_string(EngineId).
check_mask(_Domain, []) ->
ok;
check_mask(Domain, Mask) ->
try snmp_conf:check_address(Domain, Mask)
catch
{error, {invalid_address, Info}} ->
{error, {invalid_mask, Info}}
end.
%%-----------------------------------------------------------------
%% 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).