diff options
Diffstat (limited to 'lib/snmp/src/agent/snmpa_mpd.erl')
-rw-r--r-- | lib/snmp/src/agent/snmpa_mpd.erl | 148 |
1 files changed, 91 insertions, 57 deletions
diff --git a/lib/snmp/src/agent/snmpa_mpd.erl b/lib/snmp/src/agent/snmpa_mpd.erl index e9d6cdeaa8..2d37ea56f0 100644 --- a/lib/snmp/src/agent/snmpa_mpd.erl +++ b/lib/snmp/src/agent/snmpa_mpd.erl @@ -32,6 +32,7 @@ -include("SNMP-MPD-MIB.hrl"). -include("SNMPv2-TM.hrl"). -include("SNMP-FRAMEWORK-MIB.hrl"). +-include("TRANSPORT-ADDRESS-MIB.hrl"). -define(VMODULE,"MPD"). -include("snmp_verbosity.hrl"). @@ -115,8 +116,8 @@ reset() -> %% Func: process_packet(Packet, TDomain, TAddress, State, Log) -> %% {ok, SnmpVsn, Pdu, PduMS, ACMData} | {discarded, Reason} %% Types: Packet = binary() -%% TDomain = snmpUDPDomain | atom() -%% TAddress = {Ip, Udp} +%% TDomain = snmpUDPDomain | transportDomain() +%% TAddress = {Ip, Udp} (*but* depends on TDomain) %% State = #state %% Purpose: This is the main Message Dispatching function. (see %% section 4.2.1 in rfc2272) @@ -182,24 +183,30 @@ discarded_pdu(Variable) -> inc(Variable). %%----------------------------------------------------------------- %% Handles a Community based message (v1 or v2c). %%----------------------------------------------------------------- -v1_v2c_proc(Vsn, NoteStore, Community, snmpUDPDomain, +v1_v2c_proc(Vsn, NoteStore, Community, Domain, {Ip, Udp}, LocalEngineID, Data, HS, Log, Packet) -> - TAddress = tuple_to_list(Ip) ++ [Udp div 256, Udp rem 256], - AgentMS = get_engine_max_message_size(LocalEngineID), - MgrMS = snmp_community_mib:get_target_addr_ext_mms(?snmpUDPDomain, - TAddress), - PduMS = case MgrMS of - {ok, MMS} when MMS < AgentMS -> MMS - HS; - _ -> AgentMS - HS - end, + TDomain = snmp_conf:mk_tdomain(Domain), + TAddress = snmp_conf:mk_taddress(Domain, Ip, Udp), + AgentMS = get_engine_max_message_size(LocalEngineID), + MgrMS = snmp_community_mib:get_target_addr_ext_mms(TDomain, TAddress), + PduMS = case MgrMS of + {ok, MMS} when MMS < AgentMS -> MMS - HS; + _ -> AgentMS - HS + end, case (catch snmp_pdus:dec_pdu(Data)) of Pdu when is_record(Pdu, pdu) -> Log(Pdu#pdu.type, Packet), inc_snmp_in_vars(Pdu), #pdu{request_id = ReqId} = Pdu, - OkRes = {ok, Vsn, Pdu, PduMS, - {community, sec_model(Vsn), Community, TAddress}}, + + %% <TDomain> + %% We have added TDomain, what are the consequences? + ACMData = + {community, sec_model(Vsn), Community, TDomain, TAddress}, + OkRes = {ok, Vsn, Pdu, PduMS, ACMData}, + %% </TDomain> + %% Make sure that we don't process duplicate SET request %% twice. We don't know what could happen in that case. %% The mgr does, so he has to generate a new SET request. @@ -216,8 +223,6 @@ v1_v2c_proc(Vsn, NoteStore, Community, snmpUDPDomain, snmp_note_store:set_note(NoteStore, 100, Key, true), %% Uses ACMData that snmpa_acm knows of. - %% snmpUDPDomain is implicit, since that's the only - %% one we handle. OkRes; true -> {discarded, duplicate_pdu} @@ -275,12 +280,12 @@ v3_proc(NoteStore, Packet, LocalEngineID, V3Hdr, Data, Log) -> "~n msgSecurityParameters = ~w", [MsgID, MMS, MsgFlags, MsgSecurityModel, SecParams]), %% 7.2.4 - SecModule = get_security_module(MsgSecurityModel), + SecModule = get_security_module(MsgSecurityModel), %% 7.2.5 - SecLevel = check_sec_level(MsgFlags), + SecLevel = check_sec_level(MsgFlags), IsReportable = snmp_misc:is_reportable(MsgFlags), %% 7.2.6 - ?vtrace("v3_proc -> [7.2.6]" + ?vtrace("v3_proc -> [7.2.4-7.2.6]" "~n SecModule = ~p" "~n SecLevel = ~p" "~n IsReportable = ~p", @@ -541,7 +546,7 @@ check_sec_module_result(Res, V3Hdr, Data, LocalEngineID, IsReportable, Log) -> ?vdebug("security module result [7.2.6-b]:" "~n Reason: ~p", [Reason]), throw({discarded, {securityError, Reason}}); - {error, Reason, ErrorInfo} when IsReportable == true -> % case 7.2.6 a + {error, Reason, ErrorInfo} when IsReportable =:= true -> % case 7.2.6 a ?vdebug("security module result when reportable [7.2.6-a]:" "~n Reason: ~p" "~n ErrorInfo: ~p", [Reason, ErrorInfo]), @@ -584,7 +589,7 @@ generate_response_msg(Vsn, RePdu, Type, ACMData, LocalEngineID, Log) -> generate_response_msg(Vsn, RePdu, Type, ACMData, LocalEngineID, Log, 1). generate_response_msg(Vsn, RePdu, Type, - {community, _SecModel, Community, _IpUdp}, + {community, _SecModel, Community, _TDomain, _TAddress}, LocalEngineID, Log, _) -> case catch snmp_pdus:enc_pdu(RePdu) of @@ -987,12 +992,15 @@ generate_discovery_msg2(NoteStore, Pdu, discovery_note_timeout(Timeout) -> (Timeout div 100) + 1. -generate_discovery_msg(NoteStore, {?snmpUDPDomain, [A,B,C,D,U1,U2]}, +generate_discovery_msg(NoteStore, {TDomain, TAddress}, Pdu, ScopedPduBytes, ContextEngineID, ManagerEngineID, SecModel, SecName, SecLevelFlag, InitialUserName, ContextName, Timeout) -> + + {ok, {_Domain, Address}} = transform_taddr(TDomain, TAddress), + %% 7.1.7 ?vdebug("generate_discovery_msg -> 7.1.7 (~w)", [ManagerEngineID]), MsgID = generate_msg_id(), @@ -1033,7 +1041,7 @@ generate_discovery_msg(NoteStore, {?snmpUDPDomain, [A,B,C,D,U1,U2]}, %% Log(Packet), inc_snmp_out_vars(Pdu), ?vdebug("generate_discovery_msg -> done", []), - {Packet, {{A,B,C,D}, U1 bsl 8 + U2}}; + {Packet, Address}; Error -> throw(Error) @@ -1063,6 +1071,34 @@ generate_sec_discovery_msg(Message, SecModule, end. +transform_taddr(?snmpUDPDomain, TAddress) -> + transform_taddr(?transportDomainUdpIpv4, TAddress); +transform_taddr(?transportDomainUdpIpv4, [A, B, C, D, P1, P2]) -> + Domain = transportDomainUdpIpv4, + Addr = {A,B,C,D}, + Port = P1 bsl 8 + P2, + Address = {Addr, Port}, + {ok, {Domain, Address}}; +transform_taddr(?transportDomainUdpIpv4, BadAddr) -> + {error, {bad_transportDomainUdpIpv4_address, BadAddr}}; +transform_taddr(?transportDomainUdpIpv6, + [A1, A2, A3, A4, A5, A6, A7, A8, P1, P2]) -> + Domain = transportDomainUdpIpv6, + Addr = {A1, A2, A3, A4, A5, A6, A7, A8}, + Port = P1 bsl 8 + P2, + Address = {Addr, Port}, + {ok, {Domain, Address}}; +transform_taddr(?transportDomainUdpIpv6, BadAddr) -> + {error, {bad_transportDomainUdpIpv6_address, BadAddr}}; +transform_taddr(BadTDomain, TAddress) -> + case lists:member(BadTDomain, snmp_conf:all_tdomains()) of + true -> + {error, {unsupported_tdomain, BadTDomain, TAddress}}; + false -> + {error, {unknown_tdomain, BadTDomain, TAddress}} + end. + + process_taddrs(Dests) -> ?vtrace("process_taddrs -> entry with" "~n Dests: ~p", [Dests]), @@ -1072,46 +1108,44 @@ process_taddrs([], Acc) -> ?vtrace("process_taddrs -> entry when done with" "~n Acc: ~p", [Acc]), lists:reverse(Acc); - + %% v3 -process_taddrs([{{?snmpUDPDomain, [A,B,C,D,U1,U2]}, SecData} | T], Acc) -> +process_taddrs([{{TDomain, TAddress}, SecData} | T], Acc) -> ?vtrace("process_taddrs -> entry when v3 with" - "~n A: ~p" - "~n B: ~p" - "~n C: ~p" - "~n D: ~p" - "~n U1: ~p" - "~n U2: ~p" - "~n SecData: ~p", [A, B, C, D, U1, U2, SecData]), - Entry = {{snmpUDPDomain, {{A,B,C,D}, U1 bsl 8 + U2}}, SecData}, - process_taddrs(T, [Entry | Acc]); -%% Bad v3 -process_taddrs([{{TDomain, TAddr}, _SecData} | T], Acc) -> - ?vtrace("process_taddrs -> entry when bad v3 with" - "~n TDomain: ~p" - "~n TAddr: ~p", [TDomain, TAddr]), - user_err("Bad TDomain/TAddr: ~w/~w", [TDomain, TAddr]), - process_taddrs(T, Acc); + "~n TDomain: ~p" + "~n TAddress: ~p" + "~n SecData: ~p", [TDomain, TAddress, SecData]), + case transform_taddr(TDomain, TAddress) of + {ok, DestAddr} -> + ?vtrace("process_taddrs -> transformed: " + "~n DestAddr: ~p", [DestAddr]), + Entry = {DestAddr, SecData}, + process_taddrs(T, [Entry | Acc]); + {error, Reason} -> + ?vinfo("Failed transforming v3 domain and address" + "~n Reason: ~p", [Reason]), + user_err("Bad TDomain/TAddress: ~w/~w", [TDomain, TAddress]), + process_taddrs(T, Acc) + end; %% v1 & v2 -process_taddrs([{?snmpUDPDomain, [A,B,C,D,U1,U2]} | T], Acc) -> +process_taddrs([{TDomain, TAddress} | T], Acc) -> ?vtrace("process_taddrs -> entry when v1/v2 with" - "~n A: ~p" - "~n B: ~p" - "~n C: ~p" - "~n D: ~p" - "~n U1: ~p" - "~n U2: ~p", [A, B, C, D, U1, U2]), - Entry = {snmpUDPDomain, {{A,B,C,D}, U1 bsl 8 + U2}}, - process_taddrs(T, [Entry | Acc]); -%% Bad v1 or v2 -process_taddrs([{TDomain, TAddr} | T], Acc) -> - ?vtrace("process_taddrs -> entry when bad v1/v2 with" - "~n TDomain: ~p" - "~n TAddr: ~p", [TDomain, TAddr]), - user_err("Bad TDomain/TAddr: ~w/~w", [TDomain, TAddr]), - process_taddrs(T, Acc); + "~n TDomain: ~p" + "~n TAddress: ~p", [TDomain, TAddress]), + case transform_taddr(TDomain, TAddress) of + {ok, DestAddr} -> + ?vtrace("process_taddrs -> transformed: " + "~n DestAddr: ~p", [DestAddr]), + Entry = DestAddr, + process_taddrs(T, [Entry | Acc]); + {error, Reason} -> + ?vinfo("Failed transforming v1/v2 domain and address: " + "~n Reason: ~p", [Reason]), + user_err("Bad TDomain/TAddress: ~w/~w", [TDomain, TAddress]), + process_taddrs(T, Acc) + end; process_taddrs(Crap, Acc) -> - throw({error, {taddrs_crap, Crap, Acc}}). + throw({error, {bad_taddrs, Crap, Acc}}). mk_v1_v2_packet_list(To, Packet, Len, Pdu) -> |