Example #1
0
    def handle_unreachable(self, packet, packet_in):
        packet_unreachable = pkt.unreach()
        packet_unreachable.payload = packet.payload

        icmp_packet = pkt.icmp()
        icmp_packet.type = pkt.TYPE_DEST_UNREACH
        icmp_packet.payload = packet_unreachable

        ip_packet = pkt.ipv4()
        ip_packet.srcip = packet.payload.dstip
        ip_packet.dstip = packet.payload.srcip
        ip_packet.protocol = pkt.ipv4.ICMP_PROTOCOL
        ip_packet.payload = icmp_packet

        ether_packet = pkt.ethernet()
        ether_packet.type = pkt.ethernet.IP_TYPE
        ether_packet.dst = packet.src
        ether_packet.src = packet.dst
        ether_packet.payload = ip_packet

        msg = of.ofp_packet_out()
        msg.data = ether_packet.pack()
        action = of.ofp_action_output(port=packet_in.in_port)
        msg.actions.append(action)
        self.connection.send(msg)
    def unreachable_send(self, packet, packet_in):

        msgUnreachable = pkt.unreach()
        msgUnreachable.payload = packet.payload

        icmpReachable = pkt.icmp()
        icmpReachable.type = pkt.TYPE_DEST_UNREACH
        icmpReachable.payload = msgUnreachable

        #encapsulate reachable ICMP packet
        icmpPkt = pkt.ipv4()

        icmpPkt.srcip = packet.payload.dstip  #change the source ip to router's ip
        icmpPkt.dstip = packet.payload.srcip
        icmpPkt.protocol = pkt.ipv4.ICMP_PROTOCOL
        icmpPkt.payload = icmpReachable

        #encapsulate packet into frame
        icmpFrame = pkt.ethernet()
        icmpFrame.type = pkt.ethernet.IP_TYPE
        icmpFrame.dst = packet.src
        icmpFrame.src = packet.dst
        icmpFrame.payload = icmpPkt

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

        action = of.ofp_action_output(port=packet_in.in_port)
        msg.actions.append(action)
        self.connection.send(msg)
Example #3
0
 def makeICMP(self, errorType, codeType, ippkt):
     icmppkt = pktlib.icmp()
     icmppkt.type = errorType
     icmppkt.code = codeType
     icmppkt.payload = pktlib.unreach()
     
     icmppkt.payload.payload = ippkt.dump()[:28]
     return icmppkt
Example #4
0
	def destination_unreachable_icmp(self, packet, packet_in):        
		data = packet.payload
		log.debug("ICMP: destination unreachable")
		dst_unreach = pkt.unreach()
		dst_unreach.payload = data
		icmp_reply = pkt.icmp()
		icmp_reply.type = pkt.TYPE_DEST_UNREACH
		icmp_reply.payload = dst_unreach

		self.send_icmp_packet(icmp_reply, packet, packet_in)
Example #5
0
	def make_ICMP(self, TYPE, pkt, dev):
		icmppkt = pktlib.icmp()  
		if(TYPE=='PING'): #if ping type
			print 'ping reply'
			icmppkt.type = pktlib.TYPE_ECHO_REPLY
			ping = pktlib.echo()
			ping.id = pkt.payload.payload.id
			ping.seq = pkt.payload.payload.seq
			ping.payload = pkt.payload.payload.payload #It's like christmas, so much unwrapping
			icmppkt.payload = ping
		else: #if error message
			if(TYPE=='TIMEEXCEED'):
				print 'time exceed'
				icmppkt.type = pktlib.TYPE_TIME_EXCEED
			else:
				icmppkt.type = pktlib.TYPE_DEST_UNREACH
				if(TYPE=='UNREACH_NET'): #if table lookup failed
					print 'net unreach'
					icmppkt.code = pktlib.CODE_UNREACH_NET
				elif(TYPE=='UNREACH_HOST'): #if sent 5 arps and no reply from host
					print 'host unreach'
					icmppkt.code = pktlib.CODE_UNREACH_HOST
				elif(TYPE=='UNREACH_PORT'): #sent to us, but not an ICMP PING
					print 'port unreach'
					icmppkt.code = pktlib.CODE_UNREACH_PORT
				else:
					print 'wtf?  if it wasnt one of these errors, something REALLY went wrong'
			icmppkt.payload = pktlib.unreach()
			icmppkt.payload.payload = pkt.dump()[:28]
		
		#wrap up in IP then ethernet
		ipreply = pktlib.ipv4()
		ipreply.protocol = ipreply.ICMP_PROTOCOL
		ipreply.dstip = pkt.srcip
		ipreply.ttl = 65 #make this bigger, because it gets decremented when we send it
		ipreply.payload = icmppkt
		ipreply.srcip = self.net.interface_by_name(dev).ipaddr
		match = self.FT_lookup(ipreply, dev)
		intf = self.net.interface_by_name(match[3])
		prefix = match[1]
		nexthop = match[2]
		if nexthop not in self.macaddrs:
			self.queue.append([match, floor(time()), ipreply, 0])
			self.send_arp_request(match)
		else:
			self.send_packet(match, ipreply)   
		'''
Example #6
0
    def _send_icmp_reply(self, dpid, p, srcip, dstip, icmpType, event):
        pktIcmp = pkt.icmp()
        # TYPE_ECHO_REQUEST = 8, TYPE_DEST_UNREACH = 3, TYPE_ECHO_REPLY = 0
        if icmpType == pkt.TYPE_ECHO_REPLY:
            pktIcmp.payload = p.find('icmp').payload
        elif icmpType == pkt.TYPE_DEST_UNREACH:
            pktIcmp.type = pkt.TYPE_DEST_UNREACH
            unreachMsg = pkt.unreach()
            unreachMsg.payload = p.payload
            pktIcmp.payload = unreachMsg

        # Make IP header
        pktIp = ipv4()
        pktIp.protocol = pktIp.ICMP_PROTOCOL
        pktIp.srcip = dstip
        pktIp.dstip = srcip

        # Ethernet header
        eth = ethernet()
        eth.src = p.dst
        eth.dst = p.src
        eth.type = eth.IP_TYPE

        # Hook them up
        pktIp.payload = pktIcmp  # ICMP encapsulated in IP packet
        eth.payload = pktIp  # IP packet encapsulated in ethernet frame

        # Send it back to the input port
        msg = of.ofp_packet_out()
        msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT))
        msg.data = eth.pack()
        msg.in_port = self.routingTable[dpid][srcip]
        event.connection.send(msg)

        log.debug('DPID %d: IP %s pings %s, icmp reply with type %d', dpid,
                  str(srcip), str(dstip), icmpType)
        log.debug('(type 0: reply, type 3: unreach, type 8: request)')
    def unreachable_send(self, packet, packet_in):

        msgUnreachable = pkt.unreach()
        msgUnreachable.payload = packet.payload

        #encapsulate unreachable msg into icmp packet
        icmpReachable = pkt.icmp()
        icmpReachable.type = pkt.TYPE_DEST_UNREACH
        icmpReachable.payload = msgUnreachable

        #encapsulate icmp into ipv4 packet
        icmpPkt = pkt.ipv4()

        for netIP in self.routingTable.keys():
            if packet.payload.srcip.inNetwork(netIP):
                dstSubnet = netIP
        dstIP = self.routingTable[dstSubnet][2]

        #change the source ip to router's ip
        icmpPkt.srcip = IPAddr(dstIP)
        icmpPkt.dstip = packet.payload.srcip
        icmpPkt.protocol = pkt.ipv4.ICMP_PROTOCOL
        icmpPkt.payload = icmpReachable

        #encapsulate packet into ethernet frame
        icmpFrame = pkt.ethernet()
        icmpFrame.type = pkt.ethernet.IP_TYPE
        icmpFrame.dst = packet.src
        icmpFrame.src = packet.dst
        icmpFrame.payload = icmpPkt

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

        action = of.ofp_action_output(port=packet_in.in_port)
        msg.actions.append(action)
        self.connection.send(msg)
Example #8
0
  def _send_icmp_reply(self, dpid, p, srcip, dstip, icmpType, event):
    pktIcmp = pkt.icmp()
    # TYPE_ECHO_REQUEST = 8, TYPE_DEST_UNREACH = 3, TYPE_ECHO_REPLY = 0
    if icmpType == pkt.TYPE_ECHO_REPLY:
      pktIcmp.payload = p.find('icmp').payload
    elif icmpType == pkt.TYPE_DEST_UNREACH:
      pktIcmp.type = pkt.TYPE_DEST_UNREACH
      unreachMsg = pkt.unreach()
      unreachMsg.payload = p.payload
      pktIcmp.payload = unreachMsg
      
    # Make IP header
    pktIp = ipv4()
    pktIp.protocol = pktIp.ICMP_PROTOCOL
    pktIp.srcip = dstip  
    pktIp.dstip = srcip

    # Ethernet header
    eth = ethernet()
    eth.src = p.dst
    eth.dst = p.src
    eth.type = eth.IP_TYPE

    # Hook them up
    pktIp.payload = pktIcmp # ICMP encapsulated in IP packet
    eth.payload = pktIp # IP packet encapsulated in ethernet frame

    # Send it back to the input port
    msg = of.ofp_packet_out()
    msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))
    msg.data = eth.pack()
    msg.in_port = self.routingTable[dpid][srcip]
    event.connection.send(msg)

    log.debug('DPID %d: IP %s pings %s, icmp reply with type %d', dpid, str(srcip), str(dstip), icmpType)
    log.debug('(type 0: reply, type 3: unreach, type 8: request)')
Example #9
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 #10
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)
Example #11
0
 def act_like_switch (self, event, packet, packet_in):
   """
   Implement router-like behavior.
   """
   # handle ARP
   if packet.type == myPkt.ethernet.ARP_TYPE:
       # ref: pox/pox/proto/arp_helper.py && arp_responder.py && pong.py
       a = packet.payload
       if a.opcode == myPkt.arp.REQUEST:
           log.debug("port %s ARP request %s => %s", str(packet_in.in_port), str(a.protosrc), str(a.protodst))
           r = myPkt.arp()
           r.hwtype = a.hwtype
           r.prototype = a.prototype
           r.hwlen = a.hwlen
           r.protolen = a.protolen
           r.opcode = myPkt.arp.REPLY
           r.hwdst = a.hwsrc
           if str(a.protodst) == '10.0.1.1' or str(a.protodst) == '10.0.2.1' or str(a.protodst) == '10.0.3.1':
               r.hwsrc = myAddr.EthAddr("12:12:12:12:12:12")
           else:
               return
           r.protodst = a.protosrc
           r.protosrc = a.protodst
           e = myPkt.ethernet()
           e.type = myPkt.ethernet.ARP_TYPE
           e.dst = a.hwsrc
           e.src = r.hwsrc
           e.payload = r
           log.debug("Answer ARP for " + 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 = event.port
           event.connection.send(msg)
       elif packet.payload.opcode == myPkt.arp.REPLY:
           log.debug("port %s ARP reply %s => %s", str(packet_in.in_port), str(a.protosrc), str(a.hwsrc))
       else:
           log.debug("Router receive Other ARP packet")
 
   # handle ICMP
   elif packet.type == myPkt.ethernet.IP_TYPE:
       src_ip = packet.payload.srcip
       dst_ip = packet.payload.dstip
       if packet.payload.protocol == myPkt.ipv4.ICMP_PROTOCOL:
           #ref: pox/pox/proto/pong.py && pox/pox/lib/packet/icmp.py
           if self.arp_cache.get(dst_ip):
               #log.debug("packet.src = %s, packet.dst = %s", str(packet.src), str(packet.dst))
               icmp_reply = myPkt.icmp()
               icmp_reply.type = myPkt.TYPE_ECHO_REPLY
               icmp_reply.payload = packet.find("icmp").payload
               ip_pkt = myPkt.ipv4()
               ip_pkt.protocol = myPkt.ipv4.ICMP_PROTOCOL
               ip_pkt.srcip = packet.find("ipv4").dstip
               ip_pkt.dstip = packet.find("ipv4").srcip
               icmp_frame = myPkt.ethernet()
               icmp_frame.type = myPkt.ethernet.IP_TYPE
               icmp_frame.dst = packet.src
               icmp_frame.src = packet.dst
               ip_pkt.payload = icmp_reply
               icmp_frame.payload = ip_pkt
               msg = of.ofp_packet_out()
               msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))
               msg.data = icmp_frame.pack()
               msg.in_port = event.port
               event.connection.send(msg)
               log.debug("%s pinged %s", str(ip_pkt.dstip), str(ip_pkt.srcip))
           else:
               icmp_reply = myPkt.icmp()
               icmp_reply.type = myPkt.TYPE_DEST_UNREACH
               unreach_msg = myPkt.unreach()
               unreach_msg.payload = packet.payload
               icmp_reply.payload = unreach_msg
               ip_pkt = myPkt.ipv4()
               ip_pkt.protocol = myPkt.ipv4.ICMP_PROTOCOL
               ip_pkt.srcip = packet.find("ipv4").dstip
               ip_pkt.dstip = packet.find("ipv4").srcip
               icmp_frame = myPkt.ethernet()
               icmp_frame.type = myPkt.ethernet.IP_TYPE
               icmp_frame.dst = packet.src
               icmp_frame.src = packet.dst
               ip_pkt.payload = icmp_reply
               icmp_frame.payload = ip_pkt
               msg = of.ofp_packet_out()
               msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))
               msg.data = icmp_frame.pack()
               msg.in_port = event.port
               event.connection.send(msg)
               log.debug("%s pinged %s failed", str(ip_pkt.dstip), str(ip_pkt.srcip))
Example #12
0
 def destination_unreachable_icmp(self, packet, packet_in):
     log.debug("ICMP: destination unreachable")
     dst_unreach = pkt.unreach(payload=packet.payload)
     icmp_reply = pkt.icmp(type=pkt.TYPE_DEST_UNREACH, payload=dst_unreach)
     self.send_icmp_packet(icmp_reply, packet, packet_in)
Example #13
0
    def router_main(self):
        self.readfile()
        self.interfaces()
    
        firewallrules.import_rules()        

        while True:
            try:
                dev,ts,pkt = self.net.recv_packet(timeout=0.5)
            except SrpyNoPackets:
                #log_debug("Timeout waiting for packets")
                update_token_bucket()

                toDel = []
                icmpError = False
                for key in self.queue:                                                          #iterate packetObjects in the queue
                    packetObject = self.queue[key]
                    if (time.time() - packetObject.lastSend) > 1:   
                        if packetObject.retries != 0:                                           #if retries are 0
                            packetObject.retries -= 1                                           #decrement retries by
                            self.net.send_packet(packetObject.dev, packetObject.ARP_request)

                            packetObject.lastSend = time.time()
                        else:  
                            pkt = packetObject.pkt
                            ipreply = pktlib.ipv4()

                            interface = self.net.interface_by_name(dev)
                            devIP = interface.ipaddr
                            ipreply.srcip = devIP           
                            ipreply.dstip = pkt.payload.srcip               # send back to source of packet that had TTL of 1
                            ipreply.ttl = 65

                            #create ICMPpkt
                            icmppkt = pktlib.icmp()
                            icmppkt.type = pktlib.TYPE_DEST_UNREACH
                            icmppkt.code = pktlib.CODE_UNREACH_HOST
                            icmppkt.payload = pktlib.unreach()
                            icmppkt.payload.payload = pkt.dump()[:28]

                            #link the two
                            ipreply.protocol = ipreply.ICMP_PROTOCOL
                            ipreply.set_payload(icmppkt)
                            icmpError = True

                            #link the two
                            ipreply.protocol = ipreply.ICMP_PROTOCOL
                            ipreply.set_payload(icmppkt)

                            toDel.append(key)
                            
                if icmpError:
                    self.icmpError(ipreply, packetObject.pkt, packetObject.dev, self.net,packetObject.ip_header)
                for item in toDel:
                    #print "deleting item"
                    del self.queue[item]
                continue
            except SrpyShutdown:
                return
           
            #if ARP-packet (REQ or REPLY)------------------------------
            arp_header = pkt.find("arp")
            if arp_header != None:                                                  #checks if ARP-packet
                if arp_header.opcode == pktlib.arp.REQUEST:                         #checks if is an ARP request	
                    if addr_check():                                                  #fvalid address
                        packet = self.create_arp_reply(arp_header, pkt)             #creates reply
                        self.net.send_packet(dev,packet)                            #sends reply

                elif arp_header.opcode == pktlib.arp.REPLY:                         #checks if is an ARP reply
                    dstIP = arp_header.protodst
                    interface = self.net.interface_by_name(dev)
                    devIP = interface.ipaddr
                    devMAC = interface.ethaddr
                    srcMAC = arp_header.hwsrc
                    srcIP = arp_header.protosrc

                    if dstIP == devIP:                                              #is this ARP reply meant for me
                        dstMAC = srcMAC                                             #flip because you now want to send it back
                        srcMAC = devMAC
                        self.MACaddresses[srcIP] = dstMAC                           #add newly MAC address to mac dictionary
                        packetObject = self.queue[srcIP]                            #temporarily store packet ]
                        if packetObject.ICMP == False:                                #if the packet is an IPv4 packet
                            pkt = packetObject.pkt
                            packet = self.create_eth_header(pkt, dstMAC, srcMAC)        #add ethernet header to packet
                            packet.payload.dstip = ipreply.dstip
                            packet.payload.srcip = ipreply.srcip
                            self.net.send_packet(dev,packet)
                        elif packetObject.ICMP == True:                             #if packet is a ICMP packet
                            packet = self.create_eth_header(packetObject.ip_header, dstMAC, srcMAC)        #add ethernet header to packet
                            packet.payload = packetObject.ip_header
                            self.net.send_packet(dev,packet)
                        del self.queue[srcIP]                                       #delte packeet from queue                 

                else:
                    print "Error."                                                  #drop packet since not valid ARP-packet

            else:
                x = firewallrules.allow(pkt)
                if x== True:
                    #if IPv4 packet----------------------------------
                    ip_header = pkt.find("ipv4")
                    icmpError = False
                    if ip_header != None:                                                   #if IPv4packet! 
                        if ip_header.ttl == 1:                                               #AF: if TTL value is 0
                            #create IP reply
                            ipreply = pktlib.ipv4()
                            interface = self.net.interface_by_name(dev)
                            devIP = interface.ipaddr 
                            ipreply.srcip = devIP           
                            ipreply.dstip = pkt.payload.srcip 
                            ipreply.ttl = 64

                            #create ICMPpkt
                            icmppkt = pktlib.icmp()
                            icmppkt.type = pktlib.TYPE_TIME_EXCEED
                            icmppkt.payload = pktlib.unreach()
                            icmppkt.payload.payload = pkt.dump()[:28]

                            #link the two
                            ipreply.protocol = ipreply.ICMP_PROTOCOL
                            ipreply.payload = icmppkt
                            icmpError = True
                            
                        ip_header.ttl -= 1
                        dstIP = ip_header.dstip                                             #destination IP addr of IPheader
                        srcIP = ip_header.srcip
                        interface = self.net.interface_by_name(dev)
                        devIP = interface.ipaddr 

                        #packet sent to me-------------------------------------  
                        sentToMe = False
                        for intf in self.net.interfaces():
                            if dstIP == intf.ipaddr:
                                sentToMe = True 
                        if sentToMe:                                                      #if packet is for me
                            icmp_header = pkt.find("icmp")
                            if icmp_header != None:                                 #need this to check if ping...not just ICMP
                                oldPing = icmp_header.payload
                                #creat ICMP reply to send out
                                icmppkt = pktlib.icmp()                                                #create ICMP header
                                icmppkt.type = pktlib.TYPE_ECHO_REPLY
                                ping = pktlib.echo()
                                ping.id = oldPing.id 
                                ping.seq = oldPing.seq 
                                ping.payload = oldPing.payload
                                icmppkt.payload = ping
                                #create IP header
                                ipreply = pktlib.ipv4()
                                ipreply.srcip = devIP
                                ipreply.dstip = srcIP
                                ipreply.ttl = 64
                                ipreply.payload = icmppkt
                                ipreply.protocol = 1  
                                self.icmpError(ipreply, pkt, dev, self.net, ip_header)
                            else:
                                ipreply = pktlib.ipv4()
                                interface = self.net.interface_by_name(dev)
                                devIP = interface.ipaddr
                                ipreply.srcip = devIP  
                                ipreply.dstip = ip_header.srcip 
                                ipreply.ttl = 65

                                #create ICMPpkt
                                icmppkt = pktlib.icmp()
                                icmppkt.type = pktlib.TYPE_DEST_UNREACH
                                icmppkt.code = pktlib.CODE_UNREACH_PORT 
                                icmppkt.payload = pktlib.unreach()
                                icmppkt.payload.payload = pkt.dump()[:28]

                                #link the two
                                ipreply.protocol = ipreply.ICMP_PROTOCOL
                                ipreply.set_payload(icmppkt)

                                self.icmpError(ipreply, pkt, dev, self.net,ip_header)

                        #print packet not sent to me------------------------------------------
                        else:                                                                   #if packet is not for me
                            bestKey = self.in_forwarding_table(ip_header)

                            if bestKey != None:                                                 #checks if a match in forwarding table
                                if self.forwardingTable[bestKey][1]==None:                      #checks if nextHop none-directly reachable
                                    if dstIP in self.MACaddresses:                              #checks if already know MAC addr
                                        srcINTR = self.forwardingTable[bestKey][2]              #get own mac address with ^
                                        interface = self.net.interface_by_name(srcINTR)         #get own mac address
                                        srcMAC = interface.ethaddr
                                        dstMAC = self.MACaddresses[dstIP]                       #gets MACaddr for dstIP
                                        packet = self.create_eth_header(pkt, dstMAC, srcMAC)    #creates new packet to send
                                        dev = self.forwardingTable[bestKey][2]                  #gets net interface name for dstIP
                                        self.net.send_packet(dev,packet)                        #sends IPv4packet

                                    else:                                                       #if don't know mac addr
                                        IPinfo = self.forwardingTable[bestKey]
                                        packetObject = packets()
                                        packetObject.pkt = pkt
                                        packetObject.ip_header = ip_header
                                        packetObject.lastSend = time.time()
                                        self.queue[dstIP] = packetObject 
                                        packet = self.create_arp_request(ip_header, packetObject, IPinfo, dstIP)   #creates packet 
                                        dev = IPinfo[2]                                                     #dev is the interface to send on
                                        packetObject.dev = dev
                                        self.net.send_packet(dev,packet)                                    #send request
                                                                                  
                                else:                                                                       #if next HOP is not None
                                    IPinfo = self.forwardingTable[bestKey]
                                    nextHopIP = self.forwardingTable[bestKey][1]
                                    nextHopDev = self.forwardingTable[bestKey][2]
                                    if nextHopIP in self.MACaddresses:                                      #if already know MAC address
                                        srcINTR = self.forwardingTable[bestKey][2]                          #get own mac address with ^
                                        interface = self.net.interface_by_name(srcINTR)                     #get own mac address
                                        srcMAC = interface.ethaddr
                                        dstMAC = self.MACaddresses[dstIP]                                   #gets MACaddr for dstIP
                                        packet = self.create_eth_header(pkt, dstMAC, srcMAC)                #creates new packet to send
                                        dev = self.forwardingTable[bestKey][2]                              #gets netinterface name for dstIP
                                        self.net.send_packet(packetObject.dev, packetObject.ARP_request)    #sends IPv4packet 
                                       
                                    else:                                                               #If don't know MAC address
                                        if icmpError:
                                            self.icmpError(ipreply, pkt, dev, self.net,ip_header) #send
                                        else:
                                            packetObject = packets()
                                            packetObject.pkt = pkt
                                            packetObject.ip_header = ip_header
                                            packetObject.lastSend = time.time()
                                            self.queue[ip_header.srcip] = packetObject 
                                            packet = self.create_arp_request(ip_header, packetObject, IPinfo, nextHopIP)   
                                            packetObject.dev = dev
                                            packet.payload.protosrc = ipreply.srcip
                                            packet.payload.protodst = ip_header.srcip
                                            packet.src = pkt.dst
                                            packet.payload.hwsrc = pkt.dst
                                            self.net.send_packet(dev, packetObject.ARP_request)              #send request
                   
                            else:                 
                                ipreply = pktlib.ipv4()
                                interface = self.net.interface_by_name(dev)
                                devIP = interface.ipaddr
                                ipreply.srcip = devIP  
                                ipreply.dstip = ip_header.srcip             #send back to source of packet that had TTL of 1
                                ipreply.ttl = 65

                                #create ICMPpkt
                                icmppkt = pktlib.icmp()
                                icmppkt.type = pktlib.TYPE_DEST_UNREACH
                                icmppkt.code = pktlib.CODE_UNREACH_NET 
                                icmppkt.payload = pktlib.unreach()
                                icmppkt.payload.payload = pkt.dump()[:28]

                                #link the two
                                ipreply.protocol = ipreply.ICMP_PROTOCOL
                                ipreply.set_payload(icmppkt)

                                #print "entering ICMP Error area"		
                                self.icmpError(ipreply, pkt, dev, self.net,ip_header)
Example #14
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
	    log.debug(str(icmp_packet)+str(icmp_packet.payload.seq))
	    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("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:
		    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)
  def create_router(self, packet, packeti):

        if packet.type == pk.ethernet.ARP_TYPE:
            if packet.payload.opcode == pk.arp.REQUEST:
                log.debug('ARP REQUEST RECEIVED')
                reply = pk.arp()
                reply.opcode = pk.arp.REPLY
                reply.hwdst = packet.payload.hwsrc
                if str(packet.payload.protosrc) == '10.0.1.2' or str(packet.payload.protosrc) == '10.0.1.3':
                   reply.hwsrc = adr.EthAddr('ac:ac:ac:ac:ac:bd')
 		elif str(packet.payload.protosrc) == '10.0.2.2' or str(packet.payload.protosrc) == '10.0.2.3' or str(packet.payload.protosrc) == '10.0.2.4':
		   reply.hwsrc = adr.EthAddr('13:13:13:13:13:66')
                reply.protosrc = packet.payload.protodst
                reply.protodst = packet.payload.protosrc
                e = pk.ethernet(type=pk.ethernet.ARP_TYPE,src=packet.dst,dst=packet.src)
                e.set_payload(reply)
                self.open_flow_func(packeti,0,e)
                log.debug('ARP REPLY SENT')
            else:
                log.debug('ARP REPLY')

        elif packet.type == pk.ethernet.IP_TYPE:
           ip_u = packet.payload
           if ip_u.protocol == pk.ipv4.ICMP_PROTOCOL:
             icmp_p = ip_u.payload
             log.debug(packet.dst)
	     if str(packet.dst) == "ac:ac:ac:ac:ac:bd":
                  		   
                #Find whether the host is available in the routing table
                  if icmp_p.type == pk.TYPE_ECHO_REQUEST:
                     log.debug('ICMP REQUEST RECEIVED')
		     log.debug(ip_u.dstip)
		     
                     i = self.find_key(ip_u,1)
		     
		      
                     if i!=None: 
                        log.debug('ICMP Reply Sent')
                        
                        #Get the payload from echo request
                        ec = pk.echo()
                        ec.seq = icmp_p.payload.seq + 1
                        ec.id = icmp_p.payload.id
 			#Create an echo reply packet 
                        icmp_r = pk.icmp()
                        icmp_r.type = pk.TYPE_ECHO_REPLY
                        #Insert the echo payload into the reply packet
                        icmp_r.set_payload(packet.find("icmp").payload)
                        #Create an ipv4 packet and insert the ICMP 
                        ip_encap = pk.ipv4(srcip = ip_u.dstip,dstip = ip_u.srcip,protocol = pk.ipv4.ICMP_PROTOCOL)
                        ip_encap.set_payload(icmp_r)
                        #Create an Ethernet packet and insert the IPV4 in it
                        eth_encap = pk.ethernet(type = pk.ethernet.IP_TYPE,src =packet.dst,dst = packet.src)
                        eth_encap.set_payload(ip_encap)
                        self.open_flow_func(packeti,0,eth_encap)
                     else:
                        log.debug('ICMP DESTINATION UNREACHABLE')
                        #Get the payload from echo request
                        u = pk.unreach()
                        u.payload = ip_u
                        #Create an echo reply packet 
                        icmp_r = pk.icmp()
                        icmp_r.type = pk.TYPE_DEST_UNREACH
                        #Insert the echo payload into the reply packet
                        icmp_r.payload = u
                        #Create an ipv4 packet and insert the ICMP
                        ip_encap = pk.ipv4()
                        ip_encap = pk.ipv4(srcip = ip_u.dstip,dstip=ip_u.srcip,protocol = pk.ipv4.ICMP_PROTOCOL)
                        ip_encap.set_payload(icmp_r)
                        #Create an Ethernet packet and insert the IPV4 in it
                        eth_encap = pk.ethernet(type = pk.ethernet.IP_TYPE, src = packet.dst, dst = packet.src)
                        eth_encap.set_payload(ip_encap)
                        self.open_flow_func(packeti,0,eth_encap)
	     elif str(packet.dst) == "13:13:13:13:13:66":
		    #if icmp_p.type == pk.TYPE_ECHO_REQUEST:
                      log.debug('ICMP REQUEST RECEIVED')
                      
		      
 		      i = self.find_key(ip_u,0)
                      if i!=None: 
                        log.debug('ICMP Reply Sent')
                        
                        #Get the payload from echo request
                        ec = pk.echo()
                        ec.seq = icmp_p.payload.seq + 1
                        ec.id = icmp_p.payload.id
                        #Create an echo reply packet 
                        icmp_r = pk.icmp()
                        icmp_r.type = pk.TYPE_ECHO_REPLY
                        #Insert the echo payload into the reply packet
                        icmp_r.set_payload(packet.find("icmp").payload)
                        #Create an ipv4 packet and insert the ICMP 
                        ip_encap = pk.ipv4(srcip = ip_u.dstip,dstip = ip_u.srcip,protocol = pk.ipv4.ICMP_PROTOCOL)
                        ip_encap.set_payload(icmp_r)
                        #Create an Ethernet packet and insert the IPV4 in it
                        eth_encap = pk.ethernet(type = pk.ethernet.IP_TYPE,src =packet.dst,dst = packet.src)
                        eth_encap.set_payload(ip_encap)
                        self.open_flow_func(packeti,0,eth_encap)
                      else:
                        log.debug('ICMP DESTINATION UNREACHABLE')
                        #Get the payload from echo request
                        u = pk.unreach()
                        u.payload = ip_u
                        #Create an echo reply packet 
                        icmp_r = pk.icmp()
                        icmp_r.type = pk.TYPE_DEST_UNREACH
                        #Insert the echo payload into the reply packet
                        icmp_r.payload = u
                        #Create an ipv4 packet and insert the ICMP
                        ip_encap = pk.ipv4()
                        ip_encap = pk.ipv4(srcip = ip_u.dstip,dstip=ip_u.srcip,protocol = pk.ipv4.ICMP_PROTOCOL)
                        ip_encap.set_payload(icmp_r)
                        #Create an Ethernet packet and insert the IPV4 in it
                        eth_encap = pk.ethernet(type = pk.ethernet.IP_TYPE, src = packet.dst, dst = packet.src)
                        eth_encap.set_payload(ip_encap)
                        self.open_flow_func(packeti,0,eth_encap)
             else: 
			log.debug('ICMP DESTINATION UNREACHABLE')
                        #Get the payload from echo request
                        u = pk.unreach()
                        u.payload = ip_u
                        #Create an echo reply packet 
                        icmp_r = pk.icmp()
                        icmp_r.type = pk.TYPE_DEST_UNREACH
                        #Insert the echo payload into the reply packet
                        icmp_r.payload = u
                        #Create an ipv4 packet and insert the ICMP
                        ip_encap = pk.ipv4()
                        ip_encap = pk.ipv4(srcip = ip_u.dstip,dstip=ip_u.srcip,protocol = pk.ipv4.ICMP_PROTOCOL)
                        ip_encap.set_payload(icmp_r)
                        #Create an Ethernet packet and insert the IPV4 in it
                        eth_encap = pk.ethernet(type = pk.ethernet.IP_TYPE, src = packet.dst, dst = packet.src)
                        eth_encap.set_payload(ip_encap)
                        self.open_flow_func(packeti,0,eth_encap)

		    
           else:
                 j=0
		 		 
		 #log.debug(packet.dst)
		 if str(packet.dst) == "ac:ac:ac:ac:ac:bd":
		   j = self.find_key(ip_u,1)
                   if j!=None:
                     p = self.rtable1[j][3]   
                     dsthw = self.rtable1[j][2]
		     dsthw1 = adr.EthAddr(dsthw)		
                     packet.src = packet.dst
		     packet.dst = dsthw1
                     self.open_flow_func(0,p,packet)
                 elif str(packet.dst) == "13:13:13:13:13:66":
		     j = self.find_key(ip_u,0)
		     if j!=None:
		       p = self.rtable2[j][3]
                       dsthw = self.rtable2[j][2]	 
                       dsthw1 = adr.EthAddr(dsthw)
		       packet.src = packet.dst
                       packet.dst = dsthw1
                       self.open_flow_func(0,p,packet)

		 else:
		     j = self.find_key(ip_u,2) 
		     if j!=None:
		       p = self.rtable[j][3]
		       dsthw = self.rtable2[j][2]        
                       dsthw1 = adr.EthAddr(dsthw)       
                       packet.src = packet.dst
                       packet.dst = dsthw1
                       self.open_flow_func(0,p,packet)	      
  	
           self.FlowMode( packeti, packeti.in_port)
Example #16
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 #17
0
    def ICMP_Request_handler(self, packet, packet_in):
        ip_packet = packet.payload
        icmp_segment = ip_packet.payload

        ipSrcAdd = self.route_table.get(str(ip_packet.srcip))
        ipDstAdd = self.route_table.get(str(ip_packet.dstip))

        if ipDstAdd != None:
            # router
            if str(packet.dst) == '00:00:00:00:00:11':
                if str(ip_packet.dstip) == '10.0.1.1':
                    echo_segment = pkt.echo()
                    echo_segment.seq = icmp_segment.payload.seq + 1
                    echo_segment.id = icmp_segment.payload.id
                    #icmp packt|echo
                    icmp_reply = pkt.icmp()
                    icmp_reply.type = pkt.TYPE_ECHO_REPLY
                    icmp_reply.payload = echo_segment
                    #ip packet|icmp|echo
                    ip_pack = pkt.ipv4()
                    ip_pack.srcip = ip_packet.dstip
                    ip_pack.dstip = ip_packet.srcip
                    ip_pack.protocol = pkt.ipv4.ICMP_PROTOCOL
                    ip_pack.payload = icmp_reply
                    #frame|ip|icmp|echo
                    ether_pack = pkt.ethernet()
                    ether_pack.dst = packet.src
                    ether_pack.src = packet.dst
                    ether_pack.type = pkt.ethernet.IP_TYPE
                    ether_pack.payload = ip_pack
                    self.send_Packet(frame=ether_pack,
                                     out_port=packet_in.in_port)

                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(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':
                #echo rely to source Router -> H5
                if str(ip_packet.dstip) == '10.0.2.1':
                    echo_segment = pkt.echo()
                    echo_segment.seq = icmp_segment.payload.seq + 1
                    echo_segment.id = icmp_segment.payload.id
                    #icmp packt|echo
                    icmp_reply = pkt.icmp()
                    icmp_reply.type = pkt.TYPE_ECHO_REPLY
                    icmp_reply.payload = echo_segment
                    #ip packet|icmp|echo
                    ip_pack = pkt.ipv4()
                    ip_pack.srcip = ip_packet.dstip
                    ip_pack.dstip = ip_packet.srcip
                    ip_pack.protocol = pkt.ipv4.ICMP_PROTOCOL
                    ip_pack.payload = icmp_reply
                    #frame|ip|icmp|echo
                    ether_pack = pkt.ethernet()
                    ether_pack.dst = packet.src
                    ether_pack.src = packet.dst
                    ether_pack.type = pkt.ethernet.IP_TYPE
                    ether_pack.payload = ip_pack
                    self.send_Packet(frame=ether_pack,
                                     out_port=packet_in.in_port)

                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(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])
        else:
            #unreach ICMP packet
            unreachPacket = pkt.unreach()
            unreachPacket.payload = packet.payload

            icmp_unreReply = pkt.icmp()
            icmp_unreReply.type = pkt.TYPE_DEST_UNREACH
            icmp_unreReply.payload = unreachPacket

            ip_unrePack = pkt.ipv4()
            ip_unrePack.srcip = ip_packet.dstip
            ip_unrePack.dstip = ip_packet.srcip
            ip_unrePack.protocol = pkt.ipv4.ICMP_PROTOCOL
            ip_unrePack.payload = icmp_unreReply

            ether_unrePack = pkt.ethernet()
            ether_unrePack.src = packet.dst
            ether_unrePack.dst = packet.src
            ether_unrePack.type = pkt.ethernet.IP_TYPE
            ether_unrePack.payload = ip_unrePack

            self.send_Packet(frame=ether_unrePack, out_port=packet_in.in_port)
Example #18
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")
Example #19
0
 def create_echo_unreach(self, icmp_payload):
     echo = pkt.unreach()
     echo.payload = icmp_payload
     return echo
Example #20
0
    def ICMP_Request_handler(self, packet, packet_in):
        ip_packet = packet.payload
        icmp_segment = ip_packet.payload
        ipDstAdd = self.route_table.get(str(ip_packet.dstip))

        #ICMP reach
        if ipDstAdd != None:
            #ICMP -> router
            if ipDstAdd[2] == 'R':
                log.debug("----------ICMP echo packet----------")
                #echo packet
                echo_segment = pkt.echo()
                echo_segment.seq = icmp_segment.payload.seq + 1
                echo_segment.id = icmp_segment.payload.id
                #icmp packt|echo
                icmp_reply = pkt.icmp()
                icmp_reply.type = pkt.TYPE_ECHO_REQUEST
                icmp_reply.payload = echo_segment
                #ip packet|icmp|echo
                ip_pack = pkt.ipv4()
                ip_pack.srcip = ip_packet.dstip
                ip_pack.dstip = ip_packet.srcip
                ip_pack.protocol = pkt.ipv4.ICMP_PROTOCOL
                ip_pack.payload = icmp_reply
                #frame|ip|icmp|echo
                ether_pack = pkt.ethernet()
                ether_pack.dst = packet.src
                ether_pack.src = packet.dst
                ether_pack.type = pkt.ethernet.IP_TYPE
                ether_pack.payload = ip_pack

                self.send_Packet(frame=ether_pack, out_port=packet_in.in_port)

            elif ipDstAdd[2] == 'H':
                #router -> can reache ipadd
                #frame|original packet send to dst
                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[1])
        #ICMP unreach
        else:
            #log.debug("----------ICMP unreach----------")
            unreachPacket = pkt.unreach()
            unreachPacket.payload = packet.payload

            icmp_unreReply = pkt.icmp()
            icmp_unreReply.type = pkt.TYPE_DEST_UNREACH
            icmp_unreReply.payload = unreachPacket

            ip_unrePack = pkt.ipv4()
            ip_unrePack.srcip = ip_packet.dstip
            ip_unrePack.dstip = ip_packet.srcip
            ip_unrePack.protocol = pkt.ipv4.ICMP_PROTOCOL
            ip_unrePack.payload = icmp_unreReply

            ether_unrePack = pkt.ethernet()
            ether_unrePack.src = packet.dst
            ether_unrePack.dst = packet.src
            ether_unrePack.type = pkt.ethernet.IP_TYPE
            ether_unrePack.payload = ip_unrePack

            self.send_Packet(frame=ether_unrePack, out_port=packet_in.in_port)
Example #21
0
  def act_like_router (self, event, packet_in):
    """
    Implement router-like behavior 
    """
    packet = event.parsed
    ipPacket = packet.payload
    icmpPacket = packet.payload.payload
    #self.IP_to_port[ipPacket.srcip] = packet_in.in_port
    self.mac_to_port[packet.src] = packet_in.in_port

    self.mac_to_port[EthAddr("00:00:00:00:00:01")] = 1
    self.mac_to_port[EthAddr("00:00:00:00:00:02")] = 2
    self.mac_to_port[EthAddr("12:12:12:12:12:12")] = 3
    self.mac_to_port[EthAddr("00:00:00:00:00:03")] = 1
    self.mac_to_port[EthAddr("00:00:00:00:00:04")] = 2
    self.mac_to_port[EthAddr("12:12:12:12:12:12")] = 3

    self.ARP_cache[IPAddr('10.0.1.100')] = EthAddr("00:00:00:00:00:01")
    self.ARP_cache[IPAddr('10.0.1.200')] = EthAddr("00:00:00:00:00:02")
    self.ARP_cache[IPAddr('10.0.2.100')] = EthAddr("00:00:00:00:00:03")
    self.ARP_cache[IPAddr('10.0.2.200')] = EthAddr("00:00:00:00:00:04")

   # self.rt_table["10.0.1.100/24"] =['10.0.1.100', 's1-eth1', '10.0.1.1', 1]
   # self.rt_table["10.0.2.100/24"] =['10.0.2.100', 's1-eth2', '10.0.2.1', 3]
   # self.rt_table["10.0.3.100/24"] =['10.0.3.100', 's1-eth3', '10.0.3.1', 2]

    self.IP_to_port[IPAddr('10.0.1.1')]=1
    self.IP_to_port[IPAddr('10.0.1.1')]=2
    self.IP_to_port[IPAddr('10.0.2.1')]=1
    self.IP_to_port[IPAddr('10.0.2.1')]=2

    self.s1_to_s2[IPAddr('10.0.1.100')] = IPAddr('10.0.1.1')
    self.s1_to_s2[IPAddr('10.0.1.200')] = IPAddr('10.0.1.1')

    self.s2_to_s1[IPAddr('10.0.2.100')] = IPAddr('10.0.2.1') 
    self.s2_to_s1[IPAddr('10.0.2.200')] = IPAddr('10.0.2.1') 
    
    if packet.type == pck.ethernet.ARP_TYPE: 
      ip_add = ipPacket.protodst
      log.debug("arp packet: %s" % (ip_add))
    else: 
      ip_add = ipPacket.dstip
      log.debug("ip packet: %s" % (ip_add))
          
        
    if ip_add in self.IP_to_port or ip_add in self.ARP_cache: 

    
      if packet.type == pck.ethernet.ARP_TYPE:
        log.debug("Received an ARP packet")
        if ipPacket.opcode == pck.arp.REQUEST:
          log.debug("       ARP request packet with MAC: %s" % (packet.src))
          log.debug("       ARP request packet with iP: %s" % (ipPacket.protosrc))

          pck_ARP = pck.arp()

          pck_ARP.hwtype = ipPacket.hwtype
          pck_ARP.protype = ipPacket.prototype
          pck_ARP.hwlen = ipPacket.hwlen
          pck_ARP.protolen = ipPacket.protolen

          pck_ARP.hwsrc = EthAddr("12:12:12:12:12:12")
          pck_ARP.protosrc = ipPacket.protodst
          pck_ARP.protodst = ipPacket.protosrc
          pck_ARP.hwdst = ipPacket.hwsrc
          pck_ARP.opcode = pck.arp.REPLY

          pck_MAC = pck.ethernet()
          pck_MAC.type = pck.ethernet.ARP_TYPE
          pck_MAC.dst = ipPacket.hwsrc
          pck_MAC.src = EthAddr("12:12:12:12:12:12")
          pck_MAC.payload = pck_ARP

          log.debug("       Sending ARP reply  with MAC: %s" % (pck_MAC.dst))
          log.debug("       Sending ARP reply with IP: %s" % (pck_ARP.protodst))

          
          msg_to_send = of.ofp_packet_out()
          msg_to_send.data = pck_MAC.pack()
          msg_to_send.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))
          msg_to_send.in_port = event.port
          event.connection.send(msg_to_send)
          
          

      elif packet.type == pck.ethernet.IP_TYPE:
       
        log.debug("Relaying ipv4 packet")
        
        log.debug("       Received packet from  MAC: %s" % (packet.src))
        log.debug("       Received packet from  IP: %s" % (ipPacket.srcip))
        
        pck_IP = pck.ipv4()
        pck_IP.protocol = ipPacket.protocol
        pck_IP.srcip = ipPacket.srcip
        pck_IP.dstip = ipPacket.dstip
        #pck_IP.srcip = self.int_to_ip[ipPacket.srcip]
        #pck_IP.dstip = self.int_to_ip[ipPacket.dstip]
        pck_IP.payload = packet.payload.payload

        pck_MAC = pck.ethernet()
        pck_MAC.type = pck.ethernet.IP_TYPE
        pck_MAC.dst = self.ARP_cache[ipPacket.dstip]
        pck_MAC.src = EthAddr("12:12:12:12:12:12")
        pck_MAC.payload = pck_IP


      #  if ipPacket.dstip in self.IP_to_port:
          #self.resend_packet(pck_MAC, self.IP_to_port[ipPacket.dstip ])
        log.debug("       Relaying packet to  MAC: %s" % (pck_MAC.dst))
        log.debug("       Relaying packet to  IP: %s" % (pck_IP.dstip))

        if packet_in.in_port == 3:
            port_out = self.mac_to_port[pck_MAC.dst]
        else:

            if ipPacket.dstip in self.s1_to_s2 and ipPacket.srcip in self.s1_to_s2 or ipPacket.dstip in self.s2_to_s1 and ipPacket.srcip in self.s2_to_s1:
                port_out = self.mac_to_port[pck_MAC.dst]
                log.debug("we got 1")
            else:
                port_out = 3
                log.debug("we got 2")
          
        msg_to_send = of.ofp_packet_out()
        msg_to_send.data = pck_MAC.pack()
        
        msg_to_send.actions.append(of.ofp_action_output(port = port_out))
        msg_to_send.in_port = event.port
        event.connection.send(msg_to_send)

        log.debug("       Relaying to Port: %s" % port_out)
    
    else:
      log.debug("Send host unavailable message")
      log.debug("Received packet with IP: %s" % ipPacket.srcip)
      log.debug("MAC: %s" % packet.src)

      log.debug("       RCVD IP  packet with MAC source: %s" % (packet.src))
      log.debug("       IP  packet with iP source: %s" % (ipPacket.srcip))
      log.debug("       IP  packet with MAC dest: %s" % (packet.dst))
      log.debug("       IP  packet with iP dest: %s" % (ipPacket.dstip))

      pck_pay = pck.unreach()
      pck_pay.payload = ipPacket

      pck_ICMP = pck.icmp()
      pck_ICMP.type = pck.TYPE_DEST_UNREACH
      pck_ICMP.code = pck.CODE_UNREACH_HOST
      pck_ICMP.payload = pck_pay
      
      pck_IP = pck.ipv4()
      pck_IP.protocol = pck.ipv4.ICMP_PROTOCOL
      pck_IP.srcip = ipPacket.dstip
      pck_IP.dstip = ipPacket.srcip
      pck_IP.payload = pck_ICMP

      pck_MAC = pck.ethernet()
      pck_MAC.type = pck.ethernet.IP_TYPE
      pck_MAC.dst = packet.src
      pck_MAC.src = packet.dst
      pck_MAC.payload = pck_IP

      msg_to_send = of.ofp_packet_out()
      msg_to_send.data = pck_MAC.pack()
      msg_to_send.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))
      msg_to_send.in_port = event.port
      event.connection.send(msg_to_send)
Example #22
0
    def act_like_router(self, packet, packet_in):
        #handle ARP Requests and replies
        etherPayload = packet.payload  #the stripped ethFrame, contains ipv4 or arp packet
        src_mac = packet.src
        dst_mac = packet.dst

        if packet.type == pkt.ethernet.ARP_TYPE:
            src_ip = etherPayload.protosrc
            dst_ip = etherPayload.protodst
            if etherPayload.opcode == pkt.arp.REQUEST:
                print(
                    "received ARP REQUEST checking if i have info on sender: "
                    + str(src_mac))

                if src_mac not in self.mac_to_port:
                    print("sender mac unknown, adding to mac table...")
                    self.mac_to_port[src_mac] = packet_in.in_port
                if src_ip not in self.arp_table:
                    print("sender ip unknown, adding to arp table...")
                    self.arp_table[src_ip] = src_mac
                if src_ip not in self.ip_to_port:
                    print("sender ip unknown, adding to ip table...")
                    self.ip_to_port[src_ip] = packet_in.in_port

                self.displayTables()

                #creating arp reply to send back
                arp_reply = pkt.arp()
                arp_reply.hwsrc = adr.EthAddr(
                    "11:12:13:14:15:16")  # fake mac in response
                arp_reply.hwdst = etherPayload.hwsrc
                arp_reply.opcode = pkt.arp.REPLY
                arp_reply.protosrc = etherPayload.protodst
                arp_reply.protodst = etherPayload.protosrc

                # encapsulate in ethernet frame now
                ether = pkt.ethernet()
                ether.type = pkt.ethernet.ARP_TYPE
                ether.dst = packet.src
                ether.src = packet.dst
                ether.payload = arp_reply

                #sending packet to switch
                self.resend_packet(ether, packet_in.in_port)

        elif packet.type == pkt.ethernet.IP_TYPE:
            if etherPayload.protocol == pkt.ipv4.ICMP_PROTOCOL:
                icmp_packet = etherPayload.payload
                src_ip = etherPayload.srcip
                dst_ip = etherPayload.dstip
                k = 0  #subnet holder
                if icmp_packet.type == pkt.TYPE_ECHO_REQUEST:

                    if src_mac not in self.mac_to_port:
                        print("sender mac unknown, adding to mac table...")
                        self.mac_to_port[src_mac] = packet_in.in_port
                    if src_ip not in self.arp_table:
                        print("sender ip unknown, adding to arp table...")
                        self.arp_table[src_ip] = src_mac
                    if src_ip not in self.ip_to_port:
                        print("sender ip unknown, adding to ip table...")
                        self.ip_to_port[src_ip] = packet_in.in_port

                    self.displayTables()

                    for subnet in self.routing_table:
                        if dst_ip.inNetwork(subnet):
                            k = subnet
                    if k != 0:
                        #create ping reply
                        # create echo fields
                        ech = pkt.echo()  # echo contained in pkt.icmp
                        ech.id = icmp_packet.payload.id
                        ech.seq = icmp_packet.payload.seq + 1

                        # encapsulates in icmp
                        icmp_reply = pkt.icmp()
                        icmp_reply.type = pkt.TYPE_ECHO_REPLY  # code 0
                        icmp_reply.payload = ech

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

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

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

                        print("echo Reply sent!")
                        self.createflow(packet_in, eth_p, packet_in.in_port)

                    else:
                        print("ICMP destination unreachable")

                        unr = pkt.unreach()
                        unr.payload = etherPayload

                        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()
                        action = of.ofp_action_output(port=packet_in.in_port)
                        msg.actions.append(action)
                        self.connection.send(msg)
                        print("echo Unreachable Reply sent!")
                        self.createflow(packet_in, eth_p, packet_in.in_port)

            #other type of ip packet maybe udp or tcp
            else:
                src_ip = etherPayload.srcip
                dst_ip = etherPayload.dstip

                if dst_ip in self.ip_to_port and dst_ip in self.arp_table:
                    print("received other type of packet sending reply...")
                    out_port = self.ip_to_port[dst_ip]
                    eth_dest = self.arp_table[dst_ip]

                    msg = of.ofp_packet_out()
                    packet.src = packet.dst  #since who received the packet is sending the reply set src = dst
                    packet.dst = adr.EthAddr(eth_dest)
                    msg.data = packet.pack()
                    action = of.ofp_action_output(port=out_port)
                    msg.actions.append(action)

                    self.connection.send(msg)
                    self.createflow(packet_in, packet, out_port)
                else:
                    print("who do i send this to I am switch: " +
                          str(self.connection.dpid))
                    print("packet src ip: " + str(src_ip) + " to: " +
                          str(dst_ip))
                    self.resend_packet(packet, of.OFPP_ALL)
                    self.createflow(packet_in, packet, of.OFPP_ALL)
    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])
  def create_router(self, packet, packeti):

        if packet.type == pk.ethernet.ARP_TYPE:
            if packet.payload.opcode == pk.arp.REQUEST:
                log.debug('ARP REQUEST RECEIVED')  
                reply = pk.arp()
                reply.opcode = pk.arp.REPLY
                reply.hwdst = packet.payload.hwsrc
                reply.hwsrc = adr.EthAddr('AC:AC:AC:AC:AC:BD')
                reply.protosrc = packet.payload.protodst
                reply.protodst = packet.payload.protosrc
                e = pk.ethernet(type=pk.ethernet.ARP_TYPE,src=packet.dst,dst=packet.src)
                e.set_payload(reply)
		self.open_flow_func(packeti,0,e)      
                log.debug('ARP REPLY SENT')
            else:
                log.debug('ARP REPLY')
     

        elif packet.type == pk.ethernet.IP_TYPE:
           ip_u = packet.payload
           if ip_u.protocol == pk.ipv4.ICMP_PROTOCOL:
                icmp_p = ip_u.payload
                #Find whether the host is available in the routing table
                if icmp_p.type == pk.TYPE_ECHO_REQUEST:
                    log.debug('ICMP REQUEST RECEIVED')
                    n = self.find_key(ip_u)
		    log.debug(n)                  
                    if n!=None:
                        log.debug('ICMP Reply Sent') 
                        icmp_r = pk.icmp()
                        icmp_r.type = pk.TYPE_ECHO_REPLY
                        #Insert the echo payload into the reply packet
                        icmp_r.set_payload(packet.find("icmp").payload)
                        #Create an ipv4 packet and insert the ICMP 
			ip_encap = pk.ipv4(srcip = ip_u.dstip,dstip = ip_u.srcip,protocol = pk.ipv4.ICMP_PROTOCOL)
                        ip_encap.set_payload(icmp_r)
                        #Create an Ethernet packet and insert the IPV4 in it
                        eth_encap = pk.ethernet(type = pk.ethernet.IP_TYPE,src =packet.dst,dst = packet.src)
                        eth_encap.set_payload(ip_encap)
                        self.open_flow_func(packeti,0,eth_encap)
                        #Get the payload from echo request
		    else:
                        u = pk.unreach()
                        u.payload = ip_u
			log.debug("Destination Unreachable")
                        #Create an echo reply packet 
                        icmp_r = pk.icmp()
                        icmp_r.type = pk.TYPE_DEST_UNREACH
			icmp_r.code = pk.CODE_UNREACH_HOST
                        #Insert the echo payload into the reply packet
                        icmp_r.payload = u
                        #Create an ipv4 packet and insert the ICMP
                        ip_encap = pk.ipv4()
			ip_encap = pk.ipv4(srcip = ip_u.dstip,dstip=ip_u.srcip,protocol = pk.ipv4.ICMP_PROTOCOL)
                        ip_encap.set_payload(icmp_r)                  
                        #Create an Ethernet packet and insert the IPV4 in it
                        eth_encap = pk.ethernet(type = pk.ethernet.IP_TYPE, src = packet.dst, dst = packet.src)
                        eth_encap.set_payload(ip_encap)
			self.open_flow_func(packeti,0,eth_encap)
           else:
                 j=0
                 j = self.find_key(ip_u)                    
                 if j!=0:
		     dsthw = self.rtable[j][3]
                     p = self.rtable[j][4]
                     dsthw1 = adr.EthAddr(dsthw)
                     
                     packet.src = packet.dst
                     packet.dst = dsthw1
		     self.open_flow_func(0,p,packet)                                              
           self.FlowMode( packeti, packeti.in_port)