Exemple #1
0
    def load_config(self):
        """
            Parses the parameters received and instantiates the
            apps requested.
        """
        # Get CLI params and call the pcapy loop
        self.cap, self.packet_number, \
            self.load_apps, sanitizer, \
            topo_file, is_to_save = get_params(sys.argv)
        self.sanitizer.process_filters(sanitizer)

        # Load TopologyReader
        self.topo_reader.readfile(topo_file)

        # Save to File
        self.save_to_file = save_to_file(is_to_save)

        # Start Apps
        self.ofp_proxy = OFProxy()

        if 'oess_fvd' in self.load_apps:
            self.oft = OessFvdTracer(self.load_apps['oess_fvd'])

        if 'statistics' in self.load_apps:
            self.stats = OFStats()
            if 'influx' in self.load_apps:
                self.influx = InfluxClient(trigger_event=self.trigger_event)

        if 'notifications' in self.load_apps:
            self.notifications = Notifications(self.load_apps['notifications'])
Exemple #2
0
    def process_per_dev_packet_types(self, pkt, ofp):
        """
            Creates counter per dpid

            Args:
                pkt: Packet class
                ofp: OFMessage.ofp attribute (OpenFlow message)
        """
        dpid = OFProxy().get_dpid(pkt.l3.s_addr, pkt.l4.source_port)

        if isinstance(dpid, bool):
            dpid = OFProxy().get_dpid(pkt.l3.d_addr, pkt.l4.dest_port)
            if isinstance(dpid, bool):
                return

        version = str(ofp.header.version.value)
        if dpid not in self.per_dev_packet_types:
            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]
        try:
            self.per_dev_packet_types[dpid][version][message_type] += 1
        except KeyError:
            self.per_dev_packet_types[dpid][version][message_type] = 1
        self.per_dev_packet_types[dpid]['total'] += 1
def print_minimal(position, date, getlen, ip_addr, tcp):
    """
        Print TCP/IP header with minimal information
    Args:
        position: packet count
        date: date/time packet was captured
        getlen: total number of bytes captured
        ip_addr: IP class
        tcp: TCP class
    """
    string = 'Packet #%s - %s %s:%s -> %s:%s Size: %s Bytes'

    source = OFProxy().get_name(ip_addr.s_addr, tcp.source_port)
    dest = OFProxy().get_name(ip_addr.d_addr, tcp.dest_port)

    print(string % (position, date, cyan(source), cyan(
        tcp.source_port), cyan(dest), cyan(tcp.dest_port), getlen))
Exemple #4
0
    def save_last_msgs_per_dev(self, pkt, ofp):
        """
            Creates per last messages queue per datapath

            Args:
                pkt: Packet class
                ofp: OFMessage.ofp attribute (OpenFlow message)
        """
        dpid = OFProxy().get_dpid(pkt.l3.s_addr, pkt.l4.source_port)

        if isinstance(dpid, bool):
            dpid = OFProxy().get_dpid(pkt.l3.d_addr, pkt.l4.dest_port)
            if isinstance(dpid, bool):
                return

        if dpid not in self.per_dev_last_msgs:
            self.per_dev_last_msgs[dpid] = CircularList()

        self.per_dev_last_msgs[dpid].add(pkt.l1.time, ofp)
    def load_config(self):
        """
            Parses the parameters received and instantiates the
            apps requested.
        """
        # Get CLI params and call the pcapy loop
        self.cap, self.packet_number, \
            self.load_apps, sanitizer, topo_file = get_params(sys.argv)
        self.sanitizer.process_filters(sanitizer)

        # Load TopologyReader
        self.topo_reader.readfile(topo_file)

        # Start Apps
        if 'oess_fvd' in self.load_apps:
            self.oft = OessFvdTracer()

        if 'statistics' in self.load_apps:
            self.stats = OFStats()

        # Load Proxy
        self.ofp_proxy = OFProxy()
    def get_content(self, pkt):
        """ Extract the content from the OpenFlow message received

        Args:
            pkt: Packet class
        Return:
            string using format '{"text":CONTENT}'
            False if not an Port_Status or Error msg
        """

        for msg in pkt.ofmsgs:
            if msg.ofp.header.message_type.value == 12:
                source = OFProxy().get_name(pkt.l3.s_addr, pkt.l4.source_port)
                if msg.ofp.reason.value == 0:
                    txt = "Switch: %s Interface %s was Added"
                    return txt % (source, msg.ofp.desc.name)
                elif msg.ofp.reason.value == 1:
                    txt = "Switch: %s Interface %s was Removed"
                    return txt % (source, msg.ofp.desc.name)
                elif msg.ofp.reason.value == 2:
                    status = self.get_port_status(msg.ofp.desc)
                    txt = "Switch: %s Interface %s is %s"
                    return txt % (source, msg.ofp.desc.name, status)

            elif msg.ofp.header.message_type.value == 1:
                source = OFProxy().get_name(pkt.l3.s_addr, pkt.l4.source_port)
                etype, ecode = get_ofp_error(msg.ofp.error_type.value,
                                             msg.ofp.code.value)
                txt = "Switch: %s Error - Type: %s Code: %s"
                return txt % (source, etype, ecode)

        if pkt.reconnect_error:
            source = OFProxy().get_name(pkt.l3.s_addr, pkt.l4.source_port)
            txt = "TCP reconnection for switch: %s"
            return txt % source

        return False
Exemple #7
0
class RunSniffer(object):
    """
        The RunSniffer class is the main class for the OpenFlow Sniffer.
        This class instantiate all auxiliary classes, captures the packets,
        instantiate new OpenFlow messages and triggers all applications.
    """
    def __init__(self):
        self.printing_options = PrintingOptions()
        self.sanitizer = Sanitizer()
        self.oft = None
        self.stats = None
        self.influx = None
        self.notifications = None
        self.trigger_event = threading.Event()
        self.cap = None
        self.packet_number = None
        self.load_apps = dict()
        self.packet_count = 1
        self.topo_reader = TopoReader()
        self.save_to_file = None
        self.ofp_proxy = None
        self.load_config()

    def load_config(self):
        """
            Parses the parameters received and instantiates the
            apps requested.
        """
        # Get CLI params and call the pcapy loop
        self.cap, self.packet_number, \
            self.load_apps, sanitizer, \
            topo_file, is_to_save = get_params(sys.argv)
        self.sanitizer.process_filters(sanitizer)

        # Load TopologyReader
        self.topo_reader.readfile(topo_file)

        # Save to File
        self.save_to_file = save_to_file(is_to_save)

        # Start Apps
        self.ofp_proxy = OFProxy()

        if 'oess_fvd' in self.load_apps:
            self.oft = OessFvdTracer(self.load_apps['oess_fvd'])

        if 'statistics' in self.load_apps:
            self.stats = OFStats()
            if 'influx' in self.load_apps:
                self.influx = InfluxClient(trigger_event=self.trigger_event)

        if 'notifications' in self.load_apps:
            self.notifications = Notifications(self.load_apps['notifications'])

    def run(self):
        """
            cap.loop continuously capture packets w/ pcapy. For every
            captured packet, self.process_packet method is called.

            Exits:
                0 - Normal, reached end of file
                1 - Normal, user requested with CRTL + C
                2 - Error
                3 - Interface or file not found
        """
        exit_code = 0

        # DEBUG:
        # self.cap.loop(-1, self.process_packet)
        try:
            self.cap.loop(-1, self.process_packet)

        except EndOfPcapFile:
            exit_code = 3

        except KeyboardInterrupt:
            exit_code = 1

        except Exception as exception:
            print('Error on packet %s: %s ' % (self.packet_count, exception))
            exit_code = 2

        finally:

            if 'statistics' in self.load_apps:
                #  If OFP_Stats is running, set a timer
                #  before closing the app. Useful in cases
                #  where the ofp_sniffer is reading from a
                #  pcap file instead of a NIC.
                time.sleep(200)
                # pass

            print('Exiting with code: %s' % exit_code)
            # gracefully shut down
            if 'influx' in self.load_apps:
                self.influx.stop_event.set()
            sys.exit(exit_code)

    def process_packet(self, header, packet):
        """
            Every packet captured by cap.loop is then processed here.
            If packets are bigger than 62 Bytes, we process them.
            If it is 0, means there are no more packets. If it is
            something in between, it is a fragment, we ignore for now.

            Args:
                header: header of the captured packet
                packet: packet captured from file or interface
        """
        if len(packet) >= 54:
            # Verify if user asked for just one specific packet
            if self.was_packet_number_defined():
                if not self.is_the_packet_number_specified():
                    self.packet_count += 1
                    return

            # DEBUG:
            # print("Packet Number: %s" % self.packet_count)
            pkt = Packet(packet, self.packet_count, header)

            if pkt.reconnect_error:
                if isinstance(self.stats, OFStats):
                    # OFStats counts reconnects
                    self.stats.process_packet(pkt)

                if isinstance(self.notifications, Notifications):
                    # Send notifications via Slack
                    self.notifications.send_msg(pkt)

            elif pkt.is_openflow_packet:
                valid_result = pkt.process_openflow_messages()
                if valid_result:

                    # Apps go here:
                    if isinstance(self.oft, OessFvdTracer):
                        # FVD_Tracer does not print the packets
                        self.oft.process_packet(pkt)

                    if isinstance(self.ofp_proxy, OFProxy):
                        # OFP_PROXY associates IP:PORT to DPID
                        self.ofp_proxy.process_packet(pkt)

                    if isinstance(self.stats, OFStats):
                        # OFStats print the packets
                        self.stats.process_packet(pkt)

                    if isinstance(self.notifications, Notifications):
                        # Send notifications via Slack
                        self.notifications.send_msg(pkt)

                    if not isinstance(self.oft, OessFvdTracer):
                        # Print Packets
                        pkt.print_packet()

            if self.influx:
                # tell influx to wake up and update immediately
                self.trigger_event.set()

            del pkt

            if self.is_the_packet_number_specified():
                # If a specific packet was selected, end here.
                raise EndOfPcapFile

        elif len(packet) is 0:
            return 3

        self.packet_count += 1

    def was_packet_number_defined(self):
        """
            In case user wants to see a specific packet inside a
            specific pcap file, provide file name with the specific
            packet number after ":"
                -r file.pcap:packet_number
            Returns:
                True if a packet number was specified
                False: if a packet number was not specified
        """
        if self.packet_number != 0:
            return True
        return False

    def is_the_packet_number_specified(self):
        """
            If user wants to see a specific packet inside a
            specific pcap file and the packet_count is that
            number, return True. Otherwise, return false

            Returns:
                True if packet_count matches
                False: if packet_count does not match
        """
        return True if self.packet_count == self.packet_number else False
class RunSniffer(object):
    """
        The RunSniffer class is the main class for the OpenFlow Sniffer.
        This class instantiate all auxiliary classes, captures the packets,
        instantiate new OpenFlow messages and triggers all applications.
    """
    def __init__(self):
        self.printing_options = PrintingOptions()
        self.sanitizer = Sanitizer()
        self.oft = None
        self.stats = None
        self.cap = None
        self.packet_number = None
        self.load_apps = []
        self.packet_count = 1
        self.topo_reader = TopoReader()
        self.ofp_proxy = None
        self.load_config()

    def load_config(self):
        """
            Parses the parameters received and instantiates the
            apps requested.
        """
        # Get CLI params and call the pcapy loop
        self.cap, self.packet_number, \
            self.load_apps, sanitizer, topo_file = get_params(sys.argv)
        self.sanitizer.process_filters(sanitizer)

        # Load TopologyReader
        self.topo_reader.readfile(topo_file)

        # Start Apps
        if 'oess_fvd' in self.load_apps:
            self.oft = OessFvdTracer()

        if 'statistics' in self.load_apps:
            self.stats = OFStats()

        # Load Proxy
        self.ofp_proxy = OFProxy()

    def run(self):
        """
            cap.loop continuously capture packets w/ pcapy. For every
            captured packet, self.process_packet method is called.

            Exits:
                0 - Normal, reached end of file
                1 - Normal, user requested with CRTL + C
                2 - Error
                3 - Interface or file not found
        """
        exit_code = 0

        # Debug:
        # self.cap.loop(-1, self.process_packet)
        try:
            self.cap.loop(-1, self.process_packet)

            if 'statistics' in self.load_apps:
                # If OFP_Stats is running, set a timer
                # before closing the app. Useful in cases
                # where the ofp_sniffer is reading from a
                # pcap file instead of real time.
                time.sleep(200)

        except KeyboardInterrupt:
            exit_code = 1

        except Exception as exception:
            print('Error on packet %s: %s ' % (self.packet_count, exception))
            exit_code = 2

        finally:
            print('Exiting...')
            sys.exit(exit_code)

    def process_packet(self, header, packet):
        """
            Every packet captured by cap.loop is then processed here.
            If packets are bigger than 62 Bytes, we process them.
            If it is 0, means there are no more packets. If it is
            something in between, it is a fragment, we ignore for now.

            Args:
                header: header of the captured packet
                packet: packet captured from file or interface
        """
        if len(packet) >= 62 and self.packet_number_defined():

            # DEBUG:
            # print("Packet Number: %s" % self.packet_count)
            pkt = Packet(packet, self.packet_count, header)

            if pkt.is_openflow_packet:
                valid_result = pkt.process_openflow_messages()
                if valid_result:

                    # Apps go here:
                    if isinstance(self.oft, OessFvdTracer):
                        # FVD_Tracer does not print the packets
                        self.oft.process_packet(pkt)

                    if isinstance(self.ofp_proxy, OFProxy):
                        # OFP_PROXY associates IP:PORT to DPID
                        self.ofp_proxy.process_packet(pkt)

                    if isinstance(self.stats, OFStats):
                        # OFStats print the packets
                        self.stats.process_packet(pkt)

                    if not isinstance(self.oft, OessFvdTracer):
                        # Print Packets
                        pkt.print_packet()

            del pkt

        elif len(packet) is 0:
            sys.exit(0)

        self.packet_count += 1

    def packet_number_defined(self):
        """
            In case user wants to see a specific packet inside a
            specific pcap file, provide file name with the specific
            packet number
                -r file.pcap:packet_number
            Returns:
                True if packet_count matches
                False: if packet_count does not match
        """
        if self.packet_number > 0:
            return True if self.packet_count == self.packet_number else False

        return True