2018-04-03 00:12:23 +00:00
|
|
|
#
|
2018-04-27 17:35:17 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
2018-04-03 00:12:23 +00:00
|
|
|
# Wireshark tests
|
|
|
|
# By Gerald Combs <gerald@wireshark.org>
|
|
|
|
#
|
|
|
|
# Ported from a set of Bash scripts which were copyright 2005 Ulf Lamping
|
|
|
|
#
|
|
|
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#
|
|
|
|
'''Command line option tests'''
|
|
|
|
|
|
|
|
import config
|
|
|
|
import os.path
|
|
|
|
import subprocess
|
|
|
|
import subprocesstest
|
|
|
|
import unittest
|
|
|
|
|
|
|
|
#glossaries = ('fields', 'protocols', 'values', 'decodes', 'defaultprefs', 'currentprefs')
|
|
|
|
|
|
|
|
glossaries = ('decodes', 'values')
|
2018-04-27 17:35:17 +00:00
|
|
|
testout_pcap = 'testout.pcap'
|
2018-04-03 00:12:23 +00:00
|
|
|
|
|
|
|
class case_dumpcap_invalid_chars(subprocesstest.SubprocessTestCase):
|
|
|
|
# XXX Should we generate individual test functions instead of looping?
|
|
|
|
def test_dumpcap_invalid_chars(self):
|
|
|
|
'''Invalid dumpcap parameters'''
|
|
|
|
for char_arg in 'CEFGHJKNOQRTUVWXYejloxz':
|
|
|
|
self.assertRun((config.cmd_dumpcap, '-' + char_arg),
|
|
|
|
expected_return=self.exit_command_line)
|
|
|
|
|
|
|
|
|
|
|
|
class case_dumpcap_valid_chars(subprocesstest.SubprocessTestCase):
|
|
|
|
# XXX Should we generate individual test functions instead of looping?
|
|
|
|
def test_dumpcap_valid_chars(self):
|
|
|
|
for char_arg in 'hv':
|
|
|
|
self.assertRun((config.cmd_dumpcap, '-' + char_arg))
|
|
|
|
|
|
|
|
|
|
|
|
class case_dumpcap_invalid_interface_chars(subprocesstest.SubprocessTestCase):
|
|
|
|
# XXX Should we generate individual test functions instead of looping?
|
|
|
|
def test_dumpcap_interface_chars(self):
|
|
|
|
'''Valid dumpcap parameters requiring capture permissions'''
|
|
|
|
valid_returns = [self.exit_ok, self.exit_error]
|
|
|
|
for char_arg in 'DL':
|
|
|
|
process = self.runProcess((config.cmd_dumpcap, '-' + char_arg))
|
|
|
|
self.assertIn(process.returncode, valid_returns)
|
|
|
|
|
|
|
|
|
|
|
|
class case_dumpcap_capture_clopts(subprocesstest.SubprocessTestCase):
|
|
|
|
def test_dumpcap_invalid_capfilter(self):
|
|
|
|
'''Invalid capture filter'''
|
2018-04-27 16:35:37 +00:00
|
|
|
if not config.canCapture():
|
|
|
|
self.skipTest('Test requires capture privileges and an interface.')
|
2018-04-03 00:12:23 +00:00
|
|
|
invalid_filter = '__invalid_protocol'
|
|
|
|
# $DUMPCAP -f 'jkghg' -w './testout.pcap' > ./testout.txt 2>&1
|
2018-04-27 17:35:17 +00:00
|
|
|
testout_file = self.filename_from_id(testout_pcap)
|
|
|
|
self.runProcess((config.cmd_dumpcap, '-f', invalid_filter, '-w', testout_file ))
|
2018-04-03 00:12:23 +00:00
|
|
|
self.assertTrue(self.grepOutput('Invalid capture filter "' + invalid_filter + '" for interface'))
|
|
|
|
|
|
|
|
def test_dumpcap_invalid_interface_name(self):
|
|
|
|
'''Invalid capture interface name'''
|
2018-04-27 16:35:37 +00:00
|
|
|
if not config.canCapture():
|
|
|
|
self.skipTest('Test requires capture privileges and an interface.')
|
2018-04-03 00:12:23 +00:00
|
|
|
invalid_interface = '__invalid_interface'
|
|
|
|
# $DUMPCAP -i invalid_interface -w './testout.pcap' > ./testout.txt 2>&1
|
2018-04-27 17:35:17 +00:00
|
|
|
testout_file = self.filename_from_id(testout_pcap)
|
|
|
|
self.runProcess((config.cmd_dumpcap, '-i', invalid_interface, '-w', testout_file))
|
2018-04-03 00:12:23 +00:00
|
|
|
self.assertTrue(self.grepOutput('The capture session could not be initiated'))
|
|
|
|
|
|
|
|
def test_dumpcap_invalid_interface_index(self):
|
|
|
|
'''Invalid capture interface index'''
|
2018-04-27 16:35:37 +00:00
|
|
|
if not config.canCapture():
|
|
|
|
self.skipTest('Test requires capture privileges and an interface.')
|
2018-04-03 00:12:23 +00:00
|
|
|
invalid_index = '0'
|
|
|
|
# $DUMPCAP -i 0 -w './testout.pcap' > ./testout.txt 2>&1
|
2018-04-27 17:35:17 +00:00
|
|
|
testout_file = self.filename_from_id(testout_pcap)
|
|
|
|
self.runProcess((config.cmd_dumpcap, '-i', invalid_index, '-w', testout_file))
|
2018-04-03 00:12:23 +00:00
|
|
|
self.assertTrue(self.grepOutput('There is no interface with that adapter index'))
|
|
|
|
|
|
|
|
|
|
|
|
class case_basic_clopts(subprocesstest.SubprocessTestCase):
|
|
|
|
def test_existing_file(self):
|
|
|
|
# $TSHARK -r "${CAPTURE_DIR}dhcp.pcap" > ./testout.txt 2>&1
|
|
|
|
cap_file = os.path.join(config.capture_dir, 'dhcp.pcap')
|
|
|
|
self.assertRun((config.cmd_tshark, '-r', cap_file))
|
|
|
|
|
|
|
|
def test_nonexistent_file(self):
|
|
|
|
# $TSHARK - r ThisFileDontExist.pcap > ./testout.txt 2 > &1
|
|
|
|
cap_file = os.path.join(config.capture_dir, '__ceci_nest_pas_une.pcap')
|
|
|
|
self.assertRun((config.cmd_tshark, '-r', cap_file),
|
|
|
|
expected_return=self.exit_error)
|
|
|
|
|
|
|
|
|
|
|
|
class case_tshark_invalid_chars(subprocesstest.SubprocessTestCase):
|
|
|
|
# XXX Should we generate individual test functions instead of looping?
|
|
|
|
def test_tshark_invalid_chars(self):
|
|
|
|
'''Invalid tshark parameters'''
|
|
|
|
for char_arg in 'ABCEFHJKMNORTUWXYZabcdefijkmorstuwyz':
|
|
|
|
self.assertRun((config.cmd_tshark, '-' + char_arg),
|
|
|
|
expected_return=self.exit_command_line)
|
|
|
|
|
|
|
|
|
|
|
|
class case_tshark_valid_chars(subprocesstest.SubprocessTestCase):
|
|
|
|
# XXX Should we generate individual test functions instead of looping?
|
|
|
|
def test_tshark_valid_chars(self):
|
|
|
|
for char_arg in 'Ghv':
|
|
|
|
self.assertRun((config.cmd_tshark, '-' + char_arg))
|
|
|
|
|
|
|
|
|
|
|
|
class case_tshark_invalid_interface_chars(subprocesstest.SubprocessTestCase):
|
|
|
|
# XXX Should we generate individual test functions instead of looping?
|
|
|
|
def test_tshark_interface_chars(self):
|
|
|
|
'''Valid tshark parameters requiring capture permissions'''
|
|
|
|
valid_returns = [self.exit_ok, self.exit_error]
|
|
|
|
for char_arg in 'DL':
|
|
|
|
process = self.runProcess((config.cmd_tshark, '-' + char_arg))
|
|
|
|
self.assertIn(process.returncode, valid_returns)
|
|
|
|
|
|
|
|
|
|
|
|
class case_tshark_capture_clopts(subprocesstest.SubprocessTestCase):
|
|
|
|
def test_tshark_invalid_capfilter(self):
|
|
|
|
'''Invalid capture filter'''
|
2018-04-27 16:35:37 +00:00
|
|
|
if not config.canCapture():
|
|
|
|
self.skipTest('Test requires capture privileges and an interface.')
|
2018-04-03 00:12:23 +00:00
|
|
|
invalid_filter = '__invalid_protocol'
|
|
|
|
# $TSHARK -f 'jkghg' -w './testout.pcap' > ./testout.txt 2>&1
|
2018-04-27 17:35:17 +00:00
|
|
|
testout_file = self.filename_from_id(testout_pcap)
|
|
|
|
self.runProcess((config.cmd_tshark, '-f', invalid_filter, '-w', testout_file ))
|
2018-04-03 00:12:23 +00:00
|
|
|
self.assertTrue(self.grepOutput('Invalid capture filter "' + invalid_filter + '" for interface'))
|
|
|
|
|
|
|
|
def test_tshark_invalid_interface_name(self):
|
|
|
|
'''Invalid capture interface name'''
|
2018-04-27 16:35:37 +00:00
|
|
|
if not config.canCapture():
|
|
|
|
self.skipTest('Test requires capture privileges and an interface.')
|
2018-04-03 00:12:23 +00:00
|
|
|
invalid_interface = '__invalid_interface'
|
|
|
|
# $TSHARK -i invalid_interface -w './testout.pcap' > ./testout.txt 2>&1
|
2018-04-27 17:35:17 +00:00
|
|
|
testout_file = self.filename_from_id(testout_pcap)
|
|
|
|
self.runProcess((config.cmd_tshark, '-i', invalid_interface, '-w', testout_file))
|
2018-04-03 00:12:23 +00:00
|
|
|
self.assertTrue(self.grepOutput('The capture session could not be initiated'))
|
|
|
|
|
|
|
|
def test_tshark_invalid_interface_index(self):
|
|
|
|
'''Invalid capture interface index'''
|
2018-04-27 16:35:37 +00:00
|
|
|
if not config.canCapture():
|
|
|
|
self.skipTest('Test requires capture privileges and an interface.')
|
2018-04-03 00:12:23 +00:00
|
|
|
invalid_index = '0'
|
|
|
|
# $TSHARK -i 0 -w './testout.pcap' > ./testout.txt 2>&1
|
2018-04-27 17:35:17 +00:00
|
|
|
testout_file = self.filename_from_id(testout_pcap)
|
|
|
|
self.runProcess((config.cmd_tshark, '-i', invalid_index, '-w', testout_file))
|
2018-04-03 00:12:23 +00:00
|
|
|
self.assertTrue(self.grepOutput('There is no interface with that adapter index'))
|
|
|
|
|
|
|
|
|
|
|
|
class case_tshark_name_resolution_clopts(subprocesstest.SubprocessTestCase):
|
|
|
|
def test_tshark_valid_name_resolution(self):
|
2018-04-27 16:35:37 +00:00
|
|
|
if not config.canCapture():
|
|
|
|
self.skipTest('Test requires capture privileges and an interface.')
|
2018-10-05 06:54:55 +00:00
|
|
|
# $TSHARK -N mnNtdv -a duration:1 > ./testout.txt 2>&1
|
|
|
|
self.assertRun((config.cmd_tshark, '-N', 'mnNtdv', '-a', 'duration: 1'))
|
2018-04-03 00:12:23 +00:00
|
|
|
|
|
|
|
# XXX Add invalid name resolution.
|
|
|
|
|
2018-05-30 20:32:20 +00:00
|
|
|
class case_tshark_unicode_clopts(subprocesstest.SubprocessTestCase):
|
|
|
|
def test_tshark_unicode_display_filter(self):
|
|
|
|
'''Unicode (UTF-8) display filter'''
|
|
|
|
cap_file = os.path.join(config.capture_dir, 'http.pcap')
|
|
|
|
self.runProcess((config.cmd_tshark, '-r', cap_file, '-Y', 'tcp.flags.str == "·······AP···"'))
|
|
|
|
self.assertTrue(self.grepOutput('HEAD.*/v4/iuident.cab'))
|
|
|
|
|
|
|
|
|
2018-04-03 00:12:23 +00:00
|
|
|
class case_tshark_dump_glossaries(subprocesstest.SubprocessTestCase):
|
|
|
|
def test_tshark_dump_glossary(self):
|
|
|
|
for glossary in glossaries:
|
|
|
|
try:
|
|
|
|
self.log_fd.truncate()
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
self.assertRun((config.cmd_tshark, '-G', glossary))
|
2018-05-03 19:05:12 +00:00
|
|
|
self.assertEqual(self.countOutput(count_stdout=False, count_stderr=True), 0, 'Found error output while printing glossary ' + glossary)
|
2018-04-03 00:12:23 +00:00
|
|
|
|
|
|
|
def test_tshark_glossary_valid_utf8(self):
|
|
|
|
for glossary in glossaries:
|
2018-10-12 16:12:01 +00:00
|
|
|
env = config.baseEnv()
|
2018-04-03 00:12:23 +00:00
|
|
|
env['LANG'] = 'en_US.UTF-8'
|
|
|
|
g_contents = subprocess.check_output((config.cmd_tshark, '-G', glossary), env=env, stderr=subprocess.PIPE)
|
|
|
|
decoded = True
|
|
|
|
try:
|
|
|
|
g_contents.decode('UTF-8')
|
|
|
|
except UnicodeDecodeError:
|
|
|
|
decoded = False
|
|
|
|
self.assertTrue(decoded, '{} is not valid UTF-8'.format(glossary))
|
|
|
|
|
|
|
|
def test_tshark_glossary_plugin_count(self):
|
2018-10-12 16:12:01 +00:00
|
|
|
self.runProcess((config.cmd_tshark, '-G', 'plugins'), env=config.baseEnv())
|
2018-04-03 00:12:23 +00:00
|
|
|
self.assertGreaterEqual(self.countOutput('dissector'), 10, 'Fewer than 10 dissector plugins found')
|
|
|
|
|
|
|
|
|
|
|
|
# Purposefully fail a test. Used for testing the test framework.
|
|
|
|
# class case_fail_on_purpose(subprocesstest.SubprocessTestCase):
|
|
|
|
# def test_fail_on_purpose(self):
|
|
|
|
# self.runProcess(('echo', 'hello, world'))
|
|
|
|
# self.fail('Not implemented')
|