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 + -
显示快捷键?