2 # -*- coding: utf-8 -*-
4 # By Gerald Combs <gerald@wireshark.org>
6 # Ported from a set of Bash scripts which were copyright 2005 Ulf Lamping
8 # SPDX-License-Identifier: GPL-2.0-or-later
10 '''Command line option tests'''
18 #glossaries = ('fields', 'protocols', 'values', 'decodes', 'defaultprefs', 'currentprefs')
20 glossaries = ('decodes', 'values')
21 testout_pcap = 'testout.pcap'
24 @fixtures.uses_fixtures
25 class case_dumpcap_options(subprocesstest.SubprocessTestCase):
26 # XXX Should we generate individual test functions instead of looping?
27 def test_dumpcap_invalid_chars(self, cmd_dumpcap, base_env):
28 '''Invalid dumpcap parameters'''
29 for char_arg in 'CEFGHJKNOQRTUVWXYejloxz':
30 self.assertRun((cmd_dumpcap, '-' + char_arg), env=base_env,
31 expected_return=self.exit_command_line)
33 # XXX Should we generate individual test functions instead of looping?
34 def test_dumpcap_valid_chars(self, cmd_dumpcap, base_env):
36 self.assertRun((cmd_dumpcap, '-' + char_arg), env=base_env)
38 # XXX Should we generate individual test functions instead of looping?
39 def test_dumpcap_interface_chars(self, cmd_dumpcap, base_env):
40 '''Valid dumpcap parameters requiring capture permissions'''
41 valid_returns = [self.exit_ok, self.exit_error]
43 process = self.runProcess((cmd_dumpcap, '-' + char_arg), env=base_env)
44 self.assertIn(process.returncode, valid_returns)
47 @fixtures.mark_usefixtures('base_env')
48 @fixtures.uses_fixtures
49 class case_dumpcap_capture_clopts(subprocesstest.SubprocessTestCase):
50 def test_dumpcap_invalid_capfilter(self, cmd_dumpcap, capture_interface):
51 '''Invalid capture filter'''
52 invalid_filter = '__invalid_protocol'
53 # $DUMPCAP -f 'jkghg' -w './testout.pcap' > ./testout.txt 2>&1
54 testout_file = self.filename_from_id(testout_pcap)
55 self.runProcess((cmd_dumpcap, '-f', invalid_filter, '-w', testout_file))
56 self.assertTrue(self.grepOutput('Invalid capture filter "' + invalid_filter + '" for interface'))
58 def test_dumpcap_invalid_interface_name(self, cmd_dumpcap, capture_interface):
59 '''Invalid capture interface name'''
60 invalid_interface = '__invalid_interface'
61 # $DUMPCAP -i invalid_interface -w './testout.pcap' > ./testout.txt 2>&1
62 testout_file = self.filename_from_id(testout_pcap)
63 self.runProcess((cmd_dumpcap, '-i', invalid_interface, '-w', testout_file))
64 self.assertTrue(self.grepOutput('The capture session could not be initiated'))
66 def test_dumpcap_invalid_interface_index(self, cmd_dumpcap, capture_interface):
67 '''Invalid capture interface index'''
69 # $DUMPCAP -i 0 -w './testout.pcap' > ./testout.txt 2>&1
70 testout_file = self.filename_from_id(testout_pcap)
71 self.runProcess((cmd_dumpcap, '-i', invalid_index, '-w', testout_file))
72 self.assertTrue(self.grepOutput('There is no interface with that adapter index'))
75 @fixtures.mark_usefixtures('test_env')
76 @fixtures.uses_fixtures
77 class case_basic_clopts(subprocesstest.SubprocessTestCase):
78 def test_existing_file(self, cmd_tshark, capture_file):
79 # $TSHARK -r "${CAPTURE_DIR}dhcp.pcap" > ./testout.txt 2>&1
80 self.assertRun((cmd_tshark, '-r', capture_file('dhcp.pcap')))
82 def test_nonexistent_file(self, cmd_tshark, capture_file):
83 # $TSHARK - r ThisFileDontExist.pcap > ./testout.txt 2 > &1
84 self.assertRun((cmd_tshark, '-r', capture_file('__ceci_nest_pas_une.pcap')),
85 expected_return=self.exit_error)
88 @fixtures.mark_usefixtures('test_env')
89 @fixtures.uses_fixtures
90 class case_tshark_options(subprocesstest.SubprocessTestCase):
91 # XXX Should we generate individual test functions instead of looping?
92 def test_tshark_invalid_chars(self, cmd_tshark):
93 '''Invalid tshark parameters'''
94 for char_arg in 'ABCEFHJKMNORTUWXYZabcdefijkmorstuwyz':
95 self.assertRun((cmd_tshark, '-' + char_arg),
96 expected_return=self.exit_command_line)
98 # XXX Should we generate individual test functions instead of looping?
99 def test_tshark_valid_chars(self, cmd_tshark):
100 for char_arg in 'Ghv':
101 self.assertRun((cmd_tshark, '-' + char_arg))
103 # XXX Should we generate individual test functions instead of looping?
104 def test_tshark_interface_chars(self, cmd_tshark, cmd_dumpcap):
105 '''Valid tshark parameters requiring capture permissions'''
106 # These options require dumpcap
107 valid_returns = [self.exit_ok, self.exit_error]
108 for char_arg in 'DL':
109 process = self.runProcess((cmd_tshark, '-' + char_arg))
110 self.assertIn(process.returncode, valid_returns)
113 @fixtures.mark_usefixtures('test_env')
114 @fixtures.uses_fixtures
115 class case_tshark_capture_clopts(subprocesstest.SubprocessTestCase):
116 def test_tshark_invalid_capfilter(self, cmd_tshark, capture_interface):
117 '''Invalid capture filter'''
118 invalid_filter = '__invalid_protocol'
119 # $TSHARK -f 'jkghg' -w './testout.pcap' > ./testout.txt 2>&1
120 testout_file = self.filename_from_id(testout_pcap)
121 self.runProcess((cmd_tshark, '-f', invalid_filter, '-w', testout_file ))
122 self.assertTrue(self.grepOutput('Invalid capture filter "' + invalid_filter + '" for interface'))
124 def test_tshark_invalid_interface_name(self, cmd_tshark, capture_interface):
125 '''Invalid capture interface name'''
126 invalid_interface = '__invalid_interface'
127 # $TSHARK -i invalid_interface -w './testout.pcap' > ./testout.txt 2>&1
128 testout_file = self.filename_from_id(testout_pcap)
129 self.runProcess((cmd_tshark, '-i', invalid_interface, '-w', testout_file))
130 self.assertTrue(self.grepOutput('The capture session could not be initiated'))
132 def test_tshark_invalid_interface_index(self, cmd_tshark, capture_interface):
133 '''Invalid capture interface index'''
135 # $TSHARK -i 0 -w './testout.pcap' > ./testout.txt 2>&1
136 testout_file = self.filename_from_id(testout_pcap)
137 self.runProcess((cmd_tshark, '-i', invalid_index, '-w', testout_file))
138 self.assertTrue(self.grepOutput('There is no interface with that adapter index'))
141 @fixtures.mark_usefixtures('test_env')
142 @fixtures.uses_fixtures
143 class case_tshark_name_resolution_clopts(subprocesstest.SubprocessTestCase):
144 def test_tshark_valid_name_resolution(self, cmd_tshark, capture_interface):
145 # $TSHARK -N mnNtdv -a duration:1 > ./testout.txt 2>&1
146 self.assertRun((cmd_tshark, '-N', 'mnNtdv', '-a', 'duration: 1'))
148 # XXX Add invalid name resolution.
150 @fixtures.mark_usefixtures('test_env')
151 @fixtures.uses_fixtures
152 class case_tshark_unicode_clopts(subprocesstest.SubprocessTestCase):
153 def test_tshark_unicode_display_filter(self, cmd_tshark, capture_file):
154 '''Unicode (UTF-8) display filter'''
155 self.runProcess((cmd_tshark, '-r', capture_file('http.pcap'), '-Y', 'tcp.flags.str == "·······AP···"'))
156 self.assertTrue(self.grepOutput('HEAD.*/v4/iuident.cab'))
159 @fixtures.uses_fixtures
160 class case_tshark_dump_glossaries(subprocesstest.SubprocessTestCase):
161 def test_tshark_dump_glossary(self, cmd_tshark, base_env):
162 for glossary in glossaries:
164 self.log_fd.truncate()
167 self.assertRun((cmd_tshark, '-G', glossary), env=base_env)
168 self.assertEqual(self.countOutput(count_stdout=False, count_stderr=True), 0, 'Found error output while printing glossary ' + glossary)
170 def test_tshark_glossary_valid_utf8(self, cmd_tshark, base_env):
171 for glossary in glossaries:
173 env['LANG'] = 'en_US.UTF-8'
174 g_contents = subprocess.check_output((cmd_tshark, '-G', glossary), env=env, stderr=subprocess.PIPE)
177 g_contents.decode('UTF-8')
178 except UnicodeDecodeError:
180 self.assertTrue(decoded, '{} is not valid UTF-8'.format(glossary))
182 def test_tshark_glossary_plugin_count(self, cmd_tshark, base_env):
183 self.runProcess((cmd_tshark, '-G', 'plugins'), env=base_env)
184 self.assertGreaterEqual(self.countOutput('dissector'), 10, 'Fewer than 10 dissector plugins found')
186 def test_tshark_elastic_mapping(self, cmd_tshark, dirs, base_env):
187 def get_ip_props(obj):
188 return obj['mappings']['pcap_file']['properties']['layers']['properties']['ip']['properties']
189 baseline_file = os.path.join(dirs.baseline_dir, 'elastic-mapping-ip-subset.json')
190 with open(baseline_file) as f:
191 expected_obj = json.load(f)
192 keys_to_check = get_ip_props(expected_obj).keys()
193 proc = self.assertRun((cmd_tshark, '-G', 'elastic-mapping', '--elastic-mapping-filter', 'ip'))
194 actual_obj = json.loads(proc.stdout_str)
195 ip_props = get_ip_props(actual_obj)
196 for key in list(ip_props.keys()):
197 if key not in keys_to_check:
199 self.assertEqual(actual_obj, expected_obj)
202 @fixtures.mark_usefixtures('test_env')
203 @fixtures.uses_fixtures
204 class case_tshark_z_expert(subprocesstest.SubprocessTestCase):
205 def test_tshark_z_expert_all(self, cmd_tshark, capture_file):
206 self.assertRun((cmd_tshark, '-q', '-z', 'expert',
207 '-r', capture_file('http-ooo.pcap')))
208 self.assertTrue(self.grepOutput('Errors'))
209 self.assertTrue(self.grepOutput('Warns'))
210 self.assertTrue(self.grepOutput('Chats'))
212 def test_tshark_z_expert_error(self, cmd_tshark, capture_file):
213 self.assertRun((cmd_tshark, '-q', '-z', 'expert,error',
214 '-r', capture_file('http-ooo.pcap')))
215 self.assertTrue(self.grepOutput('Errors'))
216 self.assertFalse(self.grepOutput('Warns'))
217 self.assertFalse(self.grepOutput('Chats'))
219 def test_tshark_z_expert_warn(self, cmd_tshark, capture_file):
220 self.assertRun((cmd_tshark, '-q', '-z', 'expert,warn',
221 '-r', capture_file('http-ooo.pcap')))
222 self.assertTrue(self.grepOutput('Errors'))
223 self.assertTrue(self.grepOutput('Warns'))
224 self.assertFalse(self.grepOutput('Chats'))
226 def test_tshark_z_expert_note(self, cmd_tshark, capture_file):
227 self.assertRun((cmd_tshark, '-q', '-z', 'expert,note',
228 '-r', capture_file('http2-data-reassembly.pcap')))
229 self.assertTrue(self.grepOutput('Warns'))
230 self.assertTrue(self.grepOutput('Notes'))
231 self.assertFalse(self.grepOutput('Chats'))
233 def test_tshark_z_expert_chat(self, cmd_tshark, capture_file):
234 self.assertRun((cmd_tshark, '-q', '-z', 'expert,chat',
235 '-r', capture_file('http-ooo.pcap')))
236 self.assertTrue(self.grepOutput('Errors'))
237 self.assertTrue(self.grepOutput('Warns'))
238 self.assertTrue(self.grepOutput('Chats'))
240 def test_tshark_z_expert_comment(self, cmd_tshark, capture_file):
241 self.assertRun((cmd_tshark, '-q', '-z', 'expert,comment',
242 '-r', capture_file('sip.pcapng')))
243 self.assertTrue(self.grepOutput('Notes'))
244 self.assertTrue(self.grepOutput('Comments'))
246 def test_tshark_z_expert_invalid_filter(self, cmd_tshark, capture_file):
247 invalid_filter = '__invalid_protocol'
248 self.assertRun((cmd_tshark, '-q', '-z', 'expert,' + invalid_filter,
249 '-r', capture_file('http-ooo.pcap')),
250 expected_return=self.exit_command_line)
251 self.assertTrue(self.grepOutput('Filter "' + invalid_filter + '" is invalid'))
253 def test_tshark_z_expert_error_invalid_filter(self, cmd_tshark, capture_file):
254 invalid_filter = '__invalid_protocol'
255 self.assertRun((cmd_tshark, '-q', '-z', 'expert,error,' + invalid_filter,
256 '-r', capture_file('http-ooo.pcap')),
257 expected_return=self.exit_command_line)
258 self.assertTrue(self.grepOutput('Filter "' + invalid_filter + '" is invalid'))
260 def test_tshark_z_expert_filter(self, cmd_tshark, capture_file):
261 self.assertRun((cmd_tshark, '-q', '-z', 'expert,udp', # udp is a filter
262 '-r', capture_file('http-ooo.pcap')))
263 self.assertFalse(self.grepOutput('Errors'))
264 self.assertFalse(self.grepOutput('Warns'))
265 self.assertFalse(self.grepOutput('Chats'))
267 def test_tshark_z_expert_error_filter(self, cmd_tshark, capture_file):
268 self.assertRun((cmd_tshark, '-q', '-z', 'expert,error,udp', # udp is a filter
269 '-r', capture_file('http-ooo.pcap')))
270 self.assertFalse(self.grepOutput('Errors'))
271 self.assertFalse(self.grepOutput('Warns'))
272 self.assertFalse(self.grepOutput('Chats'))