From d9e63bfb1a4a452ad8eb7a9e62d5127a666e2845 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Mon, 4 Feb 2013 19:08:56 +0100 Subject: [snmp/compiler] MIB compiler did not handle forward index ref The MIB compiler could not handle a table index refering to an object defined later in the MIB. --- lib/snmp/src/compile/snmpc.erl | 51 ++++++++++++++++++++++++++++++++++---- lib/snmp/src/compile/snmpc_lib.erl | 35 +++++++++++++++++++------- 2 files changed, 72 insertions(+), 14 deletions(-) (limited to 'lib') diff --git a/lib/snmp/src/compile/snmpc.erl b/lib/snmp/src/compile/snmpc.erl index 5e6b81f1ec..b238214798 100644 --- a/lib/snmp/src/compile/snmpc.erl +++ b/lib/snmp/src/compile/snmpc.erl @@ -562,8 +562,10 @@ definitions_loop([{#mc_object_type{name = NameOfTable, units = Eunits}, {ColMEs, RestObjs} = define_cols(ColsEtc, 1, FieldList, NameOfEntry, NameOfTable, []), + AfterIdxTypes = after_indexes_type(IndexingInfo, RestObjs), + after_indexes_type(IndexingInfo, RestObjs), TableInfo = snmpc_lib:make_table_info(Eline, NameOfTable, - IndexingInfo, ColMEs), + IndexingInfo, AfterIdxTypes, ColMEs), snmpc_lib:add_cdata(#cdata.mes, [TableEntryME, TableME#me{assocList=[{table_info, @@ -644,8 +646,9 @@ definitions_loop([{#mc_object_type{name = NameOfTable, units = Eunits}, {ColMEs, RestObjs} = define_cols(ColsEtc, 1, FieldList, NameOfEntry, NameOfTable, []), + AfterIdxTypes = after_indexes_type(IndexingInfo, RestObjs), TableInfo = snmpc_lib:make_table_info(Eline, NameOfTable, - IndexingInfo, ColMEs), + IndexingInfo, AfterIdxTypes, ColMEs), snmpc_lib:add_cdata(#cdata.mes, [TableEntryME, TableME#me{assocList=[{table_info, @@ -720,8 +723,9 @@ definitions_loop([{#mc_object_type{name = NameOfTable, units = Eunits}, {ColMEs, RestObjs} = define_cols(ColsEtc, 1, FieldList, NameOfEntry, NameOfTable, []), + AfterIdxTypes = after_indexes_type(IndexingInfo, RestObjs), TableInfo = snmpc_lib:make_table_info(Eline, NameOfTable, - IndexingInfo, ColMEs), + IndexingInfo, AfterIdxTypes, ColMEs), snmpc_lib:add_cdata(#cdata.mes, [TableEntryME, TableME#me{assocList=[{table_info, @@ -1205,6 +1209,12 @@ safe_elem(N,T) -> X -> X end. + +%% An table index is either: +%% a) part of the table +%% b) not part of the table and defined *before* the table +%% c) not part of the table and defined *after* the table + %% A correct column define_cols([{#mc_object_type{name = NameOfCol, syntax = Type1, @@ -1379,14 +1389,45 @@ define_cols(Rest, _SubIndex,_,_,_,ColMEs) -> snmpc_lib:print_error("Corrupt table definition.",[]), {ColMEs,Rest}. + +%% Table indexes can either be: +%% a) part of the table (a column) +%% b) not part of the table and defined *before* the table +%% c) not part of the table and defined *after* the table + +after_indexes_type({indexes, Indexes}, Objs) -> + after_indexes_type2(Indexes, Objs); +after_indexes_type(_, _) -> + []. + +after_indexes_type2(Indexes, Objs) -> + after_indexes_type2(Indexes, Objs, []). + +after_indexes_type2([], _Objs, IndexesASN1types) -> + IndexesASN1types; +after_indexes_type2([Index|Indexes], Objs, Acc) -> + Acc2 = after_indexes_type3(Index, Objs, Acc), + after_indexes_type2(Indexes, Objs, Acc2). + +after_indexes_type3(_Index, [], Acc) -> + Acc; +after_indexes_type3(Index, + [{#mc_object_type{name = Index, + syntax = Syntax},_}|_], Acc) -> + ASN1 = snmpc_lib:make_ASN1type(Syntax), + [{Index, ASN1}|Acc]; +after_indexes_type3(Index, [_|Objs], Acc) -> + after_indexes_type3(Index, Objs, Acc). + + + ensure_macro_imported(dummy, _Line) -> ok; ensure_macro_imported(Macro, Line) -> Macros = (get(cdata))#cdata.imported_macros, case lists:member(Macro, Macros) of true -> ok; false -> - snmpc_lib:print_error("Macro ~p not imported.", [Macro], - Line) + snmpc_lib:print_error("Macro ~p not imported.", [Macro], Line) end. test_table(NameOfTable, Taccess, Kind, _Tindex, Tline) -> diff --git a/lib/snmp/src/compile/snmpc_lib.erl b/lib/snmp/src/compile/snmpc_lib.erl index 3652054298..5a661cf194 100644 --- a/lib/snmp/src/compile/snmpc_lib.erl +++ b/lib/snmp/src/compile/snmpc_lib.erl @@ -24,7 +24,7 @@ -compile({no_auto_import,[error/2]}). -export([test_father/4, make_ASN1type/1, import/1, makeInternalNode2/2, is_consistent/1, resolve_defval/1, make_variable_info/1, - check_trap_name/3, make_table_info/4, get_final_mib/2, set_dir/2, + check_trap_name/3, make_table_info/5, get_final_mib/2, set_dir/2, look_at/1, add_cdata/2, check_object_group/4, check_notification_group/4, check_notification/3, @@ -707,7 +707,8 @@ check_trap_name(EnterpriseName, Line, MEs) -> %% This information is needed to be able to create default instrumentation %% functions for tables. %%---------------------------------------------------------------------- -make_table_info(Line, TableName, {augments, SrcTableEntry}, ColumnMEs) -> + +make_table_info(Line, TableName, {augments, SrcTableEntry}, _, ColumnMEs) -> ColMEs = lists:keysort(#me.oid, ColumnMEs), Nbr_of_Cols = length(ColMEs), MEs = ColMEs ++ (get(cdata))#cdata.mes, @@ -726,16 +727,18 @@ make_table_info(Line, TableName, {augments, SrcTableEntry}, ColumnMEs) -> first_accessible = FirstAcc, not_accessible = NoAccs, index_types = Aug}; -make_table_info(Line, TableName, {indexes, []}, _ColumnMEs) -> +make_table_info(Line, TableName, {indexes, []}, _, _ColumnMEs) -> print_error("Table ~w lacks indexes.", [TableName],Line), #table_info{}; -make_table_info(Line, TableName, {indexes, Indexes}, ColumnMEs) -> +make_table_info(Line, TableName, {indexes, Indexes}, AfterIdxTypes, + ColumnMEs) -> ColMEs = lists:keysort(#me.oid, ColumnMEs), NonImpliedIndexes = lists:map(fun non_implied_name/1, Indexes), test_read_create_access(ColMEs, Line, dummy), NonIndexCol = test_index_positions(Line, NonImpliedIndexes, ColMEs), Nbr_of_Cols = length(ColMEs), - ASN1Indexes = find_asn1_types_for_indexes(Indexes, ColMEs, Line), + ASN1Indexes = find_asn1_types_for_indexes(Indexes, + AfterIdxTypes, ColMEs, Line), FA = first_accessible(TableName, ColMEs), StatCol = find_status_col(Line, TableName, ColMEs), NoAccs = list_not_accessible(NonIndexCol,ColMEs), @@ -819,11 +822,17 @@ get_defvals(ColMEs) -> lists:filter(fun drop_undefined/1, lists:map(fun column_and_defval/1, ColMEs))). -find_asn1_types_for_indexes(Indexes, ColMEs,Line) -> - MEs = ColMEs ++ (get(cdata))#cdata.mes, +find_asn1_types_for_indexes(Indexes, AfterIdxTypes, ColMEs, Line) -> + ?vtrace("find_asn1_types_for_indexes -> " + "~n Indexes: ~p" + "~n ColMEs: ~p" + "~n Line: ~p", [Indexes, ColMEs, Line]), + MEs = ColMEs ++ (get(cdata))#cdata.mes ++ + [#me{aliasname = Idx, asn1_type = Type} || {Idx, Type} <- + AfterIdxTypes], test_implied(Indexes, Line), lists:map(fun (ColumnName) -> - translate_type(get_asn1_type(ColumnName, MEs,Line)) + translate_type(get_asn1_type(ColumnName, MEs, Line)) end, Indexes). @@ -849,7 +858,11 @@ column_and_defval(#me{oid = Oid, assocList = AssocList}) -> end. %% returns: an asn1_type if ColME is an indexfield, otherwise undefined. -get_asn1_type({implied,ColumnName}, MEs, Line) -> +get_asn1_type({implied, ColumnName}, MEs, Line) -> + ?vtrace("get_asn1_type(implied) -> " + "~n ColumnName: ~p" + "~n MEs: ~p" + "~n Line: ~p", [ColumnName, MEs, Line]), case lookup(ColumnName, MEs) of {value,#me{asn1_type=A}} when A#asn1_type.bertype =:= 'OCTET STRING' -> @@ -862,6 +875,10 @@ get_asn1_type({implied,ColumnName}, MEs, Line) -> [Shit], Line) end; get_asn1_type(ColumnName, MEs, Line) -> + ?vtrace("get_asn1_type -> " + "~n ColumnName: ~p" + "~n MEs: ~p" + "~n Line: ~p", [ColumnName, MEs, Line]), case lookup(ColumnName, MEs) of {value,ME} -> ME#me.asn1_type; false -> error("Can't find object ~p. Used as INDEX in table.", -- cgit v1.2.3