aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2013-06-24 15:20:26 +0200
committerMicael Karlberg <[email protected]>2013-06-24 15:20:26 +0200
commitf9967a625fe06d47f374e30959f6bb6f098cb25e (patch)
tree9d0012f809ba5a05d325c3de8d5e34c0ea2a32a0 /lib
parent8cece79b77952c991e62ae595bcf71cde016a052 (diff)
parenta31c7b2eb22d15f1ca6c2d6bca257faa2315fcf7 (diff)
downloadotp-f9967a625fe06d47f374e30959f6bb6f098cb25e.tar.gz
otp-f9967a625fe06d47f374e30959f6bb6f098cb25e.tar.bz2
otp-f9967a625fe06d47f374e30959f6bb6f098cb25e.zip
Merge branch 'sze/fix-vacm' into bmk/snmp/agent/fix_vacm_mask/OTP-11177
Diffstat (limited to 'lib')
-rw-r--r--lib/snmp/src/agent/snmp_view_based_acm_mib.erl91
1 files changed, 85 insertions, 6 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 ad9540e886..0acef780f8 100644
--- a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl
+++ b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl
@@ -957,9 +957,9 @@ verify_vacmViewTreeFamilyTable_col(?vacmViewTreeFamilyMask, Mask) ->
null -> [];
[] -> [];
_ ->
- case (catch snmp_conf:check_oid(Mask)) of
+ case (catch check_mask(Mask)) of
ok ->
- Mask;
+ mask2oid(Mask);
_ ->
wrongValue(?vacmViewTreeFamilyMask)
end
@@ -975,7 +975,54 @@ verify_vacmViewTreeFamilyTable_col(?vacmViewTreeFamilyType, Type) ->
end;
verify_vacmViewTreeFamilyTable_col(_, Val) ->
Val.
-
+
+
+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) ->
snmp_generic:table_next(db(Name), RestOid).
@@ -1014,11 +1061,43 @@ stc(vacmSecurityToGroupTable) -> ?vacmSecurityToGroupStorageType;
stc(vacmViewTreeFamilyTable) -> ?vacmViewTreeFamilyStorageType.
next(Name, RowIndex, Cols) ->
- snmp_generic:handle_table_next(db(Name), RowIndex, Cols,
- fa(Name), foi(Name), noc(Name)).
+ Ans = snmp_generic:handle_table_next(db(Name), RowIndex, Cols,
+ fa(Name), foi(Name), noc(Name)),
+ patch_next(Name, Ans).
get(Name, RowIndex, Cols) ->
- snmp_generic:handle_table_get(db(Name), RowIndex, Cols, foi(Name)).
+ 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.
+
wrongValue(V) -> throw({wrongValue, V}).