snmp_pdus.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 744 行 · 第 1/2 页

ERL
744
字号
chk_msg_max_size(MMS) -> exit({bad_msg_max_size, MMS}).    chk_msg_sec_model(MsgSecurityModel) when MsgSecurityModel >= 0,					 MsgSecurityModel =< 2147483647 -> ok;chk_msg_sec_model(MsgSecurityModel) ->     exit({bad_msg_sec_model, MsgSecurityModel}).    %%----------------------------------------------------------------------%% Code copied from the original ASN.1 compiler written by %% klacke@erix.ericsson.se%%----------------------------------------------------------------------%%----------------------------------------------------------------------%% Returns: {Len, Tail}%%----------------------------------------------------------------------dec_len([128|_Tail]) ->    %% indefinite form - not allowed in SNMP    exit({asn1_error, indefinite_length});dec_len([Hd|Tl]) when Hd >= 0 ->    %% definite form    if	Hd < 128 -> % 8th bit is cleared	    %% Short form (actually, we can remove this test, since snmp_pdus	    %% performs this test _before_ calling this function)	    {Hd,Tl};	true ->	    %% Long form	    No = Hd band 127,  % clear 8th bit	    {DigList,Rest} = head(No,Tl),	    Size = dec_integer_len(DigList),	    {Size,Rest}    end.dec_integer_len([D]) ->    D;dec_integer_len([A,B]) ->    (A bsl 8) bor B;dec_integer_len([A,B,C]) ->    (A bsl 16) bor (B bsl 8) bor C;%% More than 3 elements for length => either *very* long packet%% (which we don't handle), or the length is encoded with more octets%% than necessary (in which case the first octet must be 0).dec_integer_len([0 | T]) ->    dec_integer_len(T).%%-----------------------------------------------------------------%% head(N, List) -> {List1, List2}%%   List == List1 ++ List2%%   length(List1) == N%%-----------------------------------------------------------------head(L,List) ->    head(L,List,[]).head(0,L,Res) ->    {lists:reverse(Res),L};head(Int,[H|Tail],Res) ->    head(Int-1,Tail,[H|Res]);head(Int, [], _Res) ->    exit({asn1_error, {bad_length, Int}}).%%%----------------------------------------------------------------------%%% ENCODING ENCODING ENCODING ENCODING ENCODING ENCODING ENCODING ENCODING %%%----------------------------------------------------------------------enc_message(#message{version = Ver, vsn_hdr = VsnHdr, data = Data}) ->    VerBytes = enc_version(Ver),    Bytes = 	case Ver of	    'version-3' ->		V3HeaderBytes = enc_v3_header(VsnHdr),		DataBytes = enc_scoped_pdu(Data),		V3HeaderBytes ++ DataBytes;	    _ ->		ComBytes = enc_community(VsnHdr),		DataBytes = enc_pdu(Data),		ComBytes ++ DataBytes	end,    Bytes2 = VerBytes ++ Bytes,    Len = elength(length(Bytes2)),    [48 | Len] ++ Bytes2.enc_message_only(#message{version = Ver, vsn_hdr = VsnHdr, data = DataBytes}) ->    VerBytes = enc_version(Ver),    Bytes = 	case Ver of	    'version-3' ->		V3HeaderBytes = enc_v3_header(VsnHdr),		V3HeaderBytes ++ DataBytes;	    _ ->		ComBytes = enc_community(VsnHdr),		ComBytes ++ DataBytes	end,    Bytes2 = VerBytes ++ Bytes,    Len = elength(length(Bytes2)),    [48 | Len] ++ Bytes2.enc_version('version-1') ->    [2,1,0];enc_version('version-2') ->    [2,1,1];enc_version('version-3') ->    [2,1,3].enc_community(Com) ->    enc_oct_str_tag(Com).enc_v3_header(#v3_hdr{msgID = MsgID,		      msgMaxSize = MsgMaxSize,		      msgFlags = MsgFlags,		      msgSecurityModel = MsgSecurityModel,		      msgSecurityParameters = MsgSecurityParameters}) ->    Bytes = lists:append([enc_integer_tag(MsgID),			  enc_integer_tag(MsgMaxSize),			  enc_oct_str_tag(MsgFlags),			  enc_integer_tag(MsgSecurityModel)]),    Len = elength(length(Bytes)),    lists:append([[48 | Len], Bytes, enc_oct_str_tag(MsgSecurityParameters)]).    enc_scoped_pdu(#scopedPdu{contextEngineID = ContextEngineID,			  contextName = ContextName,			  data = Data}) ->    Bytes = lists:append([enc_oct_str_tag(ContextEngineID),			  enc_oct_str_tag(ContextName),			  enc_pdu(Data)]),    Len = elength(length(Bytes)),    [48 | Len] ++ Bytes.enc_pdu(PDU) when PDU#pdu.type == 'get-request' ->    enc_pdu(160, PDU);enc_pdu(PDU) when PDU#pdu.type == 'get-next-request' ->    enc_pdu(161, PDU);enc_pdu(PDU) when PDU#pdu.type == 'get-response' ->    enc_pdu(162, PDU);enc_pdu(PDU) when PDU#pdu.type == 'set-request' ->    enc_pdu(163, PDU);enc_pdu(PDU) when PDU#pdu.type == 'get-bulk-request' ->    enc_pdu(165, PDU);enc_pdu(PDU) when PDU#pdu.type == 'inform-request' ->    enc_pdu(166, PDU);enc_pdu(PDU) when PDU#pdu.type == 'snmpv2-trap' ->    enc_pdu(167, PDU);enc_pdu(PDU) when PDU#pdu.type == report ->    enc_pdu(168, PDU);enc_pdu(TrapPDU) when record(TrapPDU, trappdu) ->    enc_Trap(TrapPDU).enc_pdu(Tag,PDU) ->    Bytes2 = enc_pdu2(PDU),    Len2 = elength(length(Bytes2)),    lists:append([Tag | Len2], Bytes2).enc_pdu2(#pdu{type = Type, request_id = ReqId, error_index = ErrIndex,	      error_status = ErrStat, varbinds = VBs}) ->    ReqBytes = enc_integer_tag(ReqId),    Val = err_val(ErrStat,Type),    ErrStatBytes = enc_integer_tag(Val),    ErrIndexBytes = enc_integer_tag(ErrIndex),    VBsBytes = enc_VarBindList(VBs),    lists:append([ReqBytes, ErrStatBytes, ErrIndexBytes, VBsBytes]).enc_usm_security_parameters(  #usmSecurityParameters{msgAuthoritativeEngineID = MsgAuthEngineID,			 msgAuthoritativeEngineBoots = MsgAuthEngineBoots,			 msgAuthoritativeEngineTime = MsgAuthEngineTime,			 msgUserName = MsgUserName,			 msgAuthenticationParameters = MsgAuthParams,			 msgPrivacyParameters = MsgPrivParams}) ->    Bytes1 = enc_oct_str_tag(MsgAuthEngineID),    Bytes2 = enc_integer_tag(MsgAuthEngineBoots),    Bytes3 = enc_integer_tag(MsgAuthEngineTime),    Bytes4 = enc_oct_str_tag(MsgUserName),    Bytes5 = enc_oct_str_tag(MsgAuthParams),    Bytes6 = enc_oct_str_tag(MsgPrivParams),    Bytes7 = lists:append([Bytes1, Bytes2, Bytes3, Bytes4, Bytes5, Bytes6]),    Len = elength(length(Bytes7)),    [48 | Len] ++ Bytes7.err_val(Int,'get-bulk-request') when integer(Int) -> Int;err_val(ErrStat, _) ->    {value, {_ErrStat, Val}} = lists:keysearch(ErrStat, 1, errMsgs()),    Val.errMsgs() ->    [{noError,0},{tooBig,1},{noSuchName,2},     {badValue,3},{readOnly,4},{genErr,5},     %% v2     {noAccess,6},{wrongType,7},{wrongLength,8},{wrongEncoding,9},     {wrongValue,10},{noCreation,11},{inconsistentValue,12},     {resourceUnavailable,13},{commitFailed,14},{undoFailed,15},     {authorizationError,16},{notWritable,17},{inconsistentName,18}].enc_VarBindList(EncodedVBs) when integer(hd(EncodedVBs)) ->    Len1 = elength(length(EncodedVBs)),    lists:append([48 | Len1],EncodedVBs);enc_VarBindList(VBs) ->    Bytes1 = lists:append(lists:map(fun enc_varbind/1, VBs)),    Len1 = elength(length(Bytes1)),    lists:append([48 | Len1],Bytes1).enc_varbind(Varbind) ->    Bytes1 = enc_VarBind_attributes(Varbind),    Len1 = elength(length(Bytes1)),    lists:append([48 | Len1],Bytes1).enc_VarBind_attributes(#varbind{oid = Oid, variabletype = Type,value = Val}) ->    OidBytes = enc_oid_tag(Oid),    ValueBytes = enc_value(Type, Val),    lists:append(OidBytes, ValueBytes).enc_value('INTEGER',Val) ->    enc_integer_tag(Val);enc_value('OCTET STRING', Val) ->    enc_oct_str_tag(Val);enc_value('BITS', Val) ->    enc_oct_str_tag(bits_to_str(Val));enc_value('OBJECT IDENTIFIER', Val) ->    enc_oid_tag(Val);enc_value('IpAddress',Val) ->    Bytes2 = enc_oct_str_notag(Val),    Len2 = elength(length(Bytes2)),    lists:append([64 | Len2],Bytes2);enc_value('Opaque', Val) ->    Bytes2 = enc_oct_str_notag(Val),    Len2 = elength(length(Bytes2)),    lists:append([68 | Len2],Bytes2);enc_value(_Type, noSuchObject) ->    [128,0];enc_value(_Type, noSuchInstance) ->    [129,0];enc_value(_Type, endOfMibView) ->    [130,0];enc_value('NULL', _Val) ->    [5,0];enc_value(Type, Val) ->    Bytes2 = enc_integer_notag(Val),    Len2 = elength(length(Bytes2)),    lists:append([enc_val_tag(Type,Val) | Len2],Bytes2).enc_val_tag('Counter32',Val) when Val >= 0, Val =< 4294967295 ->    65;enc_val_tag('Unsigned32', Val) when Val >= 0, Val =< 4294967295 ->    66;enc_val_tag('TimeTicks', Val) when Val >= 0, Val =< 4294967295 ->    67;enc_val_tag('Counter64', Val) when Val >= 0, Val =< 18446744073709551615 ->    70.%%----------------------------------------------------------------------%% Impl according to RFC1906, section 8%% For example: the number 1010 0000 (=160)   0100 0001 (=65) is represented as%% the octet string: 1000 0010, 0000 0101 (=[130,5])%%----------------------------------------------------------------------bits_to_str(0) -> "";bits_to_str(Int) ->    [rev_int8(Int band 255) | bits_to_str(Int div 256)].rev_int8(Val) ->    rev_int(Val,0,1,128).rev_int(_Val,Res,256,0) -> Res;rev_int(Val,Res,OldBit,NewBit) when Val band OldBit =/= 0 ->    rev_int(Val,Res+NewBit,OldBit*2,NewBit div 2);rev_int(Val,Res,OldBit,NewBit) ->    rev_int(Val,Res,OldBit*2,NewBit div 2).octet_str_to_bits(Str) ->    octet_str_to_bits(Str,1).octet_str_to_bits("",_) -> 0;octet_str_to_bits([Byte|Bytes],Mul) ->    Mul*rev_int8(Byte)+octet_str_to_bits(Bytes,Mul*256).    enc_Trap(TrapPdu) when record(TrapPdu, trappdu) ->    Bytes1 = enc_trap_data(TrapPdu),    Len1 = elength(length(Bytes1)),    lists:append([164 | Len1],Bytes1).enc_trap_data(#trappdu{enterprise = Enterprise,		       agent_addr = AgentAddr,		       generic_trap = GenericTrap,		       specific_trap = SpecificTrap,		       time_stamp = TimeStamp,		       varbinds = VBs}) ->    L1 = enc_oid_tag(Enterprise),    L2 = enc_value('IpAddress', AgentAddr),    L3 = enc_integer_tag(GenericTrap),    L4 = enc_integer_tag(SpecificTrap),    L5 = enc_value('TimeTicks', TimeStamp),    L6 = enc_VarBindList(VBs),    lists:append([L1,L2,L3,L4,L5,L6]).enc_oid_tag([E1,E2|RestOid]) when E1 * 40 + E2 =< 255 ->    Head = 40*E1 + E2,  % weird    Res = e_object_elements(RestOid, []),    lists:append([6 | elength(length(Res) + 1)],[Head|Res]).e_object_elements([Num | T], Res)  ->    e_object_elements(T, lists:append(e_object_element(Num),Res));e_object_elements([], Res) -> lists:reverse(Res).%%----------------------------------------------------------------------%% The reversed encoding for an oid-element%%----------------------------------------------------------------------e_object_element(Num) when Num > 0 ->    [Last|T] = e_object_element2(Num),    [Last-128|T];e_object_element(0) -> [0].e_object_element2(Num) when Num > 0 ->    Byte = (Num rem 128),    [128+Byte | e_object_element2((Num-Byte) div 128)];e_object_element2(0) -> [].enc_integer_tag(Val) when Val >= 0 ->  %% stdcase positive ints    Bytes = eint(Val,[]),    [2 | elength(length(Bytes))] ++ Bytes;enc_integer_tag(Val) ->  %% It's a negative number    Bytes = enint(Val,[]),    [2 | elength(length(Bytes))] ++ Bytes.enc_integer_notag(Val) when Val >= 0 ->  %% stdcase positive ints    eint(Val,[]);    enc_integer_notag(Val) -> %% It's a negative number    enint(Val,[]).eint(0, [B|Acc]) when B < 128 ->    [B|Acc];eint(N, Acc) ->    eint(N bsr 8, [N band 16#ff| Acc]).enint(-1, [B1|T]) when B1 > 127 ->    [B1|T];enint(N, Acc) ->    enint(N bsr 8, [N band 16#ff|Acc]). enc_oct_str_tag(OStr) when list(OStr) ->    lists:append([4|elength(length(OStr))],OStr);enc_oct_str_tag(OBin) ->    [4,elength(size(OBin)),OBin].enc_oct_str_notag(OStr) -> OStr.%%-----------------------------------------------------------------%% Always use definite form%%-----------------------------------------------------------------%% Shortelength(L) when L < 127 ->    [L];%% 3 cases of long formelength(L) when L =< 16#FF ->    [2#10000001,L];elength(L) when L  =< 16#FFFF ->    [2#10000010,(L bsr 8),(L band 16#FF)];elength(L) when L =< 16#7FFFFF ->    [2#10000011,(L bsr 16),((L band 16#FF00) bsr 8), (L band 16#FF)].

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?