test: allow running pytest without specifying the tests directory
[metze/wireshark/wip.git] / test / suite_text2pcap.py
1 #
2 # -*- coding: utf-8 -*-
3 # Wireshark tests
4 # By Gerald Combs <gerald@wireshark.org>
5 #
6 # Ported from a set of Bash scripts which were copyright 2005 Ulf Lamping
7 #
8 # SPDX-License-Identifier: GPL-2.0-or-later
9 #
10 '''Text2pcap tests'''
11
12 import pprint
13 import re
14 import subprocesstest
15 import json
16 import fixtures
17
18 testin_txt = 'testin.txt'
19 testout_pcap = 'testout.pcap'
20 testout_pcapng = 'testout.pcapng'
21
22 file_type_to_descr = {
23     'pcap': 'Wireshark/tcpdump/... - pcap',
24     'pcapng': 'Wireshark/... - pcapng',
25 }
26
27 file_type_to_testout = {
28     'pcap': testout_pcap,
29     'pcapng': testout_pcapng,
30 }
31
32 encap_to_link_type = {
33     'Ethernet': 1,
34     'Raw IP': 14,
35     'Linux cooked-mode capture': 113,
36     'IEEE 802.11 plus radiotap radio header': 127,
37     'DVB-CI (Common Interface)': 235,
38 }
39
40 def check_capinfos_info(self, cap_file):
41     cap_info = {
42         'filetype': None,
43         'encapsulation': None,
44         'packets': None,
45         'datasize': None,
46         'timeend': None,
47     }
48     str_pats = {
49         'filetype': 'File type',
50         'encapsulation': 'File encapsulation',
51         'timeend': 'Last packet time',
52     }
53     int_pats = {
54         'packets': 'Number of packets',
55         'datasize': 'Data size',
56     }
57     capinfos_out = self.getCaptureInfo(capinfos_args=('-tEcdMe',), cap_file=cap_file)
58
59     for ci_line in capinfos_out.splitlines():
60         for sp_key in str_pats:
61             str_pat = r'{}:\s+([\S ]+)'.format(str_pats[sp_key])
62             str_res = re.search(str_pat, ci_line)
63             if str_res is not None:
64                 cap_info[sp_key] = str_res.group(1)
65
66         for ip_key in int_pats:
67             int_pat = r'{}:\s+(\d+)'.format(int_pats[ip_key])
68             int_res = re.search(int_pat, ci_line)
69             if int_res is not None:
70                 cap_info[ip_key] = int(int_res.group(1))
71
72     return cap_info
73
74 def get_capinfos_cmp_info(cii):
75     cmp_keys = ('encapsulation', 'packets', 'datasize')
76     return { k: v for k, v in cii.items() if k in cmp_keys }
77
78 def compare_capinfos_info(self, cii1, cii2, filename1, filename2):
79     cii_cmp_i1 = get_capinfos_cmp_info(cii1)
80     cii_cmp_i2 = get_capinfos_cmp_info(cii2)
81     if not cii_cmp_i1 == cii_cmp_i2:
82         cii1_pp = pprint.pformat(cii_cmp_i1)
83         cii2_pp = pprint.pformat(cii_cmp_i2)
84         self.diffOutput(cii1_pp, cii2_pp, filename1, filename2)
85         self.fail('text2pcap output file differs from input file.')
86
87 @fixtures.fixture
88 def check_text2pcap(cmd_tshark, cmd_text2pcap, capture_file):
89     def check_text2pcap_real(self, cap_filename, file_type, expected_packets=None, expected_datasize=None):
90         # Perform the following actions
91         # - Get information for the input pcap file with capinfos
92         # - Generate an ASCII hexdump with TShark
93         # - Convert the ASCII hexdump back to pcap using text2pcap
94         # - Get information for the output pcap file with capinfos
95         # - Check that file type, encapsulation type, number of packets and data size
96         #   in the output file are the same as in the input file
97
98         cap_file = capture_file(cap_filename)
99         pre_cap_info = check_capinfos_info(self, cap_file)
100         # Due to limitations of "tshark -x", the output might contain more than one
101         # data source which is subsequently interpreted as additional frame data.
102         # See https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=14639
103         if expected_packets is not None:
104             self.assertNotEqual(pre_cap_info['packets'], expected_packets)
105             pre_cap_info['packets'] = expected_packets
106         if expected_datasize is not None:
107             self.assertNotEqual(pre_cap_info['datasize'], expected_datasize)
108             pre_cap_info['datasize'] = expected_datasize
109         self.assertTrue(pre_cap_info['encapsulation'] in encap_to_link_type)
110
111         self.assertTrue(file_type in file_type_to_testout, 'Invalid file type')
112
113         # text2pcap_generate_input()
114         # $TSHARK -o 'gui.column.format:"Time","%t"' -tad -P -x -r $1 > testin.txt
115         testin_file = self.filename_from_id(testin_txt)
116         tshark_cmd = '{cmd} -r {cf} -o gui.column.format:"Time","%t" -t ad -P -x > {of}'.format(
117             cmd = cmd_tshark,
118             cf = cap_file,
119             of = testin_file,
120         )
121         self.assertRun(tshark_cmd, shell=True)
122
123         testout_fname = file_type_to_testout[file_type]
124         testout_file = self.filename_from_id(testout_fname)
125         if 'pcapng' in pre_cap_info['filetype'] or 'nanosecond libpcap' in pre_cap_info['filetype']:
126             pcapng_flag = '-n'
127         else:
128             pcapng_flag = ''
129         text2pcap_cmd = '{cmd} {ns} -d -l {linktype} -t "%Y-%m-%d %H:%M:%S." {in_f} {out_f}'.format(
130             cmd = cmd_text2pcap,
131             ns = pcapng_flag,
132             linktype = encap_to_link_type[pre_cap_info['encapsulation']],
133             in_f = testin_file,
134             out_f = testout_file,
135         )
136         self.assertRun(text2pcap_cmd, shell=True)
137         self.assertTrue(self.grepOutput('potential packet'), "text2pcap didn't complete")
138         self.assertFalse(self.grepOutput('Inconsistent offset'), 'text2pcap detected inconsistent offset')
139
140         post_cap_info = check_capinfos_info(self, testout_file)
141         compare_capinfos_info(self, pre_cap_info, post_cap_info, cap_file, testout_fname)
142     return check_text2pcap_real
143
144
145 @fixtures.mark_usefixtures('base_env')
146 @fixtures.uses_fixtures
147 class case_text2pcap_pcap(subprocesstest.SubprocessTestCase):
148     def test_text2pcap_empty_pcap(self, check_text2pcap):
149         '''Test text2pcap with empty.pcap.'''
150         check_text2pcap(self, 'empty.pcap', 'pcap')
151
152     def test_text2pcap_dhcp_pcap(self, check_text2pcap):
153         '''Test text2pcap with dhcp.pcap.'''
154         check_text2pcap(self, 'dhcp.pcap', 'pcap')
155
156     def test_text2pcap_dhcp_nanosecond_pcap(self, check_text2pcap):
157         '''Test text2pcap with dhcp-nanosecond.pcap.'''
158         check_text2pcap(self, 'dhcp-nanosecond.pcap', 'pcap')
159
160     def test_text2pcap_segmented_fpm_pcap(self, check_text2pcap):
161         '''Test text2pcap with segmented_fpm.pcap.'''
162         check_text2pcap(self, 'segmented_fpm.pcap', 'pcap')
163
164     def test_text2pcap_c1222_std_example8_pcap(self, check_text2pcap):
165         '''Test text2pcap with c1222_std_example8.pcap.'''
166         check_text2pcap(self, 'c1222_std_example8.pcap', 'pcap')
167
168     def test_text2pcap_dns_port_pcap(self, check_text2pcap):
169         '''Test text2pcap with dns_port.pcap.'''
170         check_text2pcap(self, 'dns_port.pcap', 'pcap')
171
172     def test_text2pcap_dvb_ci_uv1_0000_pcap(self, check_text2pcap):
173         '''Test text2pcap with dvb-ci_UV1_0000.pcap.'''
174         check_text2pcap(self, 'dvb-ci_UV1_0000.pcap', 'pcap')
175
176     def test_text2pcap_ikev1_certs_pcap(self, check_text2pcap):
177         '''Test text2pcap with ikev1-certs.pcap.'''
178         check_text2pcap(self, 'ikev1-certs.pcap', 'pcap')
179
180     def test_text2pcap_rsa_p_lt_q_pcap(self, check_text2pcap):
181         '''Test text2pcap with rsa-p-lt-q.pcap.'''
182         check_text2pcap(self, 'rsa-p-lt-q.pcap', 'pcap')
183
184     def test_text2pcap_rsasnakeoil2_pcap(self, check_text2pcap):
185         '''Test text2pcap with rsasnakeoil2.pcap.'''
186         check_text2pcap(self, 'rsasnakeoil2.pcap', 'pcap')
187
188     def test_text2pcap_sample_control4_2012_03_24_pcap(self, check_text2pcap):
189         '''Test text2pcap with sample_control4_2012-03-24.pcap.'''
190         # tshark currently output decrypted ZigBee packets and
191         # as a result the number of packets and data size are different
192         check_text2pcap(self, 'sample_control4_2012-03-24.pcap', 'pcap', 239, 10103)
193
194     def test_text2pcap_snakeoil_dtls_pcap(self, check_text2pcap):
195         '''Test text2pcap with snakeoil-dtls.pcap.'''
196         check_text2pcap(self, 'snakeoil-dtls.pcap', 'pcap')
197
198     def test_text2pcap_wpa_eap_tls_pcap_gz(self, check_text2pcap):
199         '''Test text2pcap with wpa-eap-tls.pcap.gz.'''
200         # tshark reassembles some packets and because of this
201         # the number of packets and data size are different
202         check_text2pcap(self, 'wpa-eap-tls.pcap.gz', 'pcap', 88, 38872)
203
204     def test_text2pcap_wpa_induction_pcap(self, check_text2pcap):
205         '''Test text2pcap with wpa-Induction.pcap.gz.'''
206         check_text2pcap(self, 'wpa-Induction.pcap.gz', 'pcap')
207
208
209 @fixtures.mark_usefixtures('base_env')
210 @fixtures.uses_fixtures
211 class case_text2pcap_pcapng(subprocesstest.SubprocessTestCase):
212     def test_text2pcap_dhcp_pcapng(self, check_text2pcap):
213         '''Test text2pcap with dhcp.pcapng.'''
214         check_text2pcap(self, 'dhcp.pcapng', 'pcapng')
215
216     def test_text2pcap_dhcp_nanosecond_pcapng(self, check_text2pcap):
217         '''Test text2pcap with dhcp-nanosecond.pcapng.'''
218         check_text2pcap(self, 'dhcp-nanosecond.pcapng', 'pcapng')
219
220     def test_text2pcap_dhe1_pcapng_gz(self, check_text2pcap):
221         '''Test text2pcap with dhe1.pcapng.gz.'''
222         check_text2pcap(self, 'dhe1.pcapng.gz', 'pcapng')
223
224     def test_text2pcap_dmgr_pcapng(self, check_text2pcap):
225         '''Test text2pcap with dmgr.pcapng.'''
226         check_text2pcap(self, 'dmgr.pcapng', 'pcapng')
227
228     def test_text2pcap_dns_icmp_pcapng_gz(self, check_text2pcap):
229         '''Test text2pcap with dns+icmp.pcapng.gz.'''
230         # Different data size
231         # Most probably the problem is that input file timestamp precision is in microseconds
232         # File timestamp precision: microseconds (6)
233         check_text2pcap(self, 'dns+icmp.pcapng.gz', 'pcapng', None, 3202)
234
235     def test_text2pcap_packet_h2_14_headers_pcapng(self, check_text2pcap):
236         '''Test text2pcap with packet-h2-14_headers.pcapng.'''
237         check_text2pcap(self, 'packet-h2-14_headers.pcapng', 'pcapng')
238
239     def test_text2pcap_sip_pcapng(self, check_text2pcap):
240         '''Test text2pcap with sip.pcapng.'''
241         check_text2pcap(self, 'sip.pcapng', 'pcapng')
242
243
244 @fixtures.fixture
245 def check_rawip(run_text2pcap_capinfos_tshark, request):
246     def check_rawip_real(pdata, packets, datasize):
247         self = request.instance
248         self.assertEqual({'encapsulation': 'Raw IPv4', 'packets': packets,
249             'datasize': datasize, 'expert': ''},
250             run_text2pcap_capinfos_tshark(pdata, ("-l228",)))
251     return check_rawip_real
252
253
254 @fixtures.mark_usefixtures('base_env')
255 @fixtures.uses_fixtures
256 class case_text2pcap_parsing(subprocesstest.SubprocessTestCase):
257     def test_text2pcap_eol_hash(self, cmd_text2pcap, capture_file):
258         '''Test text2pcap hash sign at the end-of-line.'''
259         txt_fname = 'text2pcap_hash_eol.txt'
260         testout_file = self.filename_from_id(testout_pcap)
261         self.assertRun((cmd_text2pcap,
262             '-n',
263             '-d',
264             '-t', '%Y-%m-%d %H:%M:%S.',
265             capture_file(txt_fname),
266             testout_file,
267         ))
268         self.assertFalse(self.grepOutput('Inconsistent offset'), 'text2pcap failed to parse the hash sign at the end of the line')
269         self.assertTrue(self.grepOutput(r'Directive \[ test_directive'), 'text2pcap failed to parse #TEXT2PCAP test_directive')
270         pre_cmp_info = {'encapsulation': 'Ethernet', 'packets': 1, 'datasize': 96, 'timeend': '2015-10-01 21:16:24.317453000'}
271         post_cmp_info = check_capinfos_info(self, testout_file)
272         compare_capinfos_info(self, pre_cmp_info, post_cmp_info, txt_fname, testout_pcap)
273
274     def test_text2pcap_doc_no_line_limit(self, check_rawip):
275         '''
276         Verify: There is no limit on the width or number of bytes per line and
277         Bytes/hex numbers can be uppercase or lowercase.
278         '''
279         pdata = "0000  45 00 00 21 00 01 00 00 40 11\n" \
280                 "000A  7C C9 7F 00 00 01" \
281                 " 7f 00 00 01 ff 98 00 13 00 0d b5 48 66 69 72 73\n" \
282                 "0020  74\n"
283         check_rawip(pdata, 1, 33)
284
285     def test_text2pcap_doc_ignore_text(self, check_rawip):
286         '''
287         Verify: the text dump at the end of the line is ignored. Any hex numbers
288         in this text are also ignored. Any lines of text between the bytestring
289         lines is ignored. Any line where the first non-whitespace character is
290         '#' will be ignored as a comment.
291         '''
292         pdata = "0000 45 00 00 21 00 01 00 00  40 11 7c c9 7f 00 00 01 bad\n" \
293                 "0010 7f 00 00 01 ff 98 00 13  00 0d b5 48 66 69 72 73 - 42\n" \
294                 "0020 74\n" \
295                 "0021\n" \
296                 "That 0021 should probably be ignored as it this: 00 20\n" \
297                 "0000 45 00 00 22 00 01 00 00 40 11 7c c8 7f 00 00 01\n" \
298                 "0010 7f 00 00 01 ff 99 00 13 00 0e bc e9 73 65 63 6f  ...\n" \
299                 " \t# 0020 12 34 56<-- comment, ignore this!\n" \
300                 "0020 6e 64\n" \
301                 "12 34 56 78 90 # ignore this due to missing offset!\n"
302         check_rawip(pdata, 2, 67)
303
304     def test_text2pcap_doc_leading_text_ignored(self, check_rawip):
305         '''
306         Verify: Any test before the offset is ignored, including email
307         forwarding characters '>'. An offset is a hex number longer than two
308         characters. An offset of zero is indicative of starting a new packet.
309         '''
310         pdata = "> >> 000  45 00 00 21 00 01 00 00 40 11 7c c9 7f 00 00 01\n" \
311                 "> >> 010  7f 00 00 01 ff 98 00 13 00 0d b5 48 66 69 72 73\n" \
312                 "> >> 020  74\n" \
313                 "> >> 000  45 00 00 22 00 01 00 00 40 11 7c c8 7f 00 00 01\n" \
314                 "> >> 010  7f 00 00 01 ff 99 00 13 00 0e bc e9 73 65 63 6f\n" \
315                 "> >> 020  6e 64\n"
316         check_rawip(pdata, 2, 67)
317
318     def test_text2pcap_doc_require_offset(self, check_rawip):
319         '''Any line which has only bytes without a leading offset is ignored.'''
320         pdata = "45 00 00 21 00 01 00 00 40 11 7c c9 7f 00 00 01\n" \
321                 "7f 00 00 01 ff 98 00 13 00 0d b5 48 66 69 72 73\n"
322         check_rawip(pdata, 0, 0)
323
324     def test_text2pcap_eol_missing(self, check_rawip):
325         '''Verify that the last LF can be missing.'''
326         pdata = "0000  45 00 00 21 00 01 00 00 40 11 7c c9 7f 00 00 01\n" \
327                 "0010  7f 00 00 01 ff 98 00 13 00 0d b5 48 66 69 72 73\n" \
328                 "0020  74"
329         check_rawip(pdata, 1, 33)
330
331
332 @fixtures.fixture
333 def run_text2pcap_capinfos_tshark(cmd_text2pcap, cmd_tshark, request):
334     def run_text2pcap_capinfos_tshark_real(content, args):
335         test = request.instance
336         testin_file = test.filename_from_id(testin_txt)
337         testout_file = test.filename_from_id(testout_pcap)
338
339         with open(testin_file, "w") as f:
340             f.write(content)
341         test.assertRun((cmd_text2pcap,) + args + (testin_file, testout_file))
342
343         capinfo = get_capinfos_cmp_info(check_capinfos_info(test, testout_file))
344
345         test.assertRun((cmd_tshark, '-q', '-z', 'expert,warn',
346             '-o', 'udp.check_checksum: TRUE',
347             '-o', 'tcp.check_checksum: TRUE',
348             '-o', 'sctp.checksum:TRUE',
349             '-r', testout_file))
350         capinfo['expert'] = test.processes[-1].stdout_str
351         return capinfo
352     return run_text2pcap_capinfos_tshark_real
353
354
355 @fixtures.mark_usefixtures('base_env')
356 @fixtures.uses_fixtures
357 class case_text2pcap_headers(subprocesstest.SubprocessTestCase):
358     '''Test TCP, UDP or SCTP header without -4 or -6 option'''
359     maxDiff = None
360
361     def test_text2pcap_tcp(self, run_text2pcap_capinfos_tshark):
362         '''Test TCP over IPv4'''
363         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
364             'datasize': 60, 'expert': ''},
365             run_text2pcap_capinfos_tshark(
366                 "0000: ff ff ff ff\n", ("-T", "1234,1234")))
367
368     def test_text2pcap_udp(self, run_text2pcap_capinfos_tshark):
369         '''Test UDP over IPv4'''
370         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
371             'datasize': 60, 'expert': ''},
372             run_text2pcap_capinfos_tshark(
373                 "0000: ff ff ff ff\n", ("-u", "1234,1234")))
374
375     def test_text2pcap_sctp(self, run_text2pcap_capinfos_tshark):
376         '''Test SCTP over IPv4'''
377         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
378             'datasize': 70, 'expert': ''},
379             run_text2pcap_capinfos_tshark(
380                 "0000   00 03 00 18 00 00 00 00 00 00 00 00 00 00 00 03\n" +
381                 "0010   01 00 03 03 00 00 00 08\n",
382                 ("-s", "2905,2905,3")))
383
384     def test_text2pcap_sctp_data(self, run_text2pcap_capinfos_tshark):
385         '''Test SCTP DATA over IPv4'''
386         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
387             'datasize': 70, 'expert': ''},
388             run_text2pcap_capinfos_tshark(
389                 "0000: 01 00 03 03 00 00 00 08\n",
390                 ("-S", "2905,2905,3")))
391
392
393 @fixtures.fixture
394 def run_text2pcap_ipv4(run_text2pcap_capinfos_tshark):
395     def run_text2pcap_ipv4_real(content, args):
396         return run_text2pcap_capinfos_tshark(content,
397                 ("-4", "127.0.0.1,127.0.0.1") + args)
398     return run_text2pcap_ipv4_real
399
400
401 @fixtures.mark_usefixtures('base_env')
402 @fixtures.uses_fixtures
403 class case_text2pcap_ipv4(subprocesstest.SubprocessTestCase):
404     '''Test TCP, UDP or SCTP header with -4 option'''
405     maxDiff = None
406
407     def test_text2pcap_ipv4_tcp(self, run_text2pcap_ipv4):
408         '''Test TCP over IPv4'''
409         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
410             'datasize': 60, 'expert': ''},
411             run_text2pcap_ipv4("0000: ff ff ff ff\n", ("-T", "1234,1234")))
412
413     def test_text2pcap_ipv4_udp(self, run_text2pcap_ipv4):
414         '''Test UDP over IPv4'''
415         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
416             'datasize': 60, 'expert': ''},
417             run_text2pcap_ipv4("0000: ff ff ff ff\n", ("-u", "1234,1234")))
418
419     def test_text2pcap_ipv4_sctp(self, run_text2pcap_ipv4):
420         '''Test SCTP over IPv4'''
421         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
422             'datasize': 70, 'expert': ''},
423             run_text2pcap_ipv4(
424                 "0000   00 03 00 18 00 00 00 00 00 00 00 00 00 00 00 03\n" +
425                 "0010   01 00 03 03 00 00 00 08\n",
426                 ("-s", "2905,2905,3")))
427
428     def test_text2pcap_ipv4_sctp_data(self, run_text2pcap_ipv4):
429         '''Test SCTP DATA over IPv4'''
430         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
431             'datasize': 70, 'expert': ''},
432             run_text2pcap_ipv4("0000: 01 00 03 03 00 00 00 08\n",
433                 ("-S", "2905,2905,3")))
434
435
436 @fixtures.fixture
437 def run_text2pcap_ipv6(cmd_tshark, run_text2pcap_capinfos_tshark, request):
438     self = request.instance
439     def run_text2pcap_ipv6_real(content, text2pcap_args, tshark_args = ()):
440         #Run the common text2pcap tests
441         result = run_text2pcap_capinfos_tshark(content,
442                 ("-6", "::1,::1") + text2pcap_args)
443
444         #Decode the output pcap in JSON format
445         self.assertRun((cmd_tshark, '-T', 'json',
446             '-r', self.filename_from_id(testout_pcap)) + tshark_args)
447         data = json.loads(self.processes[-1].stdout_str)
448
449         #Add IPv6 payload length and payload length tree to the result dict
450         ipv6 = data[0]['_source']['layers']['ipv6']
451         result['ipv6'] = {
452                 'plen': ipv6.get('ipv6.plen', None),
453                 'plen_tree': ipv6.get('ipv6.plen_tree', None)}
454         return result
455     return run_text2pcap_ipv6_real
456
457
458 @fixtures.mark_usefixtures('base_env')
459 @fixtures.uses_fixtures
460 class case_text2pcap_ipv6(subprocesstest.SubprocessTestCase):
461     '''Test TCP, UDP or SCTP header with -6 option'''
462     maxDiff = None
463
464     def test_text2pcap_ipv6_tcp(self, run_text2pcap_ipv6):
465         '''Test TCP over IPv6'''
466         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
467             'datasize': 78, 'expert': '',
468             'ipv6': {'plen': '24', 'plen_tree': None}},
469             run_text2pcap_ipv6("0000: ff ff ff ff\n", ("-T", "1234,1234")))
470
471     def test_text2pcap_ipv6_udp(self, run_text2pcap_ipv6):
472         '''Test UDP over IPv6'''
473         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
474             'datasize': 66, 'expert': '',
475             'ipv6': {'plen': '12', 'plen_tree': None}},
476             run_text2pcap_ipv6("0000: ff ff ff ff\n", ("-u", "1234,1234")))
477
478     def test_text2pcap_ipv6_sctp(self, run_text2pcap_ipv6):
479         '''Test SCTP over IPv6'''
480         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
481             'datasize': 90, 'expert': '',
482             'ipv6': {'plen': '36', 'plen_tree': None}},
483             run_text2pcap_ipv6(
484                 "0000   00 03 00 18 00 00 00 00 00 00 00 00 00 00 00 03\n" +
485                 "0010   01 00 03 03 00 00 00 08\n",
486                 ("-s", "2905,2905,3")))
487
488     def test_text2pcap_ipv6_sctp_data(self, run_text2pcap_ipv6):
489         '''Test SCTP DATA over IPv6'''
490         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
491             'datasize': 90, 'expert': '',
492             'ipv6': {'plen': '36', 'plen_tree': None}},
493             run_text2pcap_ipv6("0000: 01 00 03 03 00 00 00 08\n",
494                 ("-S", "2905,2905,3")))
495
496
497 @fixtures.mark_usefixtures('base_env')
498 @fixtures.uses_fixtures
499 class case_text2pcap_i_proto(subprocesstest.SubprocessTestCase):
500     '''Test -i <proto> for IPv4 and IPv6'''
501     maxDiff = None
502
503     def test_text2pcap_i_icmp(self, run_text2pcap_capinfos_tshark):
504         '''Test -i <proto> without -4 or -6'''
505         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
506             'datasize': 98, 'expert': ''},
507             run_text2pcap_capinfos_tshark(
508                 "0000   08 00 bb b3 d7 3b 00 00 51 a7 d6 7d 00 04 51 e4\n" +
509                 "0010   08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17\n" +
510                 "0020   18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27\n" +
511                 "0030   28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37\n",
512                 ("-i", "1")))
513
514     def test_text2pcap_i_icmp_ipv4(self, run_text2pcap_capinfos_tshark):
515         '''Test -i <proto> with IPv4 (-4) header'''
516         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
517             'datasize': 98, 'expert': ''},
518             run_text2pcap_capinfos_tshark(
519                 "0000   08 00 bb b3 d7 3b 00 00 51 a7 d6 7d 00 04 51 e4\n" +
520                 "0010   08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17\n" +
521                 "0020   18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27\n" +
522                 "0030   28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37\n",
523                 ("-i", "1", "-4", "127.0.0.1,127.0.0.1")))
524
525     def test_text2pcap_i_icmpv6_ipv6(self, run_text2pcap_capinfos_tshark):
526         '''Test -i <proto> with IPv6 (-6) header'''
527         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
528             'datasize': 86, 'expert': ''},
529             run_text2pcap_capinfos_tshark(
530                 "0000   87 00 f2 62 00 00 00 00 fe 80 00 00 00 00 00 00\n" +
531                 "0010   00 00 00 00 00 00 00 02 01 01 52 54 00 12 34 56\n",
532                 ("-i", "58", "-6", "::1,::1")))
533
534     def test_text2pcap_i_sctp_ipv6(self, run_text2pcap_capinfos_tshark):
535         '''Test -i <proto> with IPv6 (-6) header'''
536         self.assertEqual({'encapsulation': 'Ethernet', 'packets': 1,
537             'datasize': 90, 'expert': ''},
538             run_text2pcap_capinfos_tshark(
539                 "0000   0b 59 0b 59 00 00 00 00 26 98 58 51 00 03 00 18\n" +
540                 "0010   00 00 00 00 00 00 00 00 00 00 00 03 01 00 03 03\n" +
541                 "0020   00 00 00 08\n",
542                 ("-i", "132", "-6", "::1,::1")))
543
544
545 @fixtures.mark_usefixtures('base_env')
546 @fixtures.uses_fixtures
547 class case_text2pcap_other_options(subprocesstest.SubprocessTestCase):
548     '''Test other command line options'''
549     def test_text2pcap_option_N(self, cmd_text2pcap, cmd_tshark, capture_file):
550         '''Test -N <intf-name> option'''
551         testin_file = self.filename_from_id(testin_txt)
552         testout_file = self.filename_from_id(testout_pcapng)
553
554         with open(testin_file, 'w') as f:
555             f.write("0000 00\n")
556             f.close()
557         self.assertRun((cmd_text2pcap, "-n", "-N", "your-interface-name", testin_file, testout_file))
558         proc = self.assertRun((cmd_tshark, "-r", testout_file, "-Tfields", "-eframe.interface_name", "-c1"))
559         self.assertEqual(proc.stdout_str.rstrip(), "your-interface-name")