Пример #1
0
 def convert(h,val):
     if h in ['srcmac','dstmac']:
         return packetaddr.EthAddr(val)
     elif h in ['srcip','dstip']:
         try:
             return packetaddr.IPAddr(val)
         except:
             return val
     elif h in ['vlan_id','vlan_pcp'] and val == 'None':
         return None
     else:
         return val
Пример #2
0
    def broadcast_routing_table(self):
        rip_msg = pkt.rip()
        rip_msg.version = 2
        rip_msg.command = pkt.RIP_RESPONSE
        for entry in self.routing_table:
            rip_entry = pkt.RIPEntry()
            rip_entry.ip = adr.IPAddr(entry.split("/")[0])
            rip_entry.netmask = int(entry.split("/")[1])
            rip_entry.metric = self.routing_table[entry][-1]
            rip_msg.entries.append(rip_entry)
            if entry[1] != forever_ttl:
                --self.routing_table[entry][1]
                if self.routing_table[entry][1] == 0:
                    del self.routing_table[entry]

        udp = pkt.udp()
        udp.srcport = 520
        udp.dstport = 520
        # log.debug( "Created rip msg of len: %d", len(rip_msg) )
        udp.len = len(rip_msg)
        udp.payload = rip_msg

        ipv4 = pkt.ipv4()
        ipv4.protocol = pkt.ipv4.UDP_PROTOCOL
        ipv4.srcip = pkt.IP_ANY
        ipv4.dstip = pkt.rip.RIP2_ADDRESS
        ipv4.payload = udp

        ether = pkt.ethernet()
        ether.type = pkt.ethernet.IP_TYPE
        ether.dst = adr.EthAddr('ff:ff:ff:ff:ff:ff')
        ether.payload = ipv4
        for port in self.port_to_hwaddr.keys()[0:-1]:
            ether.src = self.port_to_hwaddr[port]

            # log.debug( "Broadcasting routing table" )

            msg = of.ofp_packet_out()
            msg.data = ether.pack()

            # Add an action to send to the specified port
            action = of.ofp_action_output(port=port)
            msg.actions.append(action)
            self.connection.send(msg)
Пример #3
0
    def addNode(self, ip, mac, port=None):
        """
        Construct a new Node from the given argument, keep it in self.nodes,
        and perform active OVS port discovery. If there is already a node with
        the same IP and MAC, no new node will be created
        """
        ipaddr = libaddr.IPAddr(ip)
        macaddr = libaddr.EthAddr(mac)

        node = self.nodes.get(ipaddr, None)
        if node and node.mac == macaddr:
            return node

        newNode = Node(ipaddr, macaddr, port=port)
        self.nodes[ipaddr] = newNode
        self.sendArpRequest(newNode)

        log.debug('New Node object created with IP %s' % ipaddr)

        return newNode
Пример #4
0
    def __init__(self, conn, ipaddr=None):
        self.conn = conn

        # Reserved IP address for the SDN controller.
        if ipaddr:
            self._ip = libaddr.IPAddr(ipaddr)
        else:
            self._ip = IP_ANY  # we can update this later
        self._macAddress = _randomMacAddress()

        # relevant network nodes connected to this OVS
        self.nodes = {}

        # available service chains reachable by the OVS
        self.availableChains = {}

        # full SFC path between 2 endpoints. Each path is identified by an ordered
        # pair of the endpoints. Service chains can be reused by different pairs.
        # This table will be filled after active discovery by the SDN controller
        self.servicePaths = {}
Пример #5
0
    f = logging.Formatter(logging.BASIC_FORMAT)
    h.setFormatter(f)
    l.addHandler(h)


addRemoteLogger(fw_log, 9999)
addRemoteLogger(logging.getLogger(), 9998)

MAX_CONNECTIONS = 7000

PRIORITY_NORMAL = 10  #of.OFP_DEFAULT_PRIORITY
PRIORITY_ALL_TCP = PRIORITY_NORMAL - 1
PRIORITY_FLOOD_REST = PRIORITY_ALL_TCP - 1

LOCAL_NETWORK = addresses.parseCIDR("10.1.1.0/24")
INTERNAL_ADDRESS = addresses.IPAddr("10.1.1.1")

MAX_BUFFERED_PACKETS = 15000
MAX_BUFFERED_PER_CONNECTION = 500
current_buffered_packets = 0

UNKNOWN_PORT = object()

INSIDE_PORT = ["uap0", "eth0"]
OUTSIDE_PORT = "veth1"
INTERNAL_PORT = "veth1"


class ACTION_FORWARD:
    pass
Пример #6
0
	def send_arp_request(self, port_num, packet, packet_in, dpid):
		arp_data = arp(hwdst = ETHER_BROADCAST, hwlen = 6, protodst = packet.payload.dstip, hwsrc = adr.EthAddr('EF:EF:EF:EF:EF:EF'), protosrc = adr.IPAddr(self.routing_table[dpid][str(packet.payload.dstip)][2]))
		arp_data.hwtype = arp_data.HW_TYPE_ETHERNET
		arp_data.prototype = arp_data.PROTO_TYPE_IP
		arp_data.protolen = arp_data.protolen
		arp_data.opcode = arp_data.REQUEST
		e = ethernet(type=ethernet.ARP_TYPE, src=adr.EthAddr('EF:EF:EF:EF:EF:EF'), dst=ETHER_BROADCAST)
		e.set_payload(arp_data)
		message = of.ofp_packet_out()
		message.data = e.pack()
		message.actions.append(of.ofp_action_output(port = port_num))
		message.in_port = packet_in.in_port
		self.connection.send(message)

		log.debug("ARP: request sent")
Пример #7
0
 def setIP(self, ipstring):
     """
     Set an IP address for the SDN controller between this connection
     """
     ipaddr = libaddr.IPAddr(ipstring)
     self._ip = ipaddr
Пример #8
0
    def act_like_router(self, frame, packet_in, dpid):
        if frame.type == 0x0806:  # ARP type
            packet = frame.payload
            network = 0
            # arp request and in /30 subnet
            if packet.opcode == 1 and str(packet.protodst) in self.exterior:
                arp_data = pocket.arp(
                    hwtype=packet.hwtype,
                    prototype=packet.prototype,
                    hwlen=packet.hwlen,
                    protolen=packet.protolen,
                    opcode=2,
                    hwdst=packet.hwsrc,
                    protodst=packet.protosrc,
                    protosrc=packet.protodst,
                    hwsrc=addresses.EthAddr('FA:DE:DD:ED:AF:AA'))
                e_frame = ethernet(type=0x0806,
                                   src=addresses.EthAddr('FA:DE:DD:ED:AF:AA'),
                                   dst=packet.hwsrc)
                e_frame.payload = arp_data
                out_packet = of.ofp_packet_out()
                out_packet.data = e_frame.pack()
                action = of.ofp_action_output(port=packet_in.in_port)
                out_packet.actions.append(action)
                self.connection.send(out_packet)
                log.debug("arp...")
            # arp reply and in /30 subnet
            elif (packet.opcode == 2) and str(
                    packet.protodst) in self.exterior:
                self.arp_cache[packet.protosrc] = packet.hwsrc
                to_send = self.store.payload
                """
			for nw in self.routing_table[dpid]:
				nw1 = self.routing_table[dpid][nw]
				if str(to_send.dstip) in nw1:
	
					network = nw
					break
			"""
                message = of.ofp_packet_out()
                my_port = self.routing_table[dpid][str(to_send.dstip)][3]

                action = of.ofp_action_output(port=my_port)

                self.store.src = addresses.EthAddr('FA:DE:DD:ED:AF:AA')
                self.store.dst = self.arp_cache[to_send.dstip]
                message.data = self.store.pack()
                message.actions.append(action)
                self.connection.send(message)
                log.debug("ICMP: sent from router to host")
                """
			message = of.ofp_flow_mod()
			message.match.nw_dst = to_send.dstip
			message.match.dl_type = 0x0800
				
			message.actions.append(of.ofp_action_dl_addr.set_src(self.store.src))
			message.actions.append(of.ofp_action_dl_addr.set_dst(self.store.dst))
			message.actions.append(of.ofp_action_output(port = self.routing_table[dpid][network][3]))
			log.debug("Flow Mode install  Successfully")
			self.connection.send(message) 
			"""
                self.store = None
            elif packet.protodst in self.interior:
                """
                msg = of.ofp_packet_out()
                msg.data = frame.pack()
                my_port =  self.routing_table[dpid][str(packet.protodst)][3]
                action = of.ofp_action_output(port = my_port)
                msg.actions.append(action)
                self.connection.send(msg)
                """
                msg = of.ofp_flow_mod()
                msg.match = of.ofp_match.from_packet(frame)
                msg.data = packet_in
                action = of.ofp_action_output(
                    port=self.routing_table[dpid][str(packet.protodst)][3])
                msg.actions.append(action)
                self.connection.send(msg)
        elif frame.type == 0x0800:  # IP type
            """
            network = 0
            for nw in self.interior:
                     nw1 = nw
                     if str(frame.payload.dstip) in nw1:
                             network = nw
                             break
            """
            packet = frame.payload

            if str(packet.dstip) not in self.interior:  # dst unreachable
                log.debug("dst %s is unreachable" % (frame.payload.dstip))
                unreachable_type = pocket.unreach()
                unreachable_type.payload = frame.payload
                icmp_type = pocket.icmp()
                icmp_type.type = 3
                icmp_type.payload = unreachable_type
                ip_type = pocket.ipv4(srcip=frame.payload.dstip,
                                      dstip=frame.payload.srcip,
                                      protocol=1,
                                      payload=icmp_type)
                ethernet_type = pocket.ethernet(type=0x0800,
                                                src=frame.dst,
                                                dst=frame.src,
                                                payload=ip_type)
                message = of.ofp_packet_out()
                message.data = ethernet_type.pack()
                message.actions.append(
                    of.ofp_action_output(port=packet_in.in_port))
                self.connection.send(message)

            # if ICMP type
            elif packet.protocol == 1 and packet.payload.type == 8 and str(
                    packet.dstip) == self.exterior[dpid - 1]:
                data_icmp = packet.payload
                # if data_icmp.type == 8 and str(packet.dstip) in self.exterior: #if echo_request and dstip is in exterior
                echo_type = pocket.echo(seq=data_icmp.payload.seq + 1,
                                        id=data_icmp.payload.id)
                icmp_type = pocket.icmp(type=0, payload=echo_type)
                ip_type = pocket.ipv4(srcip=packet.dstip,
                                      dstip=packet.srcip,
                                      protocol=1,
                                      payload=icmp_type)
                ethernet_type = pocket.ethernet(type=0x0800,
                                                src=frame.dst,
                                                dst=frame.src,
                                                payload=ip_type)
                message = of.ofp_packet_out()
                message.data = ethernet_type.pack()
                message.actions.append(
                    of.ofp_action_output(port=packet_in.in_port))
                self.connection.send(message)
            elif packet.dstip in self.dirconnex[dpid]:
                port_num = self.routing_table[dpid][str(packet.dstip)][3]

                if packet.dstip not in self.arp_cache:  # mapping of dstip not present
                    self.store = frame
                    arp_type = arp(
                        hwlen=6,
                        hwdst=ETHER_BROADCAST,
                        protodst=packet.dstip,
                        hwsrc=addresses.EthAddr('FA:DE:DD:ED:AF:AA'),
                        protosrc=addresses.IPAddr(self.routing_table[dpid][str(
                            packet.dstip)][2]))
                    arp_type.opcode = 1
                    ethernet_type = ethernet(
                        type=0x0806,
                        src=addresses.EthAddr('FA:DE:DD:ED:AF:AA'),
                        dst=ETHER_BROADCAST)
                    ethernet_type.set_payload(arp_type)
                    message = of.ofp_packet_out()
                    message.data = ethernet_type.pack()
                    message.actions.append(
                        of.ofp_action_output(port=self.routing_table[dpid][str(
                            packet.dstip)][3]))
                    message.in_port = packet_in.in_port
                    self.connection.send(message)
                elif packet.dstip in self.arp_cache:  # mapping present in arp cache
                    message = of.ofp_packet_out()

                    action = of.ofp_action_output(
                        port=self.routing_table[dpid][str(packet.dstip)][3])

                    frame.src = addresses.EthAddr('FA:DE:DD:ED:AF:AA')
                    frame.dst = self.arp_cache[packet.dstip]
                    message.data = frame.pack()
                    message.actions.append(action)
                    self.connection.send(message)
                    """
				message = of.ofp_flow_mod()
				message.match.nw_dst = packet.dstip
				message.match.dl_type = 0x0800
					
				message.actions.append(of.ofp_action_dl_addr.set_src(frame.src))
				message.actions.append(of.ofp_action_dl_addr.set_dst(frame.dst))
				message.actions.append(of.ofp_action_output(port = self.routing_table[network][3]))
				self.connection.send(message)
				"""
            else:  # route to the next hop
                log.debug("the packet proceeds to the next hop")
                port_to_send = self.routing_table[dpid][str(packet.dstip)][3]
                next_ip = self.routing_table[dpid][str(packet.dstip)][0]
                msg = of.ofp_packet_out()
                action = of.ofp_action_output(port=port_to_send)
                frame.dst = ETHER_BROADCAST
                frame.src = addresses.EthAddr('FA:DE:DD:ED:AF:AA')
                msg.data = frame.pack()
                msg.actions.append(action)
                self.connection.send(msg)
                log.debug("IPv4 has been sent")
Пример #9
0
    def _handle_PacketIn(self, event):
        dpid = event.connection.dpid
        inport = event.port
        packet = event.parsed
        flag = 1
        packet_in = event.ofp
        self.connection = event.connection
        if not packet.parsed:
            log.warning("Router %i, input port = %i: ignoring unparsed packet",
                        dpid, inport)
            return

        icmp_packet = packet.find('icmp')
        if icmp_packet is not None:
            if icmp_packet.type == pkt.TYPE_ECHO_REQUEST:
                log.debug("Received ICMP request message")
                found = 0  #To check if destination is reachable by ping
                for node in self.node_list:
                    if packet.payload.dstip.inNetwork(
                            node):  #If the destination IP is in the network
                        found = node
                        break
                if found == 0:
                    log.debug("Destination Unreachable")
                    icmp_reply = pkt.icmp()
                    icmp_reply.type = pkt.TYPE_DEST_UNREACH
                    icmp_reply.code = pkt.ICMP.CODE_UNREACH_HOST
                    icmp_reply_payload = packet.find('ipv4').pack()
                    icmp_reply_payload = icmp_reply_payload[:packet.find('ipv4'
                                                                         ).hl *
                                                            4 + 8]
                    import struct
                    icmp_reply_payload = struct.pack("!HH", 0,
                                                     0) + icmp_reply_payload
                    icmp_reply.payload = icmp_reply_payload
                    #Making the IPv4 packet around it
                    icmp_reply_packet = pkt.ipv4()
                    icmp_reply_packet.protocol = icmp_reply_packet.ICMP_PROTOCOL
                    icmp_reply_packet.srcip = packet.find("ipv4").dstip
                    icmp_reply_packet.dstip = packet.find("ipv4").srcip
                    #Putting this packet in an ethernet frame
                    icmp_ethernet_frame = pkt.ethernet()
                    icmp_ethernet_frame.type = pkt.ethernet.IP_TYPE
                    icmp_ethernet_frame.dst = packet.src
                    icmp_ethernet_frame.src = packet.dst
                    #Encapsulating...
                    icmp_reply_packet.payload = icmp_reply
                    icmp_ethernet_frame.payload = icmp_reply_packet
                    #Sending the ping reply back through the port it came in at
                    msg = of.ofp_packet_out()
                    msg.data = icmp_ethernet_frame.pack()
                    msg.actions.append(
                        of.ofp_action_output(port=packet_in.in_port))
                    self.connection.send(msg)
                    log.debug("Sent 'Dest Unreachable' message")
                else:
                    if found == "10.0.1.1" or "10.0.2.1":
                        log.debug("Trying to reach router = %s" % found)
                        #Making the ping reply
                        icmp_reply = pkt.icmp()
                        icmp_reply.type = pkt.TYPE_ECHO_REPLY
                        icmp_reply.payload = icmp_packet.payload
                        #Making the IPv4 packet around it
                        icmp_reply_packet = pkt.ipv4()
                        icmp_reply_packet.protocol = icmp_reply_packet.ICMP_PROTOCOL
                        icmp_reply_packet.srcip = packet.find("ipv4").dstip
                        icmp_reply_packet.dstip = packet.find("ipv4").srcip
                        #Putting this packet in an ethernet frame
                        icmp_ethernet_frame = pkt.ethernet()
                        icmp_ethernet_frame.type = pkt.ethernet.IP_TYPE
                        icmp_ethernet_frame.dst = packet.src
                        icmp_ethernet_frame.src = packet.dst
                        #Encapsulating...
                        icmp_reply_packet.payload = icmp_reply
                        icmp_ethernet_frame.payload = icmp_reply_packet
                        #Sending the ping reply back through the port it came in at
                        msg = of.ofp_packet_out()
                        msg.data = icmp_ethernet_frame.pack()
                        msg.actions.append(
                            of.ofp_action_output(port=packet_in.in_port))
                        self.connection.send(msg)
                        log.debug("Sent ICMP reply")
                        flag = 0

        if dpid not in self.mac_table:
            # New switch -- create an empty table
            self.mac_table[dpid] = {}
            for subnet in self.subnets:
                self.mac_table[dpid][addr.IPAddr(subnet)] = Entry(
                    of.OFPP_NONE, dpid_to_mac(dpid))

        if isinstance(packet.next, pkt.ipv4):
            log.debug(
                "Router %i, input port = %i: Received an IP packet from %s to %s",
                dpid, inport, packet.next.srcip, packet.next.dstip)

            # Learn or update port/MAC info
            self.mac_table[dpid][packet.next.srcip] = Entry(inport, packet.src)

            # Try to forward
            dstaddr = packet.next.dstip
            if dstaddr in self.mac_table[dpid]:
                # We know where to send it
                prt = self.mac_table[dpid][dstaddr].port
                mac = self.mac_table[dpid][dstaddr].mac
                log.debug(
                    "Router %i:Forwarding the packet to dst_MAC address = %s through port = %i",
                    dpid, mac, prt)
                if flag == 1:
                    actions = []
                    actions.append(of.ofp_action_dl_addr.set_dst(mac))
                    actions.append(of.ofp_action_output(port=prt))
                    match = of.ofp_match.from_packet(packet, inport)
                    match.dl_src = None
                    msg = of.ofp_flow_mod(command=of.OFPFC_ADD,
                                          idle_timeout=FLOW_IDLE_TIMEOUT,
                                          hard_timeout=of.OFP_FLOW_PERMANENT,
                                          buffer_id=event.ofp.buffer_id,
                                          actions=actions,
                                          match=of.ofp_match.from_packet(
                                              packet, inport))
                    event.connection.send(msg.pack())
            elif self.arp_for_unknowns:
                r = arp()
                r.hwtype = r.HW_TYPE_ETHERNET
                r.prototype = r.PROTO_TYPE_IP
                r.hwlen = 6
                r.protolen = r.protolen
                r.opcode = r.REQUEST
                r.hwdst = ETHER_BROADCAST
                r.protodst = dstaddr
                r.hwsrc = packet.src
                r.protosrc = packet.next.srcip
                e = pkt.ethernet(type=pkt.ethernet.ARP_TYPE,
                                 src=packet.src,
                                 dst=ETHER_BROADCAST)
                e.set_payload(r)
                log.debug("Router %i: ARPing for %s on behalf of %s" %
                          (dpid, str(r.protodst), str(r.protosrc)))
                msg = of.ofp_packet_out()
                msg.data = e.pack()
                msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
                msg.in_port = inport
                event.connection.send(msg)

        elif isinstance(packet.next, arp):
            a = packet.next
            log.debug("Router %i, received an ARP packet at port = %i", dpid,
                      inport)

            if a.prototype == arp.PROTO_TYPE_IP:
                if a.hwtype == arp.HW_TYPE_ETHERNET:
                    if a.protosrc != 0:
                        #Update MAC table
                        self.mac_table[dpid][a.protosrc] = Entry(
                            inport, packet.src)
                        if a.opcode == arp.REQUEST:
                            if a.protodst in self.mac_table[dpid]:
                                #We know how to answer the ARP ourselves
                                r = arp()
                                r.hwtype = a.hwtype
                                r.prototype = a.prototype
                                r.hwlen = a.hwlen
                                r.protolen = a.protolen
                                r.opcode = arp.REPLY
                                r.hwdst = a.hwsrc
                                r.protodst = a.protosrc
                                r.protosrc = a.protodst
                                r.hwsrc = self.mac_table[dpid][a.protodst].mac
                                e = pkt.ethernet(type=packet.type,
                                                 src=dpid_to_mac(dpid),
                                                 dst=a.hwsrc)
                                e.set_payload(r)
                                log.debug(
                                    "Router %i, input port %i answering ARP for %s"
                                    % (dpid, inport, str(r.protosrc)))
                                msg = of.ofp_packet_out()
                                msg.data = e.pack()
                                msg.actions.append(
                                    of.ofp_action_output(port=of.OFPP_IN_PORT))
                                msg.in_port = inport
                                event.connection.send(msg)
                                return
                            else:
                                # Didn't know how to answer or otherwise handle this ARP, so just flood it
                                log.debug(
                                    "Flooding to all ports since we don't have the MAC address in mac_table"
                                )
                                msg = of.ofp_packet_out(
                                    in_port=inport,
                                    data=event.ofp,
                                    action=of.ofp_action_output(
                                        port=of.OFPP_FLOOD))
                                event.connection.send(msg)
Пример #10
0
def launch():
    subnets = "10.0.1.1 10.0.2.1"
    subnets = subnets.split()
    subnets = [addr.IPAddr(x) for x in subnets]
    arp_for_unknowns = len(subnets) > 0
    core.registerNew(router, subnets, arp_for_unknowns)
Пример #11
0
    def packet_handler (self, frame, packet_in):
        "process every packet\n"

        # disposal of different kinds of packet, including a default drop
        # generates prompt text for non-data packets and all invalid packets
        isHandled = False
        if frame.type == Packet.ethernet.ARP_TYPE:
            arpPkt = frame.payload
            if arpPkt.opcode == Packet.arp.REQUEST:
                # check if the arp request has a valid target
                arp_req = arpPkt
                srcIPStr = str(arp_req.protosrc)
                prefix = srcIPStr[0:srcIPStr.rfind(".")]
                expectedIPdest = prefix + ".1"
                if expectedIPdest == str(arp_req.protodst): # a valid arp req
                    log.info("a valid arp request is got")
                    arpReply = Packet.arp()
                    macInterface = Addr.EthAddr("00:00:00:00:00:" + prefix[-1]*2)
                    arpReply.hwsrc = macInterface
                    arpReply.hwdst = arp_req.hwsrc
                    arpReply.opcode = Packet.arp.REPLY
                    arpReply.protosrc = Addr.IPAddr(expectedIPdest)
                    arpReply.protodst = arp_req.protosrc
                    
                    ether = Packet.ethernet()
                    ether.type = Packet.ethernet.ARP_TYPE
                    ether.dst = frame.src
                    ether.src = macInterface
                    ether.payload = arpReply
                    
                    msg = of.ofp_packet_out()
                    msg.data = ether
                    action = of.ofp_action_output(port = packet_in.in_port)
                    msg.actions.append(action)
                    self.connection.send(msg)

                    isHandled = True
        elif frame.type == frame.IP_TYPE:
            datagram = frame.payload
            # if it's a valid icmp echo request, reply to it
            if datagram.protocol == datagram.ICMP_PROTOCOL:
                segment = datagram.payload
                if segment.type == Packet.TYPE_ECHO_REQUEST:
                    # check if the destination IP is correct
                    dstIPStr = str(datagram.dstip)
                    if dstIPStr in self.interface_IPs:
                        log.info("an icmp request to router interfaces is got")
                        # generate a reply and send it
                        icmpReply = Packet.icmp()
                        icmpReply.type = Packet.TYPE_ECHO_REPLY
                        icmpReply.payload = segment.payload

                        ipp = Packet.ipv4()
                        ipp.protocol = ipp.ICMP_PROTOCOL
                        ipp.srcip = datagram.dstip
                        ipp.dstip = datagram.srcip

                        e = Packet.ethernet()
                        e.src = frame.dst
                        e.dst = frame.src
                        e.type = e.IP_TYPE

                        ipp.payload = icmpReply
                        e.payload = ipp

                        msg = of.ofp_packet_out()
                        msg.data = e
                        msg.actions.append(
                            of.ofp_action_output(port = packet_in.in_port))
                        self.connection.send(msg)

                        isHandled = True

            # if it's a packet sent to one of the other two hosts
            dstIPStr = str(datagram.dstip)
            if dstIPStr in self.routing_table:
                log.info("a packet between hosts is got")

                tableEntry = self.routing_table[dstIPStr]
                # # # flow mod
                # msg = of.ofp_flow_mod(match = of.ofp_match.from_packet(frame))
                # msg.actions.append(
                #     of.ofp_action_dl_addr.set_src(Addr.EthAddr(tableEntry["intMAC"])))
                # msg.actions.append(
                #     of.ofp_action_dl_addr.set_dst(Addr.EthAddr(tableEntry["hostMAC"])))
                # msg.actions.append(of.ofp_action_output(port = tableEntry["port"]))
                # self.connection.send(msg)

                # log.info("a flow entry is installed")

                # modify data link src and dst
                frame.src = Addr.EthAddr(tableEntry["intMAC"])
                frame.dst = Addr.EthAddr(tableEntry["hostMAC"])

                # resend it out
                self.resend_packet(frame, tableEntry["port"])

                isHandled = True

        if not isHandled: # drop it
            log.info("an invalid frame is got")