diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/snmp/src/agent/snmp_view_based_acm_mib.erl | 91 |
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}). |