text2pcap: Fix IPv6 payload length
authorVasil Velichkov <vvvelichkov@gmail.com>
Sun, 28 Oct 2018 19:46:05 +0000 (21:46 +0200)
committerAnders Broman <a.broman58@gmail.com>
Tue, 30 Oct 2018 15:57:02 +0000 (15:57 +0000)
According to RFC 8200 the payload length must contain the length of the payload
without the IPv6 header's length

Change-Id: Ibeb18c243edc396eaac6d2ffde73d6c4a6fe75a0
Reviewed-on: https://code.wireshark.org/review/30406
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
test/suite_text2pcap.py
text2pcap.c

index 569f5b5..63a7899 100644 (file)
@@ -15,6 +15,7 @@ import pprint
 import re
 import subprocesstest
 import unittest
+import json
 
 # XXX We should probably generate these automatically in config.py.
 c1222_std_example8_pcap = os.path.join(config.capture_dir, 'c1222_std_example8.pcap')
@@ -278,9 +279,8 @@ class case_text2pcap_parsing(subprocesstest.SubprocessTestCase):
 
     def check_rawip(self, pdata, packets, datasize):
         self.assertEqual({'encapsulation': 'Raw IPv4', 'packets': packets,
-            'datasize': datasize},
-            get_capinfos_cmp_info(check_capinfos_info(self,
-                run_text2pcap_content(self, pdata, ("-l228",)))))
+            'datasize': datasize, 'expert': ''},
+            run_text2pcap_capinfos_tshark(self, pdata, ("-l228",)))
 
     def test_text2pcap_doc_no_line_limit(self):
         '''
@@ -351,122 +351,136 @@ def run_text2pcap_content(test, content, args):
     test.assertRun((config.cmd_text2pcap,) + args + (testin_file, testout_file))
     return testout_file
 
+def run_text2pcap_capinfos_tshark(test, content, args):
+    testout_file = run_text2pcap_content(test, content, args)
+
+    capinfo = get_capinfos_cmp_info(check_capinfos_info(test, testout_file))
+
+    test.assertRun((config.cmd_tshark, '-q', '-z', 'expert,warn',
+        '-r', testout_file))
+    capinfo['expert'] = test.processes[-1].stdout_str
+    return capinfo;
+
 class case_text2pcap_headers(subprocesstest.SubprocessTestCase):
     '''Test TCP, UDP or SCTP header without -4 or -6 option'''
+    maxDiff = None
 
     def run_text2pcap(self, content, args):
-        return run_text2pcap_content(self, content, args)
+        return run_text2pcap_capinfos_tshark(self, content, args);
 
     def test_text2pcap_tcp(self):
         '''Test TCP over IPv4'''
         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
-            'datasize': 60},
-            get_capinfos_cmp_info(check_capinfos_info(self,
-                self.run_text2pcap("0000: ff ff ff ff\n",
-                    ("-T", "1234,1234")))))
+            'datasize': 60, 'expert': ''},
+            self.run_text2pcap("0000: ff ff ff ff\n", ("-T", "1234,1234")))
 
     def test_text2pcap_udp(self):
         '''Test UDP over IPv4'''
         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
-            'datasize': 60},
-            get_capinfos_cmp_info(check_capinfos_info(self,
-                self.run_text2pcap("0000: ff ff ff ff\n",
-                    ("-u", "1234,1234")))))
+            'datasize': 60, 'expert': ''},
+            self.run_text2pcap("0000: ff ff ff ff\n", ("-u", "1234,1234")))
 
     def test_text2pcap_sctp(self):
         '''Test SCTP over IPv4'''
         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
-            'datasize': 70},
-            get_capinfos_cmp_info(check_capinfos_info(self,
-                self.run_text2pcap(
-                    "0000   00 03 00 18 00 00 00 00 00 00 00 00 00 00 00 03\n" +
-                    "0010   01 00 03 03 00 00 00 08\n",
-                    ("-s", "2905,2905,3")))))
+            'datasize': 70, 'expert': ''},
+            self.run_text2pcap(
+                "0000   00 03 00 18 00 00 00 00 00 00 00 00 00 00 00 03\n" +
+                "0010   01 00 03 03 00 00 00 08\n",
+                ("-s", "2905,2905,3")))
 
     def test_text2pcap_sctp_data(self):
         '''Test SCTP DATA over IPv4'''
         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
-            'datasize': 70},
-            get_capinfos_cmp_info(check_capinfos_info(self,
-                self.run_text2pcap("0000: 01 00 03 03 00 00 00 08\n",
-                    ("-S", "2905,2905,3")))))
+            'datasize': 70, 'expert': ''},
+            self.run_text2pcap("0000: 01 00 03 03 00 00 00 08\n",
+                ("-S", "2905,2905,3")))
 
 class case_text2pcap_ipv4(subprocesstest.SubprocessTestCase):
     '''Test TCP, UDP or SCTP header with -4 option'''
+    maxDiff = None
 
     def run_text2pcap_ipv4(self, content, args):
-        return run_text2pcap_content(self, content, ("-4", "127.0.0.1,127.0.0.1") + args)
+        return run_text2pcap_capinfos_tshark(self, content,
+                ("-4", "127.0.0.1,127.0.0.1") + args)
 
     def test_text2pcap_ipv4_tcp(self):
         '''Test TCP over IPv4'''
         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
-            'datasize': 60},
-            get_capinfos_cmp_info(check_capinfos_info(self,
-                self.run_text2pcap_ipv4("0000: ff ff ff ff\n",
-                    ("-T", "1234,1234")))))
+            'datasize': 60, 'expert': ''},
+            self.run_text2pcap_ipv4("0000: ff ff ff ff\n", ("-T", "1234,1234")))
 
     def test_text2pcap_ipv4_udp(self):
         '''Test UDP over IPv4'''
         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
-            'datasize': 60},
-            get_capinfos_cmp_info(check_capinfos_info(self,
-                self.run_text2pcap_ipv4("0000: ff ff ff ff\n",
-                    ("-u", "1234,1234")))))
+            'datasize': 60, 'expert': ''},
+            self.run_text2pcap_ipv4("0000: ff ff ff ff\n", ("-u", "1234,1234")))
 
     def test_text2pcap_ipv4_sctp(self):
         '''Test SCTP over IPv4'''
         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
-            'datasize': 70},
-            get_capinfos_cmp_info(check_capinfos_info(self,
-                self.run_text2pcap_ipv4(
-                    "0000   00 03 00 18 00 00 00 00 00 00 00 00 00 00 00 03\n" +
-                    "0010   01 00 03 03 00 00 00 08\n",
-                    ("-s", "2905,2905,3")))))
+            'datasize': 70, 'expert': ''},
+            self.run_text2pcap_ipv4(
+                "0000   00 03 00 18 00 00 00 00 00 00 00 00 00 00 00 03\n" +
+                "0010   01 00 03 03 00 00 00 08\n",
+                ("-s", "2905,2905,3")))
 
     def test_text2pcap_ipv4_sctp_data(self):
         '''Test SCTP DATA over IPv4'''
         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
-            'datasize': 70},
-            get_capinfos_cmp_info(check_capinfos_info(self,
-                self.run_text2pcap_ipv4("0000: 01 00 03 03 00 00 00 08\n",
-                    ("-S", "2905,2905,3")))))
+            'datasize': 70, 'expert': ''},
+            self.run_text2pcap_ipv4("0000: 01 00 03 03 00 00 00 08\n",
+                ("-S", "2905,2905,3")))
 
 class case_text2pcap_ipv6(subprocesstest.SubprocessTestCase):
     '''Test TCP, UDP or SCTP header with -6 option'''
+    maxDiff = None
+
+    def run_text2pcap_ipv6(self, content, text2pcap_args, tshark_args = ()):
+        #Run the common text2pcap tests
+        result = run_text2pcap_capinfos_tshark(self, content,
+                ("-6", "::1,::1") + text2pcap_args)
+
+        #Decode the output pcap in JSON format
+        self.assertRun((config.cmd_tshark, '-T', 'json',
+            '-r', self.filename_from_id(testout_pcap)) + tshark_args)
+        data = json.loads(self.processes[-1].stdout_str)
 
-    def run_text2pcap_ipv6(self, content, args):
-        return run_text2pcap_content(self, content, ("-6", "::1,::1") + args)
+        #Add IPv6 payload length and payload length tree to the result dict
+        ipv6 = data[0]['_source']['layers']['ipv6']
+        result['ipv6'] = {
+                'plen': ipv6.get('ipv6.plen', None),
+                'plen_tree': ipv6.get('ipv6.plen_tree', None)}
+        return result;
 
     def test_text2pcap_ipv6_tcp(self):
         '''Test TCP over IPv6'''
         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
-            'datasize': 78},
-            get_capinfos_cmp_info(check_capinfos_info(self,
-                self.run_text2pcap_ipv6("0000: ff ff ff ff\n",
-                    ("-T", "1234,1234")))))
+            'datasize': 78, 'expert': '',
+            'ipv6': {'plen': '24', 'plen_tree': None}},
+            self.run_text2pcap_ipv6("0000: ff ff ff ff\n", ("-T", "1234,1234")))
 
     def test_text2pcap_ipv6_udp(self):
         '''Test UDP over IPv6'''
         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
-            'datasize': 66},
-            get_capinfos_cmp_info(check_capinfos_info(self,
-                self.run_text2pcap_ipv6("0000: ff ff ff ff\n",
-                    ("-u", "1234,1234")))))
+            'datasize': 66, 'expert': '',
+            'ipv6': {'plen': '12', 'plen_tree': None}},
+            self.run_text2pcap_ipv6("0000: ff ff ff ff\n", ("-u", "1234,1234")))
 
     def test_text2pcap_ipv6_sctp(self):
         '''Test SCTP over IPv6'''
         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
-            'datasize': 90},
-            get_capinfos_cmp_info(check_capinfos_info(self,
-                self.run_text2pcap_ipv6(
-                    "0000   00 03 00 18 00 00 00 00 00 00 00 00 00 00 00 03\n" +
-                    "0010   01 00 03 03 00 00 00 08\n",
-                    ("-s", "2905,2905,3")))))
+            'datasize': 90, 'expert': '',
+            'ipv6': {'plen': '36', 'plen_tree': None}},
+            self.run_text2pcap_ipv6(
+                "0000   00 03 00 18 00 00 00 00 00 00 00 00 00 00 00 03\n" +
+                "0010   01 00 03 03 00 00 00 08\n",
+                ("-s", "2905,2905,3")))
 
     def test_text2pcap_ipv6_sctp_data(self):
         '''Test SCTP DATA over IPv6'''
         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
-            'datasize': 90},
-            get_capinfos_cmp_info(check_capinfos_info(self,
-                self.run_text2pcap_ipv6("0000: 01 00 03 03 00 00 00 08\n",
-                    ("-S", "2905,2905,3")))))
+            'datasize': 90, 'expert': '',
+            'ipv6': {'plen': '36', 'plen_tree': None}},
+            self.run_text2pcap_ipv6("0000: 01 00 03 03 00 00 00 08\n",
+                ("-S", "2905,2905,3")))
index 0a189ab..f492059 100644 (file)
@@ -616,7 +616,6 @@ write_current_packet (gboolean cont)
     guint32  length         = 0;
     guint16  padding_length = 0;
     int      err;
-    guint16  ihatemacros;
     gboolean success;
 
     if (curr_offset > header_length) {
@@ -671,7 +670,7 @@ write_current_packet (gboolean cont)
 
             HDR_IPv6.ip6_ctlun.ip6_un2_vfc &= 0x0F;
             HDR_IPv6.ip6_ctlun.ip6_un2_vfc |= (6<< 4);
-            HDR_IPv6.ip6_ctlun.ip6_un1.ip6_un1_plen = g_htons(length - ip_offset + padding_length);
+            HDR_IPv6.ip6_ctlun.ip6_un1.ip6_un1_plen = g_htons(length - ip_offset - sizeof(HDR_IPv6) + padding_length);
             HDR_IPv6.ip6_ctlun.ip6_un1.ip6_un1_nxt  = (guint8) hdr_ip_proto;
             HDR_IPv6.ip6_ctlun.ip6_un1.ip6_un1_hlim = 32;
             write_bytes((const char *)&HDR_IPv6, sizeof(HDR_IPv6));
@@ -681,8 +680,7 @@ write_current_packet (gboolean cont)
             pseudoh6.dst_addr6  = HDR_IPv6.ip6_dst;
             pseudoh6.zero       = 0;
             pseudoh6.protocol   = (guint8) hdr_ip_proto;
-            ihatemacros         = g_ntohs(HDR_IPv6.ip6_ctlun.ip6_un1.ip6_un1_plen);
-            pseudoh.length      = g_htons(length - ihatemacros + sizeof(HDR_UDP));
+            pseudoh.length      = g_htons(length - header_length + sizeof(HDR_UDP));
         }
 
         if (!hdr_ipv6) {