Example #1
0
    def build_nx_match(self,switch,inport,pred,table_id):
        ### BUILD NX MATCH
        match = nx.nx_match()
        if inport:
            if table_id == 0:
                match.of_in_port = inport
            else:
                """NXM_NX_REG2 is the per-packet metadata register where we store the current
                port value of the packet, including actions from previous tables' forwarding
                actions.
                """
                match.reg2 = inport

        if 'srcmac' in pred:
            match.of_eth_src = packetaddr.EthAddr(pred['srcmac'])
        if 'dstmac' in pred:
            match.of_eth_dst = packetaddr.EthAddr(pred['dstmac'])
        if 'vlan_id' in pred:
            assert 'vlan_pcp' in pred
            # Setting the 16-bit TCI: (from highest to least significant bits):
            # 3 bits vlan_pcp
            # 1 bit CFI forced to 1
            # 12 bits vlan_id
            # Ref: manpages.ubuntu.com/manpages/trusty/man8/ovs-ofctl.8.html
            vlan_16bit = ((int(pred['vlan_pcp']) << 13) |
                          0x1000 |
                          (int(pred['vlan_id'])))
            match.of_vlan_tci = vlan_16bit
        if 'ethtype' in pred:
            match.of_eth_type = pred['ethtype']
        if 'srcip' in pred:
            assert 'ethtype' in pred
            if pred['ethtype'] == IP_TYPE:
                match.of_ip_src = packetaddr.IPAddr(pred['srcip'])
            elif pred['ethtype'] == ARP_TYPE:
                match.arp_spa = packetaddr.IPAddr(pred['srcip'])
            else:
                raise RuntimeError("Unknown ethtype for srcip match!")
        if 'dstip' in pred:
            assert 'ethtype' in pred
            if pred['ethtype'] == IP_TYPE:
                match.of_ip_dst = packetaddr.IPAddr(pred['dstip'])
            elif pred['ethtype'] == ARP_TYPE:
                match.arp_tpa = packetaddr.IPAddr(pred['dstip'])
            else:
                raise RuntimeError("Unknown ethtype for dstip match!")
        if 'tos' in pred:
            match.of_ip_tos = pred['tos']
        if 'protocol' in pred:
            match.of_ip_proto = pred['protocol']
        if 'srcport' in pred:
            assert 'protocol' in pred
            match.append(nx.NXM_OF_TCP_SRC(pred['srcport']))
        if 'dstport' in pred:
            assert 'protocol' in pred
            match.append(nx.NXM_OF_TCP_DST(pred['dstport']))
        return match
    def ARP_Request_handler(self, packet, packet_in):
        ARP_Dst = self.route_table.get(str(packet.payload.protodst))

        if ARP_Dst[2] == 'H':
            packet.dst = adr.EthAddr(ARP_Dst[0])
            self.send_Packet(frame=packet, out_port=ARP_Dst[3])
        #host -> router
        elif ARP_Dst[2] == 'R':
            if str(packet.payload.protodst) == '10.0.1.1':
                arp_reply = pkt.arp()
                arp_reply.hwsrc = adr.EthAddr('00:00:00:00:11:05')
                arp_reply.hwdst = packet.payload.hwsrc
                arp_reply.opcode = pkt.arp.REPLY
                arp_reply.protosrc = packet.payload.protodst
                arp_reply.protodst = packet.payload.protosrc
                #make ARP packet -> Frame
                ether = pkt.ethernet()
                ether.type = pkt.ethernet.ARP_TYPE
                ether.dst = packet.src
                ether.src = packet.dst
                ether.payload = arp_reply
                #send Frame
                self.send_Packet(frame=ether, out_port=packet_in.in_port)

            elif str(packet.payload.protodst) == '10.0.2.1':
                arp_reply = pkt.arp()
                arp_reply.hwsrc = adr.EthAddr('00:00:00:00:11:06')
                arp_reply.hwdst = packet.payload.hwsrc
                arp_reply.opcode = pkt.arp.REPLY
                arp_reply.protosrc = packet.payload.protodst
                arp_reply.protodst = packet.payload.protosrc
                #make ARP packet -> Frame
                ether = pkt.ethernet()
                ether.type = pkt.ethernet.ARP_TYPE
                ether.dst = packet.src
                ether.src = packet.dst
                ether.payload = arp_reply
                #send Frame
                self.send_Packet(frame=ether, out_port=packet_in.in_port)

            elif str(packet.payload.protodst) == '10.0.3.1':
                arp_reply = pkt.arp()
                arp_reply.hwsrc = adr.EthAddr('00:00:00:00:11:07')
                arp_reply.hwdst = packet.payload.hwsrc
                arp_reply.opcode = pkt.arp.REPLY
                arp_reply.protosrc = packet.payload.protodst
                arp_reply.protodst = packet.payload.protosrc
                #make ARP packet -> Frame
                ether = pkt.ethernet()
                ether.type = pkt.ethernet.ARP_TYPE
                ether.dst = packet.src
                ether.src = packet.dst
                ether.payload = arp_reply
                #send Frame
                self.send_Packet(frame=ether, out_port=packet_in.in_port)
    def arp_send1(self, packet, packet_in):
        arpPacketProtocol = packet.payload
        if arpPacketProtocol.opcode == pkt.arp.REPLY:
            log.debug("ARP reply reveived")
            self.mac_to_port1[packet.src] = packet_in.in_port
            log.debug("Display the mac_to_port dictionary)(REPLY)")
            #log.debug(self.mac_to_port)
            self.act_like_switch1(packet, packet_in)

        elif arpPacketProtocol.opcode == pkt.arp.REQUEST:
            if str(arpPacketProtocol.protodst) == "10.0.1.1":
                # ARP reply
                arpResponse = pkt.arp()
                arpResponse.hwsrc = adr.EthAddr("10:10:10:10:10:10")
                arpResponse.hwdst = arpPacketProtocol.hwsrc
                arpResponse.opcode = pkt.arp.REPLY
                arpResponse.protosrc = arpPacketProtocol.protodst
                arpResponse.protodst = arpPacketProtocol.protosrc

                #add header to the arp packet, usign the ethernet frame
                arpFrame = pkt.ethernet()
                arpFrame.type = pkt.ethernet.ARP_TYPE
                arpFrame.dst = packet.src
                arpFrame.src = adr.EthAddr("10:10:10:10:10:10")
                arpFrame.payload = arpResponse

                #send the packet
                msg = of.ofp_packet_out()
                msg.data = arpFrame.pack()

                action = of.ofp_action_output(port=packet_in.in_port)
                msg.actions.append(action)
                self.connection.send(msg)

                #add the mac address to the port table##
                self.mac_to_port1[packet.src] = packet_in.in_port
                log.debug("Display the mac_to_port dictionary(REQUEST)")
                log.debug(self.mac_to_port1)

            else:
                find_ip = 0
                for ip in self.network1.keys():
                    if ip == str(arpPacketProtocol.protodst):
                        find_ip = ip
                if find_ip == 0:
                    log.debug(
                        "ARP: The dst ip is not in the network, we can't find it's mac address"
                    )
                else:
                    self.act_like_switch1(packet, packet_in)

        else:
            pass
Example #4
0
def _handle_arp(event):
    eth_pkt = event.parsed
    arp_pkt = event.parsed.payload
    org_mac = eth_pkt.src.toStr()
    pmac_src = adrs.EthAddr(actual_pmac[org_mac]) 
    #gratituos arp is when the src and dst ip in arp are same. check it and update tables in case of new host. or else return
    if arp_pkt.opcode == arp_pkt.REQUEST:
        dst_ip = arp_pkt.protodst.toStr()
        #print 'ARP request : ip:{0}'.format(dst_ip)
        if dst_ip in arp_table:
            #we know the mapping. respond back to inp port OFPP_IN_PORT.
            arp_reply = pkt.arp()
            arp_reply.hwsrc = adrs.EthAddr(arp_table[dst_ip])
            arp_reply.hwdst = eth_pkt.src
            arp_reply.opcode = pkt.arp.REPLY
            arp_reply.protosrc = arp_pkt.protodst
            arp_reply.protodst = arp_pkt.protosrc
            ether = pkt.ethernet()
            ether.type = pkt.ethernet.ARP_TYPE
            ether.dst = eth_pkt.src
            ether.src = arp_reply.hwsrc
            ether.payload = arp_reply
            msg = of.ofp_packet_out()
            #msg.in_port = event.port
            #msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))
            msg.actions.append(of.ofp_action_output(port = event.port))
            msg.data = ether.pack()
            event.connection.send(msg)
        else:
            #bcast with src changed to sources pmac. also if its this switch, put inport as the it came from, so that it wont go to it
            #print 'Broadcasting since we dont have ARP mapping'
            arp_pkt.hwsrc = pmac_src
            eth_pkt.src = pmac_src
            #edge bcast:
            msg = of.ofp_packet_out()
            for i in range(half_num_pods + 1, num_pods + 1):#pkt out to host ports
                msg.actions.append(of.ofp_action_output(port = i))
            msg.data = eth_pkt.pack()
            other_switches = edge_switches - set([event.dpid])
            for es in other_switches:
                core.openflow.connections[es].send(msg) 
            msg.actions.pop(event.port - half_num_pods - 1)
            event.connection.send(msg)  

    elif arp_pkt.opcode == arp_pkt.REPLY:
        #print 'ARP reply : src ip:{0}, dst ip:{1}'.format(arp_pkt.protosrc.toStr(), arp_pkt.protodst.toStr())
        arp_pkt.hwdst = adrs.EthAddr(pmac_actual[arp_pkt.hwdst.toStr()])
        arp_pkt.hwsrc = pmac_src
        eth_pkt.src = pmac_src
        msg = of.ofp_packet_out()
        msg.actions.append(of.ofp_action_output(port = of.OFPP_TABLE))
        msg.data = eth_pkt.pack()
        core.openflow.connections[cs[0]].send(msg)
 def ICMP_Reply_handler(self, packet, packet_in):
     #log.debug("----------ICMP reply----------")
     ip_packet = packet.payload
     ipDstAdd = self.route_table.get(str(ip_packet.dstip))
     if ipDstAdd != None:
         packet.src = packet.dst
         packet.dst = adr.EthAddr(ipDstAdd[0])
         self.send_Packet(frame=packet, out_port=ipDstAdd[1])
Example #6
0
    def packet_forward(self, event):
        '''
        Manually mangle a packet and forward it to its destination.
        Kick off an ARP request and enqueue the packet if the
        destination HW address is not known yet.

        Returns true if the packet will be output on this port.
        '''

        eth_fwd = event.parsed
        ip_fwd = eth_fwd.payload
        addr_dst = ip_fwd.dstip

        if not self.match_ip(ip_fwd.dstip):
            return False

        if addr_dst in self.neigh_by_ip:
            # The HW address of the peer is known:
            #  Perform the forwarding

            eth_fwd.src = self.my_mac
            eth_fwd.dst = self.neigh_by_ip[addr_dst]

            self._packet_send(eth_fwd)

        else:
            # The HW address of the peer is not known:
            #  Kick of an ARP request and store the packet in
            #  a queue to be processed when the address is known.

            arp_out = Arp(hwsrc=self.my_mac,
                          hwdst=addresses.EthAddr("ff:ff:ff:ff:ff:ff"),
                          opcode=Arp.REQUEST,
                          protosrc=self.my_ip,
                          protodst=ip_fwd.dstip)

            eth_out = Ethernet(dst=addresses.EthAddr("ff:ff:ff:ff:ff:ff"),
                               src=self.my_mac,
                               type=Ethernet.ARP_TYPE,
                               next=arp_out)

            self._packet_send(eth_out)
            self.packet_queue.append(event)

        return True
Example #7
0
def _handle_new_host(org_mac, ip, dpid, port):
    con = core.openflow.connections[dpid]
    pmac = _assign_pmac(dpid, port - 1, org_mac)
    #i guess nothing more to do here. in multi table, the switch would have sent here and replied to the host.
    msg = nx.nx_flow_mod(table_id = 0)
    msg.priority = 5000
    msg.match.NXM_OF_IN_PORT = port
    msg.match.eth_src = org_mac
    msg.actions.append(of.ofp_action_dl_addr.set_src(adrs.EthAddr(pmac)))
    msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
    con.send(msg)
    msg = nx.nx_flow_mod(table_id = 1)
    msg.priority = 5000
    msg.match.eth_dst = pmac
    msg.actions.append(of.ofp_action_dl_addr.set_dst(adrs.EthAddr(org_mac)))
    msg.actions.append(of.ofp_action_output(port = port))
    con.send(msg)
    return pmac
Example #8
0
	def send_packet_broadcast(self, port_num, packet, dpid):
		message = of.ofp_packet_out()
		action = of.ofp_action_output(port = port_num)
		packet.src = adr.EthAddr('EF:EF:EF:EF:EF:EF')
		packet.dst = ETHER_BROADCAST
		message.data = packet.pack()
		message.actions.append(action)
		self.connection.send(message)
		log.debug("IPv4: sent")
Example #9
0
 def convert(h, val):
     if h in ['srcmac', 'dstmac']:
         return packetaddr.EthAddr(val)
     elif h in ['srcip', 'dstip']:
         return packetaddr.IPAddr(val)
     elif h in ['vlan_id', 'vlan_pcp'] and val == 'None':
         return None
     else:
         return val
Example #10
0
	def  generate_arp_response(self, a, packet_in,dpid):
		r = pkt.arp(hwtype = a.hwtype, prototype = a.prototype, hwlen = a.hwlen, protolen = a.protolen, opcode = pkt.arp.REPLY, hwdst = a.hwsrc, protodst = a.protosrc, protosrc = a.protodst, hwsrc = adr.EthAddr('EF:EF:EF:EF:EF:EF'))
		e = ethernet(type = pkt.ethernet.ARP_TYPE, src = adr.EthAddr('EF:EF:EF:EF:EF:EF'), dst=a.hwsrc, payload = r)
		msg = of.ofp_packet_out()
		msg.data = e.pack()
		msg.actions.append(of.ofp_action_output(port = packet_in.in_port))
		log.debug(" answering for arp from %s: MAC for %s is %s", str(a.protosrc), str(r.protosrc), str(r.hwsrc))
		self.connection.send(msg)
		log.debug('ARP Reply Sent...')
Example #11
0
    def generate_arp_response(self, a, packet_in):
        r = pkt.arp(hwtype=a.hwtype,
                    prototype=a.prototype,
                    hwlen=a.hwlen,
                    protolen=a.protolen,
                    opcode=pkt.arp.REPLY,
                    hwdst=a.hwsrc,
                    protodst=a.protosrc,
                    protosrc=a.protodst,
                    hwsrc=adr.EthAddr('EF:EF:EF:EF:EF:EF'))

        e = ethernet(type=pkt.ethernet.ARP_TYPE,
                     src=adr.EthAddr('EF:EF:EF:EF:EF:EF'),
                     dst=a.hwsrc)
        e.payload = r
        msg = of.ofp_packet_out()
        msg.data = e.pack()
        action = of.ofp_action_output(port=packet_in.in_port)
        msg.actions.append(action)
        self.connection.send(msg)
        log.debug('ARP Reply Sent...')
Example #12
0
 def IP_handler(self, packet, packet_in):
     ip_packet = packet.payload
     ipDstAdd = self.route_table.get(str(ip_packet.dstip))
     if ipDstAdd != None:
         msg = of.ofp_flow_mod()
         msg.match.in_port = packet_in.in_port
         msg.match = of.ofp_match.from_packet(packet)
         msg.actions.append(
             of.ofp_action_dl_addr.set_dst(adr.EthAddr(ipDstAdd[0])))
         msg.actions.append(of.ofp_action_dl_addr.set_src(packet.dst))
         msg.actions.append(of.ofp_action_output(port=ipDstAdd[1]))
         self.connection.send(msg)
Example #13
0
	def send_packet(self, packet, dpid):
		port_num = self.routing_table[dpid][str(packet.payload.dstip)][3]

		message = of.ofp_packet_out()
		action = of.ofp_action_output(port = port_num)

		packet.src = adr.EthAddr('EF:EF:EF:EF:EF:EF')
		packet.dst = self.arpTable[packet.payload.dstip]
		message.data = packet.pack()
		message.actions.append(action)
		self.connection.send(message)
		log.debug("IPv4: sent")
Example #14
0
    def arp_request1(self, packet, packet_in):
        arp_packet = packet.payload
        if arp_packet.opcode == pkt.arp.REQUEST:
            if str(arp_packet.protodst) == "10.0.1.1":  # network1
                # packet: arp packet
                arp_reply = pkt.arp()
                arp_reply.hwsrc = adr.EthAddr("11:11:11:11:11:11")
                arp_reply.hwdst = arp_packet.hwsrc
                arp_reply.opcode = pkt.arp.REPLY
                arp_reply.protosrc = arp_packet.protodst
                arp_reply.protodst = arp_packet.protosrc
                # ethernet packet
                eth_packet = pkt.ethernet()
                eth_packet.type = pkt.ethernet.ARP_TYPE
                eth_packet.dst = packet.src
                eth_packet.src = adr.EthAddr("11:11:11:11:11:11")
                eth_packet.payload = arp_reply

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

                action = of.ofp_action_output(port=packet_in.in_port)
                msg.actions.append(action)
                self.connection.send(msg)

                self.mac_to_port1[packet.src] = packet_in.in_port
                log.debug(self.mac_to_port1)

            else:
                find_ip = 0
                for ip in self.routing_table1.keys():
                    if ip == str(arp_packet.protodst):
                        find_ip = ip
                if find_ip != 0:
                    self.switch1(packet, packet_in)

        elif arp_packet.opcode == pkt.arp.REPLY:
            log.debug("Received arp REPLY")
            self.mac_to_port1[packet.src] = packet_in.in_port
            self.switch1(packet, packet_in)
    def arp_send(self, packet, packet_in):
        arpPacketProtocol = packet.payload

        # ARP reply
        if arpPacketProtocol.opcode == pkt.arp.REQUEST:
            arpResponse = pkt.arp()
            arpResponse.hwsrc = adr.EthAddr("10:10:10:10:10:10")
            arpResponse.hwdst = arpPacketProtocol.hwsrc
            arpResponse.opcode = pkt.arp.REPLY
            arpResponse.protosrc = arpPacketProtocol.protodst
            arpResponse.protodst = arpPacketProtocol.protosrc

            #add header to the arp packet, sign the ethernet frame
            arpFrame = pkt.ethernet()
            arpFrame.type = pkt.ethernet.ARP_TYPE
            arpFrame.dst = packet.src
            arpFrame.src = adr.EthAddr("10:10:10:10:10:10")
            arpFrame.payload = arpResponse

            #send the packet
            msg = of.ofp_packet_out()
            msg.data = arpFrame.pack()

            action = of.ofp_action_output(port=packet_in.in_port)
            msg.actions.append(action)
            self.connection.send(msg)

            #add the mac address to the port table#
            self.mac_to_port[packet.src] = packet_in.in_port
            log.debug("Display the mac_to_port dictionary(REQUEST)")
            log.debug(self.mac_to_port)

        elif arpPacketProtocol.opcode == pkt.arp.REPLY:
            log.debug("ARP reply reveived")
            self.mac_to_port[packet.src] = packet_in.in_port
            log.debug("Display the mac_to_port dictionary(REPLY)")
            log.debug(self.mac_to_port)
        else:
            log.debug("Other arp")
Example #16
0
    def send_arp_request(self, port_num, packet, packet_in):

        arp_data = arp(hwlen=6,
                       hwdst=ETHER_BROADCAST,
                       protodst=packet.payload.dstip,
                       hwsrc=adr.EthAddr('EF:EF:EF:EF:EF:EF'),
                       protosrc=packet.next.srcip)
        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")
Example #17
0
    def __init__(self, backplane, my_ip, my_netmask, my_mac, my_ofport):
        self.backbone = backplane
        self.my_ip = addresses.IPAddr(my_ip)
        self.my_netmask = addresses.IPAddr(my_netmask)
        self.my_mac = addresses.EthAddr(my_mac)
        self.my_ofport = my_ofport

        # A list of packets that could not yet be delivered
        # due to ARP resolution being in progress.
        self.packet_queue = list()

        # IP->MAC mappings learned using ARP
        self.neigh_by_ip = dict()
Example #18
0
    def send_ipv4(self, network, packet):
        dst_port = self.routing_table[network][3]
        dst_mac = adr.EthAddr('EF:EF:EF:EF:EF:EF')

        message = of.ofp_packet_out()
        packet.dst = dst_mac
        packet.src = adr.EthAddr('EF:EF:EF:EF:EF:EF')

        message.data = packet.pack()
        message.actions.append(of.ofp_action_output(port=dst_port))
        self.connection.send(message)
        log.debug("IPv4: sent")

        message = of.ofp_flow_mod()
        message.match.nw_dst = packet.payload.dstip
        message.match.dl_type = 0x800
        message.actions.append(
            of.ofp_action_dl_addr.set_src(adr.EthAddr('EF:EF:EF:EF:EF:EF')))
        message.actions.append(of.ofp_action_dl_addr.set_dst(dst_mac))
        message.actions.append(of.ofp_action_output(port=dst_port))
        log.debug("Flow Mode install  Successfully")
        self.connection.send(message)
Example #19
0
    def ICMP_Reply_handler(self, packet, packet_in):
        ip_packet = packet.payload
        ipSrcAdd = self.route_table.get(str(ip_packet.srcip))
        ipDstAdd = self.route_table.get(str(ip_packet.dstip))

        if ipDstAdd != None:
            if str(packet.dst) == '00:00:00:00:00:11':
                if ipDstAdd[1] == '10.0.1.0/24':
                    ether_pack = pkt.ethernet()
                    ether_pack.type = pkt.ethernet.IP_TYPE
                    ether_pack.src = packet.dst
                    ether_pack.dst = adr.EthAddr(ipDstAdd[0])
                    ether_pack.payload = packet.payload
                    self.send_Packet(frame=ether_pack, out_port=ipDstAdd[3])

                elif ipDstAdd[1] == '10.0.2.0/24':
                    ether_pack = pkt.ethernet()
                    ether_pack.type = pkt.ethernet.IP_TYPE
                    ether_pack.src = packet.dst
                    ether_pack.dst = adr.EthAddr('00:00:00:00:00:22')
                    ether_pack.payload = packet.payload
                    self.send_Packet(frame=ether_pack, out_port=3)
            elif str(packet.dst) == '00:00:00:00:00:22':
                if ipDstAdd[1] == '10.0.2.0/24':
                    ether_pack = pkt.ethernet()
                    ether_pack.type = pkt.ethernet.IP_TYPE
                    ether_pack.src = packet.dst
                    ether_pack.dst = adr.EthAddr(ipDstAdd[0])
                    ether_pack.payload = packet.payload
                    self.send_Packet(frame=ether_pack, out_port=ipDstAdd[3])
                elif ipDstAdd[1] == '10.0.1.0/24':
                    ether_pack = pkt.ethernet()
                    ether_pack.type = pkt.ethernet.IP_TYPE
                    ether_pack.src = packet.dst
                    ether_pack.dst = adr.EthAddr('00:00:00:00:00:11')
                    ether_pack.payload = packet.payload
                    self.send_Packet(frame=ether_pack, out_port=1)
            else:
                self.send_Packet(frame=packet, out_port=ipDstAdd[3])
Example #20
0
  def ipv4pkt_send1(self, packet, packet_in):

      log.debug("ipv4 function pkt send src ip %r dst ip %r"%(packet.payload.srcip,packet.payload.dstip))
      dstip_pkt = packet.payload.dstip
      srcip_pkt = packet.payload.srcip
      if str(dstip_pkt) in self.network1:
          if str(srcip_pkt) in self.network1:
             
              msg = of.ofp_flow_mod()

              msg.match.dl_type = pkt.ethernet.IP_TYPE
              msg.match.dl_src = packet.src
              msg.match.dl_dst = packet.dst  
              msg.match.nw_src = packet.payload.srcip
              msg.match.nw_dst = packet.payload.dstip
              msg.match.in_port = packet_in.in_port

              msg.data = packet_in
              msg.actions.append(of.ofp_action_output(port = self.network1[str(dstip_pkt)][0]))
              self.connection.send(msg)


          elif str(srcip_pkt) in self.network2:
              
              packet.src = packet.dst
              packet.dst = EthAddr(self.network1[str(dstPktIP)][1])
              msg = of.ofp_packet_out()
              msg.data = packet.pack()

              action = of.ofp_action_output(port = self.network1[str(dstPktIP)][0])
              msg.actions.append(action)
              self.connection.send(msg)
              
          else:
              pass          
      elif str(dstip_pkt) in self.network2:
          log.debug("forward the packet from %r to %r"%(packet.payload.srcip, packet.payload.dstip))
          
          packet.src = packet.dst
          packet.dst = adr.EthAddr("20:20:20:20:20:20")

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

          action = of.ofp_action_output(port = 3)
          msg.actions.append(action)
          self.connection.send(msg)
          
      else:
          pass
Example #21
0
 def ARP_Request_handler(self, packet, packet_in):
     #make ARP reply
     arp_reply = pkt.arp()
     arp_reply.hwsrc = adr.EthAddr('00:00:00:00:00:10')
     arp_reply.hwdst = packet.payload.hwsrc
     arp_reply.opcode = pkt.arp.REPLY
     arp_reply.protosrc = packet.payload.protodst
     arp_reply.protodst = packet.payload.protosrc
     #make ARP packet -> Frame
     ether = pkt.ethernet()
     ether.type = pkt.ethernet.ARP_TYPE
     ether.dst = packet.src
     ether.src = packet.dst
     ether.payload = arp_reply
     #send Frame
     self.send_Packet(frame=ether, out_port=packet_in.in_port)
Example #22
0
 def handleThreat():
     log.info("Packet received from %s" % packet.src)
     f = open('block.list', 'rb')
     s1 = f.read()
     log.info(s1)
     macList = s1.split(',')
     log.info(str(macList))
     if s1 != "":
         for m in macList:
             log.info("m = %s" % m)
             match = of.ofp_match()
             match.dl_src = addr.EthAddr(m)
             msg = of.ofp_flow_mod(command=of.OFPFC_ADD,
                                   actions=[],
                                   match=match)
             self.connection.send(msg)
Example #23
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)
Example #24
0
    def generate_flow(self, packet, network):
        message = of.ofp_packet_out(data=packet.pack())
        message.actions.append(
            of.ofp_action_output(port=self.routing_table[network][3]))
        self.connection.send(message)
        log.debug("ICMP: sent")

        message = of.ofp_flow_mod()
        message.match.nw_dst = packet.payload.dstip
        message.match.dl_type = 0x800

        message.actions.append(
            of.ofp_action_dl_addr.set_src(adr.EthAddr('EF:EF:EF:EF:EF:EF')))
        message.actions.append(
            of.ofp_action_dl_addr.set_dst(self.arpTable[packet.payload.dstip]))
        message.actions.append(
            of.ofp_action_output(port=self.routing_table[network][3]))
        log.debug("Flow Mode install  Successfully")
        self.connection.send(message)
Example #25
0
def _handle_migration(event):
    eth_pkt = event.parsed
    arp_pkt = event.parsed.payload
    org_mac = eth_pkt.src.toStr()
    dst_ip = arp_pkt.protodst.toStr()
    #old_pmac = arp_table[dst_ip]
    old_pmac = actual_pmac[org_mac]
    sw, port = pmac_pos(old_pmac)
    if (sw != event.dpid) or (port+1 != event.port):
        '''
        this host has migrated.
        assign new pmac.
        add trans in new switch.
        remove prev trans tabbles from old switch.
        add entry in old switch to frwrd to some agg switch replacing old pmac with new pmac
        update our internal tables
        change the assigned mac string - not assign the old pmac for the timeout period of time
        '''
        new_pmac = _handle_new_host(org_mac, dst_ip, event.dpid, event.port)
        msg = nx.nx_flow_mod(table_id = 0, command=of.OFPFC_DELETE)
        msg.priority = 5000
        msg.match.eth_src = org_mac
        event.connection.send(msg)
        msg = nx.nx_flow_mod(table_id = 1, command=of.OFPFC_DELETE)
        msg.priority = 5000
        msg.match.eth_dst = old_pmac
        event.connection.send(msg)
        
        msg = nx.nx_flow_mod(table_id = 0)
        msg.priority = 8000
        msg.hard_timeout = arp_timeout
        msg.match.eth_dst = old_pmac
        msg.actions.append(of.ofp_action_dl_addr.set_dst(adrs.EthAddr(new_pmac)))
        msg.actions.append(of.ofp_action_output(port = switch_pos(event.dpid)[1] + 1 ))#simple hashing. edge switch x sends to agg switch x
        event.connection.send(msg)
        
        arp_table[dst_ip] = new_pmac
        actual_pmac.pop(pmac_actual[old_pmac])
        pmac_actual.pop(old_pmac)
        #this nxt 2 lines should be in a fn called after the timeout. we dont want to assing old pmac to anyone until then
        vmid = int(s[-5:].replace(':',''),16)
        assigned_pmac[event.dpid][event.port] = assigned_pmac[event.dpid][event.port][:vmid] + '0' + assigned_pmac[event.dpid][event.port][vmid + 1:]
Example #26
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
    def act_like_router(self, packet, packet_in):
        # handle ARP type packet
        table_num = self.get_table_num(packet)
        if packet.type == pkt.ethernet.ARP_TYPE:
            if packet.payload.opcode == pkt.arp.REQUEST:
                log.debug("ARP request received")
                # create a ARP type packet
                arp_reply = pkt.arp()
                if table_num == 1:
                    arp_reply.hwsrc = adr.EthAddr("10:00:00:00:00:00")
                elif table_num == 2:
                    arp_reply.hwsrc = adr.EthAddr("20:00:00:00:00:00")

                log.debug("ARP received from %s" % packet.payload.hwsrc)
                arp_reply.hwdst = packet.payload.hwsrc
                arp_reply.opcode = pkt.arp.REPLY
                arp_reply.protosrc = packet.payload.protodst
                arp_reply.protodst = packet.payload.protosrc
                # create a ETHERNET type packet
                # wrap ARP as the payload of the ETHERNET packet
                eth_p = self.create_Ether_packet(pkt.ethernet.ARP_TYPE,
                                                 packet.dst, packet.src,
                                                 arp_reply)
                # Send the ETHERNET packet
                self.send_EtherNet_packet(eth_p, packet_in.in_port)
                log.debug("ARP reply sent")

            elif packet.payload.opcode == pkt.arp.REPLY:
                log.debug("It's a reply!")
                self.mac_to_port[packet.src] = packet_in.in_port
            else:
                log.debug("Some other ARP opcode")

        # Handle IP type packet
        elif packet.type == pkt.ethernet.IP_TYPE:
            # Parse IP_packet information
            ip_packet = packet.payload
            src_ip = ip_packet.srcip
            dst_ip = ip_packet.dstip
            subnet = self.find_subnet(dst_ip, table_num)
            # Handle ICMP type packet
            if ip_packet.protocol == pkt.ipv4.ICMP_PROTOCOL:
                icmp_packet = ip_packet.payload
                if icmp_packet.type == pkt.TYPE_ECHO_REQUEST:
                    log.debug("ICMP request received + table_num = %d" %
                              table_num)
                    log.debug("\t\t subnet = %s" % subnet)
                    # When subnet is found in the routing table
                    if subnet != None:
                        log.debug("ICMP reply sent")
                        log.debug("network containing host: " + subnet)
                        ech = pkt.echo()
                        ech.seq = icmp_packet.payload.seq + 1
                        ech.id = icmp_packet.payload.id

                        ip_p = self.create_icmp_packet(src_ip, dst_ip,
                                                       pkt.TYPE_ECHO_REPLY,
                                                       ech)
                        eth_p = self.create_Ether_packet(
                            pkt.ethernet.IP_TYPE, packet.dst, packet.src, ip_p)
                        self.send_EtherNet_packet(eth_p, packet_in.in_port)
                    # Subnet is not fount, return an unreachable message
                    else:
                        log.debug("ICMP destination unreachable")
                        unr = pkt.unreach()
                        unr.payload = ip_packet

                        ip_p = self.create_icmp_packet(src_ip, dst_ip,
                                                       pkt.TYPE_DEST_UNREACH,
                                                       unr)
                        eth_p = self.create_Ether_packet(
                            pkt.ethernet.IP_TYPE, packet.dst, packet.src, ip_p)
                        self.send_EtherNet_packet(eth_p, packet_in.in_port)
            # Handle normal IP type packet
            else:
                if subnet != None:
                    packet.src = packet.dst
                    if table_num == 1:
                        packet.dst = adr.EthAddr(
                            self.routing_table1[subnet][4])
                        self.send_EtherNet_packet(
                            packet, self.routing_table1[subnet][3])
                    elif table_num == 2:
                        packet.dst = adr.EthAddr(
                            self.routing_table2[subnet][4])
                        self.send_EtherNet_packet(
                            packet, self.routing_table2[subnet][3])
Example #28
0
    def act_like_router(self, frame, packet_in):
        if frame.type == 0x0806:
            packet = frame.payload
            network = 0
            if packet.opcode == 1 and packet.protodst in self.routerip:  # arp request and ip dst in routing table
                arp_data = 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)

            elif (packet.opcode == 2):
                self.arp_cache[packet.protosrc] = packet.hwsrc
                to_send = self.store.payload

                for nw in self.routing_table:
                    nw1 = self.routing_table[nw]
                    if str(to_send.dstip) in nw1:
                        network = nw
                        break

                message = of.ofp_packet_out()

                action = of.ofp_action_output(
                    port=self.routing_table[network][3])

                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[network][3]))
                log.debug("Flow Mode install  Successfully")
                self.connection.send(message)
                self.store = None
        elif frame.type == 0x0800:
            network = 0
            for nw in self.routing_table.keys():
                nw1 = self.routing_table[nw]
                if str(frame.payload.dstip) in nw1:
                    network = nw
                    break
            packet = frame.payload

            if network == 0:
                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)

            elif packet.protocol == 1:
                data_icmp = packet.payload
                if data_icmp.type == 8 and packet.dstip in self.routerip:
                    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 not in self.arp_cache:
                    self.store = frame
                    arp_type = arp(
                        hwlen=6,
                        hwdst=ETHER_BROADCAST,
                        protodst=packet.dstip,
                        hwsrc=addresses.EthAddr('FA:DE:DD:ED:AF:AA'),
                        protosrc=packet.srcip)
                    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[network][3]))
                    message.in_port = packet_in.in_port
                    self.connection.send(message)
                elif packet.dstip in self.arp_cache:
                    message = of.ofp_packet_out()

                    action = of.ofp_action_output(
                        port=self.routing_table[network][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)
Example #29
0
    def act_like_router(self, packet, packet_in):
        #handle arp
        if packet.type == pkt.ethernet.ARP_TYPE:
            if packet.payload.opcode == pkt.arp.REQUEST:
                log.debug("ARP request received")
                arp_reply = pkt.arp()
                arp_reply.hwsrc = adr.EthAddr("40:10:40:10:40:10")  #fake MAC
                arp_reply.hwdst = packet.payload.hwsrc
                arp_reply.opcode = pkt.arp.REPLY
                arp_reply.protosrc = packet.payload.protodst
                arp_reply.protodst = packet.payload.protosrc
                ether = pkt.ethernet()
                ether.type = pkt.ethernet.ARP_TYPE
                ether.dst = packet.src
                ether.src = packet.dst
                ether.payload = arp_reply

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

                # Add an action to send to the specified port
                action = of.ofp_action_output(port=packet_in.in_port)
                msg.actions.append(action)
                #msg.in_port = event.port

                # Send message to switch
                self.connection.send(msg)
                log.debug("ARP reply sent")
            elif packet.payload.opcode == pkt.arp.REPLY:
                log.debug("It's a reply!")
                self.mac_to_port[packet.src] = packet_in.in_port
            else:
                log.debug("Some other ARP opcode")

        elif packet.type == pkt.ethernet.IP_TYPE:
            ip_packet = packet.payload
            if ip_packet.protocol == pkt.ipv4.ICMP_PROTOCOL:
                icmp_packet = ip_packet.payload
                if icmp_packet.type == pkt.TYPE_ECHO_REQUEST:
                    log.debug("ICMP request received")
                    src_ip = ip_packet.srcip
                    dst_ip = ip_packet.dstip
                    k = 0
                    for key in self.routing_table.keys():
                        if dst_ip.inNetwork(key):
                            k = key
                            break
                    if k != 0:
                        log.debug("ICMP reply sent")
                        log.debug("network containing host: " + k)
                        ech = pkt.echo()
                        ech.seq = icmp_packet.payload.seq + 1
                        ech.id = icmp_packet.payload.id

                        icmp_reply = pkt.icmp()
                        icmp_reply.type = pkt.TYPE_ECHO_REPLY
                        icmp_reply.payload = ech

                        ip_p = pkt.ipv4()
                        ip_p.srcip = dst_ip
                        ip_p.dstip = src_ip
                        ip_p.protocol = pkt.ipv4.ICMP_PROTOCOL
                        ip_p.payload = icmp_reply

                        eth_p = pkt.ethernet()
                        eth_p.type = pkt.ethernet.IP_TYPE
                        eth_p.dst = packet.src
                        eth_p.src = packet.dst
                        eth_p.payload = ip_p

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

                        # Add an action to send to the specified port
                        action = of.ofp_action_output(port=packet_in.in_port)
                        #fl2.actions.append(action)
                        msg.actions.append(action)
                        #msg.in_port = event.port

                        # Send message to switch
                        self.connection.send(msg)
                    else:
                        log.debug("ICMP destination unreachable")
                        unr = pkt.unreach()
                        unr.payload = ip_packet

                        icmp_reply = pkt.icmp()
                        icmp_reply.type = pkt.TYPE_DEST_UNREACH
                        icmp_reply.payload = unr

                        ip_p = pkt.ipv4()
                        ip_p.srcip = dst_ip
                        ip_p.dstip = src_ip
                        ip_p.protocol = pkt.ipv4.ICMP_PROTOCOL
                        ip_p.payload = icmp_reply

                        eth_p = pkt.ethernet()
                        eth_p.type = pkt.ethernet.IP_TYPE
                        eth_p.dst = packet.src
                        eth_p.src = packet.dst
                        eth_p.payload = ip_p

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

                        # Add an action to send to the specified port
                        action = of.ofp_action_output(port=packet_in.in_port)
                        #fl2.actions.append(action)
                        msg.actions.append(action)
                        #msg.in_port = event.port

                        # Send message to switch
                        self.connection.send(msg)
            else:
                src_ip = ip_packet.srcip
                dst_ip = ip_packet.dstip

                k = 0
                for key in self.routing_table.keys():
                    if dst_ip.inNetwork(key):
                        k = key
                        break
                if k != 0:
                    port1 = self.routing_table[k][3]
                    dsteth = adr.EthAddr(self.routing_table[k][4])

                    msg = of.ofp_packet_out()

                    action = of.ofp_action_output(port=port1)

                    packet.src = packet.dst
                    packet.dst = dsteth
                    msg.data = packet.pack()
                    msg.actions.append(action)
                    self.connection.send(msg)
            self.FlowMode(packet_in, packet_in.in_port)
Example #30
0
    def act_like_router(self, packet, packet_in):
        #handle arp

        if packet.type == pkt.ethernet.IP_TYPE:
            ip_packet = packet.payload
            if ip_packet.protocol == pkt.ipv4.UDP_PROTOCOL:
                udp_packet = ip_packet.payload
                if udp_packet.dstport == 520:
                    rip_packet = udp_packet.payload
                    self.port_to_mac[packet_in.in_port] = packet.src
                    # log.debug("got rip packet form port: %s", packet_in.in_port)
                    for entry in rip_packet.entries:
                        key = entry.ip.toStr() + '/' + str(entry.network_bits)
                        if key in self.routing_table.keys():
                            if self.routing_table[key][-1] - 1 > entry.metric:
                                self.routing_table[key][0] = packet_in.in_port
                                self.routing_table[key][-1] = entry.metric + 1
                                self.routing_table[key][1] = basic_ttl
                        else:
                            self.routing_table[key] = [packet_in.in_port, basic_ttl,\
                                                                                entry.metric+1]
                    return
        if packet.type == pkt.ethernet.ARP_TYPE:
            dst_ip = packet.payload.protodst.toStr()
            if packet.payload.opcode == pkt.arp.REQUEST \
                and dst_ip.split(".")[3] == "1":
                log.debug("ARP request received")
                log.debug("%s, port: %d", dst_ip, packet_in.in_port)
                # self.ip_to_port[dst_ip] = packet_in.in_port
                # self.routing_table[packet_in.in_port].append([ \
                #                                     packet.payload.protosrc.toStr(),\
                #                                     packet.payload.hwsrc.toStr()])
                # log.debug("%s", packet.payload.protodst.toStr().split(".")[3])
                self.routing_table[ip_to_subnet[packet.payload.protosrc.toStr()][0]] = \
                              [packet_in.in_port, forever_ttl, 0]
                self.port_to_mac[packet_in.in_port] = packet.src
                print(self.port_to_mac)
                arp_reply = pkt.arp()
                arp_reply.hwsrc = adr.EthAddr(
                    self.port_to_hwaddr[packet_in.in_port])
                arp_reply.hwdst = packet.payload.hwsrc
                arp_reply.opcode = pkt.arp.REPLY
                arp_reply.protosrc = packet.payload.protodst
                arp_reply.protodst = packet.payload.protosrc
                ether = pkt.ethernet()
                ether.type = pkt.ethernet.ARP_TYPE
                ether.dst = packet.src
                ether.src = packet.dst
                ether.payload = arp_reply

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

                # Add an action to send to the specified port
                action = of.ofp_action_output(port=packet_in.in_port)
                msg.actions.append(action)
                #msg.in_port = event.port

                # Send message to switch
                self.connection.send(msg)
                print(self.routing_table)
                print(self.ip_to_port)
                print(self.port_to_hwaddr)
                log.debug("ARP reply sent")
            elif packet.payload.opcode == pkt.arp.REPLY:
                log.debug("It's a reply!")
                self.port_to_mac[packet_in.in_port] = packet.src
            else:
                log.debug("Some other ARP opcode")

        # elif packet.type == pkt.ethernet.IP_TYPE:
        #   ip_packet = packet.payload
        #     if ip_packet.protocol == pkt.ipv4.ICMP_PROTOCOL:
        #         icmp_packet = ip_packet.payload
        #         if icmp_packet.type == pkt.TYPE_ECHO_REQUEST:
        #             log.debug("ICMP request received")
        #             src_ip = ip_packet.srcip
        #             dst_ip = ip_packet.dstip
        #             k = 0
        #             log.debug(self.routing_table.keys())
        #             for key in self.routing_table.keys():
        #                 if dst_ip.inNetwork(key):
        #                     k = key
        #                     break
        #             if k!=0:
        #                 log.debug("ICMP reply sent")
        #                 log.debug("network containing host: "+k)
        #                 ech = pkt.echo()
        #                 ech.seq = icmp_packet.payload.seq + 1
        #                 ech.id = icmp_packet.payload.id

        #                 icmp_reply = pkt.icmp()
        #                 icmp_reply.type = pkt.TYPE_ECHO_REPLY
        #                 icmp_reply.payload = ech

        #                 ip_p = pkt.ipv4()
        #                 ip_p.srcip = dst_ip
        #                 ip_p.dstip = src_ip
        #                 ip_p.protocol = pkt.ipv4.ICMP_PROTOCOL
        #                 ip_p.payload = icmp_reply

        #                 eth_p = pkt.ethernet()
        #                 eth_p.type = pkt.ethernet.IP_TYPE
        #                 eth_p.dst = packet.src
        #                 eth_p.src = packet.dst
        #                 eth_p.payload = ip_p

        #                 msg = of.ofp_packet_out()
        #                 msg.data = eth_p.pack()

        #                 # Add an action to send to the specified port
        #                 action = of.ofp_action_output(port = packet_in.in_port)
        #                 #fl2.actions.append(action)
        #                 msg.actions.append(action)
        #                 #msg.in_port = event.port

        #                 # Send message to switch
        #                 self.connection.send(msg)
        #             else:
        #                 log.debug("ICMP destination unreachable")
        #                 unr = pkt.unreach()
        #                 unr.payload = ip_packet

        #                 icmp_reply = pkt.icmp()
        #                 icmp_reply.type = pkt.TYPE_DEST_UNREACH
        #                 icmp_reply.payload = unr

        #                 ip_p = pkt.ipv4()
        #                 ip_p.srcip = dst_ip
        #                 ip_p.dstip = src_ip
        #                 ip_p.protocol = pkt.ipv4.ICMP_PROTOCOL
        #                 ip_p.payload = icmp_reply

        #                 eth_p = pkt.ethernet()
        #                 eth_p.type = pkt.ethernet.IP_TYPE
        #                 eth_p.dst = packet.src
        #                 eth_p.src = packet.dst
        #                 eth_p.payload = ip_p

        #                 msg = of.ofp_packet_out()
        #                 msg.data = eth_p.pack()

        #                 # Add an action to send to the specified port
        #                 action = of.ofp_action_output(port = packet_in.in_port)
        #                 #fl2.actions.append(action)
        #                 msg.actions.append(action)
        #                 #msg.in_port = event.port

        #                 # Send message to switch
        #                 self.connection.send(msg)
        # if ip_packet.protocol == pkt.ipv4.UDP_PROTOCOL:
        #   udp_packet = ip_packet.payload
        #   if udp_packet.dstport == 520:
        #     rip_packet = udp_packet.payload
        #     # log.debug("got rip packet form port: %s", packet_in.in_port)
        #     for entry in rip_packet.entries:
        #       key = entry.ip.toStr()+'/'+str(entry.network_bits)
        #       if key in self.routing_table.keys():
        #         if self.routing_table[key][-1]-1 > entry.metric:
        #           self.routing_table[key][0] = packet_in.in_port
        #           self.routing_table[key][-1] = entry.metric+1
        #           self.routing_table[key][1] = basic_ttl
        #       else:
        #         self.routing_table[key] = [packet_in.in_port, basic_ttl,\
        #                                                             entry.metric+1]

        else:
            src_ip = ip_packet.srcip
            dst_ip = ip_packet.dstip

            k = 0
            for key in self.routing_table.keys():
                if dst_ip.inNetwork(key):
                    k = key
                    break
            if k != 0:
                out_port = self.routing_table[k][0]
                print(out_port)
                print(k)
                print(self.routing_table)
                print(packet.dst)
                print(self.port_to_mac)
                print(self.port_to_mac[out_port])
                print(dst_ip)
                # packet.dst = adr.EthAddr(self.port_to_mac[out_port])
                # print(packet.dst)
                # msg = of.ofp_packet_out()
                match = of.ofp_match.from_packet(packet)
                action = of.ofp_action_output(port=out_port)
                msg = of.ofp_flow_mod()
                msg.match = match
                msg.match.in_port = packet_in.in_port
                # msg.out_port = out_port

                msg.idle_timeout = FLOW_IDLE_TIMEOUT
                msg.hard_timeout = FLOW_HARD_TIMEOUT
                # packet.src = packet.dst
                # packet.dst = dsteth
                # msg.data = packet.pack()
                msg.actions.append(
                    of.ofp_action_dl_addr.set_dst(
                        adr.EthAddr(self.port_to_mac[out_port])))
                msg.actions.append(action)
                self.connection.send(msg)
                # self.FlowMode( packet_in, packet_in.in_port)
            else:
                log.debug("ICMP destination unreachable")
                unr = pkt.unreach()
                unr.payload = ip_packet

                icmp_reply = pkt.icmp()
                icmp_reply.type = pkt.TYPE_DEST_UNREACH
                icmp_reply.payload = unr

                ip_p = pkt.ipv4()
                ip_p.srcip = dst_ip
                ip_p.dstip = src_ip
                ip_p.protocol = pkt.ipv4.ICMP_PROTOCOL
                ip_p.payload = icmp_reply

                eth_p = pkt.ethernet()
                eth_p.type = pkt.ethernet.IP_TYPE
                eth_p.dst = packet.src
                eth_p.src = packet.dst
                eth_p.payload = ip_p

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

                # Add an action to send to the specified port
                action = of.ofp_action_output(port=packet_in.in_port)
                #fl2.actions.append(action)
                msg.actions.append(action)
                #msg.in_port = event.port

                # Send message to switch
                self.connection.send(msg)