diff --git a/src/capture.c b/src/capture.c index 1629d76..59748c7 100644 --- a/src/capture.c +++ b/src/capture.c @@ -485,57 +485,69 @@ capture_packet_reasm_ip(capture_info_t *capinfo, const struct pcap_pkthdr *heade } } - // Get IP header - ip4 = (struct ip *) (packet + link_hl); + while (*size >= sizeof(struct ip)) { + // Get IP header + ip4 = (struct ip *) (packet + link_hl); #ifdef USE_IPV6 - // Get IPv6 header - ip6 = (struct ip6_hdr *) (packet + link_hl); + // Get IPv6 header + ip6 = (struct ip6_hdr *) (packet + link_hl); #endif - // Get IP version - ip_ver = ip4->ip_v; + // Get IP version + ip_ver = ip4->ip_v; - switch (ip_ver) { - case 4: - ip_hl = ip4->ip_hl * 4; - ip_proto = ip4->ip_p; - ip_off = ntohs(ip4->ip_off); - ip_len = ntohs(ip4->ip_len); + switch (ip_ver) { + case 4: + ip_hl = ip4->ip_hl * 4; + ip_proto = ip4->ip_p; + ip_off = ntohs(ip4->ip_off); + ip_len = ntohs(ip4->ip_len); - ip_frag = ip_off & (IP_MF | IP_OFFMASK); - ip_frag_off = (ip_frag) ? (ip_off & IP_OFFMASK) * 8 : 0; - ip_id = ntohs(ip4->ip_id); + ip_frag = ip_off & (IP_MF | IP_OFFMASK); + ip_frag_off = (ip_frag) ? (ip_off & IP_OFFMASK) * 8 : 0; + ip_id = ntohs(ip4->ip_id); - inet_ntop(AF_INET, &ip4->ip_src, src.ip, sizeof(src.ip)); - inet_ntop(AF_INET, &ip4->ip_dst, dst.ip, sizeof(dst.ip)); - break; + inet_ntop(AF_INET, &ip4->ip_src, src.ip, sizeof(src.ip)); + inet_ntop(AF_INET, &ip4->ip_dst, dst.ip, sizeof(dst.ip)); + break; #ifdef USE_IPV6 - case 6: - ip_hl = sizeof(struct ip6_hdr); - ip_proto = ip6->ip6_nxt; - ip_len = ntohs(ip6->ip6_ctlun.ip6_un1.ip6_un1_plen) + ip_hl; + case 6: + ip_hl = sizeof(struct ip6_hdr); + ip_proto = ip6->ip6_nxt; + ip_len = ntohs(ip6->ip6_ctlun.ip6_un1.ip6_un1_plen) + ip_hl; - if (ip_proto == IPPROTO_FRAGMENT) { - struct ip6_frag *ip6f = (struct ip6_frag *) (ip6 + ip_hl); - ip_frag_off = ntohs(ip6f->ip6f_offlg & IP6F_OFF_MASK); - ip_id = ntohl(ip6f->ip6f_ident); - } + if (ip_proto == IPPROTO_FRAGMENT) { + struct ip6_frag *ip6f = (struct ip6_frag *) (ip6 + ip_hl); + ip_frag_off = ntohs(ip6f->ip6f_offlg & IP6F_OFF_MASK); + ip_id = ntohl(ip6f->ip6f_ident); + } - inet_ntop(AF_INET6, &ip6->ip6_src, src.ip, sizeof(src.ip)); - inet_ntop(AF_INET6, &ip6->ip6_dst, dst.ip, sizeof(dst.ip)); - break; + inet_ntop(AF_INET6, &ip6->ip6_src, src.ip, sizeof(src.ip)); + inet_ntop(AF_INET6, &ip6->ip6_dst, dst.ip, sizeof(dst.ip)); + break; #endif - default: - return NULL; + default: + return NULL; + } + + // Fixup VSS trailer in ethernet packets + *caplen = link_hl + ip_len; + + // Remove IP Header length from payload + *size = *caplen - link_hl - ip_hl; + + if (ip_proto == IPPROTO_IPIP) { + // The payload is an incapsulated IP packet (IP-IP tunnel) + // so we simply skip the "outer" IP header and repeat. + // NOTE: this will break IP reassembly if the "outer" + // packet is fragmented. + link_hl += ip_hl; + } else { + break; + } } - // Fixup VSS trailer in ethernet packets - *caplen = link_hl + ip_len; - - // Remove IP Header length from payload - *size = *caplen - link_hl - ip_hl; - // If no fragmentation if (ip_frag == 0) { // Just create a new packet with given network data diff --git a/tests/Makefile.am b/tests/Makefile.am index 84065bd..d5f6a0b 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -2,6 +2,7 @@ AUTOMAKE_OPTIONS=subdir-objects check_PROGRAMS=test-001 test-002 test-003 test-004 test-005 check_PROGRAMS+=test-006 test-007 test-008 test-009 test-010 +check_PROGRAMS+=test-011 test_001_SOURCES=test_001.c test_002_SOURCES=test_002.c @@ -13,5 +14,6 @@ test_007_SOURCES=test_007.c ../src/vector.c ../src/util.c test_008_SOURCES=test_008.c test_009_SOURCES=test_009.c test_010_SOURCES=test_010.c ../src/hash.c +test_011_SOURCES=test_011.c TESTS = $(check_PROGRAMS) diff --git a/tests/README b/tests/README index 97dd0f9..c3b4fc2 100644 --- a/tests/README +++ b/tests/README @@ -1,6 +1,6 @@ Basic testing programs for sngrep. -This set of test will do some basic inputs to check sngrep screen navigation +This set of test will do some basic inputs to check sngrep screen navigation doesn't crash. This checks are ultra-super-basic. - test_001 : UI testing @@ -10,6 +10,7 @@ doesn't crash. This checks are ultra-super-basic. - test_005 : Column selection testing - test_006 : Message diff testing - test_007: Test vector container structures +- test_011: Test mix of normal packets with IPIP tunneled packets Sample capture files has been taken from wireshark Wiki: - https://wiki.wireshark.org/SampleCaptures diff --git a/tests/ipip.pcap b/tests/ipip.pcap new file mode 100644 index 0000000..6bf3834 Binary files /dev/null and b/tests/ipip.pcap differ diff --git a/tests/test_008.c b/tests/test_008.c index 259dd06..2fc9d74 100644 --- a/tests/test_008.c +++ b/tests/test_008.c @@ -20,7 +20,7 @@ ** ****************************************************************************/ /** - * @file test_001.c + * @file test_008.c * @author Ivan Alonso [aka Kaian] * * Test for sorting columns based on standard attributes diff --git a/tests/test_009.c b/tests/test_009.c index c988c3a..0c71244 100644 --- a/tests/test_009.c +++ b/tests/test_009.c @@ -20,7 +20,7 @@ ** ****************************************************************************/ /** - * @file test_001.c + * @file test_009.c * @author Ivan Alonso [aka Kaian] * * Test for adding a new attribute column and sorting using it. diff --git a/tests/test_011.c b/tests/test_011.c new file mode 100644 index 0000000..becdd64 --- /dev/null +++ b/tests/test_011.c @@ -0,0 +1,43 @@ +/************************************************************************** + ** + ** sngrep - SIP Messages flow viewer + ** + ** Copyright (C) 2013-2018 Ivan Alonso (Kaian) + ** Copyright (C) 2013-2018 Irontec SL. All rights reserved. + ** + ** This program is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** This program is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with this program. If not, see . + ** + ****************************************************************************/ +/** + * @file test_011.c + * @author Evgeny Khramtsov + * + * IP-IP tunnel test from ipip.pcap + */ + +const char keys[] = + { + /* Enter Call Flow */ + 10, + /* Leave Call Flow */ + 27, + /* Exit */ + 27, + 10, + 0 + }; + +#define TEST_PCAP_INPUT "ipip.pcap" + +#include "test_input.c"