spec/codecs/netflow_spec.rb in logstash-codec-netflow-3.2.2 vs spec/codecs/netflow_spec.rb in logstash-codec-netflow-3.3.0

- old
+ new

@@ -964,10 +964,190 @@ expect(JSON.parse(decode[15].to_json)).to eq(JSON.parse(json_events[0])) end end + context "Netflow 9 Streamcore" do + let(:data) do + packets = [] + packets << IO.read(File.join(File.dirname(__FILE__), "netflow9_test_streamcore_tpl_data256.dat"), :mode => "rb") + packets << IO.read(File.join(File.dirname(__FILE__), "netflow9_test_streamcore_tpl_data260.dat"), :mode => "rb") + end + + let(:json_events) do + events = [] + events << <<-END + { + "netflow": { + "in_pkts": 3, + "first_switched": "2017-01-11T11:47:23.999Z", + "flowset_id": 256, + "l4_src_port": 8080, + "streamcore_id_rule_1": 1171, + "streamcore_id_rule_2": 1179, + "in_bytes": 128, + "protocol": 6, + "streamcore_id_rule_5": 0, + "tcp_flags": 19, + "streamcore_id_rule_3": 1192, + "streamcore_id_rule_4": 1435, + "streamcore_net_app_resp_time": 0, + "l4_dst_port": 50073, + "output_snmp": 1148, + "streamcore_call_direction": 1, + "src_tos": 40, + "ipv4_dst_addr": "10.231.128.150", + "version": 9, + "streamcore_tcp_retrans_rate": 0, + "flow_seq_num": 2143054578, + "ipv4_src_addr": "100.78.40.201", + "input_snmp": 1152, + "last_switched": "2017-01-11T11:47:29.999Z", + "streamcore_wan_rtt": 0, + "streamcore_total_app_resp_time": 0 + }, + "@timestamp": "2017-01-11T11:48:15.000Z", + "@version": "1" + } + END + + events << <<-END + { + "netflow": { + "in_pkts": 4, + "first_switched": "2017-01-11T11:47:23.999Z", + "flowset_id": 256, + "l4_src_port": 50073, + "streamcore_id_rule_1": 1171, + "streamcore_id_rule_2": 1179, + "in_bytes": 172, + "protocol": 6, + "streamcore_id_rule_5": 0, + "tcp_flags": 19, + "streamcore_id_rule_3": 1192, + "streamcore_id_rule_4": 1435, + "streamcore_net_app_resp_time": 0, + "l4_dst_port": 8080, + "output_snmp": 1152, + "streamcore_call_direction": 0, + "src_tos": 40, + "ipv4_dst_addr": "100.78.40.201", + "version": 9, + "streamcore_tcp_retrans_rate": 0, + "flow_seq_num": 2143054578, + "ipv4_src_addr": "10.231.128.150", + "input_snmp": 1148, + "last_switched": "2017-01-11T11:47:29.999Z", + "streamcore_wan_rtt": 0, + "streamcore_total_app_resp_time": 0 + }, + "@timestamp": "2017-01-11T11:48:15.000Z", + "@version": "1" + } + END + + events << <<-END + { + "netflow": { + "streamcore_id_rule_10": 0, + "in_pkts": 10, + "first_switched": "2017-01-11T11:22:44.999Z", + "flowset_id": 260, + "l4_src_port": 8080, + "reamcore_id_rule_1": 1171, + "streamcore_id_rule_2": 1179, + "in_bytes": 3943, + "protocol": 6, + "streamcore_id_rule_5": 0, + "tcp_flags": 26, + "streamcore_id_rule_6": 0, + "streamcore_id_rule_3": 1192, + "streamcore_id_rule_4": 1435, + "streamcore_id_rule_9": 0, + "streamcore_id_rule_7": 0, + "streamcore_id_rule_8": 0, + "streamcore_net_app_resp_time": 17, + "l4_dst_port": 53483, + "output_snmp": 1148, + "streamcore_hostname": "live.lemde.fr", + "streamcore_call_direction": 1, + "src_tos": 40, + "ipv4_dst_addr": "10.27.8.20", + "version": 9, + "streamcore_tcp_retrans_rate": 0, + "flow_seq_num": 2142545188, + "ipv4_src_addr": "100.78.40.201", + "input_snmp": 1152, + "last_switched": "2017-01-11T11:23:35.999Z", + "streamcore_url": "\/mux.json", + "streamcore_wan_rtt": 0, + "streamcore_total_app_resp_time": 19 + }, + "@timestamp": "2017-01-11T11:23:51.000Z", + "@version": "1" + } + END + + events << <<-END + { + "netflow": { + "streamcore_id_rule_10": 0, + "in_pkts": 11, + "first_switched": "2017-01-11T11:22:44.999Z", + "flowset_id": 260, + "l4_src_port": 53483, + "streamcore_id_rule_1": 1171, + "streamcore_id_rule_2": 1179, + "in_bytes": 3052, + "protocol": 6, + "streamcore_id_rule_5": 0, + "tcp_flags": 26, + "streamcore_id_rule_6": 0, + "streamcore_id_rule_3": 1192, + "streamcore_id_rule_4": 1435, + "streamcore_id_rule_9": 0, + "streamcore_id_rule_7": 0, + "streamcore_id_rule_8": 0, + "streamcore_net_app_resp_time": 17, + "l4_dst_port": 8080, + "output_snmp": 1152, + "streamcore_hostname": "live.lemde.fr", + "streamcore_call_direction": 0, + "src_tos": 40, + "ipv4_dst_addr": "100.78.40.201", + "version": 9, + "streamcore_tcp_retrans_rate": 0, + "flow_seq_num": 2142545188, + "ipv4_src_addr": "10.27.8.20", + "input_snmp": 1148, + "last_switched": "2017-01-11T11:23:35.999Z", + "streamcore_url": "\/mux.json", + "streamcore_wan_rtt": 0, + "streamcore_total_app_resp_time": 19 + }, + "@timestamp": "2017-01-11T11:23:51.000Z", + "@version": "1" + } + END + + events.map{|event| event.gsub(/\s+/, "")} + end + + it "should decode raw data" do + expect(decode.size).to eq(4) + expect(decode[0].get("[netflow][streamcore_id_rule_1]")).to eq(1171) + expect(decode[3].get("[netflow][streamcore_hostname]")).to eq("live.lemde.fr") + end + + it "should serialize to json" do + expect(JSON.parse(decode[0].to_json)).to eq(JSON.parse(json_events[0])) + expect(JSON.parse(decode[3].to_json)).to eq(JSON.parse(json_events[3])) + end + + end + + context "IPFIX Netscaler with variable length fields" do let(:data) do # this ipfix raw data was produced by a Netscaler appliance and captured with wireshark # select packet bytes were then exported and sort of Pseudonymized to protect corp data data = [] @@ -1234,15 +1414,193 @@ expect(decode[4].get("[netflow][destinationTransportPort]")).to eq(5355) end it "should serialize to json" do expect(JSON.parse(decode[0].to_json)).to eq(JSON.parse(json_events[0])) - expect(JSON.parse(decode[1].to_json)).to eq(JSON.parse(json_events[1])) - expect(JSON.parse(decode[2].to_json)).to eq(JSON.parse(json_events[2])) - expect(JSON.parse(decode[3].to_json)).to eq(JSON.parse(json_events[3])) - expect(JSON.parse(decode[4].to_json)).to eq(JSON.parse(json_events[4])) end + end + + context "Juniper SRX options template with 0 scope field length" do + let(:data) do + packets = [] + packets << IO.read(File.join(File.dirname(__FILE__), "netflow9_test_juniper_srx_tplopt.dat"), :mode => "rb") + end + + let(:json_events) do + events = [] + events << <<-END + { + "netflow": { + "flow_seq_num": 338, + "flowset_id": 256, + "version":9, + "sampling_algorithm":2, + "sampling_interval":1 + }, + "@timestamp":"2016-11-29T00:21:56.000Z", + "@version":"1" + } + END + events.map{|event| event.gsub(/\s+/, "")} + end + + it "should decode raw data" do + expect(decode.size).to eq(1) + expect(decode[0].get("[netflow][sampling_algorithm]")).to eq(2) + end + + it "should serialize to json" do + expect(JSON.parse(decode[0].to_json)).to eq(JSON.parse(json_events[0])) + end + + end + + context "Netflow 9 template with 0 length fields" do + let(:data) do + packets = [] + packets << IO.read(File.join(File.dirname(__FILE__), "netflow9_test_0length_fields_tpl_data.dat"), :mode => "rb") + end + + let(:json_events) do + events = [] + events << <<-END + { + "netflow":{ + "output_snmp":3, + "dst_mask":32, + "in_pkts":0, + "ipv4_dst_addr":"239.255.255.250", + "first_switched":"2016-12-23T01:34:52.999Z", + "flowset_id":256, + "l4_src_port":0, + "src_mask":32, + "version":9, + "flow_seq_num":100728833, + "ipv4_src_addr":"192.168.1.33", + "in_bytes":0, + "protocol":2, + "input_snmp":2, + "last_switched":"2016-12-23T01:34:52.999Z", + "tcp_flags":0, + "engine_id":1, + "out_pkts":1, + "out_bytes":32, + "l4_dst_port":0, + "direction":1 + }, + "@timestamp":"2016-12-23T01:35:31.000Z", + "@version":"1" + } + END + events.map{|event| event.gsub(/\s+/, "")} + end + + it "should decode raw data" do + expect(decode.size).to eq(10) + expect(decode[9].get("[netflow][ipv4_src_addr]")).to eq("192.168.1.33") + end + + it "should serialize to json" do + expect(JSON.parse(decode[9].to_json)).to eq(JSON.parse(json_events[0])) + end + + end + + context "Netflow 9 Cisco ASR 9000 series options template 256" do + let(:data) do + packets = [] + packets << IO.read(File.join(File.dirname(__FILE__), "netflow9_test_cisco_asr9k_opttpl256.dat"), :mode => "rb") + packets << IO.read(File.join(File.dirname(__FILE__), "netflow9_test_cisco_asr9k_data256.dat"), :mode => "rb") + end + + let(:json_events) do + events = [] + events << <<-END + { + "netflow": { + "flow_seq_num": 24496783, + "scope_system": 3250896451, + "input_snmp": 104, + "if_desc": "TenGigE0_6_0_2", + "flowset_id": 256, + "version": 9 + }, + "@timestamp": "2016-12-06T10:09:48.000Z", + "@version": "1" + } + END + events.map{|event| event.gsub(/\s+/, "")} + end + + it "should decode raw data" do + expect(decode.size).to eq(19) + expect(decode[18].get("[netflow][if_desc]")).to eq("TenGigE0_6_0_2") + end + + it "should serialize to json" do + expect(JSON.parse(decode[18].to_json)).to eq(JSON.parse(json_events[0])) + end + + end + + context "Netflow 9 Cisco ASR 9000 series template 260" do + let(:data) do + packets = [] + packets << IO.read(File.join(File.dirname(__FILE__), "netflow9_test_cisco_asr9k_tpl260.dat"), :mode => "rb") + packets << IO.read(File.join(File.dirname(__FILE__), "netflow9_test_cisco_asr9k_data260.dat"), :mode => "rb") + end + + let(:json_events) do + events = [] + events << <<-END + { + "netflow": { + "dst_as": 64498, + "forwarding_status": { + "reason": 0, + "status": 1 + }, + "in_pkts": 2, + "first_switched": "2016-12-06T10:08:53.999Z", + "flowset_id": 260, + "l4_src_port": 443, + "in_bytes": 112, + "protocol": 6, + "tcp_flags": 18, + "ingressVRFID": 1610612736, + "l4_dst_port": 52364, + "src_as": 15169, + "direction": 1, + "output_snmp": 158, + "dst_mask": 24, + "ipv4_dst_addr": "10.0.15.38", + "src_tos": 0, + "src_mask": 24, + "version": 9, + "flow_seq_num": 24495777, + "ipv4_src_addr": "10.0.29.46", + "egressVRFID": 1610612736, + "input_snmp": 75, + "last_switched": "2016-12-06T10:08:54.999Z", + "flow_sampler_id": 1, + "bgp_ipv4_next_hop": "10.0.14.27" + }, + "@timestamp": "2016-12-06T10:09:24.000Z", + "@version": "1" + } + END + events.map{|event| event.gsub(/\s+/, "")} + end + + it "should decode raw data" do + expect(decode.size).to eq(21) + expect(decode[20].get("[netflow][egressVRFID]")).to eq(1610612736) + end + + it "should serialize to json" do + expect(JSON.parse(decode[20].to_json)).to eq(JSON.parse(json_events[0])) + end end end describe LogStash::Codecs::Netflow, 'missing templates, no template caching configured' do