From cc1ab998ce905cd673c7ea14ee4e31ddb2412350 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Tue, 20 May 2014 15:15:43 +0200 Subject: Don't encode IPv6 address into v1 trap and fix legacy arguments to snmpa_network_interface_filter functions --- lib/snmp/src/agent/snmpa_mpd.erl | 18 +++++++- lib/snmp/src/agent/snmpa_net_if.erl | 48 ++++++++++++-------- lib/snmp/src/agent/snmpa_trap.erl | 87 +++++++++++++++++++++++++++++-------- lib/snmp/src/misc/snmp_conf.erl | 13 ++++-- lib/snmp/src/misc/snmp_pdus.erl | 13 +----- 5 files changed, 126 insertions(+), 53 deletions(-) (limited to 'lib') diff --git a/lib/snmp/src/agent/snmpa_mpd.erl b/lib/snmp/src/agent/snmpa_mpd.erl index dbd57b732c..642b1f7fc5 100644 --- a/lib/snmp/src/agent/snmpa_mpd.erl +++ b/lib/snmp/src/agent/snmpa_mpd.erl @@ -1103,8 +1103,22 @@ transform_taddr(?transportDomainUdpIpv4, [A, B, C, D, P1, P2]) -> {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]) -> +transform_taddr( + ?transportDomainUdpIpv6, + [A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, + P1, P2]) -> + Domain = transportDomainUdpIpv6, + Addr = + {(A1 bsl 8) bor A2, (A3 bsl 8) bor A4, + (A5 bsl 8) bor A6, (A7 bsl 8) bor A8, + (A9 bsl 8) bor A10, (A11 bsl 8) bor A12, + (A13 bsl 8) bor A14, (A15 bsl 8) bor A16}, + Port = P1 bsl 8 + P2, + Address = {Addr, Port}, + {ok, {Domain, Address}}; +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, diff --git a/lib/snmp/src/agent/snmpa_net_if.erl b/lib/snmp/src/agent/snmpa_net_if.erl index 42e93bff65..2c800db8b6 100644 --- a/lib/snmp/src/agent/snmpa_net_if.erl +++ b/lib/snmp/src/agent/snmpa_net_if.erl @@ -327,13 +327,7 @@ loop(#state{domain = Domain} = S) -> receive {udp, _UdpId, Ip, Port, Packet} -> ?vlog("got paket from ~w:~w",[Ip,Port]), - From = - case Domain of - snmpUDPDomain -> - {Ip, Port}; - _ -> - {Domain, {Ip, Port}} - end, + From = fix_filter_address(Domain, {Domain, {Ip, Port}}), NewS = maybe_handle_recv(S, From, Packet), loop(NewS); @@ -604,7 +598,7 @@ handle_discovery_response(_From, #pdu{request_id = ReqId} = Pdu, %% Ouch, timeout? resend? S end. - + handle_recv( #state{usock = Sock, mpd_state = MpdState, @@ -655,7 +649,7 @@ handle_recv( active_once(Sock), S end. - + maybe_handle_recv_pdu( From, Vsn, #pdu{type = Type} = Pdu, PduMS, ACMData, @@ -713,12 +707,13 @@ handle_recv_pdu(From, Vsn, Pdu, PduMS, ACMData, maybe_handle_reply_pdu( - #state{filter = FilterMod} = S, Vsn, + #state{filter = FilterMod, domain = Domain} = S, Vsn, #pdu{request_id = Rid} = Pdu, Type, ACMData, To) -> S1 = update_req_counter_outgoing(S, Rid), - Addresses = [To], + %% Addresses = [To], + Addresses = [fix_filter_address(Domain, To)], case try FilterMod:accept_send_pdu(Addresses, Type) @@ -965,9 +960,10 @@ handle_response(Vsn, Pdu, From, S) -> end. maybe_udp_send( - #state{usock = Sock, filter = FilterMod}, + #state{usock = Sock, filter = FilterMod, domain = Domain}, To, Packet) -> - {To_1, To_2} = To, + %% {To_1, To_2} = To, + {To_1, To_2} = fix_filter_address(Domain, To), case try FilterMod:accept_send(To_1, To_2) catch @@ -995,11 +991,14 @@ maybe_udp_send( end. maybe_udp_send( - #state{log = Log, - usock = Sock, - filter = FilterMod}, + #state{ + log = Log, + usock = Sock, + filter = FilterMod, + domain = Domain}, To, Packet, Type, _LogData) -> - {To_1, To_2} = To, + %% {To_1, To_2} = To, + {To_1, To_2} = fix_filter_address(Domain, To), case try FilterMod:accept_send(To_1, To_2) catch @@ -1098,6 +1097,21 @@ active_once(Sock) -> inet:setopts(Sock, [{active, once}]). +%% If the agent uses legacy snmpUDPDomain e.g has not set +%% intAgentTransportDomain, then make sure +%% snmpa_network_interface_filter gets legacy arguments +%% to not break backwards compatibility. +%% +fix_filter_address(snmpUDPDomain, {Domain, Addr}) + when Domain =:= snmpUDPDomain; + Domain =:= transportDomainUdpIpv4 -> + Addr; +fix_filter_address(snmpUDPDomain, {_, Port} = Addr) + when is_integer(Port) -> + Addr; +fix_filter_address(_AgentDomain, Address) -> + Address. + %%%----------------------------------------------------------------- handle_set_log_type(#state{log = {Log, OldValue}} = State, NewType) diff --git a/lib/snmp/src/agent/snmpa_trap.erl b/lib/snmp/src/agent/snmpa_trap.erl index a2d821c099..ac0739860b 100644 --- a/lib/snmp/src/agent/snmpa_trap.erl +++ b/lib/snmp/src/agent/snmpa_trap.erl @@ -270,12 +270,13 @@ localise_type({VariableOid, Value}, Mib) when is_list(VariableOid) -> localise_type(X, _) -> X. %%----------------------------------------------------------------- -%% Func: make_v1_trap_pdu/4 +%% Func: make_v1_trap_pdu/5 %% Args: Enterprise = oid() %% Specific = integer() %% Varbinds is as returned from initiate_vars %% (but only {Oid, Type[, Value} permitted) %% SysUpTime = integer() +%% AgentIp = {A, B, C, D} %% Purpose: Make a #trappdu %% Checks the Varbinds to see that no symbolic names are %% present, and that each var has a type. Performs a get @@ -284,7 +285,7 @@ localise_type(X, _) -> X. %% Fails: yes %% NOTE: Executed at the MA %%----------------------------------------------------------------- -make_v1_trap_pdu(Enterprise, Specific, VarbindList, SysUpTime) -> +make_v1_trap_pdu(Enterprise, Specific, VarbindList, SysUpTime, AgentIp) -> {Enterp,Generic,Spec} = case Enterprise of ?snmp -> @@ -292,7 +293,6 @@ make_v1_trap_pdu(Enterprise, Specific, VarbindList, SysUpTime) -> _ -> {Enterprise,?enterpriseSpecific,Specific} end, - {value, AgentIp} = snmp_framework_mib:intAgentIpAddress(get), #trappdu{enterprise = Enterp, agent_addr = AgentIp, generic_trap = Generic, @@ -369,6 +369,7 @@ send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, LocalEngineID, {tag, T}, {err, E}, {stacktrace, erlang:get_stacktrace()}], + ?vlog("snmpa_trap:send_trap exception: ~p", [Info]), {error, {failed_sending_trap, Info}} end. @@ -797,13 +798,32 @@ send_v1_trap(#trap{enterpriseoid = Enter, specificcode = Spec}, "~n ~p" "~n to" "~n ~p", [Enter, Spec, V1Res]), - TrapPdu = make_v1_trap_pdu(Enter, Spec, Vbs, SysUpTime), - AddrCommunities = mk_addr_communities(V1Res), - lists:foreach(fun({Community, Addrs}) -> - ?vtrace("send v1 trap pdu to ~p",[Addrs]), - NetIf ! {send_pdu, 'version-1', TrapPdu, - {community, Community}, Addrs, ExtraInfo} - end, AddrCommunities); + AgentDomain = + case snmp_framework_mib:intAgentTransportDomain(get) of + {value, AD} -> + AD; + genErr -> + snmp_target_mib:default_domain() + end, + case AgentDomain of + snmpUDPDomain -> + {value, AgentIp} = snmp_framework_mib:intAgentIpAddress(get), + TrapPdu = make_v1_trap_pdu(Enter, Spec, Vbs, SysUpTime, AgentIp), + AddrCommunities = mk_addr_communities(V1Res), + lists:foreach( + fun ({Community, Addrs}) -> + ?vtrace("send v1 trap pdu to ~p",[Addrs]), + NetIf ! {send_pdu, 'version-1', TrapPdu, + {community, Community}, Addrs, ExtraInfo} + end, AddrCommunities); + _ -> + ?vtrace( + "snmpa_trap: can not send v1 trap with domain: ~w", + [AgentDomain]), + user_err( + "snmpa_trap: can not send v1 trap with domain: ~w", + [AgentDomain]) + end; send_v1_trap(#notification{oid = Oid}, V1Res, Vbs, ExtraInfo, NetIf, SysUpTime) -> %% Use alg. in rfc2089 to map a v2 trap to a v1 trap @@ -822,14 +842,33 @@ send_v1_trap(#notification{oid = Oid}, V1Res, Vbs, ExtraInfo, NetIf, {lists:reverse(First),Last} end end, - TrapPdu = make_v1_trap_pdu(Enter, Spec, NVbs, SysUpTime), - AddrCommunities = mk_addr_communities(V1Res), - lists:foreach(fun({Community, Addrs}) -> - ?vtrace("send v1 trap to ~p",[Addrs]), - NetIf ! {send_pdu, 'version-1', TrapPdu, - {community, Community}, Addrs, ExtraInfo} - end, AddrCommunities). - + AgentDomain = + case snmp_framework_mib:intAgentTransportDomain(get) of + {value, AD} -> + AD; + genErr -> + snmp_target_mib:default_domain() + end, + case AgentDomain of + snmpUDPDomain -> + {value, AgentIp} = snmp_framework_mib:intAgentIpAddress(get), + TrapPdu = make_v1_trap_pdu(Enter, Spec, NVbs, SysUpTime, AgentIp), + AddrCommunities = mk_addr_communities(V1Res), + lists:foreach( + fun ({Community, Addrs}) -> + ?vtrace("send v1 trap to ~p",[Addrs]), + NetIf ! {send_pdu, 'version-1', TrapPdu, + {community, Community}, Addrs, ExtraInfo} + end, AddrCommunities); + _ -> + ?vtrace( + "snmpa_trap: can not send v1 trap with domain: ~w", + [AgentDomain]), + user_err( + "snmpa_trap: can not send v1 trap with domain: ~w", + [AgentDomain]) + end. + send_v2_trap(_TrapRec, [], _Vbs, _Recv, _ExtraInfo, _NetIf, _SysUpTime) -> ok; send_v2_trap(TrapRec, V2Res, Vbs, Recv, ExtraInfo, NetIf, SysUpTime) -> @@ -1116,9 +1155,19 @@ transform_taddr( [A1, A2, A3, A4, A5, A6, A7, A8, P1, P2]) -> Ip = {A1, A2, A3, A4, A5, A6, A7, A8}, Port = P1 bsl 8 + P2, + {Domain, {Ip, Port}}; +transform_taddr( + transportDomainUdpIpv6 = Domain, + [A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, + P1, P2]) -> + Ip = + {(A1 bsl 8) bor A2, (A3 bsl 8) bor A4, + (A5 bsl 8) bor A6, (A7 bsl 8) bor A8, + (A9 bsl 8) bor A10, (A11 bsl 8) bor A12, + (A13 bsl 8) bor A14, (A15 bsl 8) bor A16}, + Port = P1 bsl 8 + P2, {Domain, {Ip, Port}}. - %% transform_taddr({?snmpUDPDomain, [A1, A2, A3, A4, P1, P2]}) -> % v2 %% Addr = {A1, A2, A3, A4}, %% Port = P1 bsl 8 + P2, diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl index 594cfce705..2d91cb1f55 100644 --- a/lib/snmp/src/misc/snmp_conf.erl +++ b/lib/snmp/src/misc/snmp_conf.erl @@ -634,9 +634,16 @@ mk_taddress(transportDomainUdpIpv6 = Domain, Address) -> case Address of [] -> % Empty mask []; - {Ip, Port} - when tuple_size(Ip) =:= 8, is_integer(Port) -> - tuple_to_list(Ip) ++ mk_bytes(Port); + {{A, B, C, D, E, F, G, H}, Port} -> + [A bsr 8, A band 255, + B bsr 8, B band 255, + C bsr 8, C band 255, + D bsr 8, D band 255, + E bsr 8, E band 255, + F bsr 8, F band 255, + G bsr 8, G band 255, + H bsr 8, H band 255, + Port bsr 8, Port band 255]; _ -> erlang:error(badarg, [Domain,Address]) end; diff --git a/lib/snmp/src/misc/snmp_pdus.erl b/lib/snmp/src/misc/snmp_pdus.erl index a780fee7a3..90fa4c0dea 100644 --- a/lib/snmp/src/misc/snmp_pdus.erl +++ b/lib/snmp/src/misc/snmp_pdus.erl @@ -174,7 +174,7 @@ dec_pdu_tag(168) -> dec_pdu([164 | Bytes]) -> % It's a trap Bytes2 = get_data_bytes(Bytes), {Enterprise, Rest1} = dec_oid_tag(Bytes2), - {{'IpAddress', AgentAddr}, Rest2} = dec_value(Rest1), + {{'IpAddress', [_, _, _, _] = AgentAddr}, Rest2} = dec_value(Rest1), {GenericTrap, Rest3} = dec_int_tag(Rest2), {SpecificTrap, Rest4} = dec_int_tag(Rest3), {{'TimeTicks', TimeStamp}, VBBytes} = dec_value(Rest4), @@ -666,17 +666,6 @@ enc_value('OBJECT IDENTIFIER', Val) -> enc_oid_tag(Val); enc_value('IpAddress', {A, B, C, D}) -> enc_value('IpAddress', [A,B,C,D]); -enc_value('IpAddress', {A, B, C, D, E, F, G, H}) -> - enc_value( - 'IpAddress', - [A bsr 8, A band 255, - B bsr 8, B band 255, - C bsr 8, C band 255, - D bsr 8, D band 255, - E bsr 8, E band 255, - F bsr 8, F band 255, - G bsr 8, G band 255, - H bsr 8, H band 255]); enc_value('IpAddress', Val) when is_list(Val) -> Bytes2 = enc_oct_str_notag(Val), Len2 = elength(length(Bytes2)), -- cgit v1.2.3