From e4eb1ffd9068811764319d14aed1f3c2458f7e9e Mon Sep 17 00:00:00 2001 From: Italo Valcy Date: Mon, 28 Oct 2024 15:09:52 -0300 Subject: [PATCH] fixing issues related to openflow 1.3 --- apps/influx_client.py | 41 +++---- apps/ofp_stats.py | 6 +- docs/filters.json | 13 +-- docs/requirements.txt | 9 +- libs/openflow/of13/prints.py | 221 +++++++++++++++++++++-------------- libs/tcpiplib/prints.py | 4 +- ofp_sniffer.py | 4 +- 7 files changed, 166 insertions(+), 132 deletions(-) diff --git a/apps/influx_client.py b/apps/influx_client.py index 73c582d..ae19c08 100644 --- a/apps/influx_client.py +++ b/apps/influx_client.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +import os import datetime import logging import requests @@ -13,9 +14,9 @@ class InfluxClient(object): """Class responsible for connecting to InfluxDB and send data""" def __init__(self, - host='localhost', - port=8086, - db='root', + host=os.environ.get("OFP_SNIFFER_INFLUX_HOST", "localhost"), + port=int(os.environ.get("OFP_SNIFFER_INFLUX_PORT", 8086)), + db=os.environ.get("OFP_SNIFFER_INFLUX_DB", "root"), trigger_event=''): """Connect to influxdb @@ -89,23 +90,24 @@ def _update_tcp_reconnects(self): def _update_per_dpid(self): """ This method updates stats per dpid on InfluxDB - TODO: currently, OFStats().per_dev_packet_type is empty """ - dpids = OFStats().per_dev_packet_types.keys() - self.logger.debug("dpids: {0}".format(dpids)) - for dpid in dpids: - json_body = [{ - "measurement": - "OFP_messages", - "tags": { - "dpid": dpid - }, - "time": - "{0}".format(datetime.datetime.utcnow().isoformat('T')), - "fields": - OFStats().per_dev_packet_types[dpid] - }] + for dpid, ver_stats in OFStats().per_dev_packet_types.items(): + json_body = [] + for v, fields in ver_stats.items(): + if not isinstance(fields, dict): + continue + json_body.append({ + "measurement": + "OFP_messages", + "tags": { + "dpid": dpid, + "OFP_version": v + }, + "time": + "{0}".format(datetime.datetime.utcnow().isoformat('T')), + "fields": fields + }) self.logger.debug(json_body) self.db_client.write_points(json_body) @@ -119,8 +121,7 @@ def _update_db(self): self.trigger_event.clear() try: self._update_packet_types() - # TODO: increment per dpid too - # self._update_per_dpid() + self._update_per_dpid() self._update_tcp_reconnects() except requests.exceptions.ConnectionError: self.logger.error("couldn't write data to influxdb.") diff --git a/apps/ofp_stats.py b/apps/ofp_stats.py index c9316c3..9edb875 100644 --- a/apps/ofp_stats.py +++ b/apps/ofp_stats.py @@ -184,8 +184,7 @@ def process_per_dev_packet_types(self, pkt, ofp): self.per_dev_packet_types[dpid] = self.init_type_packets(version) self.per_dev_packet_types[dpid]['total'] = 0 - message_type = str(ofp.header.message_type) - message_type = message_type.split('.')[1] + message_type = ofp.header.message_type.name try: self.per_dev_packet_types[dpid][version][message_type] += 1 except KeyError: @@ -206,8 +205,7 @@ def process_packet(self, pkt): for of_msg in pkt.ofmsgs: # Supporting /ofp_stats/packet_totals version = str(of_msg.ofp.header.version.value) - message_type = str(of_msg.ofp.header.message_type) - message_type = message_type.split('.')[1] + message_type = of_msg.ofp.header.message_type.name try: self.packet_types[version][message_type] += 1 except KeyError: diff --git a/docs/filters.json b/docs/filters.json index 07357cd..6c034d0 100644 --- a/docs/filters.json +++ b/docs/filters.json @@ -1,25 +1,16 @@ { "allowed_of_versions": { - "1.0": { - "rejected_of_types": [ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 26, 27, 28, 29 - ] - }, "1.3": { "rejected_of_types": [ - - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 ] } }, "filters":{ "ethertypes": { - "lldp" : 0, + "lldp" : 1, "fvd" : 0, "arp" : 0, - "others": [ "88b5" ] + "others": [ ] }, "packetIn_filter": { "switch_dpid": "any", diff --git a/docs/requirements.txt b/docs/requirements.txt index d5b93b8..6f8c572 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,9 +1,10 @@ termcolor hexdump netaddr -pcapy -python-openflow -flask +pcapy-ng +python-openflow@https://github.com/kytos-ng/python-openflow/archive/2023.2.0.zip +flask==2.3.3 +Werkzeug==2.3.8 influxdb pyaml -requests \ No newline at end of file +requests diff --git a/libs/openflow/of13/prints.py b/libs/openflow/of13/prints.py index 107f8c2..5fcecdd 100644 --- a/libs/openflow/of13/prints.py +++ b/libs/openflow/of13/prints.py @@ -1,6 +1,7 @@ """ OpenFlow 1.3 prints """ +import traceback from struct import unpack from hexdump import hexdump from pyof.foundation.basic_types import BinaryData @@ -54,7 +55,8 @@ def prints_ofp(msg): return msg_types[msg.header.message_type.value](msg) except Exception as err: - print("Error: %s" % err) + err_msg = traceback.format_exc().replace("\n", ", ") + print("Error: %s -- %s" % (err, err_msg)) def print_pad(pad): @@ -438,7 +440,10 @@ def print_match_oxm(oxm): # NW_SRC or NW_DST elif oxm.oxm_field in [11, 12, 22, 23]: - oxm.oxm_value = libs.tcpiplib.prints.get_ip_from_long(oxm.oxm_value) + try: + oxm.oxm_value = libs.tcpiplib.prints.get_ip_from_long(oxm.oxm_value) + except: + pass # IPv6 Extensions elif oxm.oxm_field in [39]: extensions = of13.parser.parse_ipv6_extension_header(oxm.oxm_value) @@ -620,7 +625,7 @@ def print_ofpt_multipart_request(msg): msg: OpenFlow message unpacked by python-openflow """ multipart_type = "%s" % msg.multipart_type - print('Multipart_Req: Type: %s' % multipart_type.split('.')[1]) + print('Multipart_Req: Type: %s' % multipart_type) def print_ofpt_multipart_request_description(msg): """ @@ -637,7 +642,7 @@ def print_ofpt_multipart_request_flow_aggregate(msg): Args: msg: OpenFlow message unpacked by python-openflow """ - out_port = dissector.get_phy_port_no(msg.out_port.value) + out_port = dissector.get_phy_port_no(msg.body.out_port.value) flags = green(dissector.get_multipart_request_flags(msg.flags.value)) if msg.multipart_type.value == 1: @@ -647,10 +652,10 @@ def print_ofpt_multipart_request_flow_aggregate(msg): print('Flags: % s Pad: % s Table_id: % s Pad: % s Out_Port: % s Out_group: % s Pad: %s Cookie: %s ' 'Cookie_Mask: %s' % - (flags, msg.pad, msg.table_id.value, msg.pad, out_port, - msg.out_group, msg.pad, msg.cookie, msg.cookie_mask)) + (flags, msg.pad, msg.body.table_id.value, msg.body.pad, out_port, + msg.body.out_group, msg.body.pad2, msg.body.cookie, msg.body.cookie_mask)) - print_match_type(msg.match) + print_match_type(msg.body.match) def print_ofpt_multipart_request_table(msg): """ @@ -667,10 +672,10 @@ def print_ofpt_multipart_request_port(msg): Args: msg: OpenFlow message unpacked by python-openflow """ - port_number = dissector.get_phy_port_no(msg.port_no.value) + port_number = dissector.get_phy_port_no(msg.body.port_no.value) flags = green(dissector.get_multipart_request_flags(msg.flags.value)) print(' Port(4): Flags: %s Pad: %s Port_Number: %s Pad: %s' % - (flags, msg.pad, green(port_number), msg.pad)) + (flags, msg.pad, green(port_number), msg.body.pad)) def print_print_ofpt_multipart_request_queue(msg): """ @@ -678,10 +683,10 @@ def print_print_ofpt_multipart_request_queue(msg): Args: msg: OpenFlow message unpacked by python-openflow """ - port_number = dissector.get_phy_port_no(msg.port_no.value) + port_number = dissector.get_phy_port_no(msg.body.port_no.value) flags = green(dissector.get_multipart_request_flags(msg.flags.value)) print(' Queue(5): Flags: %s Pad: %s Port_Number: %s Queue_id: %s' % - (flags, msg.pad, green(port_number), msg.queue_id)) + (flags, msg.pad, green(port_number), msg.body.queue_id)) def print_ofpt_multipart_request_group(msg): """ @@ -690,7 +695,7 @@ def print_ofpt_multipart_request_group(msg): """ flags = green(dissector.get_multipart_request_flags(msg.flags.value)) print(' Group(6): Flags: %s Pad: %s Group_ID: %s Pad: %s' % - (flags, msg.pad, msg.group_id, msg.pad)) + (flags, msg.pad, msg.body.group_id, msg.body.pad)) def print_ofpt_multipart_request_group_desc(msg): """ @@ -726,7 +731,7 @@ def print_ofpt_multipart_request_meter_config(msg): """ flags = green(dissector.get_multipart_request_flags(msg.flags.value)) print(' Meter_Config(10): Flags: %s Pad: %s Meter_ID: %s Pad: %s' % - (flags, msg.pad, msg.meter_id, msg.pad)) + (flags, msg.pad, msg.body.meter_id, msg.body.pad)) def print_ofpt_multipart_request_meter_features(msg): """ @@ -745,8 +750,8 @@ def print_ofpt_multipart_request_table_features(msg): flags = green(dissector.get_multipart_request_flags(msg.flags.value)) print(' Table_Features(12): Flags: %s Pad: %s Lenght: %s Table_ID: %s Pad: %s' 'Name: %s Metadata_Match: %s Metadata_Write: %s Config: %s Max_entries: %s' % - (flags, msg.pad, msg.lenght, msg.table_id, msg.pad, msg.name, - msg.metadata_match, msg.metadata_write, msg.config, msg.max_entries)) + (flags, msg.pad, msg.body.lenght, msg.body.table_id, msg.body.pad, msg.body.name, + msg.body.metadata_match, msg.body.metadata_write, msg.body.config, msg.body.max_entries)) # TODO: Table_feature_prop: includes instructions @@ -766,8 +771,8 @@ def print_ofps_multipart_request_experimenter(msg): msg: OpenFlow message unpacked by python-openflow """ flags = green(dissector.get_multipart_request_flags(msg.flags.value)) - print(' Experimenter(65535): Flags: %s Pad: %s Experimenter_ID: %s Experimenter_Type: %s' % - (flags, msg.pad, msg.experimenter_id.value, msg.experimenter_type)) + print(' Experimenter(65535): Flags: %s Pad: %s Experimenter: %s Experimenter_Type: %s' % + (flags, msg.pad, msg.body.experimenter.value, msg.body.exp_type)) if msg.multipart_type.value == 0: print_ofpt_multipart_request_description(msg) @@ -810,7 +815,7 @@ def print_ofpt_multipart_reply(msg): msg: OpenFlow message unpacked by python-openflow """ multipart_type = "%s" % msg.multipart_type - print('Multipart_Reply: Type: %s' % multipart_type.split('.')[1]) + print('Multipart_Reply: Type: %s' % multipart_type) if isinstance(msg.body, BinaryData) and len(msg.body) > 0: print("Multipart Request - Body: \"%s\"" % msg.body.decode("utf-8")) @@ -824,8 +829,8 @@ def print_ofpt_multipart_reply_description(msg): flags = green(dissector.get_multipart_reply_flags(msg.flags.value)) print(' Description(0): Flags: %s mfr_desc: %s hw_desc: %s' 'sw_desc: %s serial_num: %s dp_desc: %s' % - (flags, msg.mfr_desc, msg.hw_desc, msg.bsw_desc, - msg.serial_num, msg.dp_desc)) + (flags, msg.body.mfr_desc, msg.body.hw_desc, msg.body.sw_desc, + msg.body.serial_num, msg.body.dp_desc)) def print_ofpt_multipart_reply_flow_array(msg): """ @@ -851,7 +856,7 @@ def print_ofpt_multipart_reply_flow(flow): print('Multipart_Reply ', end='') print_match_type(flow.match) print('Multipart_Reply ', end='') - print_action(flow.actions) + print_instruction(flow.instructions) if len(msg.body) == 0: print('Multipart Reply Flow(1):\nNo Flows') @@ -860,17 +865,25 @@ def print_ofpt_multipart_reply_flow(flow): for flow in msg.body: # body attribute in OF1.3 is a binary data that shows empty (b'') print_ofpt_multipart_reply_flow(flow) - def print_ofpt_multipart_reply_aggregate(msg): + def print_ofpt_multipart_reply_aggregate_array(msg): """ - Args: msg: OpenFlow message unpacked by python-openflow """ - flags = green(dissector.get_multipart_reply_flags(msg.flags.value)) - print(' Aggregate(2): Flags: %s packet_count: %s, byte_count: %s flow_count: %s Pad: %s' % - (flags, msg.packet_count, msg.byte_count, msg.flow_count, msg.pad)) # Is msg.stats included in 1.3? + def print_ofpt_multipart_reply_aggregate(aggregate): + """aggregate: AggregateStatsReply unpacked by python-openflow""" + flags = green(dissector.get_multipart_reply_flags(msg.flags.value)) + print(' Aggregate(2): Flags: %s packet_count: %s, byte_count: %s flow_count: %s Pad: %s' % + (flags, aggregate.packet_count, aggregate.byte_count, aggregate.flow_count, aggregate.pad)) - def print_ofpt_multipart_reply_table(msg): + if len(msg.body) == 0: + print('Multipart Reply Aggregate(2):\nNo Aggregate') + return + + for aggregate in msg.body: + print_ofpt_multipart_reply_aggregate(aggregate) + + def print_ofpt_multipart_reply_table(table): """ Args: @@ -879,12 +892,21 @@ def print_ofpt_multipart_reply_table(msg): flags = green(dissector.get_multipart_reply_flags(msg.flags.value)) print(' Table(3): Flags: %s table_id: %s pad: %s ' ' active_count: %s lookup_count: %s matched_count: %s' % - (flags, msg.table_id.value, msg.pad, - msg.active_count.value, msg.lookup_count.value, msg.matched_count.value)) + (flags, table.table_id.value, table.pad, + table.active_count.value, table.lookup_count.value, table.matched_count.value)) + + def print_ofpt_multipart_reply_table_array(msg): + """ + + Args: + msg: OpenFlow message unpacked by python-openflow + """ if len(msg.body) == 0: - print('Multipart Reply Type Table(3):\nNo Tables') + print('Multipart Type Table(3):\nNo Table') return + for table in msg.body: + print_ofpt_multipart_reply_table(table) def print_ofpt_multipart_reply_port(port): """ @@ -942,100 +964,120 @@ def print_ofpt_multipart_reply_queue(queue): for queue in msg.body: print_ofpt_multipart_reply_queue(queue) - def print_ofpt_multipart_reply_group(msg): + def print_ofpt_multipart_reply_group_array(msg): """ Args: msg: OpenFlow message unpacked by python-openflow """ - flags = green(dissector.get_multipart_reply_flags(msg.flags.value)) - print(' Group(6): Flags: %s length: %s pad: %s group_id: %s ref_count: %s ' - 'pad: %s packet_count: %s byte_count: %s duration_sec: %s duration_nsec: %s' - 'bucket_counter[packet_count]: %s bucket_counter[byte_count]: %s' % - (flags, msg.length, msg.pad, msg.group_id, msg.ref_count, msg.pad, - msg.packet_count, msg.byte_count, msg.duration_sec, msg.duration_nsec, - msg.buckets[0].packet_count.value, msg.buckets[0].byte_count.value)) + def print_ofpt_multipart_reply_group(group): + """group: GroupStats unpacked by python-openflow.""" + flags = green(dissector.get_multipart_reply_flags(msg.flags.value)) + print(' Group(6): Flags: %s length: %s pad: %s group_id: %s ref_count: %s ' + 'pad: %s packet_count: %s byte_count: %s duration_sec: %s duration_nsec: %s' + 'bucket_counter[packet_count]: %s bucket_counter[byte_count]: %s' % + (flags, group.length, group.pad, group.group_id, group.ref_count, group.pad2, + group.packet_count, group.byte_count, group.duration_sec, group.duration_nsec, + group.bucket_stats[0].packet_count.value, group.bucket_stats[0].byte_count.value)) if len(msg.body) == 0: print('Multipart Reply Type: Group(6):\nNo groups') return + + for group in msg.body: + print_ofpt_multipart_reply_group(group) - def print_ofpt_multipart_reply_group_desc(msg): + def print_ofpt_multipart_reply_group_desc_array(msg): """ Args: msg: OpenFlow message unpacked by python-openflow """ - flags = green(dissector.get_multipart_reply_flags(msg.flags.value)) - print(' Group_Desc(7): Flags: %s length: %s pad: %s group_id: %s' - 'Bucket[length]: %s Bucket[weight]: %s Bucket[watch_port]: %s Bucket[watch_group]: %s' % - (flags, msg.length, green(msg.group_id.value), msg.pad, - msg.buckets[0].length.value, msg.buckets[0].weight.value, hex(msg.buckets[0].watch_port.value), - hex(msg.buckets[0].watch_group.value))) - - print("Bucket[actions]:") - for action in msg.buckets[0].actions: - print_action(action) + def print_ofpt_multipart_reply_group_desc(groupdesc): + """groupdesc: GroupDescStats message unpacked by pyof.""" + flags = green(dissector.get_multipart_reply_flags(msg.flags.value)) + print(' Group_Desc(7): Flags: %s length: %s pad: %s group_id: %s' + 'Bucket[length]: %s Bucket[weight]: %s Bucket[watch_port]: %s Bucket[watch_group]: %s' % + (flags, groupdesc.length, green(groupdesc.group_id.value), groupdesc.pad, + groupdesc.buckets[0].length.value, groupdesc.buckets[0].weight.value, hex(groupdesc.buckets[0].watch_port.value), + hex(groupdesc.buckets[0].watch_group.value))) + + print("Bucket[actions]:") + for action in groupdesc.buckets[0].actions: + print_action(action) if len(msg.body) == 0: print('Multipart Reply Type Group_Desc(7):\nNo group_desc') return + for groupdesc in msg.body: + print_ofpt_multipart_reply_group_desc(groupdesc) + def print_ofpt_multipart_reply_group_features(msg): """ Args: msg: OpenFlow message unpacked by python-openflow """ flags = green(dissector.get_multipart_reply_flags(msg.flags.value)) - print(' Group_Features(8): Flags: %s pad: %s capabilities: %s max_groups: %s actions: %s' % - (flags, msg.pad, msg.capabilities, msg.max_groups, msg.actions)) + print(' Group_Features(8): Flags: %s capabilities: %s max_groups1: %s max_groups2: %s max_groups3: %s max_groups4: %s actions1: %s actions2: %s actions3: %s actions4: %s' % + (flags, msg.body.capabilities, msg.body.max_groups1, msg.body.max_groups2, msg.body.max_groups3, msg.body.max_groups4, msg.body.actions1, msg.body.actions2, msg.body.actions3, msg.body.actions4)) if len(msg.body) == 0: print('Multipart Reply Type Group_Features(8):\nNo group features') return - def print_ofpt_multipart_reply_meter(msg): + def print_ofpt_multipart_reply_meter_array(msg): """ Args: msg: OpenFlow message unpacked by python-openflow """ - flags = green(dissector.get_multipart_reply_flags(msg.flags.value)) - print(' Meter(9): Flags: %s meter_id: %s len: %s pad: %s flow_count: %s' - 'packet_in_count: %s byte_in_count: %s duration_sec: %s duration_nsec: %s' - 'meter_band_stats[packet_band_count]: %s meter_band_stats[byte_band_count]: %s' % - (flags, msg.meter_id, msg.len, msg.pad, msg.flow_count, msg.packet_in_count, - msg.byte_in_count, msg.duration_sec, msg.duration_nsec, msg.meter_band_stats[0].packet_band_count.value, - msg.meter_band_stats[0].byte_band_count.value)) + def print_ofpt_multipart_reply_meter(meter): + """meter: MeterStats message unpacked by python-openflow.""" + flags = green(dissector.get_multipart_reply_flags(msg.flags.value)) + print(' MeterStats(9): Flags: %s meter_id: %s len: %s pad: %s flow_count: %s' + 'packet_in_count: %s byte_in_count: %s duration_sec: %s duration_nsec: %s' + 'meter_band_stats[packet_band_count]: %s meter_band_stats[byte_band_count]: %s' % + (flags, meter.meter_id, meter.length, meter.pad, meter.flow_count, meter.packet_in_count, + meter.byte_in_count, meter.duration_sec, meter.duration_nsec, meter.band_stats[0].packet_band_count.value, + meter.band_stats[0].byte_band_count.value)) if len(msg.body) == 0: print('Multipart Reply Type Meter(9):\nNo meters') return - def print_ofpt_multipart_reply_meter_config(msg): + for meter in msg.body: + print_ofpt_multipart_reply_meter(meter) + + def print_ofpt_multipart_reply_meter_config_array(msg): """ Args: msg: OpenFlow message unpacked by python-openflow """ - flags = green(dissector.get_multipart_reply_flags(msg.flags.value)) - print(' Meter_Config(10): Flags: %s length: %s meter_id: %s' % - (flags, msg.len, msg.meter_id.value)) - - for band in msg.meter_band_header[0].band: - if band.type == "drop": - print('Band[type]: %s Band[len]: %s Band[rate]: %s Band[burst_size]: %s Band[pad]: %s' % - (band.type.value, band.len.value, band.rate.value, band.burst_size.value, band.pad)) - if band.type == "dscp_remark": - print('Band[type]: %s Band[len]: %s Band[rate]: %s Band[burst_size]: %s Band[prec]: %s ' - 'Band[pad]: %s' % - (band.type.value, band.len.value, band.rate.value, band.burst_size.value, band.prec.value, - band.pad)) - if band.type == "experimenter": - print('Band[type]: %s Band[len]: %s Band[rate]: %s Band[burst_size]: %s Band[experimenter_id]: %s' % - (band.type.value, band.len.value, band.rate.value, band.burst_size.value, - band.experimenter_id.value)) + def print_ofpt_multipart_reply_meter_config(meter_config): + """meter_config: MeterConfig unpacked by python-openflow.""" + flags = green(dissector.get_multipart_reply_flags(msg.flags.value)) + print(' Meter_Config(10): Flags: %s length: %s meter_id: %s' % + (flags, meter_config.length, meter_config.meter_id.value)) + + for band in meter_config.bands: + if band.type == "drop": + print('Band[type]: %s Band[len]: %s Band[rate]: %s Band[burst_size]: %s Band[pad]: %s' % + (band.type.value, band.len.value, band.rate.value, band.burst_size.value, band.pad)) + if band.type == "dscp_remark": + print('Band[type]: %s Band[len]: %s Band[rate]: %s Band[burst_size]: %s Band[prec]: %s ' + 'Band[pad]: %s' % + (band.type.value, band.len.value, band.rate.value, band.burst_size.value, band.prec.value, + band.pad)) + if band.type == "experimenter": + print('Band[type]: %s Band[len]: %s Band[rate]: %s Band[burst_size]: %s Band[experimenter_id]: %s' % + (band.type.value, band.len.value, band.rate.value, band.burst_size.value, + band.experimenter_id.value)) if len(msg.body) == 0: print('Multipart Reply Type Meter_config(10):\nNo meter_configs') return + for meter_config in msg.body: + print_ofpt_multipart_reply_meter_config(meter_config) + def print_ofpt_multipart_reply_meter_features(msg): """ Args: @@ -1044,8 +1086,8 @@ def print_ofpt_multipart_reply_meter_features(msg): flags = green(dissector.get_multipart_reply_flags(msg.flags.value)) print(' Meter_Features(11): Flags: %s max_meter: %s band_type: %s capabilities: %s max_bands: %s' 'max_color: %s pad: %s' % - (flags, msg.max_meter, msg.band_type, msg.capabilities, msg.max_bands, msg.max_color, - msg.pad)) + (flags, msg.body.max_meter, msg.body.band_type, msg.body.capabilities, msg.body.max_bands, msg.body.max_color, + msg.body.pad)) if len(msg.body) == 0: print('Multipart Reply Type Meter_Features(11):\nNo meter features') @@ -1079,7 +1121,7 @@ def print_ofpt_multipart_reply_table_features(table_feature): for table_feature in msg.body: print_ofpt_multipart_reply_table_features(table_feature) - def print_ofpt_multipart_reply_port_desc(msg): + def print_ofpt_multipart_reply_port_desc_array(msg): """ Args: msg: OpenFlow message unpacked by python-openflow @@ -1091,9 +1133,8 @@ def print_ofpt_multipart_reply_port_desc(msg): if len(msg.body) == 0: print('Multipart Reply Type Port_Desc(13):\nNo port descriptions') return - else: - for port in msg.body: - print_ofp_phy_port(port) + for port in msg.body: + print_ofp_phy_port(port) def print_ofpt_multipart_reply_experimenter(msg): """ @@ -1109,29 +1150,29 @@ def print_ofpt_multipart_reply_experimenter(msg): elif msg.multipart_type.value == 1: print_ofpt_multipart_reply_flow_array(msg) elif msg.multipart_type.value == 2: - print_ofpt_multipart_reply_aggregate(msg) + print_ofpt_multipart_reply_aggregate_array(msg) elif msg.multipart_type.value == 3: - print_ofpt_multipart_reply_table(msg) + print_ofpt_multipart_reply_table_array(msg) elif msg.multipart_type.value == 4: print_ofp_multipart_reply_port_array(msg) elif msg.multipart_type.value == 5: print_ofpt_multipart_reply_queue_array(msg) elif msg.multipart_type.value == 6: - print_ofpt_multipart_reply_group(msg) + print_ofpt_multipart_reply_group_array(msg) elif msg.multipart_type.value == 7: - print_ofpt_multipart_reply_group_desc(msg) + print_ofpt_multipart_reply_group_desc_array(msg) elif msg.multipart_type.value == 8: print_ofpt_multipart_reply_group_features(msg) elif msg.multipart_type.value == 9: - print_ofpt_multipart_reply_meter(msg) + print_ofpt_multipart_reply_meter_array(msg) elif msg.multipart_type.value == 10: - print_ofpt_multipart_reply_meter_config(msg) + print_ofpt_multipart_reply_meter_config_array(msg) elif msg.multipart_type.value == 11: print_ofpt_multipart_reply_meter_features(msg) elif msg.multipart_type.value == 12: print_ofpt_multipart_reply_table_features_array(msg) elif msg.multipart_type.value == 13: - print_ofpt_multipart_reply_port_desc(msg) + print_ofpt_multipart_reply_port_desc_array(msg) elif msg.multipart_type.value == 65535: print_ofpt_multipart_reply_experimenter(msg) diff --git a/libs/tcpiplib/prints.py b/libs/tcpiplib/prints.py index b2131db..e11a751 100644 --- a/libs/tcpiplib/prints.py +++ b/libs/tcpiplib/prints.py @@ -204,8 +204,8 @@ def print_openflow_header(ofp): version = libs.tcpiplib.tcpip.get_ofp_version(ofp.header.version.value) name_version = '%s(%s)' % (version, ofp.header.version.value) - name = "%s" % ofp.header.message_type - name_type = '%s(%s)' % (name.split('.')[1], ofp.header.message_type.value) + name = ofp.header.message_type.name + name_type = '%s(%s)' % (name, ofp.header.message_type.value) print('OpenFlow Version: %s Type: %s Length: %s XID: %s' % (name_version, yellow(name_type), ofp.header.length, red(ofp.header.xid))) diff --git a/ofp_sniffer.py b/ofp_sniffer.py index 63bd5e6..e1ce9b8 100755 --- a/ofp_sniffer.py +++ b/ofp_sniffer.py @@ -10,6 +10,7 @@ import time import threading import yaml +import traceback from libs.core.printing import PrintingOptions from libs.core.sanitizer import Sanitizer from libs.core.topo_reader import TopoReader @@ -104,7 +105,8 @@ def run(self): exit_code = 1 except Exception as exception: - print('Error on packet %s: %s ' % (self.packet_count, exception)) + err = traceback.format_exc().replace("\n", ", ") + print('Error on packet %s: %s error: %s' % (self.packet_count, exception, err)) exit_code = 2 finally: