def test_dissected_pcaps_returned_values_are_not_empty(self): """ this test that the decoders dont raise any errors :return: """ logging.info( "[dissector unittests] loaded %s .pcap files for dissection tests" % len(self.pcap_for_test)) for p_file in self.pcap_for_test: logging.info('[dissector unittests] dissecting %s' % p_file) c = Capture(p_file) d = c.get_dissection(self.PROTO_CLASS_FILTER) if len(d) == 0: self.fail('got empty dissection for %s layer for .pcap %s' % (self.PROTO_CLASS_FILTER, p_file)) logging.debug('frame dissection: %s' % json.dumps(d, indent=4))
def test_that_it_can_dissect_all_pcaps(self): """ this basicallyt test that the decoders dont raise any errors :return: """ logging.info( "[dissector unittests] loaded %s .pcap files for dissection tests" % len(self.pcap_for_test)) for p_file in self.pcap_for_test: logging.info('[dissector unittests] dissecting %s' % p_file) c = Capture(p_file) d = c.get_dissection() try: logging.debug('frame dissection: %s' % json.dumps(d, indent=4)) except: logging.debug('frame dissection: %s' % d)
def test_dissection_with_wrong_pcap_file(self): with self.assertRaises(ReaderError): dis_wrong_file = Capture(self.NOT_A_PCAP_FILE) dis = dis_wrong_file.get_dissection() with self.assertRaises(ReaderError): dis_empty_file = Capture(self.EMPTY_PCAP_FILE) dis = dis_empty_file.get_dissection()
def dissect_capture(filename, proto_filter=None, output_filename=None, number_of_frames_to_skip=None): """ Dissects (decodes and converts to string representation) network traces (.pcap file). """ assert filename if os.path.isfile(filename) is False and os.path.isfile( os.path.join(TMPDIR, filename)): filename = os.path.join(TMPDIR, filename) logger.info("PCAP file dissection starts. Filename: %s" % filename) proto_matched = None if proto_filter: # In function of the protocol asked proto_matched = get_protocol(proto_filter) if proto_matched is None: raise Exception('Unknown protocol %s' % proto_filter) if number_of_frames_to_skip: filename_pcap_filtered = os.path.join( TMPDIR, 'pcap_without_some_skipped_frames.pcap') remove_first_frames(pcap_filename=filename, new_pcap_filename=filename_pcap_filtered, number_of_frames_to_skip=number_of_frames_to_skip) filename = filename_pcap_filtered cap = Capture(filename) if proto_matched and len(proto_matched) == 1: print(proto_matched) proto = eval(proto_matched[0]['name']) dissection_as_dicts = cap.get_dissection(proto) dissection_as_text = cap.get_dissection_simple_format(proto) frames_summary = cap.frames else: dissection_as_dicts = cap.get_dissection() dissection_as_text = cap.get_dissection_simple_format() frames_summary = cap.frames if frames_summary: logger.info( 'PCAP file dissected (filename: %s). Frames summary:\n%s' % (filename, json.dumps( ([repr(c) for c in frames_summary]), indent=4))) else: logger.info('PCAP file dissected (filename: %s). No frames found.') if output_filename and type(output_filename) is str: # save dissection response _dump_json_to_file(json.dumps(dissection_as_dicts), output_filename) return dissection_as_dicts, dissection_as_text
def test_summary_with_wrong_pcap_file(self): # Create two wrong dissect instances, assert an exeption is raised with self.assertRaises(ReaderError): dis_wrong_file = Capture(self.NOT_A_PCAP_FILE) dis = dis_wrong_file.summary() with self.assertRaises(ReaderError): dis_empty_file = Capture(self.EMPTY_PCAP_FILE) dis = dis_empty_file.summary()
def setUp(self): """ Initialize the frame list from the valid pcap file """ self.frames = Capture(self.PCAP_FILE).frames
class FrameTestCase(unittest.TestCase): """ Test class for the Frame object """ # #################### Tests parameters ######################### # File path TEST_FILE_DIR = 'tests/test_dumps' PCAP_FILE = TEST_FILE_DIR + '/coap/CoAP_plus_random_UDP_messages.pcap' # Create a struct checker object struct_validator = StructureValidator() FRAMES_PROTOCOL = { 1: [UDP, IPv4, NullLoopback], 2: [UDP, IPv4, NullLoopback], 3: [IPv4, NullLoopback], 4: [UDP, IPv4, NullLoopback, CoAP], 5: [UDP, IPv4, NullLoopback, CoAP] } FRAME_VALUES = {'id': int, 'ts': float, 'error': Exception, 'value': Value} # #################### Utility functions ######################### def list_diff(self, list1, list2): return_list = [] for el in list2: if el not in list1: return_list.append(el) return return_list def frames_with_protocol(self, protocol): frames_with_this_protocol = [] for frame_prot in self.FRAMES_PROTOCOL: if protocol in self.FRAMES_PROTOCOL[frame_prot]: frames_with_this_protocol.append(frame_prot) return frames_with_this_protocol # #################### Init and deinit functions ######################### def setUp(self): """ Initialize the frame list from the valid pcap file """ self.frames = Capture(self.PCAP_FILE).frames # #################### Tests functions ######################### # ##### __repr__ def test___repr__(self): # Check the str representation for frame in self.frames: self.assertEqual(type(str(frame)), str) self.assertEqual(type(repr(frame)), str) self.assertGreater(len(str(frame)), 0) self.assertGreater(len(repr(frame)), 0) # ##### summary def test_summary(self): # Check the str representation counter = 1 for frame in self.frames: # Get the summary summary = frame.summary() # Check summary structure self.assertIsNotNone(summary) self.assertEqual(type(summary), tuple) self.assertEqual(len(summary), 2) # Check first element self.assertEqual(type(summary[0]), int) self.assertEqual(summary[0], counter) # Check second element self.assertEqual(type(summary[1]), str) self.assertGreater(len(summary[1]), 0) # Increment counter counter += 1 # ##### dict def test_dict(self): # Check the str representation for frame in self.frames: # Get the dictionnary dictionnary = frame.dict() # Check dictionnary structure self.assertIsNotNone(dictionnary) self.assertEqual(type(dictionnary), OrderedDict) self.assertEqual(len(dictionnary), 5) # Check whole structure from struct checker self.struct_validator.check_frame(dictionnary) # ##### __contains__ def test___contains__(self): # Check the provided structure self.assertEqual(len(self.FRAMES_PROTOCOL), len(self.frames)) # Get all the protocols protocols = Dissector.get_implemented_protocols() # Check that the protocols are in the correct frame i = 1 for frame in self.frames: # Get the elements that shouldn't be in it should_not_be = self.list_diff(self.FRAMES_PROTOCOL[i], protocols) # Check that those which shouldn't be present really aren't for non_present in should_not_be: self.assertNotIn(non_present, frame) # Check that those which are present really are for prot in self.FRAMES_PROTOCOL[i]: self.assertIn(prot, frame) # Increment counter i += 1 def test___contains__none(self): # Check that the protocols are in the correct frame for frame in self.frames: # Expect the exception with self.assertRaises(InputParameterError): check = None in frame def test___contains__not_a_protocol(self): # Check that the protocols are in the correct frame for frame in self.frames: # Expect the exception with self.assertRaises(InputParameterError): check = Frame in frame def test___contains__higher_classes(self): # Check that the protocols are in the correct frame for frame in self.frames: # Expect the exception with self.assertRaises(InputParameterError): check = InetPacketValue in frame # Expect the exception with self.assertRaises(InputParameterError): check = PacketValue in frame # Expect the exception with self.assertRaises(InputParameterError): check = Value in frame # ##### filter_frames def test_filter_frames(self): # Get all the protocols protocols = Dissector.get_implemented_protocols() # Filter on each protocol for protocol in protocols: # Filter on each protocol filtered, ignored = Frame.filter_frames(self.frames, protocol) # Get the id of frames with this protocol ids = self.frames_with_protocol(protocol) # Check the two datas received self.assertEqual(type(filtered), list) for f in filtered: self.assertEqual(type(f), Frame) self.assertEqual(type(ignored), list) for i in ignored: self.assertEqual(type(i), Frame) self.assertEqual(len(filtered) + len(ignored), len(self.frames)) # Check the length of filtered self.assertEqual(len(filtered), len(ids)) # Check that each element goes together for frame in filtered: dictionnary = frame.dict() self.assertIn(dictionnary['id'], ids) def test_filter_frames_none_type(self): # Filter on none protocol with self.assertRaises(InputParameterError): filtered, ignored = Frame.filter_frames(self.frames, type(None)) def test_filter_frames_none(self): # Filter on none protocol with self.assertRaises(InputParameterError): filtered, ignored = Frame.filter_frames(self.frames, None) def test_filter_frames_not_a_protocol(self): # Filter on each protocol with self.assertRaises(InputParameterError): filtered, ignored = Frame.filter_frames(self.frames, Frame) def test_filter_frames_higher_classes(self): # Filter on each protocol with self.assertRaises(InputParameterError): filtered, ignored = Frame.filter_frames(self.frames, InetPacketValue) with self.assertRaises(InputParameterError): filtered, ignored = Frame.filter_frames(self.frames, PacketValue) with self.assertRaises(InputParameterError): filtered, ignored = Frame.filter_frames(self.frames, Value) def test_filter_frames_only_single_frame(self): # Get all the protocols protocols = Dissector.get_implemented_protocols() # Filter on each protocol for protocol in protocols: # Filter on none protocol with self.assertRaises(InputParameterError): filtered, ignored = Frame.filter_frames( self.frames[0], protocol) def test_filter_frames_list_of_non_frame(self): # Get all the protocols protocols = Dissector.get_implemented_protocols() # Filter on each protocol for protocol in protocols: # Filter on none protocol with self.assertRaises(TypeError): filtered, ignored = Frame.filter_frames(protocols, protocol) def test_filter_frames_list_of_frame_with_a_non_frame(self): # Get all the protocols protocols = Dissector.get_implemented_protocols() # Insert a non frame object self.frames.insert(1, protocols[1]) # Filter on each protocol for protocol in protocols: # Filter on none protocol with self.assertRaises(TypeError): filtered, ignored = Frame.filter_frames(self.frames, protocol) # ##### __getitem__ def test___getitem__values(self): # For each value name, check its type for value_name, value_type in self.FRAME_VALUES.items(): if value_name != 'error': for frame in self.frames: self.assertIsInstance(frame[value_name], value_type) else: # 'error' field can be None for frame in self.frames: if frame[value_name]: self.assertIsInstance(frame[value_name], value_type) def test___getitem__unknown_value(self): for frame in self.frames: with self.assertRaises(AttributeError): test = frame['unknown'] def test___getitem__none(self): for frame in self.frames: with self.assertRaises(InputParameterError): test = frame[None] def test___getitem__type_but_not_a_protocol(self): # Check that the protocols are in the correct frame for frame in self.frames: # Expect the exception with self.assertRaises(InputParameterError): test = frame[Frame] def test___getitem__higher_classes(self): # Check that the protocols are in the correct frame for frame in self.frames: # Expect the exception with self.assertRaises(InputParameterError): check = frame[InetPacketValue] # Expect the exception with self.assertRaises(InputParameterError): check = frame[PacketValue] # Expect the exception with self.assertRaises(InputParameterError): check = frame[Value]
def analyse( self, filename: str, tc_id: str ) -> (str, str, list_of(int), str, list_of((str, str)), list_of((type, Exception, is_traceback))): """ Analyse a dump file associated to a test case :param filename: The name of the file to analyse :param tc_id: The unique id of the test case to confront the given file :type filename: str :type tc_id: str :return: A tuple with the information about the analysis results: - The id of the test case - The verdict as a string - The list of the result important frames - A string with logs - A list of all the partial verdicts - A list of tuples representing the exceptions that occurred :rtype: (str, str, [int], str,[(str, str)], [(type, Exception, traceback)]) :raises FileNotFoundError: If the test env of the tc is not found :raises ReaderError: If the capture didn't manage to read and decode :raises ObsoleteTestCase: If the test case if obsolete .. example:: ('TD_COAP_CORE_03', 'fail', [21, 22], [('fail', "some comment"),('fail', "some other comment")] , 'verdict description', '') .. note:: Allows multiple occurrences of executions of the testcase, returns as verdict: - fail: if at least one on the occurrences failed - inconclusive: if all occurrences returned a inconclusive verdict - pass: all occurrences are inconclusive or at least one is PASS and the rest is inconclusive """ # Get the test case class test_case_class = self.import_test_cases([tc_id]) assert len(test_case_class) == 1 test_case_class = test_case_class[0] # Disable name resolution for performance improvements with Data.disable_name_resolution(): # Get the capture from the file capture = Capture(filename) # Initialize the TC with the list of conversations test_case = test_case_class(capture) verdict, rev_frames, log, partial_verdicts, exceps = test_case.run_test_case() # print('##### capture') # print(capture) # print('#####') # # # Here we execute the test case and return the result # # print('##### Verdict given') # print(verdict) # print('#####') # print('##### Review frames') # print(rev_frames) # print('#####') # print('##### Text') # print(log, partial_verdicts) # print('#####') # print('##### Exceptions') # print(exceptions) # print('#####') return tc_id, verdict, rev_frames, log, partial_verdicts, exceps
def __get_capture(self, pcap_file, dir_from_test_dumps="coap_observe"): pcap_dir_path = os.path.dirname(os.path.abspath(__file__)) pcap_dir_path = os.path.join( pcap_dir_path, os.path.join('../test_dumps/', dir_from_test_dumps)) return Capture(os.path.join(pcap_dir_path, pcap_file))
def setUp(self): """ Initialize the Capture instance """ self.capture = Capture(self.PCAP_FILE)
class CaptureAndDissectionsTestCase(unittest.TestCase): """ Test dissections. Unit testing methods """ # #################### Tests parameters ######################### # File path TEST_FILE_DIR = 'tests/test_dumps' # dissect CoAP pcap with other UDP messages: PCAP_FILE = path.join(TEST_FILE_DIR, 'coap', 'CoAP_plus_random_UDP_messages.pcap') # pcaps that MUST throw exceptions WRONG_TEST_FILE_DIR_NAME = 'others' EMPTY_PCAP_FILE = path.join(TEST_FILE_DIR, WRONG_TEST_FILE_DIR_NAME, 'empty_pcap.pcap') NOT_A_PCAP_FILE = path.join(TEST_FILE_DIR, WRONG_TEST_FILE_DIR_NAME, 'not_a_pcap_file.dia') # Create a struct checker object struct_validator = StructureValidator() # #################### Init and deinit functions ######################### def setUp(self): """ Initialize the dissector instance """ self.capture = Capture(self.PCAP_FILE) # #################### Utilities functions ######################### def check_summary(self, summary): self.assertTrue(type(summary), tuple) self.assertEqual(len(summary), 2) self.assertTrue(type(summary[0]), int) self.assertGreater(summary[0], 0) self.assertTrue(type(summary[1]), str) self.assertGreater(len(summary[1]), 0) # #################### Tests functions ######################### # ##### get_dissectable_protocols def test_get_dissectable_protocols(self): # Get implemented protocols and check their values implemented_protocols = get_dissectable_protocols() self.assertEqual(type(implemented_protocols), list) self.assertGreater(len(implemented_protocols), 0) for prot in implemented_protocols: self.assertTrue(issubclass(prot, PacketValue)) # ##### summary def test_summary_without_filtering(self): # Get and check the summary summary = self.capture.summary() self.assertTrue(type(summary), list) self.assertTrue(len(summary), 5) i = 1 for f_sum in summary: self.check_summary(f_sum) self.assertEqual(f_sum[0], i) i += 1 # Try to get another summary with None provided summary_with_none = self.capture.summary(None) self.assertEqual(summary, summary_with_none) def test_summary_with_filtering_on_coap(self): # Get and check the summary summary = self.capture.summary(CoAP) self.assertTrue(type(summary), list) self.assertTrue(len(summary), 2) i = 4 # CoAP frames are n°4 and 5 for f_sum in summary: self.check_summary(f_sum) self.assertEqual(f_sum[0], i) i += 1 def test_summary_with_filtering_on_protocols(self): # For every implemented protocols for prots in get_dissectable_protocols(): # Get and check the summary summary = self.capture.summary(prots) self.assertTrue(type(summary), list) for f_sum in summary: self.check_summary(f_sum) def test_summary_with_filtering_on_none_type(self): # Get and check the summary with self.assertRaises(InputParameterError): summary = self.capture.summary(type(None)) def test_summary_with_filtering_on_not_a_protocol(self): # Get and check the summary with self.assertRaises(InputParameterError): summary = self.capture.summary(Frame) def test_summary_with_wrong_pcap_file(self): # Create two wrong dissect instances, assert an exeption is raised with self.assertRaises(ReaderError): dis_wrong_file = Capture(self.NOT_A_PCAP_FILE) dis = dis_wrong_file.summary() with self.assertRaises(ReaderError): dis_empty_file = Capture(self.EMPTY_PCAP_FILE) dis = dis_empty_file.summary() # ##### dissect def test_dissection_without_filtering(self): # Get and check the dissect dissect = self.capture.get_dissection() self.assertTrue(type(dissect), list) self.assertTrue(len(dissect), 5) i = 1 for frame in dissect: self.struct_validator.check_frame(frame) self.assertEqual(frame['id'], i) i += 1 # Try to get another dissect with None provided dissect_with_none = self.capture.get_dissection(None) self.assertEqual(dissect, dissect_with_none) def test_dissection_with_filtering_on_coap(self): # Get and check the dissect dissect = self.capture.get_dissection(CoAP) self.assertTrue(type(dissect), list) self.assertTrue(len(dissect), 2) i = 4 # CoAP frames are n°4 and 5 for frame in dissect: self.struct_validator.check_frame(frame) self.assertEqual(frame['id'], i) i += 1 def test_dissection_with_filtering_on_protocols(self): # For every implemented protocols for prots in get_dissectable_protocols(): # Get and check the dissect dissect = self.capture.get_dissection(prots) self.assertTrue(type(dissect), list) for frame in dissect: self.struct_validator.check_frame(frame) def test_dissection_with_filtering_on_none_type(self): # Get and check the dissect with self.assertRaises(InputParameterError): dissect = self.capture.get_dissection(type(None)) def test_dissection_with_filtering_on_not_a_protocol(self): # Get and check the dissect with self.assertRaises(InputParameterError): dissect = self.capture.get_dissection(Frame) def test_dissection_with_wrong_pcap_file(self): with self.assertRaises(ReaderError): dis_wrong_file = Capture(self.NOT_A_PCAP_FILE) dis = dis_wrong_file.get_dissection() with self.assertRaises(ReaderError): dis_empty_file = Capture(self.EMPTY_PCAP_FILE) dis = dis_empty_file.get_dissection()
from ttproto.core.dissector import Capture, Dissector # filename = '/Users/fsismondi/TD_COAP_CORE_01.pcap' # # dissect with no modifs # dissector = Dissector(filename) # # # dissect with filter # finterop_tun_profile_filter(filename) # #dissector = Dissector('tmp/temp.pcap') # print(dissector.summary()) # print('#####') # print(dissector.dissect()) filename1 = 'tmp/DLT_RAW_1.pcap' # dissect with no modifs c1 = Capture(filename1) # dissect with filter remove_first_frames( number_of_frames_to_skip=2, pcap_filename=filename1, new_pcap_filename='tmp/temp.pcap', ) c2 = Capture('tmp/temp.pcap') print('#####') pprint(c1.summary()) print('#####') pprint(c2.summary())