aboutsummaryrefslogtreecommitdiffstats
path: root/lib/snmp/src
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2013-06-25 12:38:17 +0200
committerMicael Karlberg <[email protected]>2013-07-04 11:21:43 +0200
commita6ba7a3327b146d8472b154cc8ba4544f9d4d0fe (patch)
tree051a8e4d9168e8d369663ddcfb68fc9bb9fb5af0 /lib/snmp/src
parentf9967a625fe06d47f374e30959f6bb6f098cb25e (diff)
downloadotp-a6ba7a3327b146d8472b154cc8ba4544f9d4d0fe.tar.gz
otp-a6ba7a3327b146d8472b154cc8ba4544f9d4d0fe.tar.bz2
otp-a6ba7a3327b146d8472b154cc8ba4544f9d4d0fe.zip
[snmp/agent] Cleanup, renaming, appup, proper version and release notes
Add utility functions for checking view masks. Code cleanup, function renaming and comment fix (%% instead of %). Also updated the mask check in the vacm config file check function. Finally, release notes and some cosmetic changes to the agent config-file(s) user guide chapter.
Diffstat (limited to 'lib/snmp/src')
-rw-r--r--lib/snmp/src/agent/snmp_view_based_acm_mib.erl206
-rw-r--r--lib/snmp/src/app/snmp.appup.src12
-rw-r--r--lib/snmp/src/misc/snmp_conf.erl35
3 files changed, 157 insertions, 96 deletions
diff --git a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl
index 0acef780f8..c0177b1cea 100644
--- a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl
+++ b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2013. 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
@@ -49,6 +49,14 @@
-endif.
+-type internal_view_mask() :: null | [internal_view_mask_element()].
+-type internal_view_mask_element() :: 0 | 1.
+
+-type external_view_mask() :: octet_string(). % At most length of 16 octet
+-type octet_string() :: [octet()].
+-type octet() :: byte().
+
+
%%-----------------------------------------------------------------
%% Func: configure/1
%% Args: Dir is the directory where the configuration files are found.
@@ -160,14 +168,7 @@ check_vacm({vacmViewTreeFamily, ViewName, Tree, Type, Mask}) ->
{ok, TypeVal} =
snmp_conf:check_atom(Type, [{included, ?view_included},
{excluded, ?view_excluded}]),
- MaskVal =
- case (catch snmp_conf:check_atom(Mask, [{null, []}])) of
- {error, _} ->
- snmp_conf:check_oid(Mask),
- Mask;
- {ok, X} ->
- X
- end,
+ {ok, MaskVal} = snmp_conf:check_imask(Mask),
Vacm = {ViewName, Tree, MaskVal, TypeVal,
?'StorageType_nonVolatile', ?'RowStatus_active'},
{ok, {vacmViewTreeFamily, Vacm}};
@@ -194,8 +195,8 @@ init_tabs(Sec2Group, Access, View) ->
ok.
init_sec2group_table([Row | T]) ->
-%% ?vtrace("init security-to-group table: "
-%% "~n Row: ~p",[Row]),
+ %% ?vtrace("init security-to-group table: "
+ %% "~n Row: ~p",[Row]),
Key1 = element(1, Row),
Key2 = element(2, Row),
Key = [Key1, length(Key2) | Key2],
@@ -953,13 +954,23 @@ verify_vacmViewTreeFamilyTable_col(?vacmViewTreeFamilySubtree, Tree) ->
wrongValue(?vacmViewTreeFamilySubtree)
end;
verify_vacmViewTreeFamilyTable_col(?vacmViewTreeFamilyMask, Mask) ->
+ %% Mask here is in the "external" format. That is, according
+ %% to the MIB, which means that its an OCTET STRING of max 16
+ %% octets.
+ %% We however store the mask as a list of 1's (exact) and
+ %% 0's (wildcard), which means we have to convert the mask.
case Mask of
- null -> [];
- [] -> [];
+ %% The Mask can only have this value if the vacmViewTreeFamilyTable
+ %% is called locally!
+ null ->
+ [];
+ [] ->
+ [];
_ ->
- case (catch check_mask(Mask)) of
- ok ->
- mask2oid(Mask);
+ %% Check and convert to our internal format
+ case check_mask(Mask) of
+ {ok, IMask} ->
+ IMask;
_ ->
wrongValue(?vacmViewTreeFamilyMask)
end
@@ -975,53 +986,60 @@ verify_vacmViewTreeFamilyTable_col(?vacmViewTreeFamilyType, Type) ->
end;
verify_vacmViewTreeFamilyTable_col(_, Val) ->
Val.
+
+check_mask(Mask) when is_list(Mask) andalso (length(Mask) =< 16) ->
+ try
+ begin
+ {ok, emask2imask(Mask)}
+ end
+ catch
+ throw:{error, _} ->
+ {error, {bad_mask, Mask}};
+ T:E ->
+ {error, {bad_mask, Mask, T, E}}
+ end;
+check_mask(BadMask) ->
+ {error, {bad_mask, BadMask}}.
+
+-spec emask2imask(EMask :: external_view_mask()) ->
+ IMask :: internal_view_mask().
+
+%% Convert an External Mask (OCTET STRING) to Internal Mask (list of 0 or 1)
+emask2imask(EMask) ->
+ lists:flatten([octet2bits(Octet) || Octet <- EMask]).
+
+octet2bits(Octet)
+ when is_integer(Octet) andalso (Octet >= 16#00) andalso (16#FF >= Octet) ->
+ <<A:1, B:1, C:1, D:1, E:1, F:1, G:1, H:1>> = <<Octet>>,
+ [A, B, C, D, E, F, G, H];
+octet2bits(BadOctet) ->
+ throw({error, {bad_octet, BadOctet}}).
+
+-spec imask2emask(IMask :: internal_view_mask()) ->
+ EMask :: external_view_mask().
+
+%% Convert an Internal Mask (list of 0 or 1) to External Mask (OCTET STRING)
+imask2emask(IMask) ->
+ imask2emask(IMask, []).
+
+imask2emask([], EMask) ->
+ lists:reverse(EMask);
+imask2emask(IMask, EMask) ->
+ %% Make sure we have atleast 8 bits
+ %% (maybe extend with 1's)
+ IMask2 =
+ case length(IMask) of
+ Small when Small < 8 ->
+ IMask ++ lists:duplicate(8-Small, 1);
+ _ ->
+ IMask
+ end,
+ %% Extract 8 bits
+ [A, B, C, D, E, F, G, H | IMaskRest] = IMask2,
+ <<Octet:8>> = <<A:1, B:1, C:1, D:1, E:1, F:1, G:1, H:1>>,
+ imask2emask(IMaskRest, [Octet | EMask]).
-check_mask([]) ->
- ok;
-check_mask([Head | Tail]) when is_integer(Head) ->
-% we can cause exception here because the caller catches
- if
- Head > -1 andalso Head < 256 ->
- check_mask(Tail)
- end.
-
-% internally (for easier computations), the mask is stored
-% as OID and not as bit-field. Therefore, we have to convert
-% the bitstring to a list of integers before storing it.
-mask2oid(Mask) ->
- Func = fun(Byte) ->
- % what's a nice syntax for extracting bits
- % from a byte???
- <<A:1, B:1, C:1, D:1, E:1, F:1, G:1, H:1>> = <<Byte>>,
- [A, B, C, D, E, F, G, H]
- end,
- lists:flatten(lists:map(Func, Mask)).
-
-oid2mask(Oid) ->
- % convert all suboids to either 1 or 0 for sure
- Func = fun
- (0) -> 0;
- (_) -> 1
- end,
- oid2mask(lists:map(Func, Oid), []).
-
-oid2mask([], Mask) ->
- % end-of-list, return bitstring
- lists:reverse(Mask);
-oid2mask(Oid, Mask) ->
- % check whether we've got at least 8 sub-identifiers. if not,
- % extend with 1's until there are enough to fill a byte
- NOid = case length(Oid) of
- Small when Small < 8 ->
- Oid ++ lists:duplicate(8-Small, 1);
- _ ->
- Oid
- end,
- % extract sufficient suboids for 8 bits
- [A, B, C, D, E, F, G, H | Tail] = NOid,
- <<Byte:8>> = <<A:1, B:1, C:1, D:1, E:1, F:1, G:1, H:1>>,
- oid2mask(Tail, [Byte | Mask]).
table_next(Name, RestOid) ->
@@ -1061,42 +1079,40 @@ stc(vacmSecurityToGroupTable) -> ?vacmSecurityToGroupStorageType;
stc(vacmViewTreeFamilyTable) -> ?vacmViewTreeFamilyStorageType.
next(Name, RowIndex, Cols) ->
- Ans = snmp_generic:handle_table_next(db(Name), RowIndex, Cols,
- fa(Name), foi(Name), noc(Name)),
- patch_next(Name, Ans).
+ Result = snmp_generic:handle_table_next(db(Name), RowIndex, Cols,
+ fa(Name), foi(Name), noc(Name)),
+ externalize_next(Name, Result).
get(Name, RowIndex, Cols) ->
- Ans = snmp_generic:handle_table_get(db(Name), RowIndex, Cols, foi(Name)),
- patch(Name, Cols, Ans).
-
-
-patch(Name, Cols, Ans) when is_list(Ans) ->
- % function to patch returned values
- Func = fun
- ({Col, {value, Val}}) -> {value, do_patch(Name, Col, Val)};
- ({_, Other}) -> Other
- end,
- % merge column numbers and return values. there must be as much
- % return values as there are columns requested
- Tmp = lists:zip(Cols, Ans),
- % and patch all values
- lists:map(Func, Tmp);
-patch(_, _, Ans) ->
- Ans.
-
-patch_next(Name, Ans) when is_list(Ans) ->
- Func = fun
- ({[C | _] = Idx, Val}) -> {Idx, do_patch(Name, C, Val)};
- (Other) -> Other
- end,
- lists:map(Func, Ans);
-patch_next(_, Ans) ->
- Ans.
-
-do_patch(vacmViewTreeFamilyTable, ?vacmViewTreeFamilyMask, Val) ->
- oid2mask(Val);
-do_patch(_, _, Val) ->
- Val.
+ Result = snmp_generic:handle_table_get(db(Name), RowIndex, Cols,
+ foi(Name)),
+ externalize_get(Name, Cols, Result).
+
+
+externalize_next(Name, Result) when is_list(Result) ->
+ F = fun({[Col | _] = Idx, Val}) -> {Idx, externalize(Name, Col, Val)};
+ (Other) -> Other
+ end,
+ [F(R) || R <- Result];
+externalize_next(_, Result) ->
+ Result.
+
+
+externalize_get(Name, Cols, Result) when is_list(Result) ->
+ %% Patch returned values
+ F = fun({Col, {value, Val}}) -> {value, externalize(Name, Col, Val)};
+ ({_, Other}) -> Other
+ end,
+ %% Merge column numbers and return values. there must be as much
+ %% return values as there are columns requested. And then patch all values
+ [F(R) || R <- lists:zip(Cols, Result)];
+externalize_get(_, _, Result) ->
+ Result.
+
+externalize(vacmViewTreeFamilyTable, ?vacmViewTreeFamilyMask, Val) ->
+ imask2emask(Val);
+externalize(_, _, Val) ->
+ Val.
wrongValue(V) -> throw({wrongValue, V}).
diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src
index 7ffa4a725d..106fed749d 100644
--- a/lib/snmp/src/app/snmp.appup.src
+++ b/lib/snmp/src/app/snmp.appup.src
@@ -22,6 +22,12 @@
%% ----- U p g r a d e -------------------------------------------------------
[
+ {"4.24",
+ [
+ {load_module, snmp_conf, soft_purge, soft_purge, []},
+ {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, [snmp_conf]}
+ ]
+ },
{"4.23.1", [{restart_application, snmp}]},
{"4.23", [{restart_application, snmp}]}
],
@@ -29,6 +35,12 @@
%% ------D o w n g r a d e ---------------------------------------------------
[
+ {"4.24",
+ [
+ {load_module, snmp_conf, soft_purge, soft_purge, []},
+ {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, [snmp_conf]}
+ ]
+ },
{"4.23.1", [{restart_application, snmp}]},
{"4.23", [{restart_application, snmp}]}
]
diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl
index e1e7fab57b..46625989d5 100644
--- a/lib/snmp/src/misc/snmp_conf.erl
+++ b/lib/snmp/src/misc/snmp_conf.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2013. 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
@@ -50,6 +50,7 @@
check_packet_size/1,
check_oid/1,
+ check_imask/1, check_emask/1,
check_mp_model/1,
check_sec_model/1, check_sec_model/2, check_sec_model/3,
@@ -488,6 +489,7 @@ do_check_timer(WaitFor, Factor, Incr, Retry) ->
check_integer(Retry, {gte, 0}),
ok.
+
%% ---------
all_domains() ->
@@ -618,6 +620,37 @@ check_oid(X) ->
%% ---------
+%% Check a (view) mask in the internal form (all 0 and 1):
+check_imask(null) ->
+ {ok, []};
+check_imask(IMask) when is_list(IMask) ->
+ do_check_imask(IMask),
+ {ok, IMask}.
+
+do_check_imask([0|IMask]) ->
+ do_check_imask(IMask);
+do_check_imask([1|IMask]) ->
+ do_check_imask(IMask);
+do_check_imask([X|_]) ->
+ error({invalid_internal_mask_element, X}).
+
+
+%% Check a (view) mask in the external form (according to MIB,
+%% an OCTET STRING of at most length 16).
+check_emask(EMask) when is_list(EMask) andalso (length(EMask) =< 16) ->
+ do_check_emask(EMask).
+
+do_check_emask([]) ->
+ ok;
+do_check_emask([X|EMask])
+ when is_integer(X) andalso (X >= 16#00) andalso (X =< 16#FF) ->
+ do_check_emask(EMask);
+do_check_emask([X|_]) ->
+ error({invalid_external_mask_element, X}).
+
+
+%% ---------
+
all_integer([H|T]) when is_integer(H) -> all_integer(T);
all_integer([_H|_T]) -> false;
all_integer([]) -> true.