From 36426bcc894853dfd38a4d8db7b4971934df9692 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Fri, 9 May 2014 13:54:21 +0200 Subject: Go back to passing (Domain, Addr) to net_if filters --- lib/snmp/src/agent/snmp_framework_mib.erl | 17 +- lib/snmp/src/agent/snmpa_net_if.erl | 271 +++++++++++++++++---- lib/snmp/src/agent/snmpa_net_if_filter.erl | 23 +- .../src/agent/snmpa_network_interface_filter.erl | 6 +- lib/snmp/src/agent/snmpa_trap.erl | 101 +++++--- lib/snmp/src/misc/snmp_pdus.erl | 17 +- 6 files changed, 331 insertions(+), 104 deletions(-) diff --git a/lib/snmp/src/agent/snmp_framework_mib.erl b/lib/snmp/src/agent/snmp_framework_mib.erl index 0b439aa5f1..fb52f90852 100644 --- a/lib/snmp/src/agent/snmp_framework_mib.erl +++ b/lib/snmp/src/agent/snmp_framework_mib.erl @@ -190,15 +190,22 @@ check_context(Context) -> %% Agent %% {Name, Value}. %%----------------------------------------------------------------- -check_agent({intAgentTransportDomain, D}, Domain) -> +check_agent({intAgentTransportDomain, D}, _Domain) -> {snmp_conf:check_domain(D), D}; -check_agent({intAgentIpAddress, Value}, D) -> +check_agent({intAgentIpAddress = Tag, Value}, D) -> Domain = case D of - undefined -> snmp_target_mib:default_domain(); - _ -> D + undefined -> + snmp_target_mib:default_domain(); + _ -> + D end, - {snmp_conf:check_ip(Domain, Value), Domain}; + {case snmp_conf:check_ip(Domain, Value) of + ok -> + ok; + {ok, FixedIp} -> + {ok, {Tag, FixedIp}} + end, Domain}; check_agent(Entry, Domain) -> {check_agent(Entry), Domain}. diff --git a/lib/snmp/src/agent/snmpa_net_if.erl b/lib/snmp/src/agent/snmpa_net_if.erl index 96211fc5f4..53eebb1728 100644 --- a/lib/snmp/src/agent/snmpa_net_if.erl +++ b/lib/snmp/src/agent/snmpa_net_if.erl @@ -46,7 +46,8 @@ debug = false, limit = infinity, rcnt = [], - filter}). + filter, + use_tdomain = false}). -ifndef(default_verbosity). -define(default_verbosity,silence). @@ -165,6 +166,13 @@ do_init(Prio, NoteStore, MasterAgent, Parent, Opts) -> %% -- Port and address -- Domain = get_domain(), ?vdebug("domain: ~w",[Domain]), + UseTDomain = + case Domain of + snmpUDPDomain -> + false; + _ -> + true + end, UDPPort = get_port(), ?vdebug("port: ~w",[UDPPort]), IPAddress = get_address(), @@ -208,7 +216,8 @@ do_init(Prio, NoteStore, MasterAgent, Parent, Opts) -> usock_opts = IPOpts, log = Log, limit = Limit, - filter = FilterMod}, + filter = FilterMod, + use_tdomain = UseTDomain}, ?vdebug("started with MpdState: ~p", [MpdState]), {ok, S}; {error, Reason} -> @@ -541,14 +550,39 @@ update_req_counter_outgoing(#state{limit = Limit, rcnt = RCnt} = S, maybe_handle_recv( - #state{usock = Sock, filter = FilterMod} = S, From, Packet) -> - case (catch FilterMod:accept_recv(From)) of + #state{usock = Sock, filter = FilterMod, use_tdomain = UseTDomain} = S, + {Domain, Addr} = From, Packet) -> + case + try + case UseTDomain of + true -> + FilterMod:accept_recv(Domain, Addr); + false -> + {Ip, Port} = Addr, + FilterMod:accept_recv(Ip, Port) + end + catch + Class:Exception -> + error_msg( + "FilterMod:accept_recv/2 crashed for ~p: ~w:~w~n ~p", + [From,Class,Exception,erlang:get_stacktrace()]), + true + end + of false -> %% Drop the received packet inc(netIfMsgInDrops), active_once(Sock), S; - _ -> + Other -> + case Other of + true -> + ok; + _ -> + error_msg( + "FilterMod:accept_recv/2 returned: ~p for ~p", + [Other,From]) + end, handle_recv(S, From, Packet) end. @@ -620,15 +654,40 @@ handle_recv( end. maybe_handle_recv_pdu( - From, Vsn, + {Domain, Addr} = From, Vsn, #pdu{type = Type} = Pdu, PduMS, ACMData, - #state{usock = Sock, filter = FilterMod} = S) -> - case (catch FilterMod:accept_recv_pdu(From, Type)) of + #state{usock = Sock, filter = FilterMod, use_tdomain = UseTDomain} = S) -> + case + try + case UseTDomain of + true -> + FilterMod:accept_recv_pdu(Domain, Addr, Type); + false -> + {Ip, Port} = Addr, + FilterMod:accept_recv_pdu(Ip, Port, Type) + end + catch + Class:Exception -> + error_msg( + "FilterMod:accept_recv_pdu/3 crashed for ~p, ~p: ~w:~w~n" + " ~p", + [From,Type,Class,Exception,erlang:get_stacktrace()]), + true + end + of false -> inc(netIfPduInDrops), active_once(Sock), ok; - _ -> + Other -> + case Other of + true -> + ok; + _ -> + error_msg( + "FilterMod:accept_recv_pdu/3 returned: ~p for ~p, ~p", + [Other,From,Type]) + end, handle_recv_pdu(From, Vsn, Pdu, PduMS, ACMData, S) end; maybe_handle_recv_pdu(From, Vsn, Pdu, PduMS, ACMData, S) -> @@ -658,15 +717,40 @@ handle_recv_pdu(From, Vsn, Pdu, PduMS, ACMData, maybe_handle_reply_pdu( - #state{filter = FilterMod} = S, Vsn, + #state{filter = FilterMod, use_tdomain = UseTDomain} = S, Vsn, #pdu{request_id = Rid} = Pdu, - Type, ACMData, To) -> + Type, ACMData, {_Domain, Addr} = To) -> S1 = update_req_counter_outgoing(S, Rid), - case (catch FilterMod:accept_send_pdu([To], Type)) of + Addresses = + case UseTDomain of + true -> + [To]; + false -> + [Addr] + end, + case + try + FilterMod:accept_send_pdu(Addresses, Type) + catch + Class:Exception -> + error_msg( + "FilterMod:accept_send_pdu(~p, ~p) crashed: ~w:~w~n ~p", + [Addresses,Type,Class,Exception,erlang:get_stacktrace()]), + true + end + of false -> inc(netIfPduOutDrops), ok; - _ -> + Other -> + case Other of + true -> + ok; + _ -> + error_msg( + "FilterMod:accept_send_pdu(~p, ~p) returned: ~p", + [Addresses,Type,Other]) + end, handle_reply_pdu(S1, Vsn, Pdu, Type, ACMData, To) end, S1. @@ -694,7 +778,7 @@ handle_reply_pdu(#state{log = Log} = S, Vsn, Pdu, Type, ACMData, To) -> maybe_handle_send_pdu( - #state{filter = FilterMod} = S, + #state{filter = FilterMod, use_tdomain = UseTDomain} = S, Vsn, Pdu, MsgData, TDomAddrSecs, From) -> ?vtrace("maybe_handle_send_pdu -> entry with~n" @@ -702,42 +786,77 @@ maybe_handle_send_pdu( " TDomAddrSecs: ~p", [FilterMod, TDomAddrSecs]), DomAddrSecs = snmpa_mpd:process_taddrs(TDomAddrSecs), - DomAddrs = - [case DAS of - {{Domain, _Address} = DomAddr, _SecData} - when is_atom(Domain) -> % v3 - DomAddr; - {Domain, _Address} = DomAddr - when is_atom(Domain) -> % v1 & v2 - DomAddr + AddressesToFilter = + [case UseTDomain of + true -> + case DAS of + {{Domain, _Address} = DomAddr, _SecData} + when is_atom(Domain) -> % v3 + DomAddr; + {Domain, _Address} = DomAddr + when is_atom(Domain) -> % v1 & v2 + DomAddr + end; + false -> + case DAS of + {{Domain, Address}, _SecData} + when is_atom(Domain) -> % v3 + Address; + {Domain, Address} + when is_atom(Domain) -> % v1 & v2 + Address + end end || DAS <- DomAddrSecs], - - case (catch FilterMod:accept_send_pdu( - DomAddrs, pdu_type_of(Pdu))) of + Type = pdu_type_of(Pdu), + + case + try FilterMod:accept_send_pdu(AddressesToFilter, Type) + catch + Class:Exception -> + error_msg( + "FilterMod:accept_send_pdu(~p, ~p) crashed: ~w:~w~n ~p", + [AddressesToFilter,Type, + Class,Exception,erlang:get_stacktrace()]), + true + end + of false -> inc(netIfPduOutDrops), ok; true -> handle_send_pdu(S, Vsn, Pdu, MsgData, DomAddrSecs, From); - FilteredDomAddrs when is_list(FilteredDomAddrs) -> + FilteredAddresses when is_list(FilteredAddresses) -> MergedDomAddrSecs = - [DAS || DAS <- DomAddrSecs, - case DAS of - {{Domain, _Address} = DomAddr, _SData} - when is_atom(Domain) -> % v3 - lists:member( - DomAddr, FilteredDomAddrs); - {Domain, _Address} = DomAddr - when is_atom(Domain) -> % v1 & v2 - lists:member( - DomAddr, FilteredDomAddrs) - end], + [DAS || + DAS <- DomAddrSecs, + lists:member( + case UseTDomain of + true -> + case DAS of + {{Domain, _Address} = DomAddr, _SData} + when is_atom(Domain) -> % v3 + DomAddr; + {Domain, _Address} = DomAddr + when is_atom(Domain) -> % v1 & v2 + DomAddr + end; + false -> + case DAS of + {{Domain, Address}, _SData} + when is_atom(Domain) -> % v3 + Address; + {Domain, Address} + when is_atom(Domain) -> % v1 & v2 + Address + end + end, FilteredAddresses)], ?vtrace("maybe_handle_send_pdu -> MergedDomAddrSecs:~n" " ~p", [MergedDomAddrSecs]), handle_send_pdu(S, Vsn, Pdu, MsgData, MergedDomAddrSecs, From); Other -> error_msg( - "FilterMod:accept_send_pdu/2 returned: ~p", [Other]), + "FilterMod:accept_send_pdu(~p, ~p) returned: ~p", + [AddressesToFilter,Type,Other]), handle_send_pdu(S, Vsn, Pdu, MsgData, DomAddrSecs, From) end. @@ -856,31 +975,81 @@ handle_response(Vsn, Pdu, From, S) -> end. maybe_udp_send( - #state{usock = Sock, - filter = FilterMod}, To, Packet) -> - case (catch FilterMod:accept_send(To)) of + #state{usock = Sock, filter = FilterMod, use_tdomain = UseTDomain}, + {Domain, Addr} = To, Packet) -> + case + try + case UseTDomain of + true -> + FilterMod:accept_send(Domain, Addr); + false -> + {Ip, Port} = Addr, + FilterMod:accept_send(Ip, Port) + end + catch + Class:Exception -> + error_msg( + "FilterMod:accept_send/2 crashed for ~p: ~w:~w~n ~p", + [To,Class,Exception,erlang:get_stacktrace()]), + true + end + of false -> inc(netIfMsgOutDrops), ok; - _ -> + Other -> + case Other of + true -> + ok; + _ -> + error_msg( + "FilterMod:accept_send/2 returned: ~p for ~p", + [Other,To]) + end, %% XXX should be some kind of lookup of domain to socket - {_Domain, {Ip, Port}} = To, - (catch udp_send(Sock, Ip, Port, Packet)) + {SockIp, SockPort} = Addr, + (catch udp_send(Sock, SockIp, SockPort, Packet)) end. maybe_udp_send( - #state{log = Log, - usock = Sock, - filter = FilterMod}, To, Packet, Type, _LogData) -> - case (catch FilterMod:accept_send(To)) of + #state{log = Log, + usock = Sock, + filter = FilterMod, + use_tdomain = UseTDomain}, + {Domain, Addr} = To, Packet, Type, _LogData) -> + case + try + case UseTDomain of + true -> + FilterMod:accept_send(Domain, Addr); + false -> + {Ip, Port} = Addr, + FilterMod:accept_send(Ip, Port) + end + catch + Class:Exception -> + error_msg( + "FilterMod:accept_send/2 crashed for ~p: ~w:~w~n ~p", + [To,Class,Exception,erlang:get_stacktrace()]), + true + end + of false -> inc(netIfMsgOutDrops), ok; - _ -> + Other -> + case Other of + true -> + ok; + _ -> + error_msg( + "FilterMod:accept_send/2 returned: ~p for ~p", + [Other,To]) + end, log(Log, Type, Packet, To), %% XXX should be some kind of lookup of domain to socket - {_Domain, {Ip, Port}} = To, - (catch udp_send(Sock, Ip, Port, Packet)) + {SockIp, SockPort} = Addr, + (catch udp_send(Sock, SockIp, SockPort, Packet)) end. udp_send(UdpId, AgentIp, UdpPort, B) -> diff --git a/lib/snmp/src/agent/snmpa_net_if_filter.erl b/lib/snmp/src/agent/snmpa_net_if_filter.erl index e71abc4ac6..dd77b143d0 100644 --- a/lib/snmp/src/agent/snmpa_net_if_filter.erl +++ b/lib/snmp/src/agent/snmpa_net_if_filter.erl @@ -18,46 +18,39 @@ %% -module(snmpa_net_if_filter). -%% New behaviour --export([accept_recv/1, accept_send/1, accept_recv_pdu/2]). -%% Common signature for both old and new behaviour --export([accept_send_pdu/2]). -%% Old behaviour --export([accept_recv/2, accept_send/2, accept_recv_pdu/3]). +%% Behaviour +-export([accept_recv/2, accept_send/2, accept_recv_pdu/3, accept_send_pdu/2]). -include("snmp_debug.hrl"). -accept_recv({Domain, _Address}) when is_atom(Domain) -> +accept_recv(Domain, _Address) when is_atom(Domain) -> ?d("accept_recv -> entry with~n" " Domain: ~p~n" " Address: ~p", [Domain, _Address]), - true. -%% + true; accept_recv(_Addr, Port) when is_integer(Port) -> ?d("accept_recv -> entry with~n" " Addr: ~p~n" " Port: ~p", [_Addr, Port]), true. -accept_send({Domain, _Address}) when is_atom(Domain) -> +accept_send(Domain, _Address) when is_atom(Domain) -> ?d("accept_send -> entry with~n" " Domain: ~p~n" " Address: ~p", [Domain, _Address]), - true. -%% + true; accept_send(_Addr, Port) when is_integer(Port) -> ?d("accept_send -> entry with~n" " Addr: ~p~n" " Port: ~p", [_Addr, Port]), true. -accept_recv_pdu({Domain, _Address}, _PduType) when is_atom(Domain) -> +accept_recv_pdu(Domain, _Address, _PduType) when is_atom(Domain) -> ?d("accept_recv -> entry with~n" " Domain: ~p~n" " Address: ~p~n" " PduType: ~p", [Domain, _Address, _PduType]), - true. -%% + true; accept_recv_pdu(_Addr, Port, _PduType) when is_integer(Port) -> ?d("accept_recv_pdu -> entry with~n" " Addr: ~p~n" diff --git a/lib/snmp/src/agent/snmpa_network_interface_filter.erl b/lib/snmp/src/agent/snmpa_network_interface_filter.erl index 3fa83db874..90aa54a271 100644 --- a/lib/snmp/src/agent/snmpa_network_interface_filter.erl +++ b/lib/snmp/src/agent/snmpa_network_interface_filter.erl @@ -23,9 +23,9 @@ behaviour_info(callbacks) -> - [{accept_recv, 1}, - {accept_send, 1}, - {accept_recv_pdu, 2}, + [{accept_recv, 2}, + {accept_send, 2}, + {accept_recv_pdu, 3}, {accept_send_pdu, 2}]; behaviour_info(_) -> undefined. diff --git a/lib/snmp/src/agent/snmpa_trap.erl b/lib/snmp/src/agent/snmpa_trap.erl index b9a2496341..a2d821c099 100644 --- a/lib/snmp/src/agent/snmpa_trap.erl +++ b/lib/snmp/src/agent/snmpa_trap.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2012. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -1045,7 +1045,7 @@ deliver_recv(#snmpa_notification_delivery_info{tag = Tag, "~n DeliveryResult: ~p" "~n TAddr: ~p" "", [Tag, Mod, Extra, DeliveryResult, TAddr]), - Addr = transform_taddr(TAddr), + [Addr] = transform_taddrs([TAddr]), (catch Mod:delivery_info(Tag, Addr, DeliveryResult, Extra)); deliver_recv({Tag, Receiver}, MsgId, Result) -> ?vtrace("deliver_recv -> entry with" @@ -1072,35 +1072,80 @@ deliver_recv(Else, _MsgId, _Result) -> [Else]), user_err("snmpa: bad receiver, ~w\n", [Else]). -transform_taddrs(Addrs) -> - [transform_taddr(Addr) || Addr <- Addrs]. +transform_taddrs(TAddrs) -> + UseTDomain = + case snmp_framework_mib:intAgentTransportDomain(get) of + {value,snmpUDPDomain} -> + false; + {value,_} -> + true; + genErr -> + false + end, + DomAddrs = [transform_taddr(TAddr) || TAddr <- TAddrs], + case UseTDomain of + true -> + DomAddrs; + false -> + [Addr || {_Domain, Addr} <- DomAddrs] + end. -transform_taddr({?snmpUDPDomain, [A1, A2, A3, A4, P1, P2]}) -> % v2 - Addr = {A1, A2, A3, A4}, - Port = P1 bsl 8 + P2, - {Addr, Port}; -transform_taddr({?transportDomainUdpIpv4, [A1, A2, A3, A4, P1, P2]}) -> % v2 - Addr = {A1, A2, A3, A4}, - Port = P1 bsl 8 + P2, - {Addr, Port}; -transform_taddr({?transportDomainUdpIpv6, - [A1, A2, A3, A4, A5, A6, A7, A8, P1, P2]}) -> % v2 - Addr = {A1, A2, A3, A4, A5, A6, A7, A8}, +%% v2 +transform_taddr({?snmpUDPDomain, Addr}) -> + transform_taddr(transportDomainIdpIpv4, Addr); +transform_taddr({?transportDomainUdpIpv4, Addr}) -> + transform_taddr(transportDomainUdpIpv4, Addr); +transform_taddr({?transportDomainUdpIpv6, Addr}) -> + transform_taddr(transportDomainUdpIpv6, Addr); +%% v3 +transform_taddr({{?snmpUDPDomain, Addr}, _MsgData}) -> + transform_taddr(transportDomainUdpIpv4, Addr); +transform_taddr({{?transportDomainUdpIpv4, Addr}, _MsgData}) -> + transform_taddr(transportDomainUdpIpv4, Addr); +transform_taddr({{?transportDomainUdpIpv6, Addr}, _MsgData}) -> + transform_taddr(transportDomainUdpIpv6, Addr). + +transform_taddr( + transportDomainUdpIpv4 = Domain, + [A1,A2,A3,A4,P1,P2]) -> + Ip = {A1, A2, A3, A4}, Port = P1 bsl 8 + P2, - {Addr, Port}; -transform_taddr({{?snmpUDPDomain, [A1, A2, A3, A4, P1, P2]}, _MsgData}) -> % v3 - Addr = {A1, A2, A3, A4}, + {Domain, {Ip, Port}}; +transform_taddr( + transportDomainUdpIpv6 = Domain, + [A1, A2, A3, A4, A5, A6, A7, A8, P1, P2]) -> + Ip = {A1, A2, A3, A4, A5, A6, A7, A8}, Port = P1 bsl 8 + P2, - {Addr, Port}; -transform_taddr({{?transportDomainUdpIpv4, [A1, A2, A3, A4, P1, P2]}, _MsgData}) -> % v3 - Addr = {A1, A2, A3, A4}, - Port = P1 bsl 8 + P2, - {Addr, Port}; -transform_taddr({{?transportDomainUdpIpv6, - [A1, A2, A3, A4, A5, A6, A7, A8, P1, P2]}, _MsgData}) -> % v3 - Addr = {A1, A2, A3, A4, A5, A6, A7, A8}, - Port = P1 bsl 8 + P2, - {Addr, Port}. + {Domain, {Ip, Port}}. + + +%% transform_taddr({?snmpUDPDomain, [A1, A2, A3, A4, P1, P2]}) -> % v2 +%% Addr = {A1, A2, A3, A4}, +%% Port = P1 bsl 8 + P2, +%% {Addr, Port}; +%% transform_taddr({?transportDomainUdpIpv4, [A1, A2, A3, A4, P1, P2]}) -> % v2 +%% Addr = {A1, A2, A3, A4}, +%% Port = P1 bsl 8 + P2, +%% {Addr, Port}; +%% transform_taddr({?transportDomainUdpIpv6, +%% [A1, A2, A3, A4, A5, A6, A7, A8, P1, P2]}) -> % v2 +%% Addr = {A1, A2, A3, A4, A5, A6, A7, A8}, +%% Port = P1 bsl 8 + P2, +%% {Addr, Port}; +%% transform_taddr({{?snmpUDPDomain, [A1, A2, A3, A4, P1, P2]}, _MsgData}) -> % v3 +%% Addr = {A1, A2, A3, A4}, +%% Port = P1 bsl 8 + P2, +%% {Addr, Port}; +%% transform_taddr({{?transportDomainUdpIpv4, [A1, A2, A3, A4, P1, P2]}, _MsgData}) -> % v3 +%% Addr = {A1, A2, A3, A4}, +%% Port = P1 bsl 8 + P2, +%% {Addr, Port}; +%% transform_taddr({{?transportDomainUdpIpv6, +%% [A1, A2, A3, A4, A5, A6, A7, A8, P1, P2]}, _MsgData}) -> % v3 +%% Addr = {A1, A2, A3, A4, A5, A6, A7, A8}, +%% Port = P1 bsl 8 + P2, +%% {Addr, Port}. + check_all_varbinds(#notification{oid = Oid}, Vbs, MibView) -> diff --git a/lib/snmp/src/misc/snmp_pdus.erl b/lib/snmp/src/misc/snmp_pdus.erl index 15156f7467..a780fee7a3 100644 --- a/lib/snmp/src/misc/snmp_pdus.erl +++ b/lib/snmp/src/misc/snmp_pdus.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2012. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -664,7 +664,20 @@ 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) -> +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)), lists:append([64 | Len2],Bytes2); -- cgit v1.2.3