Пример #1
0
    def handle_dns(self, dpid, inport, ofp_reason, total_frame_len, buffer_id, packet):
        eaddr = util.convert_to_eaddr(packet.src)
        dnsh = packet.find('dns')

        if not self.permit_ether_addr(eaddr):
            print "Dropping DNS Packet - MAC Address not allowed"
            return STOP

        if not dnsh:
            print "Invalid DNS packet:", dnsh, packet
            return CONTINUE

        print "DNS Packet:", dnsh

        for question in dnsh.questions:
            if eaddr in Homework.st['dnsList'] and question.name in Homework.st['dnsList'][eaddr]:
                print "DNS Resquest blocked for", question.name
                return STOP

        flow = util.extract_flow(packet)
        Homework.install_datapath_flow(
             dpid, flow, 3, 10,
             [[openflow.OFPAT_OUTPUT, [-1, openflow.OFPP_NORMAL]]],
             buffer_id, openflow.OFP_DEFAULT_PRIORITY, inport, packet.arr
             )

        return CONTINUE
 def __forward_l2_packet(self, dpid, inport, packet, buf, bufid):
     """ Layer 2 forwarding """
     dstaddr = packet.dst.tostring()
     if not ord(dstaddr[0]) & 1 and dstaddr in self.switches[dpid]:
         prt = self.switches[dpid][dstaddr]
         if prt[0] == inport:
             LOG.err("**WARNING** Learned port = inport")
             self.send_openflow(dpid, bufid, buf,
                                openflow.OFPP_FLOOD,
                                inport)
         else:
             # We know the outport, set up a flow
             LOG.debug("Installing flow for %s" % str(packet))
             flow = extract_flow(packet)
             actions = [[openflow.OFPAT_OUTPUT, [0, prt[0]]]]
             self.install_datapath_flow(dpid, flow, 5,
                                        openflow.OFP_FLOW_PERMANENT,
                                        actions, bufid,
                                        openflow.OFP_DEFAULT_PRIORITY,
                                        inport, buf)
             LOG.info("New installed flow entry for dpid '%s': %s" % \
                       (str(dpid), str(flow)))
     else:
         # haven't learned destination MAC. Flood
         self.send_openflow(dpid, bufid, buf, openflow.OFPP_FLOOD, inport)
         LOG.debug("Flooding received packet...")
Пример #3
0
    def packetIsMatching(self, pkt, inport, attrs):
        """Checks whether a packet is matching a specific table entry
        
           attrs is a dictionary of attributes to match, missing attributes
           are considered wildcarded
        """
        pkt_attrs = of_util.extract_flow(pkt)
        pkt_attrs[core.IN_PORT] = inport

        skip_nw_src = False
        for a in attrs:
            if a == "nw_src_n_wild":
                mask = int(
                    0xffffffff << attrs[a]
                )  # see openflow.h in NOX for this definition of mask
                if pkt_attrs[core.NW_SRC] & mask != attrs["nw_src"] & mask:
                    return False
                else:
                    skip_nw_src = True
            elif a == "nw_src" and skip_nw_src:
                continue
            elif attrs[a] != pkt_attrs[
                    a]:  # If this throws an exception, we have an usupported attribute
                return False
        return True
Пример #4
0
    def packet_in_handler(self, dpid, inport, reason, length, bufid, packet):
        """ Handler for packet_in event """
        assert length is not None
        assert packet is not None
        # checks packet consistency
        if not packet.parsed:
            LOG.warning("Ignoring incomplete packet")
            return CONTINUE

        if packet.type == ethernet.LLDP_TYPE:
            return CONTINUE

        dpid_ = dpid_from_host(dpid)
        if not dpid_: return CONTINUE

        LOG.debug("dpid=%s, inport=%s, reason=%s, len=%s, bufid=%s, p=%s",
                  dpid_, inport, reason, length, str(bufid), str(packet))

        # Handle ARP packets
        if packet.type == ethernet.ARP_TYPE or\
           (packet.type == ethernet.VLAN_TYPE and\
            packet.find('vlan').eth_type == ethernet.ARP_TYPE):
            LOG.debug("Received ARP packet " + str(packet.find('arp')))
            if not dpid_ in self.switches:
                LOG.debug("Registering new switch %s" % dpid_)
                self.switches[dpid_] = {}

            self.__do_l2_learning(dpid_, inport, packet)
            self.__forward_l2_packet(dpid_, inport, packet, packet.arr, bufid)

        # switch over ethernet type
        if packet.type == ethernet.IP_TYPE or\
           (packet.type == ethernet.VLAN_TYPE and\
            packet.find('vlan').eth_type == ethernet.IP_TYPE):
            ip_addr = packet.find('ipv4')
            LOG.info("IPv4 packet: " + str(ip_addr))
            #  XXX FIXME: Remove the following check in order to be generic...
            if ip_addr.protocol == ipv4.ICMP_PROTOCOL:
                flow = extract_flow(packet)
                LOG.debug("Sending path request for flow: %s" % str(flow))
                payload = {"dst_port": flow[core.TP_DST],
                           "src_port": flow[core.TP_SRC],
                           "ip_dst"  : pkt_utils.ip_to_str(ip_addr.dstip),
                           "ip_src"  : pkt_utils.ip_to_str(ip_addr.srcip),
                           "ip_proto": flow[core.NW_PROTO],
                           "vlan_id" : flow[core.DL_VLAN]}

                LOG.debug("Payload=%s" % str(payload))
                if self.allow_ping == 'True':
                    req = requests.post(url=self.url + "pckt_host_path",
                                        headers=self.hs, data=json.dumps(payload))
                    LOG.debug("URL=%s, response=%s", req.url, req.text)

        return CONTINUE
Пример #5
0
    def pkt_in_handler(self, dp_id, inport, ofp_reason, total_frame_len, buffer_id, packet):
        attrs = util.extract_flow(packet)
        print "Pakcet in received "+str(inport)+ " " +packet_utils.ip_to_str(attrs['nw_dst'])
        # print attrs

        # print ("type:%s %s > %s  %s:%d > %s:%d "%(
        #         packet_utils.ethtype_to_str(attrs['dl_type']),
        #         packet_utils.mac_to_str(attrs['dl_src']),
        #         packet_utils.mac_to_str(attrs['dl_dst']),
        #         packet_utils.ip_to_str(attrs['nw_src']), attrs['tp_src'],
        #         packet_utils.ip_to_str(attrs['nw_dst']), attrs['tp_dst']
        #         ))
        return CONTINUE
    def __flow_entry_build(self, src_ip, dst_ip, in_port, packet):
        """ Build OpenFlow entries """
        assert(src_ip  is not None)
        assert(dst_ip  is not None)
        assert(in_port is not None)
        assert(packet  is not None)
        try:
            attributes = extract_flow(packet)

            attributes[IN_PORT]  = in_port
            attributes[NW_SRC]   = src_ip
            attributes[NW_DST]   = dst_ip
            return attributes

        except Exception:
            raise
Пример #7
0
    def matchFlowTable(self, pkt, inport):
        pkt_attrs = of_util.extract_flow(pkt)
        pkt_attrs[core.IN_PORT] = inport
        self.communicationObjectUsed(self, "flowTable_read", pkt_attrs)
        matching_entries = []
        for entry in self.flow_table:
            if self.packetIsMatching(pkt, inport, entry.attrs):
                self.log.debug("*FTE: " + str(entry))
                matching_entries.append(entry)
            else:
                self.log.debug("FTE: " + str(entry))

        if len(matching_entries) == 0: # no match
            return False
        elif len(matching_entries) > 1: # multiple matches, select on priority
            matching_entries.sort(key=lambda x: x.priority, reverse=True)
        entry = matching_entries[0]
        self.processActions(pkt, entry.actions, inport)
        return True
Пример #8
0
    def matchFlowTable(self, pkt, inport):
        pkt_attrs = of_util.extract_flow(pkt)
        pkt_attrs[core.IN_PORT] = inport
        self.communicationObjectUsed(self, "flowTable_read", pkt_attrs)
        matching_entries = []
        for entry in self.flow_table:
            if self.packetIsMatching(pkt, inport, entry.attrs):
                self.log.debug("*FTE: " + str(entry))
                matching_entries.append(entry)
            else:
                self.log.debug("FTE: " + str(entry))

        if len(matching_entries) == 0:  # no match
            return False
        elif len(matching_entries) > 1:  # multiple matches, select on priority
            matching_entries.sort(key=lambda x: x.priority, reverse=True)
        entry = matching_entries[0]
        self.processActions(pkt, entry.actions, inport)
        return True
Пример #9
0
    def handle_dns_response(self, dpid, inport, ofp_reason, total_frame_len, buffer_id, packet):
        eaddr = util.convert_to_eaddr(packet.dst)
        dnsh = packet.find('dns')

        if not self.permit_ether_addr(eaddr):
            print "Dropping DNS Response Packet - MAC Address not allowed"
            return STOP

        if not dnsh:
            print "\n\n +++ +++ Invalid DNS Response packet: ", dnsh
            print packet
            print dir(packet)
            print packet.__dict__
            print "\n\n"
            return CONTINUE

        print "DNS Response packet:", dnsh

        print "*******", dir(dnsh)
        print "*******", dnsh.__dict__

        for answer in dnsh.answers:
            if answer.qtype in dns.rrtype_to_str:
                domain = answer.name + ":" + dns.rrtype_to_str[answer.qtype]
            else:
                domain = answer.name + ":" + str(answer.qtype)

            if domain not in Homework.st['domains']:
                Homework.st['domains'][domain] = set([str(answer.rddata)])
            else:
                Homework.st['domains'][domain].add(str(answer.rddata))

        flow = util.extract_flow(packet)
        Homework.install_datapath_flow(
             dpid, flow, 3, 10,
             [[openflow.OFPAT_OUTPUT, [-1, openflow.OFPP_NORMAL]]],
             buffer_id, openflow.OFP_DEFAULT_PRIORITY, inport, dnsh.arr
             )

        return CONTINUE
Пример #10
0
    def packetIsMatching(self, pkt, inport, attrs):
        """Checks whether a packet is matching a specific table entry
        
           attrs is a dictionary of attributes to match, missing attributes
           are considered wildcarded
        """
        pkt_attrs = of_util.extract_flow(pkt)
        pkt_attrs[core.IN_PORT] = inport

        skip_nw_src = False
        for a in attrs:
            if a == "nw_src_n_wild":
                mask = int(0xffffffff << attrs[a]) # see openflow.h in NOX for this definition of mask
                if pkt_attrs[core.NW_SRC] & mask != attrs["nw_src"] & mask:
                    return False
                else:
                    skip_nw_src = True
            elif a == "nw_src" and skip_nw_src:
                continue
            elif attrs[a] != pkt_attrs[a]: # If this throws an exception, we have an usupported attribute
                return False
        return True
Пример #11
0
 def pkt_in_handler(self, dp_id, inport, ofp_reason, total_frame_len, buffer_id, packet):
     attrs = util.extract_flow(packet)
     print "Pakcet in received "+str(inport)+ " " +packet_utils.ip_to_str(attrs['nw_dst'])
     return CONTINUE