def _handle_ConnectionUp(self, event): #new switch connection
     self.lb_mac = EthAddr("0A:00:00:00:00:01") #fake mac of load balancer
     self.connection = event.connection
     #write your code here!!!
     ##Send initial ARP request to the servers
     for i in self.server_ips:
         r = arp()
         r.hwtype=1
         r.prototype=0x0800
         r.hwlen=6
         r.opcode = arp.REQUEST
         r.hwsrc = self.lb_mac
         r.protosrc=self.service_ip
         r.protodst=i
         r.hwdst = EthAddr("00:00:00:00:00:00")
        # print "APR Message:  "+ str(r)
         e = ethernet(type=0x0806,src=self.lb_mac,dst=EthAddr("FF:FF:FF:FF:FF:FF"))
         e.set_payload(r)
        # print "Ethernet Frame: "+ str(e)
         #"""
         msg = of.ofp_packet_out()
         msg.data=e.pack()
         msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
         msg.in_port=of.OFPP_NONE
         self.connection.send(msg)
Ejemplo n.º 2
0
  def _do_probe (self):
    """
    Send an ARP to a server to see if it's still up
    """
    self._do_expire()

    server = self.servers.pop(0)
    self.servers.append(server)

    r = arp()
    r.hwtype = r.HW_TYPE_ETHERNET
    r.prototype = r.PROTO_TYPE_IP
    r.opcode = r.REQUEST
    r.hwdst = ETHER_BROADCAST
    r.protodst = server
    r.hwsrc = self.mac
    r.protosrc = self.service_ip
    e = ethernet(type=ethernet.ARP_TYPE, src=self.mac,
                 dst=ETHER_BROADCAST)
    e.set_payload(r)
    #self.log.debug("ARPing for %s", server)
    msg = of.ofp_packet_out()
    msg.data = e.pack()
    msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD))
    msg.in_port = of.OFPP_NONE
    self.con.send(msg)

    self.outstanding_probes[server] = time.time() + self.arp_timeout

    core.callDelayed(self._probe_wait_time, self._do_probe)
	def handleARPmessages (self, packet, event):
		in_port = event.port
		# Get the ARP request from packet
		arp_req = packet.next

		# Create ARP reply
		arp_rep = arp()
		arp_rep.opcode = arp.REPLY
		arp_rep.hwsrc = WEB_SERVER_MAC
		arp_rep.hwdst = arp_req.hwsrc
		arp_rep.protosrc = WEB_SERVER_IP
		arp_rep.protodst = arp_req.protosrc

		# Create the Ethernet packet
		eth = ethernet()
		eth.type = ethernet.ARP_TYPE
		eth.dst = packet.src
		eth.src = WEB_SERVER_MAC
		eth.set_payload(arp_rep)

		# Send the ARP reply to client
		msg = of.ofp_packet_out()
		msg.data = eth.pack()
		msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))
		msg.in_port = in_port
		self.connection.send(msg)
		pass
Ejemplo n.º 4
0
  def handle_arp (self, packet, in_port):    # function No.2

    # Get the ARP request from packet
    arp_req = packet.next

    # Create ARP reply
    arp_rep = arp()
    arp_rep.opcode = arp.REPLY
    arp_rep.hwsrc = LOAD_BALANCER_MAC    # hardware source
    arp_rep.hwdst = arp_req.hwsrc    # hardware destination
    arp_rep.protosrc = LOAD_BALANCER_IP    # software source
    arp_rep.protodst = arp_req.protosrc    # software destination

    # Create the Ethernet packet
    eth = ethernet()
    eth.type = ethernet.ARP_TYPE
    eth.dst = packet.src
    eth.src = LOAD_BALANCER_MAC
    eth.set_payload(arp_rep)

    # Send the ARP reply to client
    msg = of.ofp_packet_out()
    msg.data = eth.pack()
    msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))
    msg.in_port = in_port
    self.connection.send(msg)
Ejemplo n.º 5
0
    def sendPing(cls, macEntry, ipAddr):
        """
        send Ping msg to switch.
        """
        req = arp() # Builds an "ETH/IP any-to-any ARP packet
        req.opcode = arp.REQUEST
        req.hwdst = macEntry.macaddr
        req.protodst = ipAddr
        # src is ETHER_ANY, IP_ANY
        eth = ethernet(type=ethernet.ARP_TYPE, src=req.hwsrc, dst=req.hwdst)
        eth.set_payload(req)

        log.debug("%i %i sending ARP REQ to %s %s",
                macEntry.dpid, macEntry.port, str(req.hwdst), str(req.protodst))

        msg = of.ofp_packet_out(data = eth.pack(),
                               action = of.ofp_action_output(port = macEntry.port))
        if core.openflow.sendToDPID(macEntry.dpid, msg.pack()):
            ipEntry = macEntry.ipAddrs[ipAddr]
            ipEntry.pings.sent()
        else:
            # macEntry is stale, remove it.
            log.debug("%i %i ERROR sending ARP REQ to %s %s", macEntry.dpid, macEntry.port, str(req.hwdst), str(req.protodst))
            del macEntry.ipAddrs[ipAddr]

        return
Ejemplo n.º 6
0
  def handle_arp (self, packet, in_port):
    print "ARP Packet Arrived"

    # Get the ARP request from packet
    arp_req = packet.next

    # Create ARP reply
    arp_rep = arp()
    arp_rep.opcode = arp.REPLY

    # Show the client that it's actually the "main" server
    arp_rep.hwsrc = LOAD_BALANCER_MAC
    arp_rep.hwdst = arp_req.hwsrc
    arp_rep.protosrc = LOAD_BALANCER_IP
    arp_rep.protodst = arp_req.protosrc

    # Create the Ethernet packet
    eth = ethernet()
    eth.type = ethernet.ARP_TYPE
    eth.dst = packet.src
    eth.src = LOAD_BALANCER_MAC
    eth.set_payload(arp_rep)

    # Send the ARP reply to client
    # msg is the "packet out" message. Now giving this packet special properties
    msg = of.ofp_packet_out()
    msg.data = eth.pack()
    msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))
    msg.in_port = in_port
    self.connection.send(msg)
Ejemplo n.º 7
0
 def sendPing (self, macEntry, ipAddr):
   """
   Builds an ETH/IP any-to-any ARP packet (an "ARP ping")
   """
   r = arp()
   r.opcode = arp.REQUEST
   r.hwdst = macEntry.macaddr
   r.hwsrc = self.ping_src_mac
   r.protodst = ipAddr
   # src is IP_ANY
   e = ethernet(type=ethernet.ARP_TYPE, src=r.hwsrc, dst=r.hwdst)
   e.payload = r
   log.debug("%i %i sending ARP REQ to %s %s",
             macEntry.dpid, macEntry.port, str(r.hwdst), str(r.protodst))
   msg = of.ofp_packet_out(data = e.pack(),
                           action = of.ofp_action_output(port=macEntry.port))
   if core.openflow.sendToDPID(macEntry.dpid, msg.pack()):
     ipEntry = macEntry.ipAddrs[ipAddr]
     ipEntry.pings.sent()
   else:
     # macEntry is stale, remove it.
     log.debug("%i %i ERROR sending ARP REQ to %s %s",
               macEntry.dpid, macEntry.port, str(r.hwdst), str(r.protodst))
     del macEntry.ipAddrs[ipAddr]
   return
Ejemplo n.º 8
0
  def reply_to_arp(self, event, match):

    dpid = event.connection.dpid
    inport = event.port
    packet = event.parsed
    
    #print "reply to ARP request", match.dl_dst
    r = arp()
    r.opcode = arp.REPLY
    r.hwdst = match.dl_src
    if (self.addr_is_gw(dpid, match.nw_dst.toStr())):
      r.protosrc = match.nw_dst
    mac_addr=self.find_mac_addr(dpid, inport)
    #print "mac_addr=", mac_addr
    r.hwsrc = addresses.EthAddr(mac_addr)
    r.protodst = match.nw_src
    e = ethernet(type=packet.ARP_TYPE, src=r.hwsrc, dst=r.hwdst)
    e.set_payload(r)
    log.debug("%i %i answering ARP for %s" %( dpid, inport, str(r.protosrc)))
    msg = of.ofp_packet_out()
    msg.data = e.pack()
    msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))
    msg.in_port = inport
    event.connection.send(msg)
    return
Ejemplo n.º 9
0
def send_arp_reply (reply_to, mac, src_mac = None, src_ip = None):
  """
  Send an ARP reply.

  src_mac can be None to use the "DPID MAC" or True to use the port Mac.
    (or it can be an EthAddr)
  """
  # reply_to should be a PacketIn event
  arpp = reply_to.parsed.find('arp')
  mac = EthAddr(mac)
  if src_mac is None:
    #src_mac = mac # Used to be this ???
    src_mac = reply_to.connection.eth_addr
  elif src_mac is True:
    src_mac = reply_to.connection.ports[reply_to.port].hw_addr
  else:
    src_mac = EthAddr(src_mac)
  r = arp()
  r.opcode = r.REPLY
  r.hwdst = arpp.hwsrc
  r.protodst = arpp.protosrc
  r.hwsrc = EthAddr(src_mac)
  r.protosrc = IPAddr("0.0.0.0") if src_ip is None else IPAddr(src_ip)
  e = ethernet(type=ethernet.ARP_TYPE, src=src_mac, dst=r.hwdst)
  e.payload = r
  msg = of.ofp_packet_out()
  msg.data = e.pack()
  msg.actions.append(of.ofp_action_output(port = reply_to.port))
  msg.in_port = of.OFPP_NONE
  reply_to.connection.send(msg)
Ejemplo n.º 10
0
        def arp_reply(arp_request):
            src_ip = arp_request.protosrc
            dst_ip = arp_request.protodst
            dst_mac = EthAddr(ip_mac[str(dst_ip)])

            log.info("Faking ARP Reply")
            log.info('from ' + str(dst_ip) + ' to ' + str(src_ip))

            reply = arp()
            reply.opcode = arp.REPLY
            reply.hwtype = arp_request.hwtype
            reply.prototype = arp_request.prototype
            reply.hwlen = arp_request.hwlen
            reply.protolen = arp_request.protolen
            reply.hwsrc = dst_mac
            reply.hwdst = arp_request.hwsrc    
            reply.protosrc = dst_ip
            reply.protodst = src_ip

            ether = ethernet()
            ether.type = ethernet.ARP_TYPE
            ether.dst = packet.src
            ether.src = dst_mac
            ether.set_payload(reply)

            msg = of.ofp_packet_out()
            msg.data = ether.pack()
            msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))
            msg.in_port = event.port
            
            event.connection.send(msg)
Ejemplo n.º 11
0
 def sendPing (self, macEntry, ipAddr):
   """
   Builds an ETH/IP any-to-any ARP packet (an "ARP ping")
   """
   r = arp()
   r.opcode = arp.REQUEST
   r.hwdst = macEntry.macaddr
   r.hwsrc = self.ping_src_mac
   r.protodst = ipAddr
   # src is IP_ANY
   e = ethernet(type=ethernet.ARP_TYPE, src=r.hwsrc, dst=r.hwdst)
   e.payload = r
   
   #custom code start
   the_file.write("Time: " + time.asctime(time.localtime(time.time())) + "\n")
   the_file.write("ARP Request:\n")
   the_file.write("Src MAC:" + str(self.ping_src_mac))
   the_file.write("Dest MAC:" + str(macEntry.macaddr))
   the_file.write("Dest IP:" + str(ipAddr))
   #custom code start
   
   log.debug("%i %i sending ARP REQ to %s %s",
             macEntry.dpid, macEntry.port, str(r.hwdst), str(r.protodst))
   msg = of.ofp_packet_out(data = e.pack(),
                           action = of.ofp_action_output(port=macEntry.port))
   if core.openflow.sendToDPID(macEntry.dpid, msg.pack()):
     ipEntry = macEntry.ipAddrs[ipAddr]
     ipEntry.pings.sent()
   else:
     # macEntry is stale, remove it.
     log.debug("%i %i ERROR sending ARP REQ to %s %s",
               macEntry.dpid, macEntry.port, str(r.hwdst), str(r.protodst))
     del macEntry.ipAddrs[ipAddr]
   return
Ejemplo n.º 12
0
	def arpReply(self, packet, event, additive = 0):
		if packet.payload.opcode == arp.REQUEST:
			arp_reply = arp()
			if additive == 0:
				arp_reply.hwsrc = EthAddr('fa-31-11-11-11-11')
			elif additive == 1:
				arp_reply.hwsrc = EthAddr('fa-31-11-11-11-12')
			arp_reply.hwdst = packet.src
			arp_reply.opcode = arp.REPLY
			arp_reply.protosrc = packet.payload.protodst
			arp_reply.protodst = packet.payload.protosrc
			ether = ethernet()
			ether.type = ethernet.ARP_TYPE
			ether.dst = packet.src
			ether.src = arp_reply.hwsrc
			ether.payload = arp_reply
			#send this packet to the switch
			#see section below on this topic

			msg = of.ofp_packet_out(in_port=event.port)
			msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))
			msg.data = ether
			self.connection.send(msg)

			log.debug('Replying ARP request for %s.', str(arp_reply.protosrc))
Ejemplo n.º 13
0
 def f_arp_reply(self,arpp):
     #print "It's a arp request"
     '''
     #print 'arpp.next=',arpp.next
     #print 'arpp.protosrc=',arpp.protosrc
     #print 'arpp.protodst=',arpp.protodst
     '''
     dstIP  = arpp.protodst.toStr()
     #print 'dstIP=',dstIP
     dstMac = self.f_get_arp_mac(dstIP)  
     #print 'dstMac=', dstMac
     if dstMac != None:
         arp_reply = arp()
         arp_reply.opcode = arp.REPLY
         arp_reply.hwdst = arpp.hwsrc
         arp_reply.protodst = arpp.protosrc
         arp_reply.protosrc = arpp.protodst
         arp_reply.hwsrc = dstMac
         ether = ethernet()
         ether.type = ethernet.ARP_TYPE
         ether.src = dstMac
         ether.dst = arpp.hwsrc            
         ether.payload = arp_reply
         #send this packet to the switch
         self.f_send_arp_reply_pkt(ether,self.packet_event.port) 
         #'''
     else:
         '''Send Openflow arp flood via Openflow flood port NOT ethernet flood !!!!!!!!'''
         self.f_send_arp_openflow_flood()
Ejemplo n.º 14
0
	def _router_handle_arp(self, event):
		arpPacket = event.parsed.next
		ingressPort = self.getPort(event.port)
		if arpPacket.opcode == arp.REQUEST and \
				arpPacket.protodst == ingressPort.ip:
			r = arp()
			r.opcode = arp.REPLY
			r.hwdst = arpPacket.hwsrc
			r.hwsrc = ingressPort.mac
			r.protodst = arpPacket.protosrc
			r.protosrc = arpPacket.protodst
			e = ethernet(type = ethernet.ARP_TYPE,
						 src = ingressPort.mac, 
						 dst = arpPacket.hwsrc)
			e.set_payload(r)
			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 arpPacket.opcode == arp.REPLY:
			ip = IPAddr(arpPacket.protosrc)
			mac = EthAddr(arpPacket.hwsrc)
			self.arp[ip] = EthAddr(mac)
			self._tryPurgeQueue()
			self.installRouteEntry(ip, event.port, mac)
		else:
			self._drop(event)
    def handle_arp(self, packet, packet_in):
        self.network.lock.acquire()
        port = self.network.routers[self.connection.dpid].ports[packet_in.in_port]
        log.debug("GOT ARP packet at router {}, type: {}; in port_mac {}; from hwsrc {}; to hwdst: {};".format(self.connection.dpid, packet.payload.opcode, port.mac, str(packet.payload.hwsrc), str(packet.payload.hwdst)))
        if packet.payload.opcode == arp.REQUEST and port.ip == str(packet.payload.protodst):
            my_arp = arp()
            my_arp.opcode = arp.REPLY
            my_arp.protosrc = IPAddr(port.ip)
            my_arp.protodst = packet.payload.protosrc
            my_arp.hwdst = packet.payload.hwsrc
            my_arp.hwsrc = EthAddr(port.mac)

            my_ether = ethernet()
            my_ether.type = ethernet.ARP_TYPE
            my_ether.dst = packet.payload.hwsrc
            my_ether.src = EthAddr(port.mac)
            my_ether.payload = my_arp
            log.debug("Sending ARP REPLY at router {}, to dest_ip {}; to port {};".format(self.connection.dpid, str(packet.payload.protosrc), port.id))
            self.send_packet(None, my_ether, packet_in.in_port, of.OFPP_NONE)

        elif packet.payload.opcode is arp.REPLY and port.mac == str(packet.payload.hwdst):
            log.debug("GOT ARP REPLY at router {}; from src_mac {}; src_ip {}; input_port {}".format(self.connection.dpid, str(packet.payload.hwsrc),packet.payload.protosrc, packet_in.in_port))
            if str(packet.payload.protosrc) in self.waiting_arp_requests:
                self.arp_cache[str(packet.payload.protosrc)] = (packet.payload.hwsrc, time.time())
                self.network.lock.release()
                self.handle_ip(self.waiting_arp_requests[str(packet.payload.protosrc)][0], self.waiting_arp_requests[str(packet.payload.protosrc)][1])
                self.network.lock.acquire()
                del self.waiting_arp_requests[str(packet.payload.protosrc)]
                
        self.network.lock.release()
Ejemplo n.º 16
0
    def _handle_ConnectionUp(self, event): 
        # fake mac id for service ip
        self.lb_mac = EthAddr("0A:00:00:00:00:01")
        self.connection = event.connection

        # pre emptively collecting the mac and port number of server IPs
        # by sending ARP request packets
        for ip in self.serverIp:

            # constructing ARP packet
            arpPacket = arp()
            arpPacket.opcode = arpPacket.REQUEST
            arpPacket.hwsrc = self.lb_mac
            arpPacket.hwdst = ETHER_BROADCAST
            arpPacket.protosrc = self.serviceIp
            arpPacket.protodst = ip
          
            # constructing ethernet packet with ARP as payload
            e = ethernet(type = ethernet.ARP_TYPE, src = self.connection.eth_addr, dst = ETHER_BROADCAST)
            e.set_payload(arpPacket)

            # constructing openflow out message
            msg = of.ofp_packet_out()
            msg.data = e.pack()
            msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD))
            msg.in_port = of.OFPP_NONE

            # sending message
            self.connection.send(msg)
    def send_arpResponse(self, arp_req, event, packet, mac):
        '''
        Send out an ARP response
        '''
        # create the arp response packet
        arp_res = arp()
        arp_res.hwtype = arp_req.hwtype
        arp_res.prototype = arp_req.prototype
        arp_res.hwlen = arp_req.hwlen
        arp_res.protolen = arp_req.protolen
        arp_res.opcode = arp.REPLY
        arp_res.hwdst = arp_req.hwsrc
        arp_res.protodst = arp_req.protosrc
        arp_res.protosrc = arp_req.protodst
        arp_res.hwsrc = mac

        # create an ethernet package that contains the arp response we created above
        e = ethernet(type=packet.type, src=mac, dst=arp_req.hwsrc)
        e.set_payload(arp_res)
        log.debug("%i %i answering ARP for %s" % (event.connection.dpid, event.port, str(arp_res.protosrc)))

        # send the ARP response
        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)
Ejemplo n.º 18
0
 def cheat(self,event,dpid):  
   inport = event.port
   packet = event.parsed
   a=packet.next
   print a.protodst
   if a.protodst == "10.10.1.0":
     print "pretend arp"
     r = arp()
     r.hwtype = a.hwtype
     r.prototype = a.prototype
     r.hwlen = a.hwlen
     r.protolen = a.protolen
     r.opcode = arp.REPLY
     r.hwdst = a.hwsrc
     r.protodst = a.protosrc
     r.protosrc = a.protodst
     r.hwsrc = EthAddr("BC:AE:C5:43:58:DC")
     e = ethernet(type=packet.type, src=r.hwsrc, dst=r.hwdst)
     e.set_payload(r)
     log.debug("%i %i answering ARP for %s" % (dpid, inport,
                                               str(r.protosrc)))
     msg = of.ofp_packet_out()
     msg.data = e.pack()
     msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))
     msg.in_port = inport 
     event.connection.send(msg)
          
     return
Ejemplo n.º 19
0
  def _handle_PacketIn (self, event):
    dpid = event.connection.dpid
    inport = event.port
    packet = event.parsed

    a = packet.find('arp')
    if not a: return

    if a.prototype != arp.PROTO_TYPE_IP:
      return

    if a.hwtype != arp.HW_TYPE_ETHERNET:
      return

    if a.opcode == arp.REQUEST:
      log.debug("%s ARP request %s => %s", dpid_to_str(dpid),
                a.protosrc, a.protodst)

      if self.use_port_mac:
        src_mac = event.connection.ports[inport].hw_addr
      else:
        src_mac = event.connection.eth_addr
      ev = ARPRequest(event.connection, a, src_mac,
                      self.eat_packets, inport)
      self.raiseEvent(ev)
      if ev.reply is not None:
        r = arp()
        r.hwtype = a.hwtype
        r.prototype = a.prototype
        r.hwlen = a.hwlen
        r.protolen = a.protolen
        r.opcode = arp.REPLY
        r.hwdst = a.hwsrc
        r.protodst = a.protosrc
        r.protosrc = a.protodst
        r.hwsrc = EthAddr(ev.reply)
        e = ethernet(type=packet.type, src=ev.reply_from, dst=a.hwsrc)
        e.payload = r
        log.debug("%s answering ARP for %s" % (dpid_to_str(dpid),
            str(r.protosrc)))
        msg = of.ofp_packet_out()
        msg.data = e.pack()
        msg.actions.append(of.ofp_action_output(port =
                                                of.OFPP_IN_PORT))
        msg.in_port = inport
        event.connection.send(msg)
        return EventHalt if ev.eat_packet else None

    elif a.opcode == arp.REPLY:
      log.debug("%s ARP reply %s => %s", dpid_to_str(dpid),
                a.protosrc, a.hwsrc)

      ev = ARPReply(event.connection,a,self.eat_packets,inport)
      self.raiseEvent(ev)
      return EventHalt if ev.eat_packet else None

    return EventHalt if self.eat_packets else None
Ejemplo n.º 20
0
	def _handle_PacketIn(self,event):
		packet = event.parsed
		Switch_Output[event.dpid][packet.src]=event.port

		if packet.find("arp"):
			arp_packet=packet.find("arp")
			IP_To_MAC[arp_packet.protosrc]=packet.src
			if arp_packet.opcode==arp.REQUEST:
				if arp_packet.protodst in IP_To_MAC:	#reply
					#construct arp reply packet
					arp_reply=arp()
					arp_reply.hwsrc=IP_To_MAC[arp_packet.protodst]
					arp_reply.hwdst=packet.src
					arp_reply.opcode=arp.REPLY
					arp_reply.protosrc=arp_packet.protodst
					arp_reply.protodst=arp_packet.protosrc
					ether=ethernet()
					ether.type=ethernet.ARP_TYPE
					ether.dst=packet.src
					ether.src=IP_To_MAC[arp_packet.protodst]
					ether.payload=arp_reply

					# send the created arp reply back to switch
					msg=of.ofp_packet_out()
					msg.data=ether.pack()
					msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT))
					msg.in_port=event.port
					event.connection.send(msg)

				elif (arp_packet.protosrc,arp_packet.protodst) not in Switch_AntiFlood[event.dpid]:	#flood
					msg=of.ofp_packet_out(data=event.data)
					msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
					msg.in_port=event.port
					event.connection.send(msg)
					# Switch_AntiFlood[event.dpid].append((arp_reply.protosrc,arp_packet.protodst) )


		# if packet.find('ipv4'):
		# 	ip_packet=packet.find('ipv4')
		# 	IP_To_MAC[ip_packet.dstip]=packet.dst
		# 	IP_To_MAC[ip_packet.srcip]=packet.src

		if packet.dst in Switch_Output[event.dpid]  :
			msg=of.ofp_packet_out(data=event.ofp)
			msg.actions.append(of.ofp_action_output(port=Switch_Output[event.dpid][packet.dst]))
			msg.in_port=event.port
			event.connection.send(msg)

			Install_Flow(event,packet.src,packet.dst,Switch_Output[event.dpid][packet.dst])
			Install_Flow(event,packet.dst,packet.src,Switch_Output[event.dpid][packet.src])

		print event.dpid,'packet_in:',packet
		print 'out_put:',Switch_Output
		print 'IP_MAC',IP_To_MAC
		print 'Anti',Switch_AntiFlood
		print
Ejemplo n.º 21
0
    def _send_arp_response_packet(self, arpp, out_port):
            r = arp()
            r.hwtype = r.HW_TYPE_ETHERNET
            r.prototype = r.PROTO_TYPE_IP
            r.opcode = r.REPLY
            r.hwdst = arpp.hwsrc
            r.protodst = arpp.protosrc
            r.hwsrc = self.my_mac
            r.protosrc = self.my_ip

            self._send_ethernet_packet(ethernet.ARP_TYPE,
                                       self.my_mac, arpp.hwsrc,
                                       r, out_port)
  def buildArpReply (self, arp_request):
    arp_packet = arp()
    arp_packet.hwsrc = EthAddr('00:00:0:01:01:01')
    arp_packet.hwdst = arp_request.hwsrc      
    arp_packet.opcode = arp.REPLY
    arp_packet.protosrc = IPAddr('10.1.1.1')
    arp_packet.protodst = arp_request.protosrc

    eth = pkt.ethernet(type=pkt.ethernet.ARP_TYPE)
    eth.src = arp_packet.hwsrc
    eth.dst = arp_packet.hwdst
    eth.payload = arp_packet
    return eth
  def handle_arp(self, event, packet):
    '''
    Handle the arp request if we can

    Note - this code was derived/inspired from the l3_learning.py switch in POX
    '''

    log.debug("we got an ARP packet!!!" + str(event.connection.dpid))
   
    arp_req = packet.next
    if arp_req.prototype == arp.PROTO_TYPE_IP and arp_req.hwtype == arp.HW_TYPE_ETHERNET and arp_req.protosrc != 0:
        log.debug("ARP proto source..." + str(arp_req.protosrc) + str(arp_req.protodst))
        
        # update the arp table
        self.arptable[arp_req.protosrc] = (event.port, packet.src, time.time() * ARP_TIMEOUT)

        # see if we can handle the arp request (we know the dst and it hasn't expired)
        if arp_req.opcode == arp.REQUEST and arp_req.protodst in self.arptable and self.arptable[arp_req.protodst][2] > time.time():
            # we can respond to the ARP request
            log.debug("responding to ARP request...")

            # create the arp response packet
            arp_res = arp()
            arp_res.hwtype = arp_req.hwtype
            arp_res.prototype = arp_req.prototype
            arp_res.hwlen = arp_req.hwlen
            arp_res.protolen = arp_req.protolen
            arp_res.opcode = arp.REPLY
            arp_res.hwdst = arp_req.hwsrc
            arp_res.protodst = arp_req.protosrc
            arp_res.protosrc = arp_req.protodst
            arp_res.hwsrc = self.arptable[arp_req.protodst][1]

            # create an ethernet package that contains the arp response we created above
            e = ethernet(type=packet.type, src=dpid_to_mac(event.connection.dpid), dst=arp_req.hwsrc)
            e.set_payload(arp_res)
            log.debug("%i %i answering ARP for %s" % (event.connection.dpid, event.port, str(arp_res.protosrc)))

            # send the ARP response
            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)

            return

    # we don't know where this mac is, flood the packet
    log.debug("flooding ARP packet!" + str(self.arptable))
    self.flood_packet(event)
    return 
  def handle_arp (self, packet, in_port):
    print "ARP Packet Arrived at Router R"+str(self.connection.dpid)+" at Interface"+str(in_port)
    
    if packet.payload.opcode == arp.REQUEST:
      arp_req = packet.next

      # Create ARP reply
      arp_rep = arp()
      arp_rep.opcode = arp.REPLY

      # Show the client that it's actually the me
      arp_rep.hwsrc = self.EthAddr
      arp_rep.hwdst = arp_req.hwsrc
      arp_rep.protosrc = self.IPAddr
      arp_rep.protodst = arp_req.protosrc

      # Create the Ethernet packet
      eth = ethernet()
      eth.type = ethernet.ARP_TYPE
      eth.dst = packet.src
      eth.src = self.EthAddr
      eth.set_payload(arp_rep)

      # Send the ARP reply to client
      # msg is the "packet out" message. Now giving this packet special properties
      msg = of.ofp_packet_out()
      msg.data = eth.pack()
      msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))
      msg.in_port = in_port
      self.connection.send(msg)
      print "arp reply DONE"

    if packet.payload.opcode == arp.REPLY:
      self.arp_table[packet.next.protosrc]=packet.src
      que1=[]
      for tpl in self.que:
      	eth=tpl[0]
      	Interface=tpl[1]
      	prt=tpl[2]
        if eth.payload.dstip==packet.next.protosrc:
          eth.dst=packet.src
          msg = of.ofp_packet_out()
          msg.data = eth.pack()
          # print "inport",of.OFPP_IN_PORT
          # print "outport",int(Interface)
          msg.actions.append(of.ofp_action_output(port = int(Interface)))
          msg.in_port = prt
          self.connection.send(msg)
        else:
          que1.append(tpl)
      self.que=que1
Ejemplo n.º 25
0
 def send_arp_reply(self, connection, src_mac, src_ip, dst_mac, dst_ip, port_out):
     r = arp()
     r.opcode = r.REPLY
     r.hwsrc  = EthAddr(src_mac)
     r.protosrc = IPAddr(src_ip)
     r.hwdst  = EthAddr(dst_mac)
     r.protodst = IPAddr(dst_ip)
     e = ethernet(type=ethernet.ARP_TYPE, src=EthAddr(src_mac), dst=r.hwdst)
     e.payload = r
     msg  = of.ofp_packet_out()
     msg.data = e.pack()
     msg.actions.append(of.ofp_action_output(port=port_out))
     msg.in_port = of.OFPP_NONE
     connection.send(msg)
    def send_arp_request(self, req_ip, port):
        my_arp = arp()
        my_arp.opcode = arp.REQUEST
        my_arp.protosrc = IPAddr(port.ip)
        my_arp.protodst = IPAddr(req_ip)
        my_arp.hwdst = EthAddr('FF:FF:FF:FF:FF:FF')
        my_arp.hwsrc = EthAddr(port.mac)

        my_ether = ethernet()
        my_ether.type = ethernet.ARP_TYPE
        my_ether.dst = EthAddr('FF:FF:FF:FF:FF:FF')
        my_ether.src = EthAddr(port.mac)
        my_ether.payload = my_arp

        self.send_packet(None, my_ether, port.id, of.OFPP_NONE)
Ejemplo n.º 27
0
	def _sendArpReq(self, destIp, outPort):
		r = arp()
		r.opcode = arp.REQUEST
		r.hwsrc = self.getPort(outPort).mac
		r.hwdst = ETHER_BROADCAST
		r.protodst = IPAddr(destIp)
		r.protosrc = self.getPort(outPort).ip
		e = ethernet(type = ethernet.ARP_TYPE,
					src = r.hwsrc,
					dst = r.hwdst)
		e.set_payload(r)
		msg = of.ofp_packet_out()
		msg.data = e.pack()
		msg.actions.append(of.ofp_action_output(port = outPort))
		self.connection.send(msg)
Ejemplo n.º 28
0
  def _handle_PacketIn(self, event):
    inport = event.port
    eth_packet = event.parsed
    # If packet is not parsed properly, alert
    if not eth_packet.parsed:
      log.warning("Unparsed packet")
      return

    # The ethernet packet carries an ARP packet
    if isinstance(eth_packet.next, arp):
      log.info("ARP packet has been received")
      arp_packet = eth_packet.next

      # Do src learning if possible
      if not self.icp_arp_table.Exists(arp_packet.protosrc):
        self.icp_arp_table.Insert(arp_packet.protosrc, arp_packet.hwsrc)
        log.info("Source learning: %s -> %s", arp_packet.protosrc, arp_packet.hwsrc)

      if arp_packet.opcode == arp.REQUEST:
        log.info("This is an ARP request")
        log.info("Entry found for %s? %s", arp_packet.protodst, self.icp_arp_table.Exists(arp_packet.protodst))

        if self.icp_arp_table.Exists(arp_packet.protodst):
          log.info("The mapping is stored in the table")
          arp_reply = arp()
          arp_reply.hwtype = arp_packet.hwtype
          arp_reply.prototype = arp_packet.prototype
          arp_reply.hwlen = arp_packet.hwlen
          arp_reply.protolen = arp_packet.protolen
          arp_reply.opcode = arp.REPLY
          arp_reply.hwdst = arp_packet.hwsrc
          arp_reply.protodst = arp_packet.protosrc
          arp_reply.protosrc = arp_packet.protodst
          arp_reply.hwsrc = self.icp_arp_table.Find(arp_packet.protodst)
          
          # Currently the src addres is set to the destination of query
          # I doubt whether it should be the MAC of controller
          eth_reply = ethernet(type=ethernet.ARP_TYPE, 
                               src=arp_reply.hwsrc,
                               dst=arp_reply.hwdst)
          eth_reply.set_payload(arp_reply)
          
          msg = of.ofp_packet_out()
          msg.data = eth_reply.pack() # I doubt whether the pack is needed here
          msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))
          msg.in_port = inport
          event.connection.send(msg)
          return
Ejemplo n.º 29
0
 def send_arp_request(self, connection, src_mac, src_ip, dst_ip, port_out):
     r = arp()
     r.opcode = r.REQUEST
     r.hwsrc  = EthAddr(src_mac)
     r.protosrc = IPAddr(src_ip)
     r.hwdst = ETHER_BROADCAST
     r.protodst = IPAddr(dst_ip)
     e = ethernet(type=ethernet.ARP_TYPE, src=EthAddr(src_mac), dst=r.hwdst)
     e.payload = r
     msg = of.ofp_packet_out()
     msg.data = e.pack()
     if port_out is None:
         port_out = of.OFPP_FLOOD
     msg.actions.append(of.ofp_action_output(port=port_out))
     msg.in_port = of.OFPP_NONE
     connection.send(msg)
Ejemplo n.º 30
0
 def _hanle_arp_request(self, event):
     """
     Process ARP request packet
     """
     eth_packet = event.parsed
     arp_packet = eth_packet.payload
     LOGGER.info("ARP request: ip=%s query ip=%s", arp_packet.protosrc,
                 arp_packet.protodst)
     # If entry not found, store the event and broadcast request
     if arp_packet.protodst not in self.ip_to_mac:
         LOGGER.info("Entry for %s not found, buffer and broadcast request",
                     arp_packet.protodst)
         for conn in core.openflow.connections:
             conn_ports = conn.features.ports
             # Sift out ports connecting to hosts but vxlan peers
             host_ports = [port.port_no for port in conn_ports
                           if port.port_no not in
                           self.inception.dpid_ip_to_port.values()]
             actions_out_ports = [of.ofp_action_output(port=port)
                                  for port in host_ports]
             core.openflow.sendToDPID(conn.dpid, of.ofp_packet_out(
                 data=eth_packet.pack(),
                 action=actions_out_ports))
     # Entry exists
     else:
         # setup data forwrading flows
         dst_mac = self.ip_to_mac[arp_packet.protodst]
         switch_id = event.dpid
         self._setup_data_fwd_flows(switch_id, dst_mac)
         # construct ARP reply packet and send it to the host
         LOGGER.info("Hit: dst_ip=%s, dst_mac=%s", arp_packet.protodst,
                     dst_mac)
         arp_reply = arp(opcode=arp.REPLY,
                         hwdst=arp_packet.hwsrc,
                         hwsrc=dst_mac,
                         protodst=arp_packet.protosrc,
                         protosrc=arp_packet.protodst)
         eth_reply = ethernet(type=ethernet.ARP_TYPE,
                              src=arp_reply.hwsrc,
                              dst=arp_reply.hwdst)
         eth_reply.payload = arp_reply
         event.connection.send(of.ofp_packet_out(
             data=eth_reply.pack(),
             action=of.ofp_action_output(port=event.port)))
         LOGGER.info("Send ARP reply to host=%s on port=%s on behalf of "
                     "ip=%s", arp_reply.protodst, event.port,
                     arp_reply.protosrc)
Ejemplo n.º 31
0
    def _handle_PacketIn(self, event):
        dpid = event.connection.dpid
        inport = event.port
        packet = event.parsed

        # Ignore LLDP packets
        if packet.type == ethernet.LLDP_TYPE:
            return

        if isinstance(packet.next, arp):
            # ARP packet
            a = packet.next
            inport = event.port
            log.debug("%i %i ARP %s %s => %s", dpid, inport, {
                arp.REQUEST: "request",
                arp.REPLY: "reply"
            }.get(a.opcode, 'op:%i' % (a.opcode, )), str(a.protosrc),
                      str(a.protodst))

            print packet.next
            if a.prototype == arp.PROTO_TYPE_IP:
                if a.hwtype == arp.HW_TYPE_ETHERNET:
                    if a.protosrc != 0:
                        # Learn or update port/MAC info
                        if a.protosrc in self.mac_to_ip:
                            log.debug("IP present in mac to ip table")
                        else:
                            # print a.hwsrc
                            self.mac_to_ip[a.protosrc] = a.hwsrc
                        # print self.mac_to_ip

                        # Send any waiting packets...
                        self._send_lost_buffers(dpid, a.protosrc, packet.src,
                                                inport)

                        if a.opcode == arp.REQUEST:
                            # Maybe we can answer
                            if a.protodst in self.mac_to_ip or a.hwdst == EthAddr(
                                    "00:00:00:00:00:00"):
                                # We have an answer...
                                # print "..........."
                                # Creating new ARP packet
                                r = arp()
                                r.hwtype = a.hwtype
                                r.prototype = a.prototype
                                r.hwlen = a.hwlen
                                r.protolen = a.protolen
                                r.opcode = arp.REPLY
                                r.hwdst = a.hwsrc
                                r.protodst = a.protosrc
                                r.protosrc = a.protodst
                                for entry in event.connection.ports.values():
                                    port = entry.port_no
                                    if port == inport:
                                        mac = entry.hw_addr

                                r.hwsrc = mac
                                e = ethernet(type=packet.type,
                                             src=dpid_to_mac(dpid),
                                             dst=a.hwsrc)
                                e.set_payload(r)
                                log.debug("%i %i answering ARP for %s" %
                                          (dpid, inport, str(r.protosrc)))
                                # Creating new message
                                msg = of.ofp_packet_out()
                                msg.data = e.pack()
                                msg.actions.append(
                                    of.ofp_action_output(port=of.OFPP_IN_PORT))
                                msg.in_port = inport
                                event.connection.send(msg)
                                return
        else:
            # print "Ipv4"
            log.debug("%i %i IP %s => %s", dpid, inport, packet.next.srcip,
                      packet.next.dstip)
            inport = event.port
            # Send any waiting packets...
            self._send_lost_buffers(dpid, packet.next.srcip, packet.src,
                                    inport)

            # Learn or update port/MAC info
            print packet.next.srcip
            print packet.src
            if packet.next.srcip in self.mac_to_ip:
                log.debug("IP present in mac to ip table")
            else:
                self.mac_to_ip[packet.next.srcip] = packet.src

            # Try to forward
            dstaddr = packet.next.dstip
            if dstaddr in self.mac_to_ip:
                # We have info about what port to send it out on...
                # print "Checking dstaddr..."
                prt = int(routing_table[dpid][str(dstaddr)][1])
                mac = self.mac_to_ip[dstaddr]
                print inport, prt, mac

                # Creating new Message
                actions = []
                actions.append(of.ofp_action_dl_addr.set_dst(mac))
                actions.append(of.ofp_action_output(port=prt))
                match = of.ofp_match.from_packet(packet, inport)
                match.dl_src = None  # Wildcard source MAC
                match.dl_dst = mac

                msg = of.ofp_flow_mod(command=of.OFPFC_ADD,
                                      idle_timeout=FLOW_IDLE_TIMEOUT,
                                      hard_timeout=of.OFP_FLOW_PERMANENT,
                                      buffer_id=event.ofp.buffer_id,
                                      actions=actions,
                                      match=match)

                # print "Message: "
                event.connection.send(msg)
            else:
                # We don't know this destination.
                # First, we track this buffer so that we can try to resend it later
                # if we learn the destination, second we ARP for the destination,
                # which should ultimately result in it responding and us learning
                # where it is

                # Add to tracked buffers
                if (dpid, dstaddr) not in self.lost_buffers:
                    self.lost_buffers[(dpid, dstaddr)] = []
                bucket = self.lost_buffers[(dpid, dstaddr)]
                entry = (event.ofp.buffer_id, inport)
                bucket.append(entry)
                # print "Flood..."

                r = arp()
                r.hwtype = r.HW_TYPE_ETHERNET
                r.prototype = r.PROTO_TYPE_IP
                r.hwlen = 6
                r.protolen = r.protolen
                r.opcode = r.REQUEST
                r.hwdst = ETHER_BROADCAST
                r.protodst = dstaddr
                r.hwsrc = packet.src
                r.protosrc = packet.next.srcip
                e = ethernet(type=ethernet.ARP_TYPE,
                             src=packet.src,
                             dst=ETHER_BROADCAST)
                e.set_payload(r)
                log.debug("%i %i ARPing for %s on behalf of %s" %
                          (dpid, inport, str(r.protodst), str(r.protosrc)))
                msg = of.ofp_packet_out()
                msg.data = e.pack()
                msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
                msg.in_port = inport
                event.connection.send(msg)
    def _handle_PacketIn(self, event):
        dpid = event.connection.dpid

        inport = event.port
        packet = copy.deepcopy(event.parsed)
        if not packet.parsed:
            log.warning("%i %i ignoring unparsed packet", dpid, inport)
            return

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

        # store the mac, ip info of the DNS SERVER into arpTable
        self.arpTable[dpid][IPAddr(IP_OF_DNS_SERVER)] = Entry(
            6633, EthAddr(MAC_OF_DNS_SERVER))

        if packet.type == ethernet.LLDP_TYPE:
            # Ignore LLDP packets
            return

        p = packet.find('dns')

        if p is not None and p.parsed:

            # Get dstName of the DNS Query
            dstname = ''
            for question in p.questions:
                dstname = question.name

            log.debug("DNS Query msg from %s: asking ip address for %s",
                      packet.next.srcip, dstname)

            # Learn or update port/MAC info
            if packet.next.srcip in self.arpTable[dpid]:
                if self.arpTable[dpid][packet.next.srcip] != (inport,
                                                              packet.src):
                    log.info("%i %i RE-learned %s", dpid, inport,
                             packet.next.srcip)
            else:
                log.debug("%i %i learned %s", dpid, inport,
                          str(packet.next.srcip))
            self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src)

            # generate random virtual ip for internal node
            n = random.randint(128, 254)
            vip = "10.0.0." + str(n)
            #add the srcip and virtual destination ip pair into srcip_dstip_map
            self.srcip_dstvip_map[str(packet.next.srcip)] = vip
            # forming answer
            answer = dns.rr(dstname, 1, 1, 5, len(vip), IPAddr(vip))
            # write dns reply msg
            d = dns()
            d.questions = p.questions
            d.answers.append(answer)
            d.authorities = []
            d.additional = []

            d.id = p.id
            d.qr = True  # dns reply
            d.opcode = 0  # standard
            d.aa = False
            d.tc = False
            d.rd = False
            d.ra = False
            d.z = False
            d.ad = False
            d.cd = False
            d.rcode = 0

            e = ethernet(type=ethernet.IP_TYPE,
                         src=MAC_OF_DNS_SERVER,
                         dst=str(packet.src))
            ip = ipv4(srcip=IPAddr(IP_OF_DNS_SERVER))
            ip.dstip = packet.next.srcip
            ip.protocol = ip.UDP_PROTOCOL
            u = udp()
            u.srcport = dns.SERVER_PORT
            # get srcport from the packet and set it to the udp's dstport
            m = packet.find("udp")
            m.parsed
            u.dstport = m.srcport
            u.payload = d
            ip.payload = u
            e.payload = ip

            msg = of.ofp_packet_out()
            msg.data = e.pack()
            msg.actions.append(of.ofp_action_nw_addr.set_dst(
                packet.next.srcip))
            msg.actions.append(of.ofp_action_dl_addr.set_dst(packet.src))
            msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT))
            msg.in_port = inport
            event.connection.send(msg)
            log.debug(
                " DNS reply msg has been sent to %s: %s's ip address is %s" %
                (str(packet.next.srcip), dstname, vip))

        elif isinstance(packet.next, ipv4):
            log.debug("IPv4 msg: %i %i IP %s => %s", dpid, inport,
                      packet.next.srcip, packet.next.dstip)

            # Send any waiting packets...
            self._send_lost_buffers(dpid, packet.next.srcip, packet.src,
                                    inport)
            print "Have sent lost buffers"

            # Learn or update port/MAC info
            if packet.next.srcip in self.arpTable[dpid]:
                if self.arpTable[dpid][packet.next.srcip] != (inport,
                                                              packet.src):
                    log.info("%i %i RE-learned %s", dpid, inport,
                             packet.next.srcip)
            else:
                log.debug("%i %i learned %s", dpid, inport,
                          str(packet.next.srcip))
            self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src)

            srcaddr = packet.next.srcip
            dstaddr = packet.next.dstip

            if (dstaddr in self.vipList):
                self.srcip_dstvip_map[srcaddr] = dstaddr
                dstaddr = IPAddr(REAL_IP_OF_INTERNAL_HOST)

            if dstaddr in self.arpTable[dpid]:
                # We have info about what port to send it out on...
                prt = self.arpTable[dpid][dstaddr].port
                mac = self.arpTable[dpid][dstaddr].mac

                # Try to forward
                icmpmsg = packet.find("icmp")
                icmpmsg.parsed

                # icmp echo reply from internal host
                if icmpmsg.type == 0 and srcaddr == IPAddr(
                        REAL_IP_OF_INTERNAL_HOST):
                    log.info("ICMP echo reply msg from %s to %s", srcaddr,
                             packet.next.dstip)

                    if prt == inport:
                        log.warning(
                            "%i %i not sending packet for %s back out of the "
                            + "input port" % (dpid, inport, str(dstaddr)))
                    else:
                        log.debug(
                            "%i %i installing flow for %s => %s out port %i" %
                            (dpid, inport, packet.next.srcip, dstaddr, prt))

                    # add flow entry
                    msg = of.ofp_flow_mod(command=of.OFPFC_ADD)
                    msg.match.dl_type = 0x0800  #ipv4
                    msg.match.nw_src = REAL_IP_OF_INTERNAL_HOST
                    msg.match.nw_dst = dstaddr

                    # change the srcip to virtual ip
                    msg.actions.append(
                        of.ofp_action_nw_addr.set_src(
                            IPAddr(self.srcip_dstvip_map[dstaddr])))
                    msg.actions.append(of.ofp_action_dl_addr.set_dst(mac))
                    msg.actions.append(of.ofp_action_output(port=prt))

                    event.connection.send(msg)
                    log.info(
                        "ICMP echo reply flow entry for internal node to %s has been installed",
                        packet.next.dstip)

                # icmp echo reply for internal host
                elif icmpmsg.type == 8 and dstaddr == IPAddr(
                        REAL_IP_OF_INTERNAL_HOST):
                    log.info("ICMP echo request msg from %s to %s",
                             packet.next.srcip, packet.next.dstip)

                    if prt == inport:
                        log.warning(
                            "%i %i not sending packet for %s back out of the "
                            + "input port" % (dpid, inport, str(dstaddr)))
                    else:
                        log.debug(
                            "%i %i installing flow for %s => %s out port %i" %
                            (dpid, inport, packet.next.srcip, dstaddr, prt))

                    msg = of.ofp_flow_mod(command=of.OFPFC_ADD)
                    msg.match.dl_type = 0x0800  #ipv4 msg
                    msg.match.in_port = inport
                    msg.match.nw_dst = "10.0.0.128/255.255.255.128"
                    msg.actions.append(of.ofp_action_nw_addr.set_dst(dstaddr))
                    msg.actions.append(of.ofp_action_output(port=prt))
                    msg.actions.append(of.ofp_action_dl_addr.set_dst(mac))
                    event.connection.send(msg)
                    log.info(
                        "ICMP echo request flow entry for %s to internal host has been instaled",
                        packet.next.srcip)

                else:
                    log.warning("Uninvolved icmp msg type")
                    return

            elif self.arp_for_unknowns:
                # We don't know this destination.
                # First, we track this buffer so that we can try to resend it later
                # if we learn the destination, second we ARP for the destination,
                # which should ultimately result in it responding and us learning
                # where it is

                # Add to tracked buffers
                if (dpid, dstaddr) not in self.lost_buffers:
                    self.lost_buffers[(dpid, dstaddr)] = []
                bucket = self.lost_buffers[(dpid, dstaddr)]
                entry = (time.time() + MAX_BUFFER_TIME, event.ofp.buffer_id,
                         inport)
                bucket.append(entry)
                while len(bucket) > MAX_BUFFERED_PER_IP:
                    del bucket[0]

                # Expire things from our outstanding ARP list...
                self.outstanding_arps = {
                    k: v
                    for k, v in self.outstanding_arps.iteritems()
                    if v > time.time()
                }

                # Check if we've already ARPed recently
                if (dpid, dstaddr) in self.outstanding_arps:
                    # Oop, we've already done this one recently.
                    return

                # And ARP...
                self.outstanding_arps[(dpid, dstaddr)] = time.time() + 4

                r = arp()
                r.hwtype = r.HW_TYPE_ETHERNET
                r.prototype = r.PROTO_TYPE_IP
                r.hwlen = 6
                r.protolen = r.protolen
                r.opcode = r.REQUEST
                r.hwdst = ETHER_BROADCAST

                if dstaddr in self.vipList:
                    r.protodst = IPAddr(REAL_IP_OF_INTERNAL_HOST)
                else:
                    r.protodst = dstaddr

                r.hwsrc = packet.src
                r.protosrc = packet.next.srcip
                e = ethernet(type=ethernet.ARP_TYPE,
                             src=packet.src,
                             dst=ETHER_BROADCAST)
                e.set_payload(r)
                log.debug("%i %i ARPing for %s on behalf of %s for Ipv4" %
                          (dpid, inport, str(r.protodst), str(r.protosrc)))
                msg = of.ofp_packet_out()
                msg.data = e.pack()
                msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
                msg.in_port = inport
                event.connection.send(msg)

        elif isinstance(packet.next, arp):

            a = packet.next

            if a.protosrc in self.arpTable[dpid]:
                if self.arpTable[dpid][a.protosrc] != (inport, packet.src):
                    log.info("%i %i RE-learned %s", dpid, inport,
                             str(a.protosrc))
            else:
                log.debug("%i %i learned %s", dpid, inport, str(a.protosrc))
                self.arpTable[dpid][a.protosrc] = Entry(inport, packet.src)

            if a.protodst in self.vipList:
                self.srcip_dstvip_map[a.protosrc] = str(a.protodst)
                a.protodst = REAL_IP_OF_INTERNAL_HOST

            log.info("%i %i ARP %s %s => %s", dpid, inport, {
                arp.REQUEST: "request",
                arp.REPLY: "reply"
            }.get(a.opcode, 'op:%i' % (a.opcode, )), str(a.protosrc),
                     str(a.protodst))

            if a.prototype == arp.PROTO_TYPE_IP:

                if a.hwtype == arp.HW_TYPE_ETHERNET:

                    if a.protosrc != 0:

                        # Learn or update port/MAC info
                        if a.protosrc in self.arpTable[dpid]:
                            if self.arpTable[dpid][a.protosrc] != (inport,
                                                                   packet.src):
                                log.info("%i %i RE-learned %s", dpid, inport,
                                         str(a.protosrc))
                        else:
                            log.debug("%i %i learned %s", dpid, inport,
                                      str(a.protosrc))
                        self.arpTable[dpid][a.protosrc] = Entry(
                            inport, packet.src)

                        # Send any waiting packets...
                        self._send_lost_buffers(dpid, a.protosrc, packet.src,
                                                inport)

                        if a.opcode == arp.REPLY:
                            r = arp()
                            r.hwtype = a.hwtype
                            r.prototype = a.prototype
                            r.hwlen = a.hwlen
                            r.protolen = a.protolen
                            r.opcode = arp.REPLY
                            r.hwsrc = a.hwsrc
                            if a.protosrc == IPAddr(REAL_IP_OF_INTERNAL_HOST):
                                if a.protodst in self.srcip_dstvip_map:
                                    r.protosrc = IPAddr(
                                        self.srcip_dstvip_map[a.protodst])
                            else:
                                r.protosrc = a.protosrc
                            r.protodst = a.protodst
                            r.hwdst = self.arpTable[dpid][a.protodst].mac
                            e = ethernet(type=packet.type,
                                         src=dpid_to_mac(dpid),
                                         dst=a.hwdst)
                            e.set_payload(r)
                            log.debug("%i %i answering ARP for %s to %s" %
                                      (dpid, inport, str(
                                          r.protosrc), str(r.protodst)))
                            msg = of.ofp_packet_out()
                            msg.data = e.pack()
                            msg.actions.append(
                                of.ofp_action_output(
                                    port=self.arpTable[dpid][a.protodst].port))
                            msg.in_port = inport
                            event.connection.send(msg)
                            return

                        if a.opcode == arp.REQUEST:
                            # Maybe we can answer

                            if a.protodst in self.vipList:
                                self.srcip_dstvip_map[a.protosrc] = str(
                                    a.protodst)
                                a.protodst = IPAddr(REAL_IP_OF_INTERNAL_HOST)

                            if a.protodst in self.arpTable[dpid]:
                                # We have an answer...

                                if not self.arpTable[dpid][
                                        a.protodst].isExpired():
                                    # .. and it's relatively current, so we'll reply ourselves

                                    r = arp()
                                    r.hwtype = a.hwtype
                                    r.prototype = a.prototype
                                    r.hwlen = a.hwlen
                                    r.protolen = a.protolen
                                    r.opcode = arp.REPLY
                                    r.hwdst = a.hwsrc
                                    r.hwsrc = self.arpTable[dpid][
                                        a.protodst].mac
                                    r.protodst = a.protosrc
                                    if a.protodst == IPAddr(
                                            REAL_IP_OF_INTERNAL_HOST):
                                        r.protosrc = IPAddr(
                                            self.srcip_dstvip_map[a.protosrc])
                                    else:
                                        r.protosrc = a.protodst

                                    e = ethernet(type=packet.type,
                                                 src=dpid_to_mac(dpid),
                                                 dst=a.hwsrc)
                                    e.set_payload(r)
                                    log.debug("%i %i answering ARP for %s" %
                                              (dpid, inport, str(r.protosrc)))
                                    msg = of.ofp_packet_out()
                                    msg.data = e.pack()
                                    msg.actions.append(
                                        of.ofp_action_output(
                                            port=of.OFPP_IN_PORT))
                                    msg.in_port = inport
                                    event.connection.send(msg)
                                    return

            # Didn't know how to answer or otherwise handle this ARP, so just flood it
                            log.debug("%i %i flooding ARP %s %s => %s" %
                                      (dpid, inport, {
                                          arp.REQUEST: "request",
                                          arp.REPLY: "reply"
                                      }.get(a.opcode, 'op:%i' % (a.opcode, )),
                                       str(a.protosrc), str(a.protodst)))
                            r1 = arp()
                            r1.hwtype = a.HW_TYPE_ETHERNET
                            r1.prototype = a.PROTO_TYPE_IP
                            r1.hwlen = 6
                            r1.protolen = a.protolen
                            r1.opcode = arp.REQUEST
                            r1.hwdst = ETHER_BROADCAST
                            r1.protodst = IPAddr(a.protodst)
                            r1.hwsrc = a.hwsrc
                            r1.protosrc = a.protosrc
                            e1 = ethernet(type=ethernet.ARP_TYPE,
                                          src=a.hwsrc,
                                          dst=ETHER_BROADCAST)
                            e1.set_payload(r1)
                            log.debug("%i %i ARPing for %s on behalf of %s" %
                                      (dpid, inport, str(
                                          r1.protodst), str(r1.protosrc)))
                            msg1 = of.ofp_packet_out()
                            msg1.data = e1.pack()
                            msg1.actions.append(
                                of.ofp_action_output(port=of.OFPP_FLOOD))
                            msg1.in_port = inport
                            event.connection.send(msg1)
Ejemplo n.º 33
0
    def _handle_PacketIn(self, event):
        self.packetin = self.packetin + 1
        dpid = event.connection.dpid
        inport = event.port

        packet = event.parsed
        if not packet.parsed:
            log.warning("%i %i ignoring unparsed packet", dpid, inport)
            return

        if dpid not in self.arpTable:
            # New switch -- create an empty table
            print "new switch"
            self.arpTable[dpid] = {}

            for fake in self.fakeways:
                self.arpTable[dpid][IPAddr(fake)] = Entry(
                    of.OFPP_NONE, dpid_to_mac(dpid))

        if packet.type == ethernet.LLDP_TYPE:
            # Ignore LLDP packets
            return

        flag = 0
        # This part of code handles packet in and write to file.py count variable that informs
        # us how many malicious packets Arrived to Virtual IPs
        ###################################################################################################
        if isinstance(packet.next, ipv4):
            if (self.isVirtualIPAddress(str(packet.next.dstip))):
                flag = 1
            elif (self.isRealIPAddress(str(packet.next.dstip))):
                flag = 1
            if (flag == 0):
                print "Unknown IP: %s,Dropping packet" % str(packet.next.dstip)

        if isinstance(packet.next, arp):
            print "after if arp: %s " % str(packet.next.protodst)

            if (self.isVirtualIPAddress(str(packet.next.protodst))):
                flag = 1
                self.count = self.count + 1
                print "$$$$$$$$$$ count = %i $$$$$$$$$$" % self.count
            if (flag == 0):
                print "Unknown IP: %s,Dropping packet" % str(
                    packet.next.protodst)
        f = open('file.py', 'w')
        f.write('count = ' + str(self.count) + '   ' + 'num of packts in:' +
                ' ' + str(self.packetin) + '\n')
        f.close()
        ########################################################################################

        # handling IPV4 packets
        if isinstance(packet.next, ipv4):
            log.debug("%i %i IP %s => %s", dpid, inport, packet.next.srcip,
                      packet.next.dstip)
            srcaddr = packet.next.srcip
            srcaddr_old = packet.next.srcip
            dstaddr = packet.next.dstip
            dstaddr_old = packet.next.dstip
            # if source is virtual we change it to real
            if self.isVirtualIPAddress(str(srcaddr)):
                srcaddr = IPAddr(self.V2R_Map[str(srcaddr)])
                print("Changing SRC VIRTUAL IP " + self.R2V_Map[str(srcaddr)] +
                      "---> REAL SRC IP " + str(srcaddr))

# if destination is virtual we change it to real
            if self.isVirtualIPAddress(str(dstaddr)):
                dstaddr = IPAddr(self.V2R_Map[str(dstaddr)])
                print("Changing DST VIRTUAL IP " + self.R2V_Map[str(dstaddr)] +
                      "---> REAL SRC IP " + str(dstaddr))
# if the IP was real we update HostMem (ip---dpid) mapping
            if self.isRealIPAddress(
                    str(srcaddr_old)) and srcaddr not in self.HostMem.keys():
                self.HostMem[srcaddr] = dpid
            dpid = self.HostMem[srcaddr]
            if self.isRealIPAddress(
                    str(dstaddr_old)) and dstaddr not in self.HostMem.keys():
                self.HostMem[dstaddr] = dpid
            dpid = self.HostMem[dstaddr]

            #update the correct macaddr
            if self.isVirtualIPAddress(str(srcaddr_old)):
                macaddr = dpid_to_mac(dpid)
            else:
                macaddr = packet.src
            self._send_lost_buffers(dpid, srcaddr, macaddr, inport)
            # Learn or update the correct port/MAC fron arpTable
            if srcaddr in self.arpTable[dpid]:
                if self.arpTable[dpid][srcaddr] != (inport, macaddr):
                    log.info("%i %i RE-learned %s", dpid, inport, srcaddr)
            else:
                log.debug("%i %i learned %s", dpid, inport, str(srcaddr))
            # if source was real update arpTable
            if (self.isRealIPAddress(str(srcaddr_old))):
                self.arpTable[dpid][srcaddr] = Entry(inport, macaddr)
            # if source was virtual take the correct values from arpTable
# mininet give us wrong values when we use virtual IP
            if self.isVirtualIPAddress(str(srcaddr_old)):
                inport = self.arpTable[dpid][srcaddr].port
                macaddr = self.arpTable[dpid][srcaddr].mac

            # if we have a destination forward the packet
            if dstaddr in self.arpTable[dpid]:

                prt = self.arpTable[dpid][dstaddr].port
                mac = self.arpTable[dpid][dstaddr].mac
                if prt == inport:
                    log.warning(
                        "%i %i not sending packet for %s back out of the " +
                        "input port" % (dpid, inport, str(dstaddr)))
                else:
                    log.debug(
                        "%i %i installing flow for %s => %s out port %i" %
                        (dpid, inport, srcaddr, dstaddr, prt))

                    actions = []
                    actions.append(of.ofp_action_dl_addr.set_dst(mac))
                    actions.append(of.ofp_action_output(port=prt))
                    match = of.ofp_match.from_packet(packet, inport)
                    match.dl_src = None  # Wildcard source MAC

                    msg = of.ofp_flow_mod(command=of.OFPFC_ADD,
                                          idle_timeout=FLOW_IDLE_TIMEOUT,
                                          hard_timeout=of.OFP_FLOW_PERMANENT,
                                          buffer_id=event.ofp.buffer_id,
                                          actions=actions,
                                          match=of.ofp_match.from_packet(
                                              packet, inport))
                    event.connection.send(msg.pack())
# if we don't have a destination drop the packet.
            elif not (self.isRealIPAddress(
                    str(dstaddr))) or not (self.isRealIPAddress(str(srcaddr))):
                po = of.ofp_packet_out(buffer_id=buffer_id, in_port=in_port)
                core.openflow.sendToDPID(dpid, po)
                log.warning(
                    "Moving Targed Defense has blocked a packet from unknown source"
                )

# handles arp packet
        elif isinstance(packet.next, arp):
            a = packet.next

            log.debug("%i %i ARP %s %s => %s", dpid, inport, {
                arp.REQUEST: "request",
                arp.REPLY: "reply"
            }.get(a.opcode, 'op:%i' % (a.opcode, )), str(a.protosrc),
                      str(a.protodst))
            dstaddr2 = a.protodst
            dstaddr2_old = a.protodst
            srcaddr2 = a.protosrc
            srcaddr2_old = srcaddr2

            if self.isVirtualIPAddress(str(srcaddr2)):
                srcaddr2 = IPAddr(self.V2R_Map[str(srcaddr2)])
                print("arp: Changing SRC VIRTUAL IP " +
                      self.R2V_Map[str(srcaddr2)] + "---> REAL SRC IP " +
                      str(srcaddr2))
            if self.isVirtualIPAddress(str(dstaddr2)):
                dstaddr2 = IPAddr(self.V2R_Map[str(dstaddr2)])
                print("arp: Changing DST VIRTUAL IP " +
                      self.R2V_Map[str(dstaddr2)] + "---> REAL DST IP " +
                      str(dstaddr2))
            if self.isRealIPAddress(
                    str(srcaddr2_old)) and srcaddr2 not in self.HostMem.keys():
                self.HostMem[srcaddr2] = dpid
            if self.isRealIPAddress(
                    str(dstaddr2_old)) and dstaddr2 not in self.HostMem.keys():
                self.HostMem[dstaddr2] = dpid
            dpid = self.HostMem[srcaddr2]
            if self.isVirtualIPAddress(str(srcaddr2_old)):
                macaddr = dpid_to_mac(dpid)
            else:
                macaddr = packet.src
            #macaddr = self.arpTable[dpid][srcaddr2].mac
            a.prototype = arp.PROTO_TYPE_IP
            a.hwtype = arp.HW_TYPE_ETHERNET

            if srcaddr2 != 0:

                # Learn or update port/MAC info
                if srcaddr2 in self.arpTable[dpid]:
                    if self.arpTable[dpid][srcaddr2] != (inport, macaddr):
                        log.info("%i %i RE-learned %s", dpid, inport,
                                 str(srcaddr2))
                else:
                    log.debug("%i %i learned %s", dpid, inport, str(srcaddr2))
                if (self.isRealIPAddress(str(srcaddr2_old))):
                    self.arpTable[dpid][srcaddr2] = Entry(inport, macaddr)
                if self.isVirtualIPAddress(str(srcaddr2_old)):
                    #for keys,values in self.HostMem :
                    # print (keys)
                    #print (values)
                    inport = self.arpTable[dpid][srcaddr2].port
                # Send any waiting packets...
                self._send_lost_buffers(dpid, str(srcaddr2), macaddr, inport)

                if a.opcode == arp.REQUEST:
                    # Check if we can answer
                    dstaddr2 = a.protodst

                    if dstaddr2 in self.arpTable[dpid]:
                        # destination exists

                        if not self.arpTable[dpid][dstaddr2].isExpired():

                            # We will reply ourselves

                            r = arp()
                            r.hwtype = a.hwtype
                            r.prototype = a.prototype
                            r.hwlen = a.hwlen
                            r.protolen = a.protolen
                            r.opcode = arp.REPLY
                            r.hwdst = a.hwsrc
                            r.protodst = IPAddr(self.ReturnRealIP(srcaddr2))
                            r.protosrc = IPAddr(self.ReturnRealIP(dstaddr2))
                            r.hwsrc = self.arpTable[dpid][dstaddr2].mac
                            e = ethernet(type=packet.type,
                                         src=dpid_to_mac(dpid),
                                         dst=a.hwsrc)
                            e.set_payload(r)
                            log.debug("%i %i answering ARP for %s" %
                                      (dpid, inport, str(r.protosrc)))
                            msg = of.ofp_packet_out()
                            msg.data = e.pack()
                            msg.actions.append(
                                of.ofp_action_output(port=of.OFPP_IN_PORT))
                            msg.in_port = inport
                            event.connection.send(msg)
                            return

# if source and dest were not virtual or real we dropp the packet
                    elif not (self.isRealIPAddress(str(dstaddr2))) or not (
                            self.isRealIPAddress(str(srcaddr2))):
                        po = of.ofp_packet_out(buffer_id=buffer_id,
                                               in_port=in_port)
                        core.openflow.sendToDPID(dpid, po)
                        log.warning(
                            "Moving Targed Defense has blocked a packet from unknown source"
                        )

            srcaddr2_old = srcaddr2

            # unrecognized arp: if source is recognized av Virtual or Real than
            # we flood the packet throgh the network

            if self.isVirtualIPAddress(str(srcaddr2)):
                srcaddr2 = IPAddr(self.V2R_Map[str(srcaddr2)])
                print("arp flood: Changing SRC VIRTUAL IP " +
                      self.R2V_Map[str(srcaddr2)] + "---> REAL SRC IP " +
                      str(srcaddr2))
            if self.isVirtualIPAddress(str(dstaddr2)):
                dstaddr2 = IPAddr(self.V2R_Map[str(dstaddr2)])
                print("arp flood: Changing DST VIRTUAL IP " +
                      self.R2V_Map[str(dstaddr2)] + "---> REAL DST IP " +
                      str(dstaddr2))
            if self.isRealIPAddress(
                    str(srcaddr2_old)) and srcaddr2 not in self.HostMem.keys():
                self.HostMem[srcaddr2] = dpid
            dpid = self.HostMem[srcaddr2]
            macaddr = self.arpTable[dpid][srcaddr2].mac
            macaddr = dpid_to_mac(dpid)
            if self.isVirtualIPAddress(str(srcaddr2_old)):
                inport = self.arpTable[dpid][srcaddr2].port
            # just flood it
            log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport, {
                arp.REQUEST: "request",
                arp.REPLY: "reply"
            }.get(a.opcode, 'op:%i' %
                  (a.opcode, )), str(srcaddr2), str(dstaddr2)))
            msg = of.ofp_packet_out(
                in_port=inport,
                data=event.ofp,
                action=of.ofp_action_output(port=of.OFPP_FLOOD))
            event.connection.send(msg)
Ejemplo n.º 34
0
class l3_switch (EventMixin):
  def __init__ (self, fakeways = [], arp_for_unknowns = False):
    # These are "fake gateways" -- we'll answer ARPs for them with MAC
    # of the switch they're connected to.
    self.fakeways = set(fakeways)

    # If this is true and we see a packet for an unknown
    # host, we'll ARP for it.
    self.arp_for_unknowns = arp_for_unknowns

    # (dpid,IP) -> expire_time
    # We use this to keep from spamming ARPs
    self.outstanding_arps = {}

    # (dpid,IP) -> [(expire_time,buffer_id,in_port), ...]
    # These are buffers we've gotten at this datapath for this IP which
    # we can't deliver because we don't know where they go.
    self.lost_buffers = {}

    # For each switch, we map IP addresses to Entries
    self.arpTable = {}

    # This timer handles expiring stuff
    self._expire_timer = Timer(5, self._handle_expiration, recurring=True)

    self.listenTo(core)

  def _handle_expiration (self):
    # Called by a timer so that we can remove old items.
    empty = []
    for k,v in self.lost_buffers.iteritems():
      dpid,ip = k

      for item in list(v):
        expires_at,buffer_id,in_port = item
        if expires_at < time.time():
          # This packet is old.  Tell this switch to drop it.
          v.remove(item)
          po = of.ofp_packet_out(buffer_id = buffer_id, in_port = in_port)
          core.openflow.sendToDPID(dpid, po)
      if len(v) == 0: empty.append(k)

    # Remove empty buffer bins
    for k in empty:
      del self.lost_buffers[k]

  def _send_lost_buffers (self, dpid, ipaddr, macaddr, port):
    """
    We may have "lost" buffers -- packets we got but didn't know
    where to send at the time.  We may know now.  Try and see.
    """
    if (dpid,ipaddr) in self.lost_buffers:
      # Yup!
      bucket = self.lost_buffers[(dpid,ipaddr)]
      del self.lost_buffers[(dpid,ipaddr)]
      log.debug("Sending %i buffered packets to %s from %s"
                % (len(bucket),ipaddr,dpid_to_str(dpid)))
      for _,buffer_id,in_port in bucket:
        po = of.ofp_packet_out(buffer_id=buffer_id,in_port=in_port)
        po.actions.append(of.ofp_action_dl_addr.set_dst(macaddr))
        po.actions.append(of.ofp_action_output(port = port))
        core.openflow.sendToDPID(dpid, po)

  def _handle_GoingUpEvent (self, event):
    self.listenTo(core.openflow)
    log.debug("Up...")

  def _handle_PacketIn (self, event):
    dpid = event.connection.dpid
    inport = event.port
    packet = event.parsed
    
    #print "------------------------------------------------------------------------"
    #print "IPv4: ", event.parsed.find('ipv4')
    #print "ARP: ", event.parsed.find('arp')
    #print "Packet Type: " , packet.type
    
    #print datetime.datetime.now(), ":", packet
    #print "\n", packet.parsed
    #print "\n", event.ofp
    global call_Timer
    global set_Timer
    global diction
    timerSet =False
    
    def preventing():
      global diction
      global set_Timer
      if not set_Timer:
        set_Timer =True

      if len(diction) == 0:
        diction[event.connection.dpid] = {}
        diction[event.connection.dpid][event.port] = 1
      elif event.connection.dpid not in diction:
        diction[event.connection.dpid] = {}
        diction[event.connection.dpid][event.port] = 1
      else:
        if event.connection.dpid in diction:
          if event.port in diction[event.connection.dpid]:
            temp_count=0
            temp_count =diction[event.connection.dpid][event.port]
            temp_count = temp_count+1
            diction[event.connection.dpid][event.port]=temp_count
          else:
            diction[event.connection.dpid][event.port] = 1
   
      print "\n",datetime.datetime.now(), ": printing diction ",str(diction),"\n"
    
    
    def _timer_func ():
      global diction
      #print "Dictionary:", diction
      global set_Timer
      if not set_Timer:
        set_Timer =True

      if set_Timer==True:
        for k,v in diction.iteritems():
          for i,j in v.iteritems():
            if j >=20:
              print "\n",datetime.datetime.now(),"DDOS DETECTED"
              print "\n",str(diction)
              print "\n",datetime.datetime.now(),": BLOCKED PORT NUMBER : ", str(i), " OF SWITCH ID: ", str(k)
              #appending no actions to the out_msg the packets will be dropped from the current DPID-PORT pair  
              dpid = k									    		
              msg = of.ofp_packet_out(in_port=i)
              core.openflow.sendToDPID(dpid,msg)
      diction={}
    
    if not packet.parsed:
      log.warning("%i %i ignoring unparsed packet", dpid, inport)
      return

    if dpid not in self.arpTable:
      # New switch -- create an empty table
      self.arpTable[dpid] = {}
      for fake in self.fakeways:
        self.arpTable[dpid][IPAddr(fake)] = Entry(of.OFPP_NONE,
         dpid_to_mac(dpid))
    #print "Arp table: ", str(self.arpTable)
    if packet.type == ethernet.LLDP_TYPE:
      # Ignore LLDP packets
      return

    if isinstance(packet.next, ipv4):
      log.debug("%i %i IP %s => %s", dpid,inport,
                packet.next.srcip,packet.next.dstip)
      #print "\n"
      chi_obj.stats(packet.next.srcip)      #edit
      chi_obj.baseLine()		    #edit
      if chi_obj.y < 0.05 :
        print "DDoS might be there"
        preventing()
	      Timer(10, _timer_func)              

      # Send any waiting packets...
      self._send_lost_buffers(dpid, packet.next.srcip, packet.src, inport)
      #print "LOST BUFFERS: " , str(self.lost_buffers) #edited

      # Learn or update port/MAC info
      if packet.next.srcip in self.arpTable[dpid]:
        #print packet.next.srcip , "#editing"
        if self.arpTable[dpid][packet.next.srcip] != (inport, packet.src):
          log.info("%i %i RE-learned %s", dpid,inport,packet.next.srcip)
      else:
        log.debug("%i %i learned %s", dpid,inport,str(packet.next.srcip))
      self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src)
      #print "Arp table: ", str(self.arpTable)
      # Try to forward
      dstaddr = packet.next.dstip
      if dstaddr in self.arpTable[dpid]:
        # We have info about what port to send it out on...

        prt = self.arpTable[dpid][dstaddr].port
        mac = self.arpTable[dpid][dstaddr].mac
        if prt == inport:
          log.warning("%i %i not sending packet for %s back out of the " +
                      "input port" % (dpid, inport, str(dstaddr)))
        else:
          log.debug("%i %i installing flow for %s => %s out port %i"
                    % (dpid, inport, packet.next.srcip, dstaddr, prt))

          actions = []
          actions.append(of.ofp_action_dl_addr.set_dst(mac))
          actions.append(of.ofp_action_output(port = prt))
          match = of.ofp_match.from_packet(packet, inport)
          match.dl_src = None # Wildcard source MAC

          msg = of.ofp_flow_mod(command=of.OFPFC_ADD,
                                idle_timeout=FLOW_IDLE_TIMEOUT,
                                hard_timeout=of.OFP_FLOW_PERMANENT,
                                buffer_id=event.ofp.buffer_id,
                                actions=actions,
                                match=of.ofp_match.from_packet(packet,
                                                               inport))
          event.connection.send(msg.pack())
      elif self.arp_for_unknowns:
        # We don't know this destination.
        # First, we track this buffer so that we can try to resend it later
        # if we learn the destination, second we ARP for the destination,
        # which should ultimately result in it responding and us learning
        # where it is

        # Add to tracked buffers
        if (dpid,dstaddr) not in self.lost_buffers:
          self.lost_buffers[(dpid,dstaddr)] = []
        bucket = self.lost_buffers[(dpid,dstaddr)]
        entry = (time.time() + MAX_BUFFER_TIME,event.ofp.buffer_id,inport)
        bucket.append(entry)
        while len(bucket) > MAX_BUFFERED_PER_IP: del bucket[0]

        # Expire things from our outstanding ARP list...
        self.outstanding_arps = {k:v for k,v in
         self.outstanding_arps.iteritems() if v > time.time()}

        # Check if we've already ARPed recently
        if (dpid,dstaddr) in self.outstanding_arps:
          # Oop, we've already done this one recently.
          return

        # And ARP...
        self.outstanding_arps[(dpid,dstaddr)] = time.time() + 4

        r = arp()
        r.hwtype = r.HW_TYPE_ETHERNET
        r.prototype = r.PROTO_TYPE_IP
        r.hwlen = 6
        r.protolen = r.protolen
        r.opcode = r.REQUEST
        r.hwdst = ETHER_BROADCAST
        r.protodst = dstaddr
        r.hwsrc = packet.src
        r.protosrc = packet.next.srcip
        e = ethernet(type=ethernet.ARP_TYPE, src=packet.src,
                     dst=ETHER_BROADCAST)
        e.set_payload(r)
        log.debug("%i %i ARPing for %s on behalf of %s" % (dpid, inport,
         str(r.protodst), str(r.protosrc)))
        msg = of.ofp_packet_out()
        msg.data = e.pack()
        msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD))
        msg.in_port = inport
        event.connection.send(msg)

    elif isinstance(packet.next, arp):
      a = packet.next
      log.debug("%i %i ARP %s %s => %s", dpid, inport,
       {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode,
       'op:%i' % (a.opcode,)), str(a.protosrc), str(a.protodst))

      if a.prototype == arp.PROTO_TYPE_IP:
        if a.hwtype == arp.HW_TYPE_ETHERNET:
          if a.protosrc != 0:

            # Learn or update port/MAC info
            if a.protosrc in self.arpTable[dpid]:
              if self.arpTable[dpid][a.protosrc] != (inport, packet.src):
                log.info("%i %i RE-learned %s", dpid,inport,str(a.protosrc))
            else:
              log.debug("%i %i learned %s", dpid,inport,str(a.protosrc))
            self.arpTable[dpid][a.protosrc] = Entry(inport, packet.src)

            # Send any waiting packets...
            self._send_lost_buffers(dpid, a.protosrc, packet.src, inport)

            if a.opcode == arp.REQUEST:
              # Maybe we can answer

              if a.protodst in self.arpTable[dpid]:
                # We have an answer...

                if not self.arpTable[dpid][a.protodst].isExpired():
                  # .. and it's relatively current, so we'll reply ourselves

                  r = arp()
                  r.hwtype = a.hwtype
                  r.prototype = a.prototype
                  r.hwlen = a.hwlen
                  r.protolen = a.protolen
                  r.opcode = arp.REPLY
                  r.hwdst = a.hwsrc
                  r.protodst = a.protosrc
                  r.protosrc = a.protodst
                  r.hwsrc = self.arpTable[dpid][a.protodst].mac
                  e = ethernet(type=packet.type, src=dpid_to_mac(dpid),
                               dst=a.hwsrc)
                  e.set_payload(r)
                  log.debug("%i %i answering ARP for %s" % (dpid, inport,
                   str(r.protosrc)))
                  msg = of.ofp_packet_out()
                  msg.data = e.pack()
                  msg.actions.append(of.ofp_action_output(port =
                                                          of.OFPP_IN_PORT))
                  msg.in_port = inport
                  event.connection.send(msg)
                  return

      # Didn't know how to answer or otherwise handle this ARP, so just flood it
      log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport,
       {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode,
       'op:%i' % (a.opcode,)), str(a.protosrc), str(a.protodst)))

      msg = of.ofp_packet_out(in_port = inport, data = event.ofp,
          action = of.ofp_action_output(port = of.OFPP_FLOOD))
      event.connection.send(msg)
Ejemplo n.º 35
0
def _handle_PacketIn (event):
    global l1_dpid,l2_dpid,l3_dpid,s4_dpid,s5_dpid,status
    packet = event.parsed
    arp_table = {"10.0.0.1": "00:00:00:00:00:01", "10.0.0.2": "00:00:00:00:00:02", "10.0.0.3": "000000000003", "10.0.0.4": "000000000004", "10.0.0.5": "000000000005", "10.0.0.6": "000000000006"}
    if packet.type == packet.ARP_TYPE:
        a = packet.find("arp")
        if a.opcode == a.REQUEST:

            #obtain ARP request from packet and create ARP reply
            r = arp()
            r.hwtype = a.hwtype
            r.prototype = a.prototype
            r.hwsrc = EthAddr(arp_table[str(packet.payload.protodst)])# request MAC address
            r.hwdst = packet.src
            r.opcode = arp.REPLY
            r.protosrc =  packet.payload.protodst
            r.protodst = packet.payload.protosrc

            #make ethernet packet
            eth = ethernet()
            eth.type = ethernet.ARP_TYPE
            eth.dst = packet.src
            eth.src = r.hwsrc
            eth.payload = r

            #send ARP to client
            msg = of.ofp_packet_out()
            msg.data = eth.pack()
            msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))
            msg.in_port = event.port
            event.connection.send(msg)
    if event.connection.dpid==l1_dpid:
		#print("Hello")
		sw = 0
		for i in range(1,3):
			for j in range(1,7):
				if i != j :
					msg = of.ofp_flow_mod()
					msg.match.dl_type = 0x0800
					src = "10.0.0." + str(i) 
					dst = "10.0.0." + str(j)
					msg.match.nw_src = src
					msg.match.nw_dst = dst
#					print(msg)
#					print(msg.match)
#					print(status)
#					print(sw)
#					print(Table[status][sw])
#					print((i,j))
#					print(Table[status][sw][(i,j)][0])
#					print(Table[status][sw][(i,j)][1])
					outPort = Table[status][sw][(i,j)][0]
					msg.actions.append(of.ofp_action_output(port = outPort))
					msg.priority = Table[status][sw][(i,j)][1]
					event.connection.send(msg)
					# exchange i j
					msg = of.ofp_flow_mod()
					msg.match.dl_type = 0x0800
					src = "10.0.0." + str(j) 
					dst = "10.0.0." + str(i)
					msg.match.nw_src = src
					msg.match.nw_dst = dst
#					print(status)
#					print(sw)
#					print(Table[status][sw])
#					print((j,i))
#					print(Table[status][sw][(j,i)][0])
#					print(Table[status][sw][(j,i)][1])
					outPort = Table[status][sw][(j,i)][0]
					msg.actions.append(of.ofp_action_output(port = outPort))
					msg.priority = Table[status][sw][(j,i)][1]
					event.connection.send(msg)
		for i in range(1,7):
			for j in range(1,7):
				if i != j :		
					src = EthAddr("00:00:00:00:00:0"+ str(i))
					dst = EthAddr("00:00:00:00:00:0"+ str(j))
					if src == packet.src:
						if dst == packet.dst:
							outPort = Table[status][sw][(i,j)][0]
							msg1 = of.ofp_packet_out(data = event.ofp)
							msg1.actions.append(of.ofp_action_output(port = outPort))
							event.connection.send(msg1)
                                                        log.debug("Sent a message for %s -> %s" % (src, dst, ))
    elif event.connection.dpid==l2_dpid:
		sw = 1
		for i in range(3,5):
			for j in range(1,7):
				if i != j :
					msg = of.ofp_flow_mod()
					msg.match.dl_type = 0x0800
					src = "10.0.0." + str(i) 
					dst = "10.0.0." + str(j)
					msg.match.nw_src = src
					msg.match.nw_dst = dst
#					print(status)
#					print(sw)
#					print(Table[status][sw])
#					print((i,j))
#					print(Table[status][sw][(i,j)][0])
#					print(Table[status][sw][(i,j)][1])
					outPort = Table[status][sw][(i,j)][0]
					msg.actions.append(of.ofp_action_output(port = outPort))
					msg.priority = Table[status][sw][(i,j)][1]
					event.connection.send(msg)
					# exchange i j
					msg = of.ofp_flow_mod()
					msg.match.dl_type = 0x0800
					src = "10.0.0." + str(j) 
					dst = "10.0.0." + str(i)
					msg.match.nw_src = src
					msg.match.nw_dst = dst
#					print(status)
#					print(sw)
#					print(Table[status][sw])
#					print((j,i))
#					print(Table[status][sw][(j,i)][0])
#					print(Table[status][sw][(j,i)][1])
					outPort = Table[status][sw][(j,i)][0]
					msg.actions.append(of.ofp_action_output(port = outPort))
					msg.priority = Table[status][sw][(j,i)][1]
					event.connection.send(msg)
		for i in range(1,7):
			for j in range(1,7):
				if i != j :		
					src = EthAddr("00:00:00:00:00:0"+ str(i))
					dst = EthAddr("00:00:00:00:00:0"+ str(j))
					if src == packet.src:
						if dst == packet.dst:
							outPort = Table[status][sw][(i,j)][0]
							msg1 = of.ofp_packet_out(data = event.ofp)
							msg1.actions.append(of.ofp_action_output(port = outPort))
							event.connection.send(msg1)
    elif event.connection.dpid==l3_dpid:
		sw = 2
		for i in range(5,7):
			for j in range(1,7):
				if i != j :
					msg = of.ofp_flow_mod()
					msg.match.dl_type = 0x0800
					src = "10.0.0." + str(i) 
					dst = "10.0.0." + str(j)
					msg.match.nw_src = src
					msg.match.nw_dst = dst
#					print(status)
#					print(sw)
#					print(Table[status][sw])
#					print((i,j))
#					print(Table[status][sw][(i,j)][0])
#					print(Table[status][sw][(i,j)][1])
					outPort = Table[status][sw][(i,j)][0]
					msg.actions.append(of.ofp_action_output(port = outPort))
					msg.priority = Table[status][sw][(i,j)][1]
					event.connection.send(msg)
					# exchange i j
					msg = of.ofp_flow_mod()
					msg.match.dl_type = 0x0800
					src = "10.0.0." + str(j) 
					dst = "10.0.0." + str(i)
					msg.match.nw_src = src
					msg.match.nw_dst = dst
#					print(status)
#					print(sw)
#					print(Table[status][sw])
#					print((j,i))
#					print(Table[status][sw][(j,i)][0])
#					print(Table[status][sw][(j,i)][1])
					outPort = Table[status][sw][(j,i)][0]
					msg.actions.append(of.ofp_action_output(port = outPort))
					msg.priority = Table[status][sw][(j,i)][1]
					event.connection.send(msg)
		for i in range(1,7):
			for j in range(1,7):
				if i != j :		
					src = EthAddr("00:00:00:00:00:0"+ str(i))
					dst = EthAddr("00:00:00:00:00:0"+ str(j))
					if src == packet.src:
						if dst == packet.dst:
							outPort = Table[status][sw][(i,j)][0]
							msg1 = of.ofp_packet_out(data = event.ofp)
							msg1.actions.append(of.ofp_action_output(port = outPort))
							event.connection.send(msg1)
    elif event.connection.dpid==s4_dpid:
		sw = 3
		if status == 0:
			for i in range(1,7,2):
				for j in range(1,7):
					if i != j and i+1 != j:
						msg = of.ofp_flow_mod()
						msg.match.dl_type = 0x0800
						src = "10.0.0." + str(i) 
						dst = "10.0.0." + str(j)
						msg.match.nw_src = src
						msg.match.nw_dst = dst
#						print(status)
#						print(sw)
#						print(Table[status][sw])
#						print((i,j))
#						print(Table[status][sw][(i,j)][0])
#						print(Table[status][sw][(i,j)][1])
						outPort = Table[status][sw][(i,j)][0]
						msg.actions.append(of.ofp_action_output(port = outPort))
						msg.priority = Table[status][sw][(i,j)][1]
						event.connection.send(msg)
			for i in range(1,7):
				for j in range(1,7):
					if i != j :		
						src = EthAddr("00:00:00:00:00:0"+ str(i))
						dst = EthAddr("00:00:00:00:00:0"+ str(j))
						if src == packet.src:
							if dst == packet.dst:
								outPort = Table[status][sw][(i,j)][0]
								msg1 = of.ofp_packet_out(data = event.ofp)
								msg1.actions.append(of.ofp_action_output(port = outPort))
								event.connection.send(msg1)
		elif status == 1:
			for i in range(1,7):
				for j in range(1,7):
					if i != j and (i,j) != (1,2) and (i,j) != (2,1) and (i,j) != (3,4) and (i,j) != (4,3) and (i,j) != (5,6) and (i,j) != (6,5) :
						msg = of.ofp_flow_mod()
						msg.match.dl_type = 0x0800
						src = "10.0.0." + str(i) 
						dst = "10.0.0." + str(j)
						msg.match.nw_src = src
						msg.match.nw_dst = dst
#						print(status)
#						print(sw)
#						print(Table[status][sw])
#						print((i,j))
#						print(Table[status][sw][(i,j)][0])
#						print(Table[status][sw][(i,j)][1])
						outPort = Table[status][sw][(i,j)][0]
						msg.actions.append(of.ofp_action_output(port = outPort))
						msg.priority = Table[status][sw][(i,j)][1]
						event.connection.send(msg)
			for i in range(1,7):
				for j in range(1,7):
					if i != j :		
						src = EthAddr("00:00:00:00:00:0"+ str(i))
						dst = EthAddr("00:00:00:00:00:0"+ str(j))
						if src == packet.src:
							if dst == packet.dst:
								outPort = Table[status][sw][(i,j)][0]
								msg1 = of.ofp_packet_out(data = event.ofp)
								msg1.actions.append(of.ofp_action_output(port = outPort))
								event.connection.send(msg1)	
    elif event.connection.dpid==s5_dpid:
		sw = 4
		if status == 0:
			for i in range(2,8,2):
				for j in range(1,7):
					if i != j and i-1 != j:
						msg = of.ofp_flow_mod()
						msg.match.dl_type = 0x0800
						src = "10.0.0." + str(i) 
						dst = "10.0.0." + str(j)
						msg.match.nw_src = src
						msg.match.nw_dst = dst
#						print(status)
#						print(sw)
#						print(Table[status][sw])
#						print((i,j))
#						print(Table[status][sw][(i,j)][0])
#						print(Table[status][sw][(i,j)][1])
						outPort = Table[status][sw][(i,j)][0]
						msg.actions.append(of.ofp_action_output(port = outPort))
						msg.priority = Table[status][sw][(i,j)][1]
						event.connection.send(msg)
			for i in range(1,7):
				for j in range(1,7):
					if i != j :		
						src = EthAddr("00:00:00:00:00:0"+ str(i))
						dst = EthAddr("00:00:00:00:00:0"+ str(j))
						if src == packet.src:
							if dst == packet.dst:
								outPort = Table[status][sw][(i,j)][0]
								msg1 = of.ofp_packet_out(data = event.ofp)
								msg1.actions.append(of.ofp_action_output(port = outPort))
								event.connection.send(msg1)
		elif status == 2:
			for i in range(1,7):
				for j in range(1,7):
					if i != j and (i,j) != (1,2) and (i,j) != (2,1) and (i,j) != (3,4) and (i,j) != (4,3) and (i,j) != (5,6) and (i,j) != (6,5) :
						msg = of.ofp_flow_mod()
						msg.match.dl_type = 0x0800
						src = "10.0.0." + str(i) 
						dst = "10.0.0." + str(j)
						msg.match.nw_src = src
						msg.match.nw_dst = dst
#						print(status)
#						print(sw)
#						print(Table[status][sw])
#						print((i,j))
#						print(Table[status][sw][(i,j)][0])
#						print(Table[status][sw][(i,j)][1])
						outPort = Table[status][sw][(i,j)][0]
						msg.actions.append(of.ofp_action_output(port = outPort))
						msg.priority = Table[status][sw][(i,j)][1]
						event.connection.send(msg)
			for i in range(1,7):
				for j in range(1,7):
					if i != j :		
						src = EthAddr("00:00:00:00:00:0"+ str(i))
						dst = EthAddr("00:00:00:00:00:0"+ str(j))
						if src == packet.src:
							if dst == packet.dst:
								outPort = Table[status][sw][(i,j)][0]
								msg1 = of.ofp_packet_out(data = event.ofp)
								msg1.actions.append(of.ofp_action_output(port = outPort))
								event.connection.send(msg1)	
Ejemplo n.º 36
0
def client_handler(address, fd, events):
  global ip_type
  sock = tables.fd_map[fd]
  if events & io_loop.READ:
    data = sock.recv(16384)
    if data == '':
      print "connection dropped"
      #when switch is dropped, the outdated information should be deleted
      io_loop.remove_handler(fd)
      if fd in tables.fd_map.iterkeys() and fd in tables.sock_dpid.iterkeys():
        dpid = tables.sock_dpid[fd][1]
        tables.sock_dpid.pop(fd)
        tables.fd_map.pop(fd)
      
        for link in tables.topo_map.iterkeys():
          if tables.topo_map[link]['status'] != -1 and (link[0] == dpid or link[2] == dpid):
            tables.topo_map[link]['status'] = -1#the link will not be re-counted
            dc.topo_flag += 2#when topo_flag>0, controller will stop dealing with packet
        tables.switch_map.pop(dpid)
        if dpid in tables.info_map.iterkeys():
          tables.info_map.pop(dpid)
        if dpid in tables.flow_map.iterkeys():
          tables.flow_map.pop(dpid)
      
        create_topo._connection_down(dpid)#renew the topo in discovery.py
        create_topo._sender._connection_down(dpid)
        
    if len(data)<8:
      print "not a openflow message"
    else:
      if len(data)>8:
        rmsg = of.ofp_header(data[0:8])
        body = data[8:]
      else:
        rmsg = of.ofp_header(data)

      if rmsg.type == 0:
        print "OFPT_HELLO"
        msg = of.ofp_header(type = 5)#we send the features_request here.
        print "OFPT_FEATURES_REQUEST"
        io_loop.update_handler(fd, io_loop.WRITE)
        message_queue_map[sock].put(data)
        message_queue_map[sock].put(str(msg))

      elif rmsg.type == 1:
        print "OFPT_ERROR"
        of.ofp_error_msg(body).show()

      elif rmsg.type == 2:
        #since the ECHO is too frequent, the print is canceled
        #print "OFPT_ECHO_REQUEST"
        msg = of.ofp_header(type=3, xid=rmsg.xid)
        message_queue_map[sock].put(str(msg))
        io_loop.update_handler(fd, io_loop.WRITE)

      elif rmsg.type == 3:
        print "OFPT_ECHO_REPLY"

      elif rmsg.type == 4:
        print "OFPT_VENDOR"

      elif rmsg.type == 5:
        print "OFPT_FEATURES_REQUEST"

      elif rmsg.type == 6:
        print "OFPT_FEATURES_REPLY"
        msg = of.ofp_features_reply(body[0:24])                   #length of reply msg
        tables.sock_dpid[fd]=[0, msg.datapath_id]                             #sock_dpid[fd] comes from here.

        port_info_raw = str(body[24:])                            #we change it into str so we can manipulate it.
        port_info = {}
        print "port number:",len(port_info_raw)/48, "total length:", len(port_info_raw)
        for i in range(len(port_info_raw)/48):
          port_info[i] = of.ofp_phy_port(port_info_raw[0+i*48:48+i*48])
          print port_info[i].port_no     
                
      elif rmsg.type == 10:
        #print "OFPT_PACKET_IN"
        pkt_in_msg = of.ofp_packet_in(body)#buffer_id+in_port
        raw = pkt_in_msg.load
        pkt_ = ethernet(raw)#this method can be located in pox
        pkt_parsed = of.Ether(raw)
        dpid = tables.sock_dpid[fd][1]
        if pkt_.effective_ethertype == 0x88cc:#deal with the LLDP for topo
          create_topo._handle_openflow_PacketIn(pkt_in_msg, pkt_, dpid)
        if dc.topo_flag:#when the topo is not completed, do nothing
          pass
        else:      
          if pkt_.effective_ethertype == 0x0806:
            #the ARP table is maintained for hosts' MAC in tables.py
            print "\n\nARP\n\n"
            request = pkt_parsed.next         
            if request.opcode == arp.REQUEST:
              reply = arp()
              reply.hwtype = request.hwtype
              reply.prototype = request.prototype
              reply.hwlen = request.hwlen
              reply.protolen = request.protolen
              reply.opcode = arp.REPLY
              reply.hwdst = request.hwsrc
              reply.protodst = request.protosrc
              reply.protosrc = request.protodst
              reply.hwsrc = tables.get_mac(request.protodst.toStr())
              #reply.hwsrc = tables.ip_mac[request.protodst]
              e_dpid = tables.sock_dpid[fd][1]
              for p,v in tables.switch_map[e_dpid]['port'].items():
                if v.port_no == pkt_in_msg.in_port:
                  e_src = v.hw_addr
              e = ethernet(type = pkt_parsed.type, src = e_src, dst = pkt_parsed.src)
              e.set_payload(reply)               
              msg = off.ofp_packet_out()
              msg.data = e.pack()
              msg.actions.append(off.ofp_action_output(port = off.OFPP_IN_PORT))#port problem
              msg.in_port = pkt_in_msg.in_port
              msg = msg.pack()

              io_loop.update_handler(fd, io_loop.WRITE)
              message_queue_map[sock].put(str(msg))
          elif pkt_.effective_ethertype == 0x8100:
            #to detect VLAN packets
            print "VLAN:\n"
            packet = pkt_.next
            print packet.__dict__
          elif pkt_.effective_ethertype == 0x0800:
            #print "\n\nIP\n\n"
            #use the packet to produce flow_mod
            packet = pkt_.next
            if isinstance(packet, ipv4):
              src = packet.srcip.toStr()
              dst = packet.dstip.toStr()
              dpid = tables.sock_dpid[fd][1]
              #the routing type of the link(src,dst) is based on s_type
              if (src, dst) in ip_type.iterkeys():
                s_type = ip_type[(src,dst)]
			  elif stype != '0':
                s_type = stype
              else:
                s_type = '0'
              #src_mac = tables.switch_map[dpid]['port'][src_port].hw_addr
              #dst_mac = tables.switch_map[dpid]['port'][dst_port].hw_addr
              road, rlink, route_type = route.add_link(src, dst, s_type)
              #establish info for barrier
              if (src,dst) not in tables.road_map.iterkeys():
                tables.road_map[(src,dst)] = road
              if (src,dst) not in tables.barrier_map.iterkeys():
                tables.barrier_map[(src,dst)] = {}
              if dpid not in tables.barrier_map[(src,dst)].iterkeys():
                tables.barrier_map[(src,dst)][dpid] = rmsg.xid
              if route_type == 0:#ip link, send flow
                ip_type[(src,dst)] = '1'
                if dpid in rlink.iterkeys():
                  src_port, dst_port = rlink[dpid][0], rlink[dpid][1] 
                  print "flow from ", src, " to ", dst, "\n"
                  print "dpid:",dpid," inport:",src_port," outport:",dst_port, "\n"
                  print "-------------------------"
                  header = of.ofp_header(type=14, length = 88, xid=rmsg.xid)
                  wildcards = of.ofp_flow_wildcards(OFPFW_NW_TOS=1,      OFPFW_DL_VLAN_PCP=1,
                                              OFPFW_NW_DST_MASK=63, OFPFW_NW_SRC_MASK=63,
                                              OFPFW_TP_DST=1,      OFPFW_TP_SRC=1,
                                              OFPFW_NW_PROTO=1,    OFPFW_DL_TYPE=1,
                                              OFPFW_DL_DST=0,      OFPFW_DL_SRC=0,
                                              OFPFW_DL_VLAN=1,     OFPFW_IN_PORT=0)
                  match = of.ofp_match(in_port=pkt_in_msg.in_port,
                          dl_src = pkt_parsed.src, dl_dst = pkt_parsed.dst,
                          dl_type = pkt_parsed.type,
                          nw_tos = pkt_parsed.payload.tos, 
                          nw_proto = pkt_parsed.payload.proto,
                          nw_src=src,  nw_dst=dst)
                  flow_mod = of.ofp_flow_mod(buffer_id = pkt_in_msg.buffer_id, idle_timeout = 0, hard_timeout = 30, flags = 1, cookie = rmsg.xid, out_port = dst_port)
                  action_header = oof.ofp_action_header(type = 0)
                  action_output = of.ofp_action_output(type = 0, port = dst_port, len = 8)
                  msg = header/wildcards/match/flow_mod/action_header/action_output
                  #here is to renew the flow_map
                  if dpid not in tables.flow_map.iterkeys():
                    tables.flow_map[dpid] = []
                    tables.flow_map[dpid].append(msg)
                  else:
                    for flow in tables.flow_map[dpid]:
                      flow_match = of.ofp_match((str(flow))[12:48])
                      if match == flow_match:
                        tables.flow_map[dpid].remove(flow)
                        break
                    tables.flow_map[dpid].append(msg)
                message_queue_map[sock].put(str(msg))
                io_loop.update_handler(fd, io_loop.WRITE)

              elif route_type == 1:#otn or wavelenth
                ip_type[(src,dst)] = '2'
                if dpid in rlink.iterkeys():
                  src = packet.srcip.toStr()
                  dst = packet.dstip.toStr()
                  src_port, dst_port = rlink[dpid][0], rlink[dpid][1]
                  if (src,dst) not in tables.source_map.iterkeys():
                    tables.source_map[(src,dst)] = {}
                  if dpid not in tables.source_map[(src,dst)].iterkeys():
                    tables.source_map[(src,dst)][dpid] = {}
                  if src_port not in tables.source_map[(src,dst)][dpid].iterkeys():
                    tables.source_map[(src,dst)][dpid][src_port] = []
                  if dst_port not in tables.source_map[(src,dst)][dpid].iterkeys():
                    tables.source_map[(src,dst)][dpid][dst_port] = []
                  if dpid == road[-1]:#src host port has no slot
                    src_slot = -1
                  else:
                    for i in xrange(0,80):
                      if tables.info_map[dpid][src_port][i]['status'] == 0:
                        tables.info_map[dpid][src_port][i]['status'] = 1
                        src_slot = i
                        tables.source_map[(src,dst)][dpid][src_port].append(i)
                        break
                  if dpid == road[0]:#dst host port has no slot:
                    dst_slot = -1
                  else:
                    for i in xrange(0,80):
                      if tables.info_map[dpid][dst_port][i]['status'] == 0:
                        tables.info_map[dpid][dst_port][i]['status'] = 1
                        dst_slot = i
                        tables.source_map[(src,dst)][dpid][dst_port].append(i)
                        break

                  cflow_mod = of.ofp_header(type=0xff, xid=rmsg.xid)\
                       /of.ofp_cflow_mod(command=0)\
                       /of.ofp_connect_wildcards()\
                       /of.ofp_connect(in_port = pkt_in_msg.in_port)\
                       /of.ofp_action_output(type=0, port=dst_port, len=8)
                  type = switch_info[tables.sock_dpid[fd][0]]

                  if route_type == 1:#for OTN
                    if src_slot == -1:
                      cflow_mod.payload.payload.payload.nport_in = 81
                    else:
                      cflow_mod.payload.payload.payload.nport_in = src_slot
                    if dst_slot == -1:
                      cflow_mod.payload.payload.payload.nport_out = 81
                    else:  
                      cflow_mod.payload.payload.payload.nport_out = dst_slot
                    cflow_mod.payload.payload.payload.supp_sw_otn_gran_out = tables.switch_map[dpid]['port'][dst_port].SUPP_SW_GRAN
                    cflow_mod.payload.payload.payload.sup_otn_port_bandwidth_out = tables.switch_map[dpid]['port'][dst_port].sup_otn_port_bandwidth

                  elif route_type == 2:#for wavelength
                    cflow_mod.payload.payload.payload.wport_in = src_slot
                    cflow_mod.payload.payload.payload.wport_out = dst_slot
                  
                  #this field is used to record cflow, but I have no ideal about how to delete the outdate flow---------------------
                  
                  if dpid not in tables.cflow_map.iterkeys():#cflow_map,12.19 
                    tables.cflow_map[dpid] = {}
                  tables.cflow_map[dpid][(src,dst)] = cflow_mod

                  print "cflow from ", src, " to ", dst, "\n"
                  print "dpid:", dpid, " in_port:", cflow_mod.payload.payload.payload.in_port, " out_port:", cflow_mod.payload.payload.payload.payload.port, "\n"
                  print "------------------------"
                  message_queue_map[sock].put(str(cflow_mod))
                  io_loop.update_handler(fd, io_loop.WRITE)
              

              #send barrier
              msg = of.ofp_header(type = 18,xid = rmsg.xid) 
              message_queue_map[sock].put(str(msg))
              io_loop.update_handler(fd, io_loop.WRITE)

      elif rmsg.type == 11: 
        print "OFPT_FLOW_REMOVED"
      elif rmsg.type == 12:
        print "OFPT_PORT_STATUS"
      elif rmsg.type == 13:
        print "OFPT_PACKET_OUT"
      elif rmsg.type == 14:
        print "OFPT_FLOW_MOD"
      elif rmsg.type == 15:
        print "OFPT_PORT_MOD"
      elif rmsg.type == 16:
        print "OFPT_STATS_REQUEST"
                
      elif rmsg.type == 17 and len(data)> 12:
        print "OFPT_STATS_REPLY"
        # 1. parsing ofp_stats_reply
        reply_header = of.ofp_stats_reply(body[:4])
        # 2.parsing ofp_flow_stats msg
        if reply_header.type == 0:
          reply_desc = of.ofp_desc_stats(body[4:])
          reply.show()
        elif reply_header.type == 1 and len(data)>92:
          #here informatioin is used for flow stats
          reply_body_data1 = of.ofp_flow_stats(body[4:8])
          # match field in ofp_flow_stats
          reply_body_wildcards = of.ofp_flow_wildcards(body[8:12])
          reply_body_match = of.ofp_match(body[12:48])
          # second part in ofp_flow_stats
          reply_body_data2 = of.ofp_flow_stats_data(body[48:92])
          # 3.parsing actions
          reply_body_action = []
          if len(body[92:])>8:                         #it is very important!
            num = len(body[92:])/8
            for x in xrange(num):
              reply_body_action.append(of.ofp_action_output(body[92+x*8:100+x*8]))
                            
          msg = reply_header/reply_body_data1/reply_body_wildcards/reply_body_match/reply_body_data2

          #the followings are about Load Balancing
          if fd in tables.fd_map.iterkeys() and fd in tables.sock_dpid.iterkeys():
            dpid = tables.sock_dpid[fd][1]
          if dpid in tables.flow_map.iterkeys():
            src_mac = reply_body_match.dl_src
            dst_mac = reply_body_match.dl_dst
            for flow in tables.flow_map[dpid]:
              if flow.payload.payload.dl_src == src_mac and flow.payload.payload.dl_dst == dst_mac:
                src_ip = flow.payload.payload.nw_src
                dst_ip = flow.payload.payload.nw_dst
                pair = (src_ip,dst_ip)
                flow_time = float(reply_body_data2.duration_sec) + float(reply_body_data2.duration_nsec/1000000000)
                flow_data = float(reply_body_data2.byte_count)
                if pair not in ip_stats.iterkeys():
                  ip_stats[pair] = {}
                  ip_stats[pair][0] = {}
                  ip_stats[pair][0]['flow_time'] = flow_time
                  ip_stats[pair][0]['flow_data'] = flow_data
                else:
                  if 1 in ip_stats[pair].iterkeys():#have a pair
                    ip_stats[pair][0]['flow_time'] = ip_stats[pair][1]['flow_time']
                    ip_stats[pair][0]['flow_data'] = ip_stats[pair][1]['flow_data']
                  else:
                    ip_stats[pair][1] = {}
                  ip_stats[pair][1]['flow_time'] = flow_time
                  ip_stats[pair][1]['flow_data'] = flow_data
                  if flow_time != ip_stats[pair][0]['flow_time']:
                    load = (flow_data - ip_stats[pair][0]['flow_data']) / (flow_time - ip_stats[pair][0]['flow_time'])
                    print "now the link ", pair, " load is ", load, "(byte/s)\n"
                    global switch_load
                    if load > switch_load:#change to cflow
                      ip_type[pair] = '2'
                      #todo:flow_mod(delete)

        elif reply_header.type == 2:
          reply_aggregate = of.ofp_aggregate_stats_reply(body[4:])
          reply_aggregate.show()

        elif reply_header.type == 3:
          #table_stats
          length = rmsg.length - 12
          num = length/64
          for i in xrange(num):
            table_body = body[4+i*64:i*64+68]
            reply_table_stats = of.ofp_table_stats(table_body[:36])
            table_wildcards = of.ofp_flow_wildcards(table_body[36:40])
            reply_table_stats_data = of.ofp_table_stats_data(table_body[40:64])
            msg_tmp = reply_header/reply_table_stats/table_wildcards/reply_table_stats_data
          msg = rmsg/msg_tmp
          msg.show() 
        elif reply_header.type == 4:
          #port stats reply
          length = rmsg.length - 12
          num = length/104
          for i in xrange(num):
            offset = 4+i*104
            reply_port_stats = of.ofp_port_stats_reply(body[offset:(offset+104)])
            msg_tmp = reply_header/reply_port_stats
          msg = rmsg/msg_tmp
          msg.show()
        elif reply_header.type == 5:
          #queue reply
          length = rmsg.length - 12
          num = length/32
          if num:                     #if the queue is empty ,you need to check it !
            for i in xrange(num):
              offset = 4+i*32
              queue_reply = of.ofp_queue_stats(body[offset:offset+32])
              msg_tmp = reply_header/queue_reply
            msg = rmsg/msg_tmp
            msg.show()
        elif reply_header.type == 0xffff:
          #vendor reply
          msg = rmsg/reply_header/of.ofp_vendor(body[4:])

      elif rmsg.type == 18:
        print "OFPT_BARRIER_REQUEST"
      #no message body, the xid is the previous barrier request xid
      elif rmsg.type == 19:
        barrier = 0
        dpid = tables.sock_dpid[fd][1]
        for a,b in tables.barrier_map.items():
          for k,v in b.items():
            if k == dpid and v == rmsg.xid:
              if dpid == tables.road_map[a][0]:#if the barrier is from the dst switch, then the road is completed   
                barrier = 1
                print "road ", a, " is completed!\n"
                tables.barrier_map.pop(a)
          if barrier:
            break
          
        #print "OFPT_BARRIER_REPLY: ", rmsg.xid, "Successful"
      elif rmsg.type == 20:
        print "OFPT_QUEUE_GET_CONFIG_REQUEST"
      elif rmsg.type == 21:
        print "OFPT_QUEUE_GET_CONFIG_REPLY"
      elif rmsg.type == 24:
        print "OFPT_CFEATURES_REPLY"
        msg = of.ofp_cfeatures_reply(body[0:24])#length of reply msg
        #bind the bpid and type  (type,  dpid)
        #OTN:WAVE:IP  b'000'
        TYPE = msg.OFPC_IP_SWITCH + msg.OFPC_WAVE_SWITCH * 2 + msg.OFPC_OTN_SWITCH * 4
        tables.sock_dpid[fd] = [TYPE, msg.datapath_id]#IP only
        port_info_raw = body[24:]
        port_info = {}
        port_i = {}
        print "port number:",len(port_info_raw)/72, "total length:", len(port_info_raw)
        for i in range(len(port_info_raw)/72):
          port_info[i] = of.ofp_phy_cport(port_info_raw[i*72:72+i*72])
          port_i[port_info[i].port_no] = port_info[i]

        switch_type = tables.sock_dpid[fd][0]#features recorded in switch_map
        tables.switch_map[msg.datapath_id] = {'features':msg, 'type':switch_type, 'port':port_i}
        tables.info_map[msg.datapath_id] = {} 
 
        #start to discovery
        lldp_flow = create_topo._connection_up(msg.datapath_id)
        
        message_queue_map[sock].put(str(lldp_flow))
        io_loop.update_handler(fd, io_loop.WRITE)#discovery-handle
        
        create_topo._sender._connection_up(msg.datapath_id, port_info)
Ejemplo n.º 37
0
    def _handle_PacketIn(self, event):
        dpid = event.connection.dpid
        inport = event.port
        packet = event.parsed
        if not packet.parsed:
            log.warning("DPID %i PORT %i ignoring unparsed packet", dpid,
                        inport)
            return

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

        if packet.type == ethernet.LLDP_TYPE:
            # Ignore LLDP packets
            return

        if isinstance(packet.next, ipv4):
            log.debug("DPID %i PORT %i IP %s => %s", dpid, inport,
                      packet.next.srcip, packet.next.dstip)

            # Send any waiting packets...
            self._send_lost_buffers(dpid, packet.next.srcip, packet.src,
                                    inport)

            # Learn or update port/MAC info
            if packet.next.srcip in self.arpTable[dpid]:
                if self.arpTable[dpid][packet.next.srcip] != (inport,
                                                              packet.src):
                    log.info("DPID %i PORT %i RE-learned %s", dpid, inport,
                             packet.next.srcip)
            else:
                log.debug("DPID %i PORT %i learned %s", dpid, inport,
                          str(packet.next.srcip))
            self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src)

            # Try to forward
            dstaddr = packet.next.dstip

            if (packet.find("icmp") and (dstaddr in switch)):
                # Reply to pings

                # Make the ping reply
                icmp = pkt.icmp()
                icmp.type = pkt.TYPE_ECHO_REPLY
                icmp.payload = packet.find("icmp").payload

                # Make the IP packet around it
                ipp = pkt.ipv4()
                ipp.protocol = ipp.ICMP_PROTOCOL
                ipp.srcip = packet.find("ipv4").dstip
                ipp.dstip = packet.find("ipv4").srcip

                # Ethernet around that...
                e = pkt.ethernet()
                e.src = packet.dst
                e.dst = packet.src
                e.type = e.IP_TYPE

                # Hook them up...
                ipp.payload = icmp
                e.payload = ipp

                # 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 = e.pack()
                msg.in_port = event.port
                event.connection.send(msg)

                log.debug("%s pinged %s", ipp.dstip, ipp.srcip)

            if dstaddr in self.arpTable[dpid]:
                # We have info about what port to send it out on...

                prt = self.arpTable[dpid][dstaddr].port
                mac = self.arpTable[dpid][dstaddr].mac
                if prt == inport:
                    log.warning(
                        "DPID %i PORT %i not sending packet for %s back out of the "
                        + "input port" % (dpid, inport, str(dstaddr)))
                else:
                    log.debug(
                        "DPID %i PORT %i installing flow for %s => %s out port %i"
                        % (dpid, inport, packet.next.srcip, dstaddr, prt))

                    actions = []
                    actions.append(of.ofp_action_dl_addr.set_dst(mac))
                    actions.append(of.ofp_action_output(port=prt))
                    match = of.ofp_match.from_packet(packet, inport)
                    match.dl_src = None  # Wildcard source MAC

                    msg = of.ofp_flow_mod(command=of.OFPFC_ADD,
                                          idle_timeout=FLOW_IDLE_TIMEOUT,
                                          hard_timeout=of.OFP_FLOW_PERMANENT,
                                          buffer_id=event.ofp.buffer_id,
                                          actions=actions,
                                          match=of.ofp_match.from_packet(
                                              packet, inport))
                    event.connection.send(msg.pack())
            elif (dstaddr not in self.arpTable[dpid]) and (dstaddr
                                                           not in switch):
                # We don't know this destination.
                # First, we track this buffer so that we can try to resend it later
                # if we learn the destination, second we ARP for the destination,
                # which should ultimately result in it responding and us learning
                # where it is

                # Add to tracked buffers
                if (dpid, dstaddr) not in self.lost_buffers:
                    self.lost_buffers[(dpid, dstaddr)] = []
                bucket = self.lost_buffers[(dpid, dstaddr)]
                entry = (time.time() + MAX_BUFFER_TIME, event.ofp.buffer_id,
                         inport)
                bucket.append(entry)
                while len(bucket) > MAX_BUFFERED_PER_IP:
                    del bucket[0]

                # Expire things from our outstanding ARP list...
                self.outstanding_arps = {
                    k: v
                    for k, v in self.outstanding_arps.iteritems()
                    if v > time.time()
                }

                # Check if we've already ARPed recently
                if (dpid, dstaddr) in self.outstanding_arps:
                    # Oop, we've already done this one recently.
                    return

                # And ARP...
                self.outstanding_arps[(dpid, dstaddr)] = time.time()

                r = arp()
                r.hwtype = r.HW_TYPE_ETHERNET
                r.prototype = r.PROTO_TYPE_IP
                r.hwlen = 6
                r.protolen = r.protolen
                r.opcode = r.REQUEST
                r.hwdst = ETHER_BROADCAST
                r.protodst = dstaddr
                r.hwsrc = packet.src
                r.protosrc = packet.next.srcip
                e = ethernet(type=ethernet.ARP_TYPE,
                             src=packet.src,
                             dst=ETHER_BROADCAST)
                e.set_payload(r)
                log.debug("DPID %i PORT %i ARPing for %s on behalf of %s" %
                          (dpid, inport, str(r.protodst), str(r.protosrc)))
                msg = of.ofp_packet_out()
                msg.data = e.pack()
                msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
                msg.in_port = inport
                event.connection.send(msg)

            if (packet.find("ipv4").dstip not in node):
                icmp = pkt.icmp()
                icmp.type = pkt.TYPE_DEST_UNREACH
                icmp.code = pkt.CODE_UNREACH_HOST
                orig_ip = event.parsed.find('ipv4')

                pay = orig_ip.pack()
                pay = pay[:orig_ip.hl * 4 + 8]
                import struct
                pay = struct.pack("!HH", 0, 0) + pay
                icmp.payload = pay

                # Make the IP packet around it
                ipp = pkt.ipv4()
                ipp.protocol = ipp.ICMP_PROTOCOL
                ipp.srcip = packet.find("ipv4").dstip
                ipp.dstip = packet.find("ipv4").srcip
                # Ethernet around that...
                e = pkt.ethernet()
                e.src = packet.dst
                e.dst = packet.src
                e.type = e.IP_TYPE
                # Hook them up...
                ipp.payload = icmp
                e.payload = ipp
                # 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 = e.pack()
                msg.in_port = event.port
                event.connection.send(msg)
                log.debug("%s pinged %s", ipp.dstip, ipp.srcip)

        elif isinstance(packet.next, arp):
            a = packet.next
            log.debug("DPID %i PORT %i ARP %s %s => %s", dpid, inport, {
                arp.REQUEST: "request",
                arp.REPLY: "reply"
            }.get(a.opcode, 'op:%i' % (a.opcode, )), str(a.protosrc),
                      str(a.protodst))

            if a.prototype == arp.PROTO_TYPE_IP:
                if a.hwtype == arp.HW_TYPE_ETHERNET:
                    if a.protosrc != 0:

                        # Learn or update port/MAC info
                        if a.protosrc in self.arpTable[dpid]:
                            if self.arpTable[dpid][a.protosrc] != (inport,
                                                                   packet.src):
                                log.info("DPID %i PORT %i RE-learned %s", dpid,
                                         inport, str(a.protosrc))
                        else:
                            log.debug("DPID %i PORT %i learned %s", dpid,
                                      inport, str(a.protosrc))
                        self.arpTable[dpid][a.protosrc] = Entry(
                            inport, packet.src)

                        # Send any waiting packets...
                        self._send_lost_buffers(dpid, a.protosrc, packet.src,
                                                inport)

                        if a.opcode == arp.REQUEST:
                            # Maybe we can answer
                            if a.protodst != None:
                                #if a.protodst in self.arpTable[dpid]:
                                # We have an answer...

                                #if not self.arpTable[dpid][a.protodst].isExpired():
                                # .. and it's relatively current, so we'll reply ourselves

                                r = arp()
                                r.hwtype = a.hwtype
                                r.prototype = a.prototype
                                r.hwlen = a.hwlen
                                r.protolen = a.protolen
                                r.opcode = arp.REPLY
                                r.hwdst = a.hwsrc
                                r.protodst = a.protosrc
                                r.protosrc = a.protodst
                                r.hwsrc = dpid_to_mac(dpid)
                                e = ethernet(type=packet.type,
                                             src=dpid_to_mac(dpid),
                                             dst=a.hwsrc)
                                e.payload = r
                                #e.set_payload(r)
                                log.debug(
                                    "DPID %i PORT %i answering ARP for %s" %
                                    (dpid, inport, str(r.protosrc)))
                                msg = of.ofp_packet_out()
                                msg.data = e.pack()
                                msg.actions.append(
                                    of.ofp_action_output(port=of.OFPP_IN_PORT))
                                msg.in_port = inport
                                event.connection.send(msg)
                                return

            # Didn't know how to answer or otherwise handle this ARP, so just flood it
            log.debug("DPID %i PORT %i flooding ARP %s %s => %s" %
                      (dpid, inport, {
                          arp.REQUEST: "request",
                          arp.REPLY: "reply"
                      }.get(a.opcode, 'op:%i' %
                            (a.opcode, )), str(a.protosrc), str(a.protodst)))

            msg = of.ofp_packet_out(
                in_port=inport,
                data=event.ofp,
                action=of.ofp_action_output(port=of.OFPP_FLOOD))
            event.connection.send(msg)
Ejemplo n.º 38
0
class l3_switch (EventMixin):
  def __init__ (self, fakeways = [], arp_for_unknowns = False):
    # These are "fake gateways" -- we'll answer ARPs for them with MAC
    # of the switch they're connected to.
    self.fakeways = set(fakeways)

    # If this is true and we see a packet for an unknown
    # host, we'll ARP for it.
    self.arp_for_unknowns = arp_for_unknowns

    # (dpid,IP) -> expire_time
    # We use this to keep from spamming ARPs
    self.outstanding_arps = {}

    # (dpid,IP) -> [(expire_time,buffer_id,in_port), ...]
    # These are buffers we've gotten at this datapath for this IP which
    # we can't deliver because we don't know where they go.
    self.lost_buffers = {}

    # For each switch, we map IP addresses to Entries
    self.arpTable = {}

    # This timer handles expiring stuff
    self._expire_timer = Timer(5, self._handle_expiration, recurring=True)

    self.listenTo(core)

  def _handle_expiration (self):
    # Called by a timer so that we can remove old items.
    empty = []
    for k,v in self.lost_buffers.iteritems():
      dpid,ip = k

      for item in list(v):
        expires_at,buffer_id,in_port = item
        if expires_at < time.time():
          # This packet is old.  Tell this switch to drop it.
          v.remove(item)
          po = of.ofp_packet_out(buffer_id = buffer_id, in_port = in_port)
          core.openflow.sendToDPID(dpid, po)
	  print dpid, po
      if len(v) == 0: empty.append(k)

    # Remove empty buffer bins
    for k in empty:
      del self.lost_buffers[k]

  def _send_lost_buffers (self, dpid, ipaddr, macaddr, port):
    """
    We may have "lost" buffers -- packets we got but didn't know
    where to send at the time.  We may know now.  Try and see.
    """
    if (dpid,ipaddr) in self.lost_buffers:
      # Yup!
      bucket = self.lost_buffers[(dpid,ipaddr)]
      del self.lost_buffers[(dpid,ipaddr)]
      log.info("Sending %i buffered packets to %s from %s and port %s"
                % (len(bucket),ipaddr,dpid_to_str(dpid), port))
      for _,buffer_id,in_port in bucket:
        po = of.ofp_packet_out(buffer_id=buffer_id,in_port=in_port)
        po.actions.append(of.ofp_action_dl_addr.set_dst(macaddr))
        po.actions.append(of.ofp_action_output(port = port))
        core.openflow.sendToDPID(dpid, po)
	print po

  def _handle_GoingUpEvent (self, event):
    self.listenTo(core.openflow)
    log.debug("Up...")

  def _handle_PacketIn (self, event):
    dpid = event.connection.dpid
    inport = event.port
    packet = event.parsed
    #know = packet.next.next.srcport
    if not packet.parsed:
      log.info("%i %i ignoring unparsed packet", dpid, inport, packet)
      return

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

    if packet.type == ethernet.LLDP_TYPE:
      # Ignore LLDP packets
      return
    ## -- gilnei - Cap Flows
    if isinstance(packet.next.next,tcp):
      sport = 0
      dport = 0
      sport = packet.next.next.srcport
      dport = packet.next.next.dstport
      log.info (" DPID %i src_port %i dst_port %i" , dpid, sport, dport)
      switchs = Switchs.objects.get(name_switch = dpid)
      fl = TemporaryFlows(id_switch=switchs, switchport = inport, ip_src = packet.next.srcip, ip_dst = packet.next.dstip, src_port = sport, dst_port = dport, timestamp = datetime.datetime.now())
      fl.save() 
      #swt = Switchs(name_switch = dpid, temporary_flows_id_temporaryflow = fl)
      #swt.save()
    # reg = SwitchsHasTemporaryFlows(switchs_id_switch = switch.id_switch, temporary_flows_id_temporaryflow = fl.id_temporaryflow)	     
     #reg.save()
      if isinstance(packet.next, ipv4):
      		log.debug("%i %i IP %s => %s", dpid,inport,
                packet.next.srcip,packet.next.dstip)

      # Send any waiting packets...
      self._send_lost_buffers(dpid, packet.next.srcip, packet.src, inport)

      # Learn or update port/MAC info
      if packet.next.srcip in self.arpTable[dpid]:
        if self.arpTable[dpid][packet.next.srcip] != (inport, packet.src):
          log.debug("%i %i RE-learned %s", dpid,inport,packet.next.srcip)
      else:
        log.debug("%i %i learned %s", dpid,inport,str(packet.next.srcip))
      self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src)

      # Try to forward
      dstaddr = packet.next.dstip
      srcaddr = packet.next.srcip
      #dstport = packet.next.tos

      if dstaddr in self.arpTable[dpid]:
        # We have info about what port to send it out on...

        prt = self.arpTable[dpid][dstaddr].port
        mac = self.arpTable[dpid][dstaddr].mac
	self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src)
	sport = ("-")
	dport = ("-")
	srcmac = self.arpTable[dpid][srcaddr].mac
	#fl = TemporaryFlow(switchport = inport, ip_src = packet.next.srcip, ip_dst = packet.next.dstip, mac_src = srcmac, mac_dst = mac, s_port = sport, d_port = dport)
        #fl.save()

#	print srcmac
#	print mac
#	print sport
#	if isinstance (packet.next.next, tcp):
#		print packet.next.next.srcport
#		print packet.next.next.dstport
#		print mac
#		print "hi"
#	print ("%s ITS MAC --- %s ITS PORT " % (mac, prt))
        if prt == inport:
          log.info("%i %i not sending packet for %s back out of the " +
                      "input port" % (dpid, inport, str(dstaddr)))
        else:
          log.debug("%i %i installing flow for %s WHATTHEFuck %i  => %s out port %i"
                    % (dpid, inport, packet.next.srcip, packet.next.tos, dstaddr, prt))

          actions = []
          actions.append(of.ofp_action_dl_addr.set_dst(mac))
          actions.append(of.ofp_action_output(port = prt))
          match = of.ofp_match.from_packet(packet, inport)
          match.dl_src = None # Wildcard source MAC

       """  msg = of.ofp_flow_mod(command=of.OFPFC_ADD,
                                idle_timeout=FLOW_IDLE_TIMEOUT,
                                hard_timeout=of.OFP_FLOW_PERMANENT,
                                buffer_id=event.ofp.buffer_id,
                                actions=actions,
                                match=of.ofp_match.from_packet(packet,
                                                               inport))
          event.connection.send(msg.pack())"""
      elif self.arp_for_unknowns:
        # We don't know this destination.
        # First, we track this buffer so that we can try to resend it later
        # if we learn the destination, second we ARP for the destination,
        # which should ultimately result in it responding and us learning
        # where it is

        # Add to tracked buffers
        if (dpid,dstaddr) not in self.lost_buffers:
          self.lost_buffers[(dpid,dstaddr)] = []
        bucket = self.lost_buffers[(dpid,dstaddr)]
        entry = (time.time() + MAX_BUFFER_TIME,event.ofp.buffer_id,inport)
        bucket.append(entry)
        while len(bucket) > MAX_BUFFERED_PER_IP: del bucket[0]

        # Expire things from our outstanding ARP list...
        self.outstanding_arps = {k:v for k,v in
         self.outstanding_arps.iteritems() if v > time.time()}

        # Check if we've already ARPed recently
        if (dpid,dstaddr) in self.outstanding_arps:
          # Oop, we've already done this one recently.
          return

        # And ARP...
        self.outstanding_arps[(dpid,dstaddr)] = time.time() + 4

        r = arp()
        r.hwtype = r.HW_TYPE_ETHERNET
        r.prototype = r.PROTO_TYPE_IP
        r.hwlen = 6
        r.protolen = r.protolen
        r.opcode = r.REQUEST
        r.hwdst = ETHER_BROADCAST
        r.protodst = dstaddr
        r.hwsrc = packet.src
        r.protosrc = packet.next.srcip
        e = ethernet(type=ethernet.ARP_TYPE, src=packet.src,
                     dst=ETHER_BROADCAST)
        e.set_payload(r)
        log.debug("%i %i ARPing for %s on behalf of %s" % (dpid, inport,
         str(r.protodst), str(r.protosrc)))
        msg = of.ofp_packet_out()
        msg.data = e.pack()
        msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD))
        msg.in_port = inport
        event.connection.send(msg)

    elif isinstance(packet.next, arp):
      a = packet.next
      log.debug("%i %i ARP %s %s => %s", dpid, inport,
       {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode,
       'op:%i' % (a.opcode,)), str(a.protosrc), str(a.protodst))

      if a.prototype == arp.PROTO_TYPE_IP:
        if a.hwtype == arp.HW_TYPE_ETHERNET:
          if a.protosrc != 0:

            # Learn or update port/MAC info
            if a.protosrc in self.arpTable[dpid]:
              if self.arpTable[dpid][a.protosrc] != (inport, packet.src):
                log.info("%i %i RE-learned %s", dpid,inport,str(a.protosrc))
            else:
              log.info("%i %i learned %s", dpid,inport,str(a.protosrc))
            self.arpTable[dpid][a.protosrc] = Entry(inport, packet.src)

            # Send any waiting packets...
            self._send_lost_buffers(dpid, a.protosrc, packet.src, inport)

            if a.opcode == arp.REQUEST:
              # Maybe we can answer

              if a.protodst in self.arpTable[dpid]:
                # We have an answer...

                if not self.arpTable[dpid][a.protodst].isExpired():
                  # .. and it's relatively current, so we'll reply ourselves

                  r = arp()
                  r.hwtype = a.hwtype
                  r.prototype = a.prototype
                  r.hwlen = a.hwlen
                  r.protolen = a.protolen
                  r.opcode = arp.REPLY
                  r.hwdst = a.hwsrc
                  r.protodst = a.protosrc
                  r.protosrc = a.protodst
                  r.hwsrc = self.arpTable[dpid][a.protodst].mac
                  e = ethernet(type=packet.type, src=dpid_to_mac(dpid),
                               dst=a.hwsrc)
                  e.set_payload(r)
                  log.info("%i %i answering ARP for %s" % (dpid, inport,
                   str(r.protosrc)))
                  msg = of.ofp_packet_out()
		  print msg
                  msg.data = e.pack()
                  msg.actions.append(of.ofp_action_output(port =
                                                          of.OFPP_IN_PORT))
                  msg.in_port = inport
                  event.connection.send(msg)
                  return

      # Didn't know how to answer or otherwise handle this ARP, so just flood it
      log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport,
       {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode,
       'op:%i' % (a.opcode,)), str(a.protosrc), str(a.protodst)))

      msg = of.ofp_packet_out(in_port = inport, data = event.ofp,
          action = of.ofp_action_output(port = of.OFPP_FLOOD))
      event.connection.send(msg)"""

	# When we get flow stats, print stuff out
"""  def handle_flow_stats (self, event):
Ejemplo n.º 39
0
    def _handle_openflow_PacketIn(self, event):
        dpid = event.connection.dpid
        inport = event.port
        packet = event.parsed

        if not packet.parsed:
            log.warning("%i %i ignoring unparsed packet", dpid, inport)
            return

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

        if packet.type == ethernet.LLDP_TYPE:
            # Ignore LLDP packets
            return

        if isinstance(packet.next, ipv4):
            log.debug("%i %i IP %s => %s", dpid, inport,
                      packet.next.srcip, packet.next.dstip)

            ip_flag_df = 0
            ip_flag_mf = 0
            tcp_flag_ack = 0
            tcp_flag_push = 0
            tcp_flag_reset = 0
            tcp_flag_syn = 0
            tcp_flag_fin = 0

            if packet.next.flags == 1:
                ip_flag_df = 1
            elif packet.next.flags == 2:
                ip_flag_mf = 1

            if packet.next.next.flags == 1:
                tcp_flag_fin = 1
            elif packet.next.next.flags == 2:
                tcp_flag_syn = 1
            elif packet.next.next.flags == 4:
                tcp_flag_reset = 1
            elif packet.next.next.flags == 8:
                tcp_flag_push = 1
            elif packet.next.next.flags == 16:
                tcp_flag_ack = 1

            input_packet = [len(packet), packet.next.hl, packet.next.iplen, ip_flag_df, ip_flag_mf, packet.next.frag, packet.next.ttl, packet.next.protocol, packet.next.next.srcport, packet.next.next.dstport, len(packet.next.next), packet.next.next.ACK, tcp_flag_ack, tcp_flag_push, tcp_flag_reset, tcp_flag_syn, tcp_flag_fin, packet.next.next.win]

            global packets_arr
            packets_arr.append(input_packet)

            if len(packets_arr) > 18:
                packets_arr.pop(0)

                model = load_model("/home/ubuntu/pox/pox/forwarding/model_18_features.h5")
                scalar = pickle.load(open('/home/ubuntu/pox/pox/forwarding/myScalar2.pkl', 'rb'))
                data = np.array(packets_arr)
                data = scalar.transform(data)
                prediction = model.predict(np.array([data]), verbose=1)

                if prediction.round():
                    print "****************************************************"
                    print "                    Normal Packet"
                    print "                    try forwarding"
                    print "              prediction: ", prediction[0][0]
                    print "****************************************************"
                else:
                    print "****************************************************"
                    print "                  !!DDos Detected!!"
                    print "                   packet dropped"
                    print "              prediction: ", prediction[0][0]
                    print "****************************************************"
                    msg = of.ofp_packet_out(in_port=inport)
                    core.openflow.sendToDPID(dpid, msg)
                    return

            # Send any waiting packets...
            self._send_lost_buffers(dpid, packet.next.srcip, packet.src, inport)

            # Learn or update port/MAC info
            if packet.next.srcip in self.arpTable[dpid]:
                if self.arpTable[dpid][packet.next.srcip] != (inport, packet.src):
                    log.info("%i %i RE-learned %s", dpid, inport, packet.next.srcip)
                    if self.wide:
                        # Make sure we don't have any entries with the old info...
                        msg = of.ofp_flow_mod(command=of.OFPFC_DELETE)
                        msg.match.nw_dst = packet.next.srcip
                        msg.match.dl_type = ethernet.IP_TYPE
                        event.connection.send(msg)
            else:
                log.debug("%i %i learned %s", dpid, inport, packet.next.srcip)
            self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src)

            # Try to forward
            dstaddr = packet.next.dstip
            if dstaddr in self.arpTable[dpid]:
                # We have info about what port to send it out on...

                prt = self.arpTable[dpid][dstaddr].port
                mac = self.arpTable[dpid][dstaddr].mac
                if prt == inport:
                    log.warning("%i %i not sending packet for %s back out of the "
                                "input port" % (dpid, inport, dstaddr))
                else:
                    log.debug("%i %i installing flow for %s => %s out port %i"
                              % (dpid, inport, packet.next.srcip, dstaddr, prt))

                    actions = []
                    actions.append(of.ofp_action_dl_addr.set_dst(mac))
                    actions.append(of.ofp_action_output(port=prt))
                    if self.wide:
                        match = of.ofp_match(dl_type=packet.type, nw_dst=dstaddr)
                    else:
                        match = of.ofp_match.from_packet(packet, inport)

                    msg = of.ofp_flow_mod(command=of.OFPFC_ADD,
                                          idle_timeout=FLOW_IDLE_TIMEOUT,
                                          hard_timeout=of.OFP_FLOW_PERMANENT,
                                          buffer_id=event.ofp.buffer_id,
                                          actions=actions,
                                          match=match)
                    event.connection.send(msg.pack())
            elif self.arp_for_unknowns:
                # We don't know this destination.
                # First, we track this buffer so that we can try to resend it later
                # if we learn the destination, second we ARP for the destination,
                # which should ultimately result in it responding and us learning
                # where it is

                # Add to tracked buffers
                if (dpid, dstaddr) not in self.lost_buffers:
                    self.lost_buffers[(dpid, dstaddr)] = []
                bucket = self.lost_buffers[(dpid, dstaddr)]
                entry = (time.time() + MAX_BUFFER_TIME, event.ofp.buffer_id, inport)
                bucket.append(entry)
                while len(bucket) > MAX_BUFFERED_PER_IP: del bucket[0]

                # Expire things from our outstanding ARP list...
                self.outstanding_arps = {k: v for k, v in
                                         self.outstanding_arps.iteritems() if v > time.time()}

                # Check if we've already ARPed recently
                if (dpid, dstaddr) in self.outstanding_arps:
                    # Oop, we've already done this one recently.
                    return

                # And ARP...
                self.outstanding_arps[(dpid, dstaddr)] = time.time() + 4

                r = arp()
                r.hwtype = r.HW_TYPE_ETHERNET
                r.prototype = r.PROTO_TYPE_IP
                r.hwlen = 6
                r.protolen = r.protolen
                r.opcode = r.REQUEST
                r.hwdst = ETHER_BROADCAST
                r.protodst = dstaddr
                r.hwsrc = packet.src
                r.protosrc = packet.next.srcip
                e = ethernet(type=ethernet.ARP_TYPE, src=packet.src,
                             dst=ETHER_BROADCAST)
                e.set_payload(r)
                log.debug("%i %i ARPing for %s on behalf of %s" % (dpid, inport,
                                                                   r.protodst, r.protosrc))
                msg = of.ofp_packet_out()
                msg.data = e.pack()
                msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
                msg.in_port = inport
                event.connection.send(msg)

        elif isinstance(packet.next, arp):
            a = packet.next
            log.debug("%i %i ARP %s %s => %s", dpid, inport,
                      {arp.REQUEST: "request", arp.REPLY: "reply"}.get(a.opcode,
                                                                       'op:%i' % (a.opcode,)), a.protosrc, a.protodst)

            if a.prototype == arp.PROTO_TYPE_IP:
                if a.hwtype == arp.HW_TYPE_ETHERNET:
                    if a.protosrc != 0:

                        # Learn or update port/MAC info
                        if a.protosrc in self.arpTable[dpid]:
                            if self.arpTable[dpid][a.protosrc] != (inport, packet.src):
                                log.info("%i %i RE-learned %s", dpid, inport, a.protosrc)
                                if self.wide:
                                    # Make sure we don't have any entries with the old info...
                                    msg = of.ofp_flow_mod(command=of.OFPFC_DELETE)
                                    msg.match.dl_type = ethernet.IP_TYPE
                                    msg.match.nw_dst = a.protosrc
                                    event.connection.send(msg)
                        else:
                            log.debug("%i %i learned %s", dpid, inport, a.protosrc)
                        self.arpTable[dpid][a.protosrc] = Entry(inport, packet.src)

                        # Send any waiting packets...
                        self._send_lost_buffers(dpid, a.protosrc, packet.src, inport)

                        if a.opcode == arp.REQUEST:
                            # Maybe we can answer

                            if a.protodst in self.arpTable[dpid]:
                                # We have an answer...

                                if not self.arpTable[dpid][a.protodst].isExpired():
                                    # .. and it's relatively current, so we'll reply ourselves

                                    r = arp()
                                    r.hwtype = a.hwtype
                                    r.prototype = a.prototype
                                    r.hwlen = a.hwlen
                                    r.protolen = a.protolen
                                    r.opcode = arp.REPLY
                                    r.hwdst = a.hwsrc
                                    r.protodst = a.protosrc
                                    r.protosrc = a.protodst
                                    r.hwsrc = self.arpTable[dpid][a.protodst].mac
                                    e = ethernet(type=packet.type, src=dpid_to_mac(dpid),
                                                 dst=a.hwsrc)
                                    e.set_payload(r)
                                    log.debug("%i %i answering ARP for %s" % (dpid, inport,
                                                                              r.protosrc))
                                    msg = of.ofp_packet_out()
                                    msg.data = e.pack()
                                    msg.actions.append(of.ofp_action_output(port=
                                                                            of.OFPP_IN_PORT))
                                    msg.in_port = inport
                                    event.connection.send(msg)
                                    return

            # Didn't know how to answer or otherwise handle this ARP, so just flood it
            log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport,
                                                          {arp.REQUEST: "request", arp.REPLY: "reply"}.get(a.opcode,
                                                                                                           'op:%i' % (
                                                                                                               a.opcode,)),
                                                          a.protosrc, a.protodst))

            msg = of.ofp_packet_out(in_port=inport, data=event.ofp,
                                    action=of.ofp_action_output(port=of.OFPP_FLOOD))
            event.connection.send(msg)
Ejemplo n.º 40
0
  def _handle_PacketIn (self, event):
    dpid = event.connection.dpid
    inport = event.port
    packet = event.parsed
    #know = packet.next.next.srcport
    if not packet.parsed:
      log.info("%i %i ignoring unparsed packet", dpid, inport, packet)
      return

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

    if packet.type == ethernet.LLDP_TYPE:
      # Ignore LLDP packets
      return
    ## -- gilnei - Cap Flows
    if isinstance(packet.next.next,tcp):
      sport = 0
      dport = 0
      sport = packet.next.next.srcport
      dport = packet.next.next.dstport
      log.info (" DPID %i src_port %i dst_port %i" , dpid, sport, dport)
      switchs = Switchs.objects.get(name_switch = dpid)
      fl = TemporaryFlows(id_switch=switchs, switchport = inport, ip_src = packet.next.srcip, ip_dst = packet.next.dstip, src_port = sport, dst_port = dport, timestamp = datetime.datetime.now())
      fl.save() 
      #swt = Switchs(name_switch = dpid, temporary_flows_id_temporaryflow = fl)
      #swt.save()
    # reg = SwitchsHasTemporaryFlows(switchs_id_switch = switch.id_switch, temporary_flows_id_temporaryflow = fl.id_temporaryflow)	     
     #reg.save()
      if isinstance(packet.next, ipv4):
      		log.debug("%i %i IP %s => %s", dpid,inport,
                packet.next.srcip,packet.next.dstip)

      # Send any waiting packets...
      self._send_lost_buffers(dpid, packet.next.srcip, packet.src, inport)

      # Learn or update port/MAC info
      if packet.next.srcip in self.arpTable[dpid]:
        if self.arpTable[dpid][packet.next.srcip] != (inport, packet.src):
          log.debug("%i %i RE-learned %s", dpid,inport,packet.next.srcip)
      else:
        log.debug("%i %i learned %s", dpid,inport,str(packet.next.srcip))
      self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src)

      # Try to forward
      dstaddr = packet.next.dstip
      srcaddr = packet.next.srcip
      #dstport = packet.next.tos

      if dstaddr in self.arpTable[dpid]:
        # We have info about what port to send it out on...

        prt = self.arpTable[dpid][dstaddr].port
        mac = self.arpTable[dpid][dstaddr].mac
	self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src)
	sport = ("-")
	dport = ("-")
	srcmac = self.arpTable[dpid][srcaddr].mac
	#fl = TemporaryFlow(switchport = inport, ip_src = packet.next.srcip, ip_dst = packet.next.dstip, mac_src = srcmac, mac_dst = mac, s_port = sport, d_port = dport)
        #fl.save()

#	print srcmac
#	print mac
#	print sport
#	if isinstance (packet.next.next, tcp):
#		print packet.next.next.srcport
#		print packet.next.next.dstport
#		print mac
#		print "hi"
#	print ("%s ITS MAC --- %s ITS PORT " % (mac, prt))
        if prt == inport:
          log.info("%i %i not sending packet for %s back out of the " +
                      "input port" % (dpid, inport, str(dstaddr)))
        else:
          log.debug("%i %i installing flow for %s WHATTHEFuck %i  => %s out port %i"
                    % (dpid, inport, packet.next.srcip, packet.next.tos, dstaddr, prt))

          actions = []
          actions.append(of.ofp_action_dl_addr.set_dst(mac))
          actions.append(of.ofp_action_output(port = prt))
          match = of.ofp_match.from_packet(packet, inport)
          match.dl_src = None # Wildcard source MAC

       """  msg = of.ofp_flow_mod(command=of.OFPFC_ADD,
                                idle_timeout=FLOW_IDLE_TIMEOUT,
                                hard_timeout=of.OFP_FLOW_PERMANENT,
                                buffer_id=event.ofp.buffer_id,
                                actions=actions,
                                match=of.ofp_match.from_packet(packet,
                                                               inport))
          event.connection.send(msg.pack())"""
      elif self.arp_for_unknowns:
        # We don't know this destination.
        # First, we track this buffer so that we can try to resend it later
        # if we learn the destination, second we ARP for the destination,
        # which should ultimately result in it responding and us learning
        # where it is

        # Add to tracked buffers
        if (dpid,dstaddr) not in self.lost_buffers:
          self.lost_buffers[(dpid,dstaddr)] = []
        bucket = self.lost_buffers[(dpid,dstaddr)]
        entry = (time.time() + MAX_BUFFER_TIME,event.ofp.buffer_id,inport)
        bucket.append(entry)
        while len(bucket) > MAX_BUFFERED_PER_IP: del bucket[0]

        # Expire things from our outstanding ARP list...
        self.outstanding_arps = {k:v for k,v in
         self.outstanding_arps.iteritems() if v > time.time()}

        # Check if we've already ARPed recently
        if (dpid,dstaddr) in self.outstanding_arps:
          # Oop, we've already done this one recently.
          return

        # And ARP...
        self.outstanding_arps[(dpid,dstaddr)] = time.time() + 4

        r = arp()
        r.hwtype = r.HW_TYPE_ETHERNET
        r.prototype = r.PROTO_TYPE_IP
        r.hwlen = 6
        r.protolen = r.protolen
        r.opcode = r.REQUEST
        r.hwdst = ETHER_BROADCAST
        r.protodst = dstaddr
        r.hwsrc = packet.src
        r.protosrc = packet.next.srcip
        e = ethernet(type=ethernet.ARP_TYPE, src=packet.src,
                     dst=ETHER_BROADCAST)
        e.set_payload(r)
        log.debug("%i %i ARPing for %s on behalf of %s" % (dpid, inport,
         str(r.protodst), str(r.protosrc)))
        msg = of.ofp_packet_out()
        msg.data = e.pack()
        msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD))
        msg.in_port = inport
        event.connection.send(msg)
Ejemplo n.º 41
0
    def _handle_openflow_PacketIn(self, event):
        dpid = event.connection.dpid
        inport = event.port
        packet = event.parsed
        global set_Timer
        global defendDDOS
        global blockPort
        timerSet = False
        global diction

        def preventing():
            global diction
            global set_Timer
            if not set_Timer:
                set_Timer = True
            #Timer(1, _timer_func(), recurring=True)

            #print"\n\n*********new packetIN************"
            if len(diction) == 0:
                print("Enpty diction ", str(event.connection.dpid),
                      str(event.port))
                diction[event.connection.dpid] = {}
                diction[event.connection.dpid][event.port] = 1
            elif event.connection.dpid not in diction:
                diction[event.connection.dpid] = {}
                diction[event.connection.dpid][event.port] = 1
                #print "ERROR"
            else:
                if event.connection.dpid in diction:
                    # temp = diction[event.connection.dpid]
                    #print(temp)
                    #print "error check " , str(diction[event.connection.dpid][event.port])
                    if event.port in diction[event.connection.dpid]:
                        temp_count = 0
                        temp_count = diction[event.connection.dpid][event.port]
                        temp_count = temp_count + 1
                        diction[event.connection.dpid][event.port] = temp_count
                        #print "printting dpid port number and its packet count: ",  str(event.connection.dpid), str(diction[event.connection.dpid]), str(diction[event.connection.dpid][event.port])
                    else:
                        diction[event.connection.dpid][event.port] = 1

            print "\n", datetime.datetime.now(), ": printing diction ", str(
                diction), "\n"

        def _timer_func():
            global diction
            global set_Timer
            if set_Timer == True:
                #print datetime.datetime.now(),": calling timer fucntion now!!!!!"
                for k, v in diction.iteritems():
                    for i, j in v.iteritems():
                        if j >= 50:
                            print "_____________________________________________________________________________________________"
                            print "\n", datetime.datetime.now(
                            ), "*******    DDOS DETECTED   ********"
                            print "\n", str(diction)
                            print "\n", datetime.datetime.now(
                            ), ": BLOCKED PORT NUMBER  : ", str(
                                i), " OF SWITCH ID: ", str(k)
                            print "\n_____________________________________________________________________________________________"

                            #self.dropDDOS ()
                            dpid = k
                            msg = of.ofp_packet_out(in_port=i)
                            #msg.priority=42
                            #msg.in_port = event.port
                            #po = of.ofp_packet_out(buffer_id = buffer_id, in_port = in_port)
                            core.openflow.sendToDPID(dpid, msg)

            diction = {}

        if not packet.parsed:
            log.warning("%i %i ignoring unparsed packet", dpid, inport)
            return

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

        if packet.type == ethernet.LLDP_TYPE:
            # Ignore LLDP packets
            return

        if isinstance(packet.next, ipv4):
            log.debug("%i %i IP %s => %s", dpid, inport, packet.next.srcip,
                      packet.next.dstip)
            ent_obj.statcolect(event.parsed.next.dstip)  #editing
            print "\n***** Entropy Value = ", str(ent_obj.value), "*****\n"
            if ent_obj.value < 0.5:
                preventing()
                if timerSet is not True:
                    Timer(2, _timer_func, recurring=True)
                    timerSet = False
            else:
                timerSet = False

            # Send any waiting packets...
            self._send_lost_buffers(dpid, packet.next.srcip, packet.src,
                                    inport)

            # Learn or update port/MAC info
            if packet.next.srcip in self.arpTable[dpid]:
                if self.arpTable[dpid][packet.next.srcip] != (inport,
                                                              packet.src):
                    log.info("%i %i RE-learned %s", dpid, inport,
                             packet.next.srcip)
                    if self.wide:
                        # Make sure we don't have any entries with the old info...
                        msg = of.ofp_flow_mod(command=of.OFPFC_DELETE)
                        msg.match.nw_dst = packet.next.srcip
                        msg.match.dl_type = ethernet.IP_TYPE
                        event.connection.send(msg)
            else:
                log.debug("%i %i learned %s", dpid, inport, packet.next.srcip)
            self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src)
            #nandan: getting source ip address from the packetIn
            #myPacketInSrcIP= packet.next.srcip
            #myPacketInSrcEth= packet.src
            #myPacketInDstIP= packet.next.dstip
            #myPacketInDstEth= packet.dst

            #print "switcID: "+str(dpid)+" ,Port: "+str(event.port)+" ,MAC address: "+str(myPacketInSrcEth)+" ,SrcIP: "+ str(myPacketInSrcIP)+", Dst Mac: "+str(myPacketInDstEth)+", Dst IP: "+str(myPacketInDstEth)
            # Try to forward
            dstaddr = packet.next.dstip
            if dstaddr in self.arpTable[dpid]:
                # We have info about what port to send it out on...

                prt = self.arpTable[dpid][dstaddr].port
                mac = self.arpTable[dpid][dstaddr].mac
                if prt == inport:
                    log.warning(
                        "%i %i not sending packet for %s back out of the "
                        "input port" % (dpid, inport, dstaddr))
                else:
                    log.debug(
                        "%i %i installing flow for %s => %s out port %i" %
                        (dpid, inport, packet.next.srcip, dstaddr, prt))

                    actions = []
                    actions.append(of.ofp_action_dl_addr.set_dst(mac))
                    actions.append(of.ofp_action_output(port=prt))
                    if self.wide:
                        match = of.ofp_match(dl_type=packet.type,
                                             nw_dst=dstaddr)
                    else:
                        match = of.ofp_match.from_packet(packet, inport)

                    msg = of.ofp_flow_mod(command=of.OFPFC_ADD,
                                          idle_timeout=FLOW_IDLE_TIMEOUT,
                                          hard_timeout=of.OFP_FLOW_PERMANENT,
                                          buffer_id=event.ofp.buffer_id,
                                          actions=actions,
                                          match=match)
                    event.connection.send(msg.pack())
            elif self.arp_for_unknowns:
                # We don't know this destination.
                # First, we track this buffer so that we can try to resend it later
                # if we learn the destination, second we ARP for the destination,
                # which should ultimately result in it responding and us learning
                # where it is

                # Add to tracked buffers
                if (dpid, dstaddr) not in self.lost_buffers:
                    self.lost_buffers[(dpid, dstaddr)] = []
                bucket = self.lost_buffers[(dpid, dstaddr)]
                entry = (time.time() + MAX_BUFFER_TIME, event.ofp.buffer_id,
                         inport)
                bucket.append(entry)
                while len(bucket) > MAX_BUFFERED_PER_IP:
                    del bucket[0]

                # Expire things from our outstanding ARP list...
                self.outstanding_arps = {
                    k: v
                    for k, v in self.outstanding_arps.iteritems()
                    if v > time.time()
                }

                # Check if we've already ARPed recently
                if (dpid, dstaddr) in self.outstanding_arps:
                    # Oop, we've already done this one recently.
                    return

                # And ARP...
                self.outstanding_arps[(dpid, dstaddr)] = time.time() + 4

                r = arp()
                r.hwtype = r.HW_TYPE_ETHERNET
                r.prototype = r.PROTO_TYPE_IP
                r.hwlen = 6
                r.protolen = r.protolen
                r.opcode = r.REQUEST
                r.hwdst = ETHER_BROADCAST
                r.protodst = dstaddr
                r.hwsrc = packet.src
                r.protosrc = packet.next.srcip
                e = ethernet(type=ethernet.ARP_TYPE,
                             src=packet.src,
                             dst=ETHER_BROADCAST)
                e.set_payload(r)
                log.debug("%i %i ARPing for %s on behalf of %s" %
                          (dpid, inport, r.protodst, r.protosrc))
                msg = of.ofp_packet_out()
                msg.data = e.pack()
                msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
                msg.in_port = inport
                event.connection.send(msg)

        elif isinstance(packet.next, arp):
            a = packet.next
            log.debug("%i %i ARP %s %s => %s", dpid, inport, {
                arp.REQUEST: "request",
                arp.REPLY: "reply"
            }.get(a.opcode, 'op:%i' % (a.opcode, )), a.protosrc, a.protodst)

            if a.prototype == arp.PROTO_TYPE_IP:
                if a.hwtype == arp.HW_TYPE_ETHERNET:
                    if a.protosrc != 0:

                        # Learn or update port/MAC info
                        if a.protosrc in self.arpTable[dpid]:
                            if self.arpTable[dpid][a.protosrc] != (inport,
                                                                   packet.src):
                                log.info("%i %i RE-learned %s", dpid, inport,
                                         a.protosrc)
                                if self.wide:
                                    # Make sure we don't have any entries with the old info...
                                    msg = of.ofp_flow_mod(
                                        command=of.OFPFC_DELETE)
                                    msg.match.dl_type = ethernet.IP_TYPE
                                    msg.match.nw_dst = a.protosrc
                                    event.connection.send(msg)
                        else:
                            log.debug("%i %i learned %s", dpid, inport,
                                      a.protosrc)
                        self.arpTable[dpid][a.protosrc] = Entry(
                            inport, packet.src)

                        # Send any waiting packets...
                        self._send_lost_buffers(dpid, a.protosrc, packet.src,
                                                inport)

                        if a.opcode == arp.REQUEST:
                            # Maybe we can answer

                            if a.protodst in self.arpTable[dpid]:
                                # We have an answer...

                                if not self.arpTable[dpid][
                                        a.protodst].isExpired():
                                    # .. and it's relatively current, so we'll reply ourselves

                                    r = arp()
                                    r.hwtype = a.hwtype
                                    r.prototype = a.prototype
                                    r.hwlen = a.hwlen
                                    r.protolen = a.protolen
                                    r.opcode = arp.REPLY
                                    r.hwdst = a.hwsrc
                                    r.protodst = a.protosrc
                                    r.protosrc = a.protodst
                                    r.hwsrc = self.arpTable[dpid][
                                        a.protodst].mac
                                    e = ethernet(type=packet.type,
                                                 src=dpid_to_mac(dpid),
                                                 dst=a.hwsrc)
                                    e.set_payload(r)
                                    log.debug("%i %i answering ARP for %s" %
                                              (dpid, inport, r.protosrc))
                                    msg = of.ofp_packet_out()
                                    msg.data = e.pack()
                                    msg.actions.append(
                                        of.ofp_action_output(
                                            port=of.OFPP_IN_PORT))
                                    msg.in_port = inport
                                    event.connection.send(msg)
                                    return

            # Didn't know how to answer or otherwise handle this ARP, so just flood it
            log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport, {
                arp.REQUEST: "request",
                arp.REPLY: "reply"
            }.get(a.opcode, 'op:%i' % (a.opcode, )), a.protosrc, a.protodst))

            msg = of.ofp_packet_out(
                in_port=inport,
                data=event.ofp,
                action=of.ofp_action_output(port=of.OFPP_FLOOD))
            event.connection.send(msg)
  def _handle_PacketIn (self, event):
    """
    Packets not handled by the router rules will be
    forwarded to this method to be handled by the controller
    """

    packet = event.parsed # This is the parsed packet data.
    if not packet.parsed:
      log.warning("Ignoring incomplete packet")
      return
    packet_in = event.ofp # The actual ofp_packet_in message.
    dpid =self.connection.dpid
    """
    if packet.type == packet.LLDP_TYPE or packet.type == packet.IPV6_TYPE:
      # Drop LLDP packets 
      # Drop IPv6 packets
      # send of command without actions

      msg = of.ofp_packet_out()
      msg.buffer_id = event.ofp.buffer_id
      msg.in_port = event.port
      self.connection.send(msg)
    """
    
    if packet.type ==packet.ARP_TYPE:
        """
        packet.next.srcip is a source IP address 
        packet.src is its source MAC address.
        """
        srcip = packet.payload.protosrc #use next maybe
        dstip = packet.payload.protodst #use next maybe
        #scrip = packet.next.srcip
        #dstip = packet.next.dstip
        if packet.payload.opcode ==arp.REQUEST:
            print("dpid ",dpid)
            if dpid not in self.arpTable:
                self.arpTable[dpid] = {}
            if packet.src not in self.arpTable[dpid]:
                # store it in arpTable
                
                self.arpTable[dpid][srcip]=Entry(packet.src,event.port) #IP map to mac and port
                msg = of.ofp_flow_mod()
     	        msg.priority = 8
                msg.match.dl_type =0x0800
                msg.match.nw_dst = srcip 
                msg.actions.append(of.ofp_action_dl_addr.set_dst(packet.src)) # dst mac 
                msg.actions.append(of.ofp_action_dl_addr.set_src(dpid_to_mac(dpid))) # dst mac 
                #msg.actions.append(of.ofp_action_nw_addr.set_dst(srcip)) #dst ip
                msg.actions.append(of.ofp_action_output(port = event.port))
                self.connection.send(msg)
            #create arp based on self.Mac
            arp_reply = arp()
            arp_reply.hwsrc = dpid_to_mac(dpid) # switch mac
            arp_reply.hwdst = packet.src        # host mac
            arp_reply.opcode = arp.REPLY        
            arp_reply.protodst = srcip
            arp_reply.protosrc = dstip#GatewayIPaddr
            #ethernet
            ether = ethernet()
            ether.type = ethernet.ARP_TYPE
            ether.dst = packet.src
            ether.src = dpid_to_mac(dpid)
            ether.set_payload(arp_reply)
            # send out arp reply
            print("dpid ",dpid," mac ",dpid_to_mac(dpid),"srcip ",srcip," dstip ",dstip)
            print("My mac",self.arpTable[dpid][srcip].mac,self.arpTable[dpid][srcip].port)
            self.resend_packet(ether.pack(),self.arpTable[dpid][srcip].port)
            return
        elif packet.type ==packet.ARP_TYPE:
            print("get arp reply My IP",dstip," from ",srcip) 
            
    #elif packet.type == packet.IP_TYPE:
        # Handle client's request

        # Only accept ARP request for load balancer
        # log.debug("Receive an IPv4 packet from %s" % packet.next.srcip)
        print ("Unhandled packet from " + str(self.connection.dpid) + ":" + packet.dump())
Ejemplo n.º 43
0
    def _handle_PacketIn(self, event):
        packet = event.parsed
        if not packet.parsed:
            return

        port = event.port
        dpid = event.connection.dpid
        pnext = packet.next

        # A new switch has connected with no arp table
        # initialize table
        if dpid not in self._arp_table:
            self._arp_table[dpid] = {}
            log.info("Initiating ARP table for dpid: %i" % (dpid, ))

            if int(dpid) in [1, 2, 3]:
                #left node of the same leaf switch
                ipaddrL = "10.0.0.%s" % str(2 * int(dpid) - 1)
                macL = "00:00:00:00:00:0%s" % str(2 * int(dpid) - 1)
                #right node of the same leaf switch
                ipaddrR = "10.0.0.%s" % str(2 * int(dpid))
                macR = "00:00:00:00:00:0%s" % str(2 * int(dpid))
                self._arp_table[dpid] = {IPAddr(ipaddrL): (EthAddr(macL), 3)}
                self._arp_table[dpid] = {IPAddr(ipaddrR): (EthAddr(macR), 4)}
                log.info("Initiating ARP ipL: %s, macL: %s, ipR: %s, macR: %s" %\
                        (ipaddrL,macL,ipaddrR,macR))
        # If it is an IPv4 packet
        if isinstance(pnext, ipv4):
            # Learn or update mac and port info for IP
            self._arp_table[dpid][pnext.srcip] = (packet.src, port)
            self._master_arp_table[pnext.srcip] = packet.src
            log.info("Updating ARP table for dpid: %i & IP: %s with (%s, %i)" %\
              (dpid, pnext.srcip, packet.src, port,))
            dst_ip = pnext.dstip  # Find the packet destination

            # number hosts for computing convenience
            odd_ips = {
                IPAddr('10.0.0.1'): 1,
                IPAddr('10.0.0.3'): 3,
                IPAddr('10.0.0.5'): 5
            }
            even_ips = {
                IPAddr('10.0.0.2'): 2,
                IPAddr('10.0.0.4'): 4,
                IPAddr('10.0.0.6'): 6
            }

            # create msg and append destination port
            message = of.ofp_flow_mod(buffer_id=event.ofp.buffer_id)

            # If destination is known then
            if dst_ip in self._arp_table[dpid]:
                # Obtain its mac and port
                dst_mac, dst_port = self._arp_table[dpid][dst_ip]

                message.actions.append(of.ofp_action_dl_addr.set_dst(dst_mac))
                #log.info("arp ref available dpid: %i & IP: %s to get (%s, %i)" %\
                #  (dpid, dst_ip, dst_mac, dst_port,))

                # Add the flow rule to switch
                if dst_port != port:
                    message.actions.append(of.ofp_action_output(port=dst_port))
                    message.match = of.ofp_match.from_packet(packet, port)
                    event.connection.send(message)
                # (topology specific) if leaf switches (dpid is 1 , 2 or 3 in out case)
                if int(dpid) in [1, 2, 3]:
                    ''' if dpid indicates leaf switch and src and dst shade that node
         directly redirect to the destination'''
                    if pnext.srcip in odd_ips and \
                       odd_ips[pnext.srcip]+1 == even_ips[dst_ip]:
                        message.actions.append(of.ofp_action_output(port=4))
                        message.match = of.ofp_match.from_packet(packet, port)
                        event.connection.send(message)
                    elif pnext.srcip in even_ips and \
                       even_ips[pnext.srcip]-1 == odd_ips[dst_ip]:
                        message.actions.append(of.ofp_action_output(port=3))
                        message.match = of.ofp_match.from_packet(packet, port)
                        event.connection.send(message)
                    else:
                        # route requests from odd numbered hosts through s4
                        if pnext.srcip in odd_ips:
                            #message.actions.append(of.ofp_action_output(port = dst_port))
                            #core.openflow.sendToDPID(self.S4, message)
                            message.actions.append(
                                of.ofp_action_output(port=1))
                            message.match = of.ofp_match.from_packet(
                                packet, port)
                            log.info("Odd IP: %s should be routed through S4" %
                                     (pnext.srcip, ))
                            event.connection.send(message)

                        # route requests from even numbered hosts through s5
                        elif pnext.srcip in even_ips:
                            #message.actions.append(of.ofp_action_output(port = dst_port))
                            message.actions.append(
                                of.ofp_action_output(port=2))
                            message.match = of.ofp_match.from_packet(
                                packet, port)
                            log.info(
                                "Even IP: %s should be routed through S5" %
                                (pnext.srcip, ))
                            event.connection.send(message)
                            #core.openflow.sendToDPID(self.S5, message)

                # If this is a spine switch send message to all other links except the port in came on
                elif int(dpid) in [4, 5]:
                    lnk_ports = [1, 2, 3]  # ports on spine connecting to links
                    lnk_ports = lnk_ports.remove(event.port)
                    for i in lnk_ports:
                        message.actions.append(of.ofp_action_output(port=i))
                        #message.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD))
                        message.match = of.ofp_match.from_packet(packet, port)
                        event.connection.send(message)
                #If it is none of the switches
                else:
                    # unknown dpid
                    log.info("Encountered unknown IP: %s" % (pnext.srcip, ))

        # Else if it is an ARP packet
        elif isinstance(pnext, arp):
            if pnext.prototype == arp.PROTO_TYPE_IP and pnext.hwtype == arp.HW_TYPE_ETHERNET \
              and pnext.protosrc != 0:
                # Learn or update MAC & port info for IP
                self._arp_table[dpid][pnext.protosrc] = (packet.src, port)
                self._master_arp_table[pnext.protosrc] = packet.src
                log.info("ARP: Updating ARP table for dpid: %i & IP: %s with (%s, %i)" %\
                  (dpid, pnext.protosrc, packet.src, port,))
                # If it is an ARP request and we know the destination
                # if pnext.opcode == arp.REQUEST and pnext.protodst in self._arp_table[dpid]:
                if pnext.opcode == arp.REQUEST and pnext.protodst in self._master_arp_table:
                    # Send the ARP response
                    res = arp()
                    # res.hwsrc, _  = self._arp_table[dpid][pnext.protodst]
                    res.hwsrc = self._master_arp_table[pnext.protodst]
                    res.hwtype = arp.HW_TYPE_ETHERNET
                    res.hwdst = pnext.hwsrc
                    res.hwlen = pnext.hwlen
                    res.prototype = arp.PROTO_TYPE_IP
                    res.protodst = pnext.protosrc
                    res.protosrc = pnext.protodst
                    res.protolen = pnext.protolen
                    res.opcode = arp.REPLY
                    eth = ethernet()
                    eth.type = packet.type
                    eth.src = EthAddr("%012x" % (dpid & 0xFFFFFFFFFFFF))
                    eth.dst = res.hwdst
                    eth.set_payload(res)
                    message = of.ofp_packet_out()
                    message.in_port = port
                    message.data = eth.pack()
                    message.actions.append(
                        of.ofp_action_output(port=of.OFPP_IN_PORT))
                    event.connection.send(message)
                    log.info("Responded to ARP request for dpid: %s and destination: %s" %\
                      (dpid, pnext.protodst,))
Ejemplo n.º 44
0
    def ARP_Handler(self, packet, packet_in):
        log.debug("ARP FRAME RECEIVED FROM %s" % packet_in.in_port)
	
        if packet.payload.opcode == arp.REQUEST:
            log.debug("IT'S AN ARP REQUEST!")

            arp_payload = packet.payload
            arp_request_ip = str(arp_payload.protodst)
            if arp_request_ip in self.arp_table:
		log.debug("I know the MAC of this ARp REQUEST's IP!")
                arp_reply = arp()
                arp_reply.opcode = arp.REPLY
                arp_reply.hwsrc = EthAddr(self.arp_table[arp_request_ip])
                arp_reply.hwdst = arp_payload.hwsrc
                arp_reply.protosrc = arp_payload.protodst
                arp_reply.protodst = arp_payload.protosrc

                ether = ethernet()
                ether.type = ether.ARP_TYPE
                ether.src = EthAddr(self.arp_table[arp_request_ip])
                ether.dst = arp_payload.hwsrc
                ether.payload = arp_reply

                self.resend_packet(ether, packet_in.in_port)
                log.debug("ARP REPLY SENT!")

        elif packet.payload.opcode == arp.REPLY:
            log.debug("IT'S AN ARP REPLY!")

            arp_payload = packet.payload
            hwsrc = str(arp_payload.hwsrc)
            srcip = str(arp_payload.protosrc)
            if srcip not in self.arp_table:
                self.arp_table[srcip] = hwsrc
                self.mac_to_port[hwsrc] = packet_in.in_port
                log.debug("%s %s INSTALLED TO CAM TABLE" % (srcip, hwsrc))

            # If there are packets in buffer waiting to be sent out
            if srcip in self.buffer.keys():

		##DEBUG FROM HERE

		
                log.debug("A packet is detected in buffer!")
                out_port = self.routing_table[self.buffer[srcip]['DestinationNetwork']]['Port']
                ip_packet = self.buffer[srcip]['IP_Packet']
		source_ip = str(ip_packet.srcip)
                etherFrame = ethernet()
                etherFrame.type = etherFrame.IP_TYPE
                etherFrame.src = EthAddr(self.arp_table[self.routing_table[self.buffer[srcip]['DestinationNetwork']]['RouterInterface']])
                etherFrame.dst = EthAddr(self.arp_table[srcip])
                etherFrame.payload = ip_packet
                self.resend_packet(etherFrame, out_port)
                msg = of.ofp_flow_mod()
                print self.buffer[srcip]['DestinationNetwork']
                msg.priority = 10
                msg.match.dl_type = ethernet.IP_TYPE
                #msg.match.nw_proto = ipv4.ICMP_PROTOCOL
		if srcip == "10.0.4.100":
			print "Matching Source Ip Address too in flow push ("+source_ip+")"
			msg.match.nw_src = IPAddr(source_ip)
		else:
			print "source_ip match constraint not added"
                msg.match.set_nw_dst(self.buffer[srcip]['DestinationNetwork'])
                # msg.match.nw_dst = IPAddr(srcip)
                msg.actions.append(of.ofp_action_dl_addr.set_src(EthAddr(self.arp_table[self.routing_table[self.buffer[srcip]['DestinationNetwork']]['RouterInterface']])))
                msg.actions.append(of.ofp_action_dl_addr.set_dst(EthAddr(self.arp_table[srcip])))
		if srcip == "10.0.4.100": #NOTE: srcip denotes the ip of the node that REPLIED to the ARP (it's hence the dest IP of the current packet)
			if source_ip == "10.0.1.100":
				queueno=1
			elif source_ip == "10.0.2.100": 
				queueno=2
			else: 
				queueno=0
			print "PUSHING QOS FLOW for source_ip "+source_ip+" @queue "+str(queueno)
			msg.actions.append(of.ofp_action_enqueue(port = 4, queue_id=queueno))
		else:        
			print "PUSHING REGULAR FLOW!"         
			msg.actions.append(of.ofp_action_output(port=out_port))
                self.connection.send(msg)
                log.debug("Flow mod for destination network %s sent!", self.buffer[srcip]['DestinationNetwork'])
                self.buffer.pop(srcip)
Ejemplo n.º 45
0
    def act_like_switch(self, packet, packet_in):
        """
    Implement switch-like behavior.
    """
        def drop():
            if event.ofp.buffer_id is not None:
                msg = of.ofp_packet_out()
                msg.buffer_id = event.ofp.buffer_id
                event.ofp.buffer_id = None
                msg.in_port = packet_in.in_port
                self.connection.send(msg)

        # Here's some psuedocode to start you off implementing a learning
        # switch.  You'll need to rewrite it as real Python code.

        # Learn the port for the source MAC
        self.mac_to_port[packet.src] = packet_in.in_port
        import pox.lib.packet as pkt

        #Ignore unnecessary packets
        if packet.type == packet.LLDP_TYPE:
            drop()
            return
        if packet.type == pkt.ethernet.IPV6_TYPE:
            return

        if packet.type == pkt.ethernet.IP_TYPE:
            ipv4_packet = packet.find("ipv4")
            src_ip = ipv4_packet.srcip
            dst_ip = ipv4_packet.dstip
            (nothing, sN, iPt, nada) = str(packet.next.srcip).split(".")
            (nothing, dN, dP, nada) = str(packet.next.dstip).split(".")

            srcNode = int(sN)
            dstNode = int(dN)
            destPort = int(dP)

            #Get all strictly shortest paths (e.g. same length) and randomly
            #select one from the top 8.
            allPaths = nx.all_shortest_paths(netGraph, self.sid, int(dstNode))
            listPaths = []
            for p in allPaths:
                listPaths.append(p)
            paths = listPaths[randint(0, min(len(listPaths) - 1, 7))]
            #Add corresponding flow table entry
            msg = of.ofp_flow_mod()
            msg.match = of.ofp_match.from_packet(packet)
            msg.match.idle_timeout = 10000
            if dstNode == self.sid:
                msg.actions.append(of.ofp_action_output(port=destPort))
                self.resend_packet(packet_in, destPort)

            else:
                nextPort = adjacency[paths[0]][paths[1]]
                msg.actions.append(of.ofp_action_output(port=nextPort))
                self.resend_packet(packet_in, nextPort)
            self.connection.send(msg)

        #Handle ARP reply
        elif packet.type == packet.ARP_TYPE:
            if packet.payload.opcode == arp.REQUEST:
                mac_reply = ip_to_mac(packet.payload.protodst)
                print mac_reply
                print packet.payload.protodst
                arp_reply = arp()
                arp_reply.hwsrc = mac_reply
                arp_reply.hwdst = packet.src
                arp_reply.opcode = arp.REPLY
                arp_reply.protosrc = packet.payload.protodst
                arp_reply.protodst = packet.payload.protosrc
                ether = ethernet()
                ether.type = ethernet.ARP_TYPE
                ether.dst = packet.src
                ether.src = mac_reply
                ether.payload = arp_reply
                msg = of.ofp_packet_out()
                msg.data = ether.pack()
                msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT))
                msg.in_port = packet_in.in_port
                self.connection.send(msg)

        #Handle worst case unknown packet via flooding
        elif packet.type != packet.LLDP_TYPE:

            if packet.dst in self.mac_to_port:
                #if the port associated with the destination MAC of the packet is known:
                # Send packet out the associated port
                self.resend_packet(packet_in, self.mac_to_port[packet.dst])

                # Once you have the above working, try pushing a flow entry
                # instead of resending the packet (comment out the above and
                # uncomment and complete the below.)

                log.debug("Installing flow...")
                # Maybe the log statement should have source/destination/port?

                #msg = of.ofp_flow_mod()
                #
                ## Set fields to match received packet
                #msg.match = of.ofp_match.from_packet(packet)
                #
                #< Set other fields of flow_mod (timeouts? buffer_id?) >
                #
                #< Add an output action, and send -- similar to resend_packet() >

            else:
                # Flood the packet out everything but the input port
                # This part looks familiar, right?
                self.resend_packet(packet_in, of.OFPP_ALL)
Ejemplo n.º 46
0
    def _handle_PacketIn(self, event):
        """
        Handles packet in messages from the switch.
        """
        etherFrame = event.parsed  # This is the parsed packet data.

        if not etherFrame.parsed:
            log.warning("Ignoring incomplete packet")
            return

        packet_in = event.ofp  # The actual ofp_packet_in message.

        # Add the new MAC into CAM table
        if str(etherFrame.src) not in self.mac_to_port:
            log.debug('Adding %s into CAM' % str(etherFrame.src))
            self.mac_to_port[str(etherFrame.src)] = packet_in.in_port

        # ARP
        if etherFrame.type == ethernet.ARP_TYPE:
            log.debug('RECEIVED: EtherType -> ARP')
            self.ARP_Handler(etherFrame, packet_in)
        # IP
        elif etherFrame.type == ethernet.IP_TYPE:
            log.debug('RECEIVED: EtherType -> IP')

            # Extract IP Packet from Ethernet Frame
            ip_packet = etherFrame.payload

            # Routable?
            destination_ip = str(ip_packet.dstip)
	    source_ip = str(ip_packet.srcip)

	    log.debug('DESTIP of THE CURRENT PACKET: '+destination_ip)


            routable = False
            for netaddr in self.routing_table:
                destination_network = netaddr
                if IPAddress(destination_ip) in IPNetwork(destination_network):
                    log.debug('PACKET IS ROUTABLE!')
                    routable = True
                    break

            if routable:
                # Destined for router
                if self.routing_table[str(destination_network)]['RouterInterface'] == destination_ip:
                    if ip_packet.protocol == ipv4.ICMP_PROTOCOL:
                        log.debug('ICMP ECHO -> ROUTER INTERFACE')
                        self.ICMP_Handler(etherFrame, packet_in)

                # Check if any there's any routable networks for the destination IP
                elif routable:
                    # Route the packet to it's respective ports
                    output_port = self.routing_table[destination_network]['Port']

                    # ARP if host MAC Address is not present
                    if destination_ip not in self.arp_table:
                        # Push frame to buffer
                        self.buffer[destination_ip] = {'IP_Packet': ip_packet, 'DestinationNetwork': destination_network}

                        # Construct ARP Packet
                        arp_request = arp()
                        arp_request.opcode = arp.REQUEST
                        arp_request.protosrc = IPAddr(self.routing_table[destination_network]['RouterInterface'])
                        arp_request.protodst = IPAddr(destination_ip)

                        arp_request.hwsrc = EthAddr(self.arp_table[self.routing_table[destination_network]['RouterInterface']])
                        arp_request.hwdst = EthAddr('00:00:00:00:00:00')

                        ether = ethernet()
                        ether.type = ether.ARP_TYPE
                        ether.src = EthAddr(self.arp_table[self.routing_table[destination_network]['RouterInterface']])
                        ether.dst = EthAddr('FF:FF:FF:FF:FF:FF')
                        ether.payload = arp_request
                        self.resend_packet(ether, output_port)

                    if destination_ip in self.arp_table:
                        etherFrame.src = EthAddr(self.arp_table[self.routing_table[destination_network]['RouterInterface']])
                        etherFrame.dst = EthAddr(self.arp_table[destination_ip])
                        self.resend_packet(etherFrame, output_port)
            # ICMP Destination Unreachable for non-routable networks
            else:
                log.debug('PACKET IS NOT ROUTABLE!')
                ethernet_frame = etherFrame
                ip_packet = etherFrame.payload
                icmp_request_packet = ip_packet.payload
                icmp_echo_reply_packet = icmp()
                icmp_echo_reply_packet.code = 0
                icmp_echo_reply_packet.type = 3
                icmp_echo_reply_packet.payload = icmp_request_packet.payload

                ip = ipv4()
                ip.srcip = ip_packet.dstip
                ip.dstip = ip_packet.srcip
                ip.protocol = ipv4.ICMP_PROTOCOL
                ip.payload = icmp_echo_reply_packet

                ether = ethernet()
                ether.type = ethernet.IP_TYPE
                ether.src = ethernet_frame.dst
                ether.dst = ethernet_frame.src
                ether.payload = ip

                self.resend_packet(ether, packet_in.in_port)
                log.debug("ICMP DESTINATION UNREACHABLE SENT")
Ejemplo n.º 47
0
  def _handle_PacketIn (self, event):
    dpid = event.connection.dpid
    inport = event.port
    packet = event.parsed
    
    #print "------------------------------------------------------------------------"
    #print "IPv4: ", event.parsed.find('ipv4')
    #print "ARP: ", event.parsed.find('arp')
    #print "Packet Type: " , packet.type
    
    #print datetime.datetime.now(), ":", packet
    #print "\n", packet.parsed
    #print "\n", event.ofp
    global call_Timer
    global set_Timer
    global diction
    timerSet =False
    
    def preventing():
      global diction
      global set_Timer
      if not set_Timer:
        set_Timer =True

      if len(diction) == 0:
        diction[event.connection.dpid] = {}
        diction[event.connection.dpid][event.port] = 1
      elif event.connection.dpid not in diction:
        diction[event.connection.dpid] = {}
        diction[event.connection.dpid][event.port] = 1
      else:
        if event.connection.dpid in diction:
          if event.port in diction[event.connection.dpid]:
            temp_count=0
            temp_count =diction[event.connection.dpid][event.port]
            temp_count = temp_count+1
            diction[event.connection.dpid][event.port]=temp_count
          else:
            diction[event.connection.dpid][event.port] = 1
   
      print "\n",datetime.datetime.now(), ": printing diction ",str(diction),"\n"
    
    
    def _timer_func ():
      global diction
      #print "Dictionary:", diction
      global set_Timer
      if not set_Timer:
        set_Timer =True

      if set_Timer==True:
        for k,v in diction.iteritems():
          for i,j in v.iteritems():
            if j >=20:
              print "\n",datetime.datetime.now(),"DDOS DETECTED"
              print "\n",str(diction)
              print "\n",datetime.datetime.now(),": BLOCKED PORT NUMBER : ", str(i), " OF SWITCH ID: ", str(k)
              #appending no actions to the out_msg the packets will be dropped from the current DPID-PORT pair  
              dpid = k									    		
              msg = of.ofp_packet_out(in_port=i)
              core.openflow.sendToDPID(dpid,msg)
      diction={}
    
    if not packet.parsed:
      log.warning("%i %i ignoring unparsed packet", dpid, inport)
      return

    if dpid not in self.arpTable:
      # New switch -- create an empty table
      self.arpTable[dpid] = {}
      for fake in self.fakeways:
        self.arpTable[dpid][IPAddr(fake)] = Entry(of.OFPP_NONE,
         dpid_to_mac(dpid))
    #print "Arp table: ", str(self.arpTable)
    if packet.type == ethernet.LLDP_TYPE:
      # Ignore LLDP packets
      return

    if isinstance(packet.next, ipv4):
      log.debug("%i %i IP %s => %s", dpid,inport,
                packet.next.srcip,packet.next.dstip)
      #print "\n"
      chi_obj.stats(packet.next.srcip)      #edit
      chi_obj.baseLine()		    #edit
      if chi_obj.y < 0.05 :
        print "DDoS might be there"
        preventing()
	      Timer(10, _timer_func)              

      # Send any waiting packets...
      self._send_lost_buffers(dpid, packet.next.srcip, packet.src, inport)
      #print "LOST BUFFERS: " , str(self.lost_buffers) #edited

      # Learn or update port/MAC info
      if packet.next.srcip in self.arpTable[dpid]:
        #print packet.next.srcip , "#editing"
        if self.arpTable[dpid][packet.next.srcip] != (inport, packet.src):
          log.info("%i %i RE-learned %s", dpid,inport,packet.next.srcip)
      else:
        log.debug("%i %i learned %s", dpid,inport,str(packet.next.srcip))
      self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src)
      #print "Arp table: ", str(self.arpTable)
      # Try to forward
      dstaddr = packet.next.dstip
      if dstaddr in self.arpTable[dpid]:
        # We have info about what port to send it out on...

        prt = self.arpTable[dpid][dstaddr].port
        mac = self.arpTable[dpid][dstaddr].mac
        if prt == inport:
          log.warning("%i %i not sending packet for %s back out of the " +
                      "input port" % (dpid, inport, str(dstaddr)))
        else:
          log.debug("%i %i installing flow for %s => %s out port %i"
                    % (dpid, inport, packet.next.srcip, dstaddr, prt))

          actions = []
          actions.append(of.ofp_action_dl_addr.set_dst(mac))
          actions.append(of.ofp_action_output(port = prt))
          match = of.ofp_match.from_packet(packet, inport)
          match.dl_src = None # Wildcard source MAC

          msg = of.ofp_flow_mod(command=of.OFPFC_ADD,
                                idle_timeout=FLOW_IDLE_TIMEOUT,
                                hard_timeout=of.OFP_FLOW_PERMANENT,
                                buffer_id=event.ofp.buffer_id,
                                actions=actions,
                                match=of.ofp_match.from_packet(packet,
                                                               inport))
          event.connection.send(msg.pack())
      elif self.arp_for_unknowns:
        # We don't know this destination.
        # First, we track this buffer so that we can try to resend it later
        # if we learn the destination, second we ARP for the destination,
        # which should ultimately result in it responding and us learning
        # where it is

        # Add to tracked buffers
        if (dpid,dstaddr) not in self.lost_buffers:
          self.lost_buffers[(dpid,dstaddr)] = []
        bucket = self.lost_buffers[(dpid,dstaddr)]
        entry = (time.time() + MAX_BUFFER_TIME,event.ofp.buffer_id,inport)
        bucket.append(entry)
        while len(bucket) > MAX_BUFFERED_PER_IP: del bucket[0]

        # Expire things from our outstanding ARP list...
        self.outstanding_arps = {k:v for k,v in
         self.outstanding_arps.iteritems() if v > time.time()}

        # Check if we've already ARPed recently
        if (dpid,dstaddr) in self.outstanding_arps:
          # Oop, we've already done this one recently.
          return

        # And ARP...
        self.outstanding_arps[(dpid,dstaddr)] = time.time() + 4

        r = arp()
        r.hwtype = r.HW_TYPE_ETHERNET
        r.prototype = r.PROTO_TYPE_IP
        r.hwlen = 6
        r.protolen = r.protolen
        r.opcode = r.REQUEST
        r.hwdst = ETHER_BROADCAST
        r.protodst = dstaddr
        r.hwsrc = packet.src
        r.protosrc = packet.next.srcip
        e = ethernet(type=ethernet.ARP_TYPE, src=packet.src,
                     dst=ETHER_BROADCAST)
        e.set_payload(r)
        log.debug("%i %i ARPing for %s on behalf of %s" % (dpid, inport,
         str(r.protodst), str(r.protosrc)))
        msg = of.ofp_packet_out()
        msg.data = e.pack()
        msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD))
        msg.in_port = inport
        event.connection.send(msg)
    def _handle_PacketIn(self, event):
        global arpRecieved
        print('#####################################################')
        packet = event.parsed
        if packet.type == packet.ARP_TYPE:
            print('arp msg')
            arpRecieved = True
            if packet.payload.opcode == arp.REQUEST:
                print('arp request')
                # arp request packet from h1 to h2
                if packet.payload.protosrc == ip_addr[
                        1] and packet.payload.protodst == ip_addr[2]:
                    # sending arp reply to h3 by modifying source as h2
                    arp_reply = arp()
                    arp_reply.hwsrc = mac_addr[3]
                    arp_reply.hwdst = packet.payload.hwsrc
                    arp_reply.opcode = arp.REPLY
                    arp_reply.protosrc = ip_addr[2]
                    arp_reply.protodst = packet.payload.protosrc
                    ether = ethernet()
                    ether.type = ethernet.ARP_TYPE
                    ether.dst = packet.src
                    ether.src = mac_addr[3]
                    ether.payload = arp_reply
                    msg = of.ofp_packet_out()
                    msg.data = ether.pack()
                    msg.actions.append(of.ofp_action_output(port=1))
                    event.connection.send(msg)

                # arp request coming from h3 for h1
                if packet.payload.protosrc == ip_addr[
                        3] and packet.payload.protodst == ip_addr[1]:
                    # sending arp reply to h1 by sending the mac address of h3
                    arp_reply = arp()
                    arp_reply.hwsrc = mac_addr[1]
                    arp_reply.hwdst = packet.payload.hwsrc
                    arp_reply.opcode = arp.REPLY
                    arp_reply.protosrc = ip_addr[1]
                    arp_reply.protodst = packet.payload.protosrc
                    ether = ethernet()
                    ether.type = ethernet.ARP_TYPE
                    ether.dst = packet.src
                    ether.src = mac_addr[1]
                    ether.payload = arp_reply
                    msg = of.ofp_packet_out()
                    msg.data = ether.pack()
                    msg.actions.append(of.ofp_action_output(port=3))
                    event.connection.send(msg)
        # handling icmp packets
        if packet.find('icmp'):
            print('icmp packet found')
            icmp_request_packet = packet.payload.payload
            if arpRecieved:  # sometimes hosts are sending icmp packets before sending arp packets, dropping those icmp packets
                if icmp_request_packet.type == 8:
                    # if icmp packet is for h2 sending it to h3
                    if packet.payload.dstip == ip_addr[2]:
                        packet.payload.dstip = ip_addr[3]
                        msg = of.ofp_packet_out()
                        msg.data = packet
                        msg.actions.append(of.ofp_action_output(port=3))
                        event.connection.send(msg)

                if icmp_request_packet.type == 0:
                    # seding icmp reply coming from h3 to h1 by changing its src address to h2
                    if packet.payload.srcip == ip_addr[3]:
                        packet.payload.dstip = ip_addr[1]
                        packet.payload.srcip = ip_addr[2]
                        msg = of.ofp_packet_out()
                        msg.data = packet
                        msg.actions.append(of.ofp_action_output(port=1))
                        event.connection.send(msg)
Ejemplo n.º 49
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")
Ejemplo n.º 50
0
    def _handle_openflow_PacketIn(self, event):
        dpid = event.connection.dpid
        inport = event.port
        packet = event.parsed
        global set_Timer
        global defendDDOS
        global blockPort
        timerSet = False
        global diction

        def preventing():
            global diction
            global set_Timer
            if not set_Timer:
                set_Timer = True

            if len(diction) == 0:
                print("Empty diction ", str(event.connection.dpid),
                      str(event.port))
                diction[event.connection.dpid] = {}
                diction[event.connection.dpid][event.port] = 1
            elif event.connection.dpid not in diction:
                diction[event.connection.dpid] = {}
                diction[event.connection.dpid][event.port] = 1
            else:
                if event.connection.dpid in diction:
                    if event.port in diction[event.connection.dpid]:
                        temp_count = 0
                        temp_count = diction[event.connection.dpid][event.port]
                        temp_count = temp_count + 1
                        diction[event.connection.dpid][event.port] = temp_count
                        #print "*****************************************************************************************************************************************************************************"
                        print "dpid port and its packet count: ", str(
                            event.connection.dpid), str(
                                diction[event.connection.dpid]), str(
                                    diction[event.connection.dpid][event.port])
                        #print "*****************************************************************************************************************************************************************************"
                    else:
                        diction[event.connection.dpid][event.port] = 1

        def _timer_func():
            global diction
            global set_Timer

            if set_Timer == True:
                for k, v in diction.iteritems():
                    for i, j in v.iteritems():
                        if j >= 32:
                            print "_____________________________________________________________________________________________"
                            print "\n                               DDOS DETECTED                                              \n"
                            print "\n", str(diction)
                            print "\n", datetime.datetime.now(
                            ), ": BLOCKED PORT NUMBER  : ", str(
                                i), " OF SWITCH ID: ", str(k)
                            print "\n___________________________________________________________________________________________"
                            os._exit(0)
                            dpid = k
                            msg = of.ofp_packet_out(in_port=i)
                            core.openflow.sendToDPID(dpid, msg)
            diction = {}

        if not packet.parsed:
            log.warning("%i %i ignoring unparsed packet", dpid, inport)
            return

        if dpid not in self.arpTable:
            self.arpTable[dpid] = {}
            for fake in self.fakeways:
                self.arpTable[dpid][IPAddr(fake)] = Entry(
                    of.OFPP_NONE, dpid_to_mac(dpid))

        if packet.type == ethernet.LLDP_TYPE:
            return

        if isinstance(packet.next, ipv4):
            log.debug("%i %i IP %s => %s", dpid, inport, packet.next.srcip,
                      packet.next.dstip)
            ent_obj.collectStats(event.parsed.next.dstip)
            print "Entropy : ", str(ent_obj.value)
            if ent_obj.value < 1.0:
                preventing()
                if timerSet is not True:
                    Timer(1, _timer_func, recurring=True)
                    timerSet = False
            else:
                timerSet = False

            self._send_lost_buffers(dpid, packet.next.srcip, packet.src,
                                    inport)

            if packet.next.srcip in self.arpTable[dpid]:
                if self.arpTable[dpid][packet.next.srcip] != (inport,
                                                              packet.src):
                    log.info("%i %i RE-learned %s", dpid, inport,
                             packet.next.srcip)
                    if self.wide:
                        msg = of.ofp_flow_mod(command=of.OFPFC_DELETE)
                        msg.match.nw_dst = packet.next.srcip
                        msg.match.dl_type = ethernet.IP_TYPE
                        event.connection.send(msg)
            else:
                log.debug("%i %i learned %s", dpid, inport, packet.next.srcip)
            self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src)

            dstaddr = packet.next.dstip
            if dstaddr in self.arpTable[dpid]:

                prt = self.arpTable[dpid][dstaddr].port
                mac = self.arpTable[dpid][dstaddr].mac
                if prt == inport:
                    log.warning(
                        "%i %i not sending packet for %s back out of the "
                        "input port" % (dpid, inport, dstaddr))
                else:
                    log.debug(
                        "%i %i installing flow for %s => %s out port %i" %
                        (dpid, inport, packet.next.srcip, dstaddr, prt))

                    actions = []
                    actions.append(of.ofp_action_dl_addr.set_dst(mac))
                    actions.append(of.ofp_action_output(port=prt))
                    if self.wide:
                        match = of.ofp_match(dl_type=packet.type,
                                             nw_dst=dstaddr)
                    else:
                        match = of.ofp_match.from_packet(packet, inport)

                    msg = of.ofp_flow_mod(command=of.OFPFC_ADD,
                                          idle_timeout=FLOW_IDLE_TIMEOUT,
                                          hard_timeout=of.OFP_FLOW_PERMANENT,
                                          buffer_id=event.ofp.buffer_id,
                                          actions=actions,
                                          match=match)
                    event.connection.send(msg.pack())
            elif self.arp_for_unknowns:
                if (dpid, dstaddr) not in self.lost_buffers:
                    self.lost_buffers[(dpid, dstaddr)] = []
                bucket = self.lost_buffers[(dpid, dstaddr)]
                entry = (time.time() + MAX_BUFFER_TIME, event.ofp.buffer_id,
                         inport)
                bucket.append(entry)
                while len(bucket) > MAX_BUFFERED_PER_IP:
                    del bucket[0]

                self.outstanding_arps = {
                    k: v
                    for k, v in self.outstanding_arps.iteritems()
                    if v > time.time()
                }

                if (dpid, dstaddr) in self.outstanding_arps:
                    return

                self.outstanding_arps[(dpid, dstaddr)] = time.time() + 4

                r = arp()
                r.hwtype = r.HW_TYPE_ETHERNET
                r.prototype = r.PROTO_TYPE_IP
                r.hwlen = 6
                r.protolen = r.protolen
                r.opcode = r.REQUEST
                r.hwdst = ETHER_BROADCAST
                r.protodst = dstaddr
                r.hwsrc = packet.src
                r.protosrc = packet.next.srcip
                e = ethernet(type=ethernet.ARP_TYPE,
                             src=packet.src,
                             dst=ETHER_BROADCAST)
                e.set_payload(r)
                log.debug("%i %i ARPing for %s on behalf of %s" %
                          (dpid, inport, r.protodst, r.protosrc))
                msg = of.ofp_packet_out()
                msg.data = e.pack()
                msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
                msg.in_port = inport
                event.connection.send(msg)

        elif isinstance(packet.next, arp):
            a = packet.next
            log.debug("%i %i ARP %s %s => %s", dpid, inport, {
                arp.REQUEST: "request",
                arp.REPLY: "reply"
            }.get(a.opcode, 'op:%i' % (a.opcode, )), a.protosrc, a.protodst)

            if a.prototype == arp.PROTO_TYPE_IP:
                if a.hwtype == arp.HW_TYPE_ETHERNET:
                    if a.protosrc != 0:

                        if a.protosrc in self.arpTable[dpid]:
                            if self.arpTable[dpid][a.protosrc] != (inport,
                                                                   packet.src):
                                log.info("%i %i RE-learned %s", dpid, inport,
                                         a.protosrc)
                                if self.wide:
                                    msg = of.ofp_flow_mod(
                                        command=of.OFPFC_DELETE)
                                    msg.match.dl_type = ethernet.IP_TYPE
                                    msg.match.nw_dst = a.protosrc
                                    event.connection.send(msg)
                        else:
                            log.debug("%i %i learned %s", dpid, inport,
                                      a.protosrc)
                        self.arpTable[dpid][a.protosrc] = Entry(
                            inport, packet.src)

                        self._send_lost_buffers(dpid, a.protosrc, packet.src,
                                                inport)

                        if a.opcode == arp.REQUEST:

                            if a.protodst in self.arpTable[dpid]:

                                if not self.arpTable[dpid][
                                        a.protodst].isExpired():

                                    r = arp()
                                    r.hwtype = a.hwtype
                                    r.prototype = a.prototype
                                    r.hwlen = a.hwlen
                                    r.protolen = a.protolen
                                    r.opcode = arp.REPLY
                                    r.hwdst = a.hwsrc
                                    r.protodst = a.protosrc
                                    r.protosrc = a.protodst
                                    r.hwsrc = self.arpTable[dpid][
                                        a.protodst].mac
                                    e = ethernet(type=packet.type,
                                                 src=dpid_to_mac(dpid),
                                                 dst=a.hwsrc)
                                    e.set_payload(r)
                                    log.debug("%i %i answering ARP for %s" %
                                              (dpid, inport, r.protosrc))
                                    msg = of.ofp_packet_out()
                                    msg.data = e.pack()
                                    msg.actions.append(
                                        of.ofp_action_output(
                                            port=of.OFPP_IN_PORT))
                                    msg.in_port = inport
                                    event.connection.send(msg)
                                    return

            log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport, {
                arp.REQUEST: "request",
                arp.REPLY: "reply"
            }.get(a.opcode, 'op:%i' % (a.opcode, )), a.protosrc, a.protodst))

            msg = of.ofp_packet_out(
                in_port=inport,
                data=event.ofp,
                action=of.ofp_action_output(port=of.OFPP_FLOOD))
            event.connection.send(msg)
Ejemplo n.º 51
0
    def _handle_PacketIn(self, event):
        # Note: arp.hwsrc is not necessarily equal to ethernet.src
        # (one such example are arp replies generated by this module itself
        # as ethernet mac is set to switch dpid) so we should be careful
        # to use only arp addresses in the learning code!
        squelch = False

        dpid = event.connection.dpid
        inport = event.port
        packet = event.parsed
        if not packet.parsed:
            log.warning("%s: ignoring unparsed packet", dpid_to_str(dpid))
            return

        a = packet.find('arp')
        if not a: return

        log.debug("%s ARP %s %s => %s", dpid_to_str(dpid), {
            arp.REQUEST: "request",
            arp.REPLY: "reply"
        }.get(a.opcode, 'op:%i' % (a.opcode, )), str(a.protosrc),
                  str(a.protodst))

        if a.prototype == arp.PROTO_TYPE_IP:
            if a.hwtype == arp.HW_TYPE_ETHERNET:
                if a.protosrc != 0:

                    if _learn:
                        # Learn or update port/MAC info
                        if a.protosrc in _arp_table:
                            if _arp_table[a.protosrc] != Entry(a.hwsrc):
                                log.warn("%s RE-learned %s: %s->%s",
                                         dpid_to_str(dpid), a.protosrc,
                                         _arp_table[a.protosrc].mac, a.hwsrc)
                        else:
                            log.info("%s learned %s", dpid_to_str(dpid),
                                     a.protosrc)
                        _arp_table[a.protosrc] = Entry(a.hwsrc)

                    if a.opcode == arp.REQUEST:
                        # Maybe we can answer

                        if a.protodst in _arp_table:
                            # We have an answer...

                            r = arp()
                            r.hwtype = a.hwtype
                            r.prototype = a.prototype
                            r.hwlen = a.hwlen
                            r.protolen = a.protolen
                            r.opcode = arp.REPLY
                            r.hwdst = a.hwsrc
                            r.protodst = a.protosrc
                            r.protosrc = a.protodst
                            mac = _arp_table[a.protodst].mac
                            if mac is True:
                                # Special case -- use ourself
                                mac = _dpid_to_mac(dpid)
                            r.hwsrc = mac
                            e = ethernet(type=packet.type,
                                         src=_dpid_to_mac(dpid),
                                         dst=a.hwsrc)
                            e.payload = r
                            if packet.type == ethernet.VLAN_TYPE:
                                v_rcv = packet.find('vlan')
                                e.payload = vlan(eth_type=e.type,
                                                 payload=e.payload,
                                                 id=v_rcv.id,
                                                 pcp=v_rcv.pcp)
                                e.type = ethernet.VLAN_TYPE
                            log.info("%s answering ARP for %s" %
                                     (dpid_to_str(dpid), str(r.protosrc)))
                            msg = of.ofp_packet_out()
                            msg.data = e.pack()
                            msg.actions.append(
                                of.ofp_action_output(port=of.OFPP_IN_PORT))
                            msg.in_port = inport
                            event.connection.send(msg)
                            return EventHalt if _eat_packets else None
                        else:
                            # Keep track of failed queries
                            squelch = a.protodst in _failed_queries
                            _failed_queries[a.protodst] = time.time()

        if self._check_for_flood(dpid, a):
            # Didn't know how to handle this ARP, so just flood it
            msg = "%s flooding ARP %s %s => %s" % (dpid_to_str(dpid), {
                arp.REQUEST: "request",
                arp.REPLY: "reply"
            }.get(a.opcode, 'op:%i' % (a.opcode, )), a.protosrc, a.protodst)

            if squelch:
                log.debug(msg)
            else:
                log.info(msg)

            msg = of.ofp_packet_out()
            msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
            msg.data = event.ofp
            event.connection.send(msg.pack())

        return EventHalt if _eat_packets else None
Ejemplo n.º 52
0
    def _handle_PacketIn(self, event):
        dpid = event.connection.dpid
        inport = event.port
        packet = event.parsed
        if not packet.parsed:
            log.warning("%i %i ignoring unparsed packet", dpid, inport)
            return

        if dpid not in self.arpTable:
            # New switch -- create an empty table
            log.debug("Add switch %s", str(dpid))
            self.arpTable[dpid] = {}
            for fake in self.fakeways[dpid - 1]:
                self.arpTable[dpid][IPAddr(fake)] = Entry(
                    of.OFPP_NONE, dpid_to_mac(dpid))

            self.set_firewall(dpid)

        if packet.type == ethernet.LLDP_TYPE:
            # Ignore LLDP packets
            return

        if isinstance(packet.next, ipv4):
            log.debug("%i %i IP %s => %s", dpid, inport, packet.next.srcip,
                      packet.next.dstip)
            '''deal with ICMP'''
            # in case the host may ping router (not 127.0.0.1)
            if packet.payload.protocol == packet.payload.ICMP_PROTOCOL and str(
                    packet.payload.dstip) in self.fakeways[dpid - 1]:
                print "ICMP"
                packet.payload.payload.type = 0  # ICMP reachable
                packet.payload.dstip, packet.payload.srcip = packet.payload.srcip, packet.payload.dstip
                packet.src, packet.dst = packet.dst, packet.src
                msg = of.ofp_packet_out()
                msg.data = packet
                action = of.ofp_action_output(port=inport)
                msg.actions.append(action)
                event.connection.send(msg)
                return

            # Send any waiting packets...
            self._send_lost_buffers(dpid, packet.next.srcip, packet.src,
                                    inport)

            # Learn or update port/MAC info
            if packet.next.srcip in self.arpTable[dpid]:
                if self.arpTable[dpid][packet.next.srcip] != (inport,
                                                              packet.src):
                    log.info("%i %i RE-learned %s", dpid, inport,
                             packet.next.srcip)
            else:
                log.debug("%i %i learned %s", dpid, inport,
                          str(packet.next.srcip))
            self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src)

            # Try to forward
            dstaddr = packet.next.dstip
            if dstaddr in self.arpTable[dpid]:
                # We have info about what port to send it out on...

                prt = self.arpTable[dpid][dstaddr].port
                mac = self.arpTable[dpid][dstaddr].mac
                if prt == inport:
                    log.warning(
                        "%i %i not sending packet for %s back out of the " +
                        "input port" % (
                            dpid,
                            inport,
                            str(dstaddr),
                        ))
                else:
                    log.debug(
                        "%i %i installing flow for %s => %s out port %i" %
                        (dpid, inport, packet.next.srcip, dstaddr, prt))

                    actions = []
                    actions.append(of.ofp_action_dl_addr.set_dst(mac))
                    actions.append(of.ofp_action_output(port=prt))
                    match = of.ofp_match.from_packet(packet, inport)
                    match.dl_src = None  # Wildcard source MAC

                    msg = of.ofp_flow_mod(command=of.OFPFC_ADD,
                                          idle_timeout=FLOW_IDLE_TIMEOUT,
                                          hard_timeout=of.OFP_FLOW_PERMANENT,
                                          buffer_id=event.ofp.buffer_id,
                                          actions=actions,
                                          match=of.ofp_match.from_packet(
                                              packet, inport))
                    event.connection.send(msg.pack())
            elif self.arp_for_unknowns:
                # We don't know this destination.
                # First, we track this buffer so that we can try to resend it later
                # if we learn the destination, second we ARP for the destination,
                # which should ultimately result in it responding and us learning
                # where it is

                # Add to tracked buffers
                if (dpid, dstaddr) not in self.lost_buffers:
                    self.lost_buffers[(dpid, dstaddr)] = []
                bucket = self.lost_buffers[(dpid, dstaddr)]
                #entry = (time.time() + MAX_BUFFER_TIME,event.ofp.buffer_id,inport)
                entry = (time.time() + MAX_BUFFER_TIME, event.ofp.buffer_id,
                         inport, packet)
                bucket.append(entry)
                while len(bucket) > MAX_BUFFERED_PER_IP:
                    del bucket[0]

                # Expire things from our outstanding ARP list...
                self.outstanding_arps = {
                    k: v
                    for k, v in self.outstanding_arps.iteritems()
                    if v > time.time()
                }

                # Check if we've already ARPed recently
                if (dpid, dstaddr) in self.outstanding_arps:
                    # Oop, we've already done this one recently.
                    return

                # And ARP...
                self.outstanding_arps[(dpid, dstaddr)] = time.time() + 4

                r = arp()
                r.hwtype = r.HW_TYPE_ETHERNET
                r.prototype = r.PROTO_TYPE_IP
                r.hwlen = 6
                r.protolen = r.protolen
                r.opcode = r.REQUEST
                r.hwdst = ETHER_BROADCAST
                r.protodst = dstaddr
                r.hwsrc = packet.src
                r.protosrc = packet.next.srcip
                e = ethernet(type=ethernet.ARP_TYPE,
                             src=packet.src,
                             dst=ETHER_BROADCAST)
                e.set_payload(r)
                log.debug("%i %i ARPing for %s on behalf of %s" %
                          (dpid, inport, str(r.protodst), str(r.protosrc)))
                msg = of.ofp_packet_out()
                msg.data = e.pack()
                msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
                msg.in_port = inport
                event.connection.send(msg)

        elif isinstance(packet.next, arp):
            a = packet.next
            log.debug("%i %i ARP %s %s => %s", dpid, inport, {
                arp.REQUEST: "request",
                arp.REPLY: "reply"
            }.get(a.opcode, 'op:%i' % (a.opcode, )), str(a.protosrc),
                      str(a.protodst))

            if a.prototype == arp.PROTO_TYPE_IP:
                if a.hwtype == arp.HW_TYPE_ETHERNET:
                    if a.protosrc != 0:

                        # Learn or update port/MAC info
                        if a.protosrc in self.arpTable[dpid]:
                            if self.arpTable[dpid][a.protosrc] != (inport,
                                                                   packet.src):
                                log.info("%i %i RE-learned %s", dpid, inport,
                                         str(a.protosrc))
                        else:
                            log.debug("%i %i learned %s", dpid, inport,
                                      str(a.protosrc))
                        self.arpTable[dpid][a.protosrc] = Entry(
                            inport, packet.src)

                        # Send any waiting packets...
                        self._send_lost_buffers(dpid, a.protosrc, packet.src,
                                                inport)

                        if a.opcode == arp.REQUEST:
                            # Maybe we can answer

                            if a.protodst in self.arpTable[dpid]:
                                # We have an answer...

                                if not self.arpTable[dpid][
                                        a.protodst].isExpired():
                                    # .. and it's relatively current, so we'll reply ourselves

                                    r = arp()
                                    r.hwtype = a.hwtype
                                    r.prototype = a.prototype
                                    r.hwlen = a.hwlen
                                    r.protolen = a.protolen
                                    r.opcode = arp.REPLY
                                    r.hwdst = a.hwsrc
                                    r.protodst = a.protosrc
                                    r.protosrc = a.protodst
                                    r.hwsrc = self.arpTable[dpid][
                                        a.protodst].mac
                                    e = ethernet(type=packet.type,
                                                 src=dpid_to_mac(dpid),
                                                 dst=a.hwsrc)
                                    e.set_payload(r)
                                    log.debug("%i %i answering ARP for %s" %
                                              (dpid, inport, str(r.protosrc)))
                                    msg = of.ofp_packet_out()
                                    msg.data = e.pack()
                                    msg.actions.append(
                                        of.ofp_action_output(
                                            port=of.OFPP_IN_PORT))
                                    msg.in_port = inport
                                    event.connection.send(msg)
                                    return

            # Didn't know how to answer or otherwise handle this ARP, so just flood it
            log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport, {
                arp.REQUEST: "request",
                arp.REPLY: "reply"
            }.get(a.opcode, 'op:%i' %
                  (a.opcode, )), str(a.protosrc), str(a.protodst)))

            msg = of.ofp_packet_out(
                in_port=inport,
                data=event.ofp,
                action=of.ofp_action_output(port=of.OFPP_FLOOD))
            event.connection.send(msg)
Ejemplo n.º 53
0
    def _handle_PacketIn(self, event):
        packet = event.parsed
        Switch_Output[event.dpid][packet.src] = event.port

        if packet.find("arp"):
            arp_packet = packet.find("arp")
            IP_To_MAC[arp_packet.protosrc] = packet.src
            if arp_packet.opcode == arp.REQUEST:
                if arp_packet.protodst in IP_To_MAC:  #reply
                    #construct arp reply packet
                    arp_reply = arp()
                    arp_reply.hwsrc = IP_To_MAC[arp_packet.protodst]
                    arp_reply.hwdst = packet.src
                    arp_reply.opcode = arp.REPLY
                    arp_reply.protosrc = arp_packet.protodst
                    arp_reply.protodst = arp_packet.protosrc
                    ether = ethernet()
                    ether.type = ethernet.ARP_TYPE
                    ether.dst = packet.src
                    ether.src = IP_To_MAC[arp_packet.protodst]
                    ether.payload = arp_reply

                    # send the created arp reply back to switch
                    msg = of.ofp_packet_out()
                    msg.data = ether.pack()
                    msg.actions.append(
                        of.ofp_action_output(port=of.OFPP_IN_PORT))
                    msg.in_port = event.port
                    event.connection.send(msg)

                elif (arp_packet.protosrc, arp_packet.protodst
                      ) not in Switch_AntiFlood[event.dpid]:  #flood
                    msg = of.ofp_packet_out(data=event.data)
                    msg.actions.append(
                        of.ofp_action_output(port=of.OFPP_FLOOD))
                    msg.in_port = event.port
                    event.connection.send(msg)
                    # Switch_AntiFlood[event.dpid].append((arp_reply.protosrc,arp_packet.protodst) )

        # if packet.find('ipv4'):
        # 	ip_packet=packet.find('ipv4')
        # 	IP_To_MAC[ip_packet.dstip]=packet.dst
        # 	IP_To_MAC[ip_packet.srcip]=packet.src

        if packet.dst in Switch_Output[event.dpid]:
            msg = of.ofp_packet_out(data=event.ofp)
            msg.actions.append(
                of.ofp_action_output(
                    port=Switch_Output[event.dpid][packet.dst]))
            msg.in_port = event.port
            event.connection.send(msg)

            Install_Flow(event, packet.src, packet.dst,
                         Switch_Output[event.dpid][packet.dst])
            Install_Flow(event, packet.dst, packet.src,
                         Switch_Output[event.dpid][packet.src])

        print event.dpid, 'packet_in:', packet
        print 'out_put:', Switch_Output
        print 'IP_MAC', IP_To_MAC
        print 'Anti', Switch_AntiFlood
        print
Ejemplo n.º 54
0
    def _handle_PacketIn(self, event):
        dpid = event.connection.dpid
        inport = event.port
        packet = event.parsed
        if not packet.parsed:
            log.warning("%i %i ignoring unparsed packet", dpid, inport)
            return
        """ FIREWALL"""

        p = "54312, 12311, 21311"
        blocking_port.update(int(x) for x in p.replace(",", " ").split())
        core.openflow.addListenerByName("PacketIn", firewall)

        if dpid not in self.arpTable:
            # New switch -- create an empty table
            self.arpTable[dpid] = {}
            for fake in self.fakeways:
                self.arpTable[dpid][IPAddr(fake)] = Entry(
                    of.OFPP_NONE, dpid_to_mac(dpid))
        if dpid not in self.routing:
            # New switch -- create an empty table
            self.routing[dpid] = {}
            if dpid == 1:
                self.routing[dpid][IPAddr('10.0.2.1')] = 1
                self.routing[dpid][IPAddr('10.0.3.1')] = 2
            if dpid == 2:
                self.routing[dpid][IPAddr('10.0.1.1')] = 1
                self.routing[dpid][IPAddr('10.0.3.1')] = 2
            if dpid == 3:
                self.routing[dpid][IPAddr('10.0.1.1')] = 1
                self.routing[dpid][IPAddr('10.0.2.1')] = 2

        if packet.type == ethernet.LLDP_TYPE:
            # Ignore LLDP packets
            return

        if isinstance(packet.next, ipv4):

            dstaddr = packet.next.dstip
            srcaddr = packet.next.srcip
            n = str(dstaddr).split('.')
            l = str(srcaddr).split('.')
            log.debug("%i %i IP %s => %s here", dpid, inport,
                      packet.next.srcip, packet.next.dstip)
            if n[2] != str(dpid) and l[2] != str(dpid):
                log.debug("Not destined to this subnet: Packet Dropped")
                return
            # Send any waiting packets...
            self._send_lost_buffers(dpid, packet.next.srcip, packet.src,
                                    inport)

            # Learn or update port/MAC info
            if packet.next.srcip in self.arpTable[dpid]:
                if self.arpTable[dpid][packet.next.srcip] != (inport,
                                                              packet.src):
                    log.info("%i %i RE-learned %s", dpid, inport,
                             packet.next.srcip)
            else:
                log.debug("%i %i learned %s ", dpid, inport,
                          str(packet.next.srcip))
                self.arpTable[dpid][packet.next.srcip] = Entry(
                    inport, packet.src)

            if packet.next.srcip not in self.routing[dpid]:
                self.routing[dpid][packet.next.srcip] = inport

            if n[0] != '10':
                self.icmp_message(dpid, packet, packet.next.srcip,
                                  packet.next.dstip, pkt.TYPE_DEST_UNREACH,
                                  event)
                return
            if n[1] != '0':
                self.icmp_message(dpid, packet, packet.next.srcip,
                                  packet.next.dstip, pkt.TYPE_DEST_UNREACH,
                                  event)
                return
            if n[2] != '1' and n[2] != '2' and n[2] != '3':
                self.icmp_message(dpid, packet, packet.next.srcip,
                                  packet.next.dstip, pkt.TYPE_DEST_UNREACH,
                                  event)
                return
            if n[2] == '1':
                if n[3] != '2' and n[3] != '3' and n[3] != '1' and n[3] != '4':
                    self.icmp_message(dpid, packet, packet.next.srcip,
                                      packet.next.dstip, pkt.TYPE_DEST_UNREACH,
                                      event)
                    return
            if n[2] == '2':
                if n[3] != '2' and n[3] != '1' and n[3] != '3' and n[3] != '4':
                    self.icmp_message(dpid, packet, packet.next.srcip,
                                      packet.next.dstip, pkt.TYPE_DEST_UNREACH,
                                      event)
                    return
            if n[2] == '3':
                if n[3] != '2' and n[3] != '1' and n[3] != '3' and n[3] != '4':
                    self.icmp_message(dpid, packet, packet.next.srcip,
                                      packet.next.dstip, pkt.TYPE_DEST_UNREACH,
                                      event)
                    return
        # Try to forward
            if dstaddr in self.fakeways and int(n[2]) == dpid:
                if isinstance(packet.next.next, icmp):
                    if packet.next.next.type == pkt.TYPE_ECHO_REQUEST:
                        self.icmp_message(dpid, packet, packet.next.srcip,
                                          packet.next.dstip,
                                          pkt.TYPE_ECHO_REPLY, event)
            elif n[2] == l[2]:
                if dstaddr not in self.routing[
                        dpid] or dstaddr not in self.arpTable[dpid]:
                    if (dpid, dstaddr) not in self.lost_buffers:
                        self.lost_buffers[(dpid, dstaddr)] = []
                    bucket = self.lost_buffers[(dpid, dstaddr)]
                    entry = (time.time() + MAX_BUFFER_TIME,
                             event.ofp.buffer_id, inport)
                    bucket.append(entry)
                    while len(bucket) > MAX_BUFFERED_PER_IP:
                        del bucket[0]

                    # Expire things from our outstanding ARP list...
                    self.outstanding_arps = {
                        k: v
                        for k, v in self.outstanding_arps.iteritems()
                        if v > time.time()
                    }

                    # Check if we've already ARPed recently
                    if (dpid, dstaddr) in self.outstanding_arps:
                        # Oop, we've already done this one recently.
                        return
                    r = arp()
                    r.hwtype = r.HW_TYPE_ETHERNET
                    r.prototype = r.PROTO_TYPE_IP
                    r.hwlen = 6
                    r.protolen = r.protolen
                    r.opcode = r.REQUEST
                    r.hwdst = ETHER_BROADCAST
                    r.protodst = dstaddr
                    r.hwsrc = packet.src
                    r.protosrc = packet.next.srcip
                    e = ethernet(type=ethernet.ARP_TYPE,
                                 src=packet.src,
                                 dst=ETHER_BROADCAST)
                    e.set_payload(r)
                    log.debug("%i %i ARPing for %s on behalf of %s" %
                              (dpid, inport, str(r.protodst), str(r.protosrc)))
                    msg = of.ofp_packet_out()
                    msg.data = e.pack()
                    msg.actions.append(
                        of.ofp_action_output(port=of.OFPP_FLOOD))
                    msg.in_port = inport
                    event.connection.send(msg)
                if dstaddr in self.arpTable[dpid]:
                    # We have info about what port to send it out on...

                    prt = self.arpTable[dpid][dstaddr].port
                    mac = self.arpTable[dpid][dstaddr].mac
                    log.debug(
                        "%i %i installing flow for %s => %s out port %i" %
                        (dpid, inport, packet.next.srcip, dstaddr, prt))

                    actions = []
                    actions.append(of.ofp_action_dl_addr.set_dst(mac))
                    actions.append(of.ofp_action_output(port=prt))
                    match = of.ofp_match.from_packet(packet, inport)
                    match.dl_src = None  # Wildcard source MAC

                    msg = of.ofp_flow_mod(command=of.OFPFC_ADD,
                                          idle_timeout=FLOW_IDLE_TIMEOUT,
                                          hard_timeout=of.OFP_FLOW_PERMANENT,
                                          buffer_id=event.ofp.buffer_id,
                                          actions=actions,
                                          match=of.ofp_match.from_packet(
                                              packet, inport))
                    event.connection.send(msg.pack())
            else:
                if dstaddr in self.arpTable[dpid]:
                    n_addr = IPAddr('10.0.%d.1' % int(n[2]))
                    mac = self.arpTable[dpid][dstaddr].mac
                    prt = self.routing[dpid][dstaddr]

                    actions = []
                    actions.append(of.ofp_action_dl_addr.set_dst(mac))
                    actions.append(of.ofp_action_output(port=prt))
                    match = of.ofp_match.from_packet(packet, inport)
                    match.dl_src = None  # Wildcard source MAC

                    msg = of.ofp_flow_mod(command=of.OFPFC_ADD,
                                          idle_timeout=FLOW_IDLE_TIMEOUT,
                                          hard_timeout=of.OFP_FLOW_PERMANENT,
                                          buffer_id=event.ofp.buffer_id,
                                          actions=actions,
                                          match=of.ofp_match.from_packet(
                                              packet, inport))
                    event.connection.send(msg.pack())

                elif self.arp_for_unknowns:
                    if dstaddr not in self.routing[
                            dpid] or dstaddr not in self.arpTable[dpid]:
                        if (dpid, dstaddr) not in self.lost_buffers:
                            self.lost_buffers[(dpid, dstaddr)] = []
                        bucket = self.lost_buffers[(dpid, dstaddr)]
                        entry = (time.time() + MAX_BUFFER_TIME,
                                 event.ofp.buffer_id, inport)
                        bucket.append(entry)
                        while len(bucket) > MAX_BUFFERED_PER_IP:
                            del bucket[0]

                        # Expire things from our outstanding ARP list...
                        self.outstanding_arps = {
                            k: v
                            for k, v in self.outstanding_arps.iteritems()
                            if v > time.time()
                        }

                        # Check if we've already ARPed recently
                        if (dpid, dstaddr) in self.outstanding_arps:
                            # Oop, we've already done this one recently.
                            return
                        r = arp()
                        r.hwtype = r.HW_TYPE_ETHERNET
                        r.prototype = r.PROTO_TYPE_IP
                        r.hwlen = 6
                        r.protolen = r.protolen
                        r.opcode = r.REQUEST
                        r.hwdst = ETHER_BROADCAST
                        r.protodst = dstaddr
                        r.hwsrc = packet.src
                        r.protosrc = packet.next.srcip
                        e = ethernet(type=ethernet.ARP_TYPE,
                                     src=packet.src,
                                     dst=ETHER_BROADCAST)
                        e.set_payload(r)
                        log.debug(
                            "%i %i ARPing for %s on behalf of %s" %
                            (dpid, inport, str(r.protodst), str(r.protosrc)))
                        msg = of.ofp_packet_out()
                        msg.data = e.pack()
                        msg.actions.append(
                            of.ofp_action_output(port=of.OFPP_FLOOD))
                        msg.in_port = inport
                        event.connection.send(msg)
        elif isinstance(packet.next, arp):
            a = packet.next
            n = str(packet.next.protodst).split('.')
            l = str(packet.next.protosrc).split('.')
            log.debug("%i %i ARP %s %s => %s", dpid, inport, {
                arp.REQUEST: "request",
                arp.REPLY: "reply"
            }.get(a.opcode, 'op:%i' % (a.opcode, )), str(a.protosrc),
                      str(a.protodst))
            if n[2] != str(dpid) and l[2] != str(dpid):
                log.debug("Not destined to this subnet: Packet Dropped")
                return
            flag = 0
            q = str(a.protodst).split('.')

            if a.prototype == arp.PROTO_TYPE_IP:
                if a.hwtype == arp.HW_TYPE_ETHERNET:
                    if a.protosrc != 0:

                        # Learn or update port/MAC info
                        if a.protosrc in self.arpTable[dpid]:
                            if self.arpTable[dpid][a.protosrc] != (inport,
                                                                   packet.src):
                                log.info("%i %i RE-learned %s", dpid, inport,
                                         str(a.protosrc))
                        else:
                            log.debug("%i %i learned %s", dpid, inport,
                                      str(a.protosrc))
                        self.arpTable[dpid][a.protosrc] = Entry(
                            inport, packet.src)

                        if packet.next.protosrc not in self.routing[dpid]:
                            self.routing[dpid][packet.next.protosrc] = inport

                        # Send any waiting packets..
                        self._send_lost_buffers(dpid, a.protosrc, packet.src,
                                                inport)

                        if a.opcode == arp.REQUEST:
                            # Maybe we can answer

                            if a.protodst in self.arpTable[dpid]:
                                # We have an answer...

                                if self.arpTable[dpid][a.protodst] or (
                                        self.fakeways and int(n[2]) == dpid):
                                    # .. and it's relatively current, so we'll reply ourselves

                                    r = arp()
                                    r.hwtype = a.hwtype
                                    r.prototype = a.prototype
                                    r.hwlen = a.hwlen
                                    r.protolen = a.protolen
                                    r.opcode = arp.REPLY
                                    r.hwdst = a.hwsrc
                                    r.protodst = a.protosrc
                                    r.protosrc = a.protodst
                                    r.hwsrc = self.arpTable[dpid][
                                        a.protodst].mac
                                    e = ethernet(type=packet.type,
                                                 src=dpid_to_mac(dpid),
                                                 dst=a.hwsrc)
                                    e.set_payload(r)
                                    log.debug("%i %i answering ARP for %s" %
                                              (dpid, inport, str(r.protosrc)))
                                    msg = of.ofp_packet_out()
                                    msg.data = e.pack()
                                    msg.actions.append(
                                        of.ofp_action_output(
                                            port=of.OFPP_IN_PORT))

                                    msg.in_port = inport
                                    event.connection.send(msg)
                                    return
                                else:
                                    n_addr = IPAddr('10.0.%d.1' % int(n[2]))
                                    mac = self.arpTable[dpid][n_addr].mac
                                    prt = self.routing[dpid][a.protodst]
                                    r = arp()
                                    r.hwtype = a.hwtype
                                    r.prototype = a.prototype
                                    r.hwlen = a.hwlen
                                    r.protolen = a.protolen
                                    r.opcode = arp.REPLY
                                    r.hwdst = mac
                                    r.protodst = a.protosrc
                                    r.protosrc = a.protodst
                                    r.hwsrc = self.arpTable[dpid][
                                        a.protodst].mac
                                    e = ethernet(type=packet.type,
                                                 src=dpid_to_mac(dpid),
                                                 dst=a.hwdst)
                                    e.set_payload(r)
                                    log.debug("%i %i answering ARP for %s" %
                                              (dpid, inport, str(r.protosrc)))
                                    msg = of.ofp_packet_out()
                                    msg.data = e.pack()
                                    msg.actions.append(
                                        of.ofp_action_output(port=prt))

                                    msg.in_port = inport
                                    event.connection.send(msg)
                                    return
                        elif a.opcode == arp.REPLY and a.protodst != IPAddr(
                                '10.0.%d.1' % (dpid)):
                            if a.protodst in self.routing[dpid] and n[2] != l[
                                    2] and inport != 1 and inport != 2:
                                flag = 1
                                n_addr = IPAddr('10.0.%d.1' % int(n[2]))
                                prt = self.routing[dpid][a.protodst]

                                msg = of.ofp_packet_out()
                                msg.data = event.ofp
                                action = of.ofp_action_output(port=prt)
                                msg.actions.append(action)
                                event.connection.send(msg)
                            else:
                                flag = 1
                                msg = of.ofp_packet_out(
                                    in_port=inport,
                                    data=event.ofp,
                                    action=of.ofp_action_output(
                                        port=of.OFPP_FLOOD))
                                event.connection.send(msg)

            if flag == 0:
                # Didn't know how to answer or otherwise handle this ARP, so just flood it
                log.debug(
                    "%i %i flooding ARP %s %s => %s" % (dpid, inport, {
                        arp.REQUEST: "request",
                        arp.REPLY: "reply"
                    }.get(a.opcode, 'op:%i' %
                          (a.opcode, )), str(a.protosrc), str(a.protodst)))

                msg = of.ofp_packet_out(
                    in_port=inport,
                    data=event.ofp,
                    action=of.ofp_action_output(port=of.OFPP_FLOOD))
                event.connection.send(msg)
Ejemplo n.º 55
0
    def _handle_PacketIn(self, event):
        packet = event.parsed
        if not packet.parsed:
            return

        port = event.port
        dpid = event.connection.dpid
        pnext = packet.next

        # A new switch has connected
        if dpid not in self._arp_table:
            self._arp_table[dpid] = {}
            log.info("Initiating ARP table for dpid: %i" % (dpid, ))

        # If it is an IPv4 packet
        if isinstance(pnext, ipv4):
            # Learn or update mac and port info for IP
            self._arp_table[dpid][pnext.srcip] = (packet.src, port)
            self._master_arp_table[pnext.srcip] = packet.src
            log.info("Updating ARP table for dpid: %i & IP: %s with (%s, %i)" %\
              (dpid, pnext.srcip, packet.src, port,))
            # Find the packet destination
            dst_ip = pnext.dstip

            # number hosts for computing convenience
            odd_ips = {"10.0.0.1": 1, "10.0.0.3": 3, "10.0.0.5": 5}
            even_ips = {"10.0.0.2": 2, "10.0.0.4": 4, "10.0.0.6": 6}

            # create msg
            message = of.ofp_flow_mod(buffer_id=event.ofp.buffer_id)
            message.actions.append(of.ofp_action_dl_addr.set_dst(dst_mac))

            # if dpid indicates leaf switch and src and dst shade that node
            # directly redirect to the destination
            if pnext.srcip in odd_ips and \
               odd_ips[pnext.srcip]+1 == even_ips[dst_ip]:
                message.actions.append(of.ofp_action_output(port=4))
            if pnext.srcip in even_ips and \
               even_ips[pnext.srcip]-1 == odd_ips[dst_ip]:
                message.actions.append(of.ofp_action_output(port=3))

            # If destination is known then
            if dst_ip in self._arp_table[dpid]:
                # Obtain its mac and port
                dst_mac, dst_port = self._arp_table[dpid][dst_ip]
                log.info("Probed ARP table for dpid: %i & IP: %s to get (%s, %i)" %\
                  (dpid, dst_ip, dst_mac, dst_port,))
                # Add the flow rule to switch
                if dst_port != port:
                    #message = of.ofp_flow_mod(buffer_id=event.ofp.buffer_id)
                    #message.actions.append(of.ofp_action_dl_addr.set_dst(dst_mac))
                    message.actions.append(of.ofp_action_output(port=dst_port))
                    message.match = of.ofp_match.from_packet(packet, port)
                    event.connection.send(message)
            # route odd leaf switches through s4 and even ones through s5
            else:
                # (topology specific)if leaf switches (dpid is 1 , 2 or 3 in out case)
                if pnext.srcip in odd_ips and int(dpid) in [1, 2, 3]:
                    # route throgh s4
                    # (topology specific)port 1 on leaf nodes always connect to s4
                    message.actions.append(of.ofp_action_output(port=1))
                    log.info("Odd IP: %s should be routed through S4" %
                             (pnext.srcip, ))
                elif pnext.srcip in even_ips:
                    # (topology specific)port 2 on leaf nodes always connect to s5
                    message.actions.append(of.ofp_action_output(port=2))
                    log.info("Even IP: %s should be routed through S5" %
                             (pnext.srcip, ))
                else:
                    # unknown dpid
                    log.info("Encountered unknown IP: %s" % (pnext.srcip, ))

        # Else if it is an ARP packet
        elif isinstance(pnext, arp):
            if pnext.prototype == arp.PROTO_TYPE_IP and pnext.hwtype == arp.HW_TYPE_ETHERNET \
              and pnext.protosrc != 0:
                # Learn or update MAC & port info for IP
                self._arp_table[dpid][pnext.protosrc] = (packet.src, port)
                self._master_arp_table[pnext.protosrc] = packet.src
                log.info("Updating ARP table for dpid: %i & IP: %s with (%s, %i)" %\
                  (dpid, pnext.protosrc, packet.src, port,))
                # If it is an ARP request and we know the destination
                # if pnext.opcode == arp.REQUEST and pnext.protodst in self._arp_table[dpid]:
                if pnext.opcode == arp.REQUEST and pnext.protodst in self._master_arp_table:
                    # Send the ARP response
                    res = arp()
                    # res.hwsrc, _  = self._arp_table[dpid][pnext.protodst]
                    res.hwsrc = self._master_arp_table[pnext.protodst]
                    res.hwtype = arp.HW_TYPE_ETHERNET
                    res.hwdst = pnext.hwsrc
                    res.hwlen = pnext.hwlen
                    res.prototype = arp.PROTO_TYPE_IP
                    res.protodst = pnext.protosrc
                    res.protosrc = pnext.protodst
                    res.protolen = pnext.protolen
                    res.opcode = arp.REPLY
                    eth = ethernet()
                    eth.type = packet.type
                    eth.src = EthAddr("%012x" % (dpid & 0xFFFFFFFFFFFF))
                    eth.dst = res.hwdst
                    eth.set_payload(res)
                    message = of.ofp_packet_out()
                    message.in_port = port
                    message.data = eth.pack()
                    message.actions.append(
                        of.ofp_action_output(port=of.OFPP_IN_PORT))
                    event.connection.send(message)
                    log.info("Responded to ARP request for dpid: %s and destination: %s" %\
                      (dpid, pnext.protodst,))
Ejemplo n.º 56
0
def _handle_PacketIn(event):
    # check if the entry is in the table or not
    # if it's not in the table, add an entry to the table
    # We don't know where the destination is yet.  So, we'll just
    # send the packet out all ports (except the one it came in on!)
    # and hope the destination is out there somewhere. :)
    # To send out all ports, we can use either of the special ports
    # OFPP_FLOOD or OFPP_ALL.
    # if the appropriate entry is in the table, just forward the packet to that port

    # parse the packet

    packet = event.parsed
    src_mac = packet.src
    dst_mac = packet.dst
    switch = event.connection
    port_in = event.port
    switch = event.connection
    match = of.ofp_match.from_packet(packet)
    arp_request = packet.find('arp')
    #identify switch
    dpid = event.connection.dpid

    if not arp_request:
        #part 2
        if (dpid_to_str(dpid) == "00-00-00-00-00-01"):
            port_out = l1[str(dst_mac)]
        elif (dpid_to_str(dpid) == "00-00-00-00-00-02"):
            port_out = l2[str(dst_mac)]
        elif (dpid_to_str(dpid) == "00-00-00-00-00-03"):
            port_out = l3[str(dst_mac)]
        elif (dpid_to_str(dpid) == "00-00-00-00-00-04"):
            port_out = s4[str(dst_mac)]
        elif (dpid_to_str(dpid) == "00-00-00-00-00-05"):
            port_out = s5[str(dst_mac)]

        msg = of.ofp_packet_out()
        msg.data = event.ofp
        msg.actions.append(of.ofp_action_output(port=port_out))
        switch.send(msg)
    else:
        if arp_request.prototype == arp.PROTO_TYPE_IP:
            if arp_request.hwtype == arp.HW_TYPE_ETHERNET:
                if arp_request.protosrc != 0:
                    if arp_request.opcode == arp.REQUEST:
                        dst_ip = arp_request.protodst
                        src_ip = arp_request.protosrc
                        res = arp()
                        res.hwtype = arp_request.hwtype
                        res.prototype = arp_request.prototype
                        res.hwlen = arp_request.hwlen
                        res.protolen = arp_request.protolen
                        res.opcode = arp.REPLY
                        res.hwdst = arp_request.hwsrc
                        res.protodst = src_ip
                        res.protosrc = dst_ip
                        mac = EthAddr(arp_table[str(dst_ip)])

                        res.hwsrc = mac
                        e = ethernet(type=packet.type,
                                     src=mac,
                                     dst=arp_request.hwsrc)
                        e.payload = res
                        msg = of.ofp_packet_out()
                        msg.data = e.pack()
                        msg.actions.append(
                            of.ofp_action_output(port=of.OFPP_IN_PORT))
                        msg.in_port = port_in
                        switch.send(msg)
Ejemplo n.º 57
0
  def _handle_PacketIn (self, event):
    dpid = event.connection.dpid
    inport = event.port
    packet = event.parsed

    if not packet.parsed:
      log.warning("%i %i ignoring unparsed packet", dpid, inport)
      return

    if dpid not in self.arpTable:
      # New switch -- create an empty table
      self.arpTable[dpid] = {}
      ##### Cria uma tabela vazia para registro de disponibilidade de QoS
      self.hasQoS[dpid] = {}
      for fake in self.fakeways:
        self.arpTable[dpid][IPAddr(fake)] = Entry(of.OFPP_NONE,
         dpid_to_mac(dpid))

    if packet.type == ethernet.LLDP_TYPE:
      # Ignore LLDP packets
      return

    if isinstance(packet.next, ipv4):
      log.debug("%i %i IP %s => %s", dpid,inport,
                packet.next.srcip,packet.next.dstip)

      # Send any waiting packets...
      self._send_lost_buffers(dpid, packet.next.srcip, packet.src, inport)

      # Learn or update port/MAC info
      if packet.next.srcip in self.arpTable[dpid]:
        if self.arpTable[dpid][packet.next.srcip] != (inport, packet.src):
          log.info("%i %i RE-learned %s", dpid,inport,packet.next.srcip)
      else:
        log.debug("%i %i learned %s", dpid,inport,str(packet.next.srcip))
      self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src)

      # Try to forward
      dstaddr = packet.next.dstip
      if dstaddr in self.arpTable[dpid]:
        # We have info about what port to send it out on...

        prt = self.arpTable[dpid][dstaddr].port
        mac = self.arpTable[dpid][dstaddr].mac
        if prt == inport:
          log.warning("%i %i not sending packet for %s back out of the " +
                      "input port" % (dpid, inport, str(dstaddr)))
        else:
          log.debug("%i %i installing flow for %s => %s out port %i"
                    % (dpid, inport, packet.next.srcip, dstaddr, prt))

          actions = []
          actions.append(of.ofp_action_dl_addr.set_dst(mac))
          actions.append(of.ofp_action_output(port = prt))
          match = of.ofp_match.from_packet(packet, inport)
          match.dl_src = None # Wildcard source MAC

          msg = of.ofp_flow_mod(command=of.OFPFC_ADD,
                                idle_timeout=FLOW_IDLE_TIMEOUT,
                                hard_timeout=of.OFP_FLOW_PERMANENT,
                                buffer_id=event.ofp.buffer_id,
                                actions=actions,
                                match=of.ofp_match.from_packet(packet,
                                                               inport))
          event.connection.send(msg.pack())

	##########################################################################################################
	########################################### Instrucoes QoS ###############################################
	##########################################################################################################
	net=packet.next
	transp=packet.next.next
	
	#Realiza o mapeamento inicial entre IP, porta e QoS (-1)
	if net.protocol==6 and transp.dstport==SERVER_PORT:
		if not self.portMap.has_key(net.srcip):
			self.portMap={net.srcip:(transp.srcport,-1)}

	#Testa se o pacote eh UDP (troca de mensagens RSVP)
	if net.protocol==17:
		#Testa se a mensagem eh RSVP originada pelo solicitador
		if transp.srcport==23231:
			#Testa se a mensagem eh RSVP RESV
			if net.tos!=0:
				#Atualiza a fila do mapeamento IP, porta e QoS
				port,queue=self.portMap[net.srcip]
				queue=(net.tos/10)-1
				self.portMap[net.srcip]=(port,queue)
				#Consulta a disponibilidade de QoS na porta de saida do roteador
				if not self.hasQoS[dpid].has_key(inport):
					self.hasQoS[dpid][inport] = be
				if self.hasQoS[dpid][inport] + classlist[queue].pico <= TX_MAX:
					log.info("QoS disponivel em R%d - porta %d: %d",dpid,inport,TX_MAX-self.hasQoS[dpid][inport])
				else:
					log.info("QoS nao disponivel - largura de banda insuficiente")				
			#Testa se a mensagem eh RSVP FIN
			else:
				#Exclui o mapeamento IP, porta e QoS
				if self.portMap.has_key(net.srcip):
					del self.portMap[net.srcip]

		#Testa se a mensagem eh RSVP originada pelo prestador
		if transp.srcport==23232:
			#Testa se a mensagem eh RSVP RESV_CONF
			if net.tos!=0:
				port,queue=self.portMap[net.dstip]
				#Aplica QoS na porta de saida do roteador
				qos=os.popen("ovs-vsctl list qos | grep _uuid | awk '{print $3}'").read().strip('\n')
				os.system('ovs-vsctl set port r%d-eth%d qos=%s' %(dpid,prt,qos))
				log.info("QoS %s aplicada em R%s - porta %d",qos,dpid,prt)
				#Acrescenta a banda alocada a tabela de disponibilidade de QoS
				self.hasQoS[dpid][prt]+=classlist[self.portMap[net.dstip][1]].pico
				#Copia os parametros de cabecalho do pacote UDP
				msg1=of.ofp_flow_mod(command=of.OFPFC_MODIFY)
				msg1.match = of.ofp_match.from_packet(packet,inport)
				#Altera os parametros de cabecalho para o futuro fluxo TCP
				msg1.priority=65535
				msg1.idle_timeout=30
				msg1.hard_timeout=120
				msg1.match.nw_proto=6
				msg1.match.nw_tos=0
				msg1.match.tp_src=SERVER_PORT
				msg1.match.tp_dst=port
				msg1.actions.append(of.ofp_action_enqueue(port=prt,queue_id=queue))
				#Instala a regra no roteador
				event.connection.send(msg1)
				log.info("Fila %d aplicada ao fluxo tp_dst %d",queue,port)
			


	##########################################################################################################
	########################################### Instrucoes QoS ###############################################
	##########################################################################################################

      elif self.arp_for_unknowns:
        # We don't know this destination.
        # First, we track this buffer so that we can try to resend it later
        # if we learn the destination, second we ARP for the destination,
        # which should ultimately result in it responding and us learning
        # where it is

        # Add to tracked buffers
        if (dpid,dstaddr) not in self.lost_buffers:
          self.lost_buffers[(dpid,dstaddr)] = []
        bucket = self.lost_buffers[(dpid,dstaddr)]
        entry = (time.time() + MAX_BUFFER_TIME,event.ofp.buffer_id,inport)
        bucket.append(entry)
        while len(bucket) > MAX_BUFFERED_PER_IP: del bucket[0]

        # Expire things from our outstanding ARP list...
        self.outstanding_arps = {k:v for k,v in
         self.outstanding_arps.iteritems() if v > time.time()}

        # Check if we've already ARPed recently
        if (dpid,dstaddr) in self.outstanding_arps:
          # Oop, we've already done this one recently.
          return

        # And ARP...
        self.outstanding_arps[(dpid,dstaddr)] = time.time() + 4

        r = arp()
        r.hwtype = r.HW_TYPE_ETHERNET
        r.prototype = r.PROTO_TYPE_IP
        r.hwlen = 6
        r.protolen = r.protolen
        r.opcode = r.REQUEST
        r.hwdst = ETHER_BROADCAST
        r.protodst = dstaddr
        r.hwsrc = packet.src
        r.protosrc = packet.next.srcip
        e = ethernet(type=ethernet.ARP_TYPE, src=packet.src,
                     dst=ETHER_BROADCAST)
        e.set_payload(r)
        log.debug("%i %i ARPing for %s on behalf of %s" % (dpid, inport,
         str(r.protodst), str(r.protosrc)))
        msg = of.ofp_packet_out()
        msg.data = e.pack()
        msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD))
        msg.in_port = inport
        event.connection.send(msg)

    elif isinstance(packet.next, arp):
      a = packet.next
      log.debug("%i %i ARP %s %s => %s", dpid, inport,
       {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode,
       'op:%i' % (a.opcode,)), str(a.protosrc), str(a.protodst))

      if a.prototype == arp.PROTO_TYPE_IP:
        if a.hwtype == arp.HW_TYPE_ETHERNET:
          if a.protosrc != 0:

            # Learn or update port/MAC info
            if a.protosrc in self.arpTable[dpid]:
              if self.arpTable[dpid][a.protosrc] != (inport, packet.src):
                log.info("%i %i RE-learned %s", dpid,inport,str(a.protosrc))
            else:
              log.debug("%i %i learned %s", dpid,inport,str(a.protosrc))
            self.arpTable[dpid][a.protosrc] = Entry(inport, packet.src)

            # Send any waiting packets...
            self._send_lost_buffers(dpid, a.protosrc, packet.src, inport)

            if a.opcode == arp.REQUEST:
              # Maybe we can answer

              if a.protodst in self.arpTable[dpid]:
                # We have an answer...

                if not self.arpTable[dpid][a.protodst].isExpired():
                  # .. and it's relatively current, so we'll reply ourselves

                  r = arp()
                  r.hwtype = a.hwtype
                  r.prototype = a.prototype
                  r.hwlen = a.hwlen
                  r.protolen = a.protolen
                  r.opcode = arp.REPLY
                  r.hwdst = a.hwsrc
                  r.protodst = a.protosrc
                  r.protosrc = a.protodst
                  r.hwsrc = self.arpTable[dpid][a.protodst].mac
                  e = ethernet(type=packet.type, src=dpid_to_mac(dpid),
                               dst=a.hwsrc)
                  e.set_payload(r)
                  log.debug("%i %i answering ARP for %s" % (dpid, inport,
                   str(r.protosrc)))
                  msg = of.ofp_packet_out()
                  msg.data = e.pack()
                  msg.actions.append(of.ofp_action_output(port =
                                                          of.OFPP_IN_PORT))
                  msg.in_port = inport
                  event.connection.send(msg)
                  return

      # Didn't know how to answer or otherwise handle this ARP, so just flood it
      log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport,
       {arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode,
       'op:%i' % (a.opcode,)), str(a.protosrc), str(a.protodst)))

      msg = of.ofp_packet_out(in_port = inport, data = event.ofp,
          action = of.ofp_action_output(port = of.OFPP_FLOOD))
      event.connection.send(msg)
Ejemplo n.º 58
0
    def _handle_openflow_PacketIn(self, event):
        dpid = event.connection.dpid
        inport = event.port
        packet = event.parsed

        if not packet.parsed:
            log.warning("%i %i ignoring unparsed packet", dpid, inport)
            return

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

        if packet.type == ethernet.LLDP_TYPE:
            # Ignore LLDP packets
            return

        if isinstance(packet.next, ipv4):
            log.debug("%i %i IP %s => %s", dpid, inport, packet.next.srcip,
                      packet.next.dstip)
            """
      stdout ipv4 header
      """
            ##################################

            print 'l3 prototype packet received'

            currentTime = time.time() - self.startTime
            sourceIP = packet.next.srcip
            destinationIP = packet.next.dstip

            packetString = str(packet.next)
            protocol = 0
            if 'UDP' in packetString:
                protocol = 17
            elif 'ICMP' in packetString:
                protocol = 1
            elif 'TCP' in packetString:
                protocol = 6

            #trafficClass = 1 if '18' in str(packet.next.ttl)
            trafficClass = 0
            if '18' in str(packet.next.ttl):
                trafficClass = '1'
            else:
                trafficClass = '0'

            self.svm.classify(
                [currentTime, sourceIP, destinationIP, protocol, trafficClass])

            ####################################

            # Send any waiting packets...
            self._send_lost_buffers(dpid, packet.next.srcip, packet.src,
                                    inport)

            # Learn or update port/MAC info
            if packet.next.srcip in self.arpTable[dpid]:
                if self.arpTable[dpid][packet.next.srcip] != (inport,
                                                              packet.src):
                    log.info("%i %i RE-learned %s", dpid, inport,
                             packet.next.srcip)
                    if self.wide:
                        # Make sure we don't have any entries with the old info...
                        msg = of.ofp_flow_mod(command=of.OFPFC_DELETE)
                        msg.match.nw_dst = packet.next.srcip
                        msg.match.dl_type = ethernet.IP_TYPE
                        event.connection.send(msg)
            else:
                log.debug("%i %i learned %s", dpid, inport, packet.next.srcip)
            self.arpTable[dpid][packet.next.srcip] = Entry(inport, packet.src)

            # Try to forward
            dstaddr = packet.next.dstip
            if dstaddr in self.arpTable[dpid]:
                # We have info about what port to send it out on...

                prt = self.arpTable[dpid][dstaddr].port
                mac = self.arpTable[dpid][dstaddr].mac
                if prt == inport:
                    log.warning(
                        "%i %i not sending packet for %s back out of the "
                        "input port" % (dpid, inport, dstaddr))
                else:
                    log.debug(
                        "%i %i installing flow for %s => %s out port %i" %
                        (dpid, inport, packet.next.srcip, dstaddr, prt))

                    actions = []
                    actions.append(of.ofp_action_dl_addr.set_dst(mac))
                    actions.append(of.ofp_action_output(port=prt))
                    if self.wide:
                        match = of.ofp_match(dl_type=packet.type,
                                             nw_dst=dstaddr)
                    else:
                        match = of.ofp_match.from_packet(packet, inport)

                    msg = of.ofp_flow_mod(command=of.OFPFC_ADD,
                                          idle_timeout=FLOW_IDLE_TIMEOUT,
                                          hard_timeout=of.OFP_FLOW_PERMANENT,
                                          buffer_id=event.ofp.buffer_id,
                                          actions=actions,
                                          match=match)
                    event.connection.send(msg.pack())
            elif self.arp_for_unknowns:
                # We don't know this destination.
                # First, we track this buffer so that we can try to resend it later
                # if we learn the destination, second we ARP for the destination,
                # which should ultimately result in it responding and us learning
                # where it is

                # Add to tracked buffers
                if (dpid, dstaddr) not in self.lost_buffers:
                    self.lost_buffers[(dpid, dstaddr)] = []
                bucket = self.lost_buffers[(dpid, dstaddr)]
                entry = (time.time() + MAX_BUFFER_TIME, event.ofp.buffer_id,
                         inport)
                bucket.append(entry)
                while len(bucket) > MAX_BUFFERED_PER_IP:
                    del bucket[0]

                # Expire things from our outstanding ARP list...
                self.outstanding_arps = {
                    k: v
                    for k, v in self.outstanding_arps.iteritems()
                    if v > time.time()
                }

                # Check if we've already ARPed recently
                if (dpid, dstaddr) in self.outstanding_arps:
                    # Oop, we've already done this one recently.
                    return

                # And ARP...
                self.outstanding_arps[(dpid, dstaddr)] = time.time() + 4

                r = arp()
                r.hwtype = r.HW_TYPE_ETHERNET
                r.prototype = r.PROTO_TYPE_IP
                r.hwlen = 6
                r.protolen = r.protolen
                r.opcode = r.REQUEST
                r.hwdst = ETHER_BROADCAST
                r.protodst = dstaddr
                r.hwsrc = packet.src
                r.protosrc = packet.next.srcip
                e = ethernet(type=ethernet.ARP_TYPE,
                             src=packet.src,
                             dst=ETHER_BROADCAST)
                e.set_payload(r)
                log.debug("%i %i ARPing for %s on behalf of %s" %
                          (dpid, inport, r.protodst, r.protosrc))
                msg = of.ofp_packet_out()
                msg.data = e.pack()
                msg.actions.append(of.ofp_action_output(port=of.OFPP_FLOOD))
                msg.in_port = inport
                event.connection.send(msg)

        elif isinstance(packet.next, arp):
            a = packet.next
            log.debug("%i %i ARP %s %s => %s", dpid, inport, {
                arp.REQUEST: "request",
                arp.REPLY: "reply"
            }.get(a.opcode, 'op:%i' % (a.opcode, )), a.protosrc, a.protodst)

            if a.prototype == arp.PROTO_TYPE_IP:
                if a.hwtype == arp.HW_TYPE_ETHERNET:
                    if a.protosrc != 0:

                        # Learn or update port/MAC info
                        if a.protosrc in self.arpTable[dpid]:
                            if self.arpTable[dpid][a.protosrc] != (inport,
                                                                   packet.src):
                                log.info("%i %i RE-learned %s", dpid, inport,
                                         a.protosrc)
                                if self.wide:
                                    # Make sure we don't have any entries with the old info...
                                    msg = of.ofp_flow_mod(
                                        command=of.OFPFC_DELETE)
                                    msg.match.dl_type = ethernet.IP_TYPE
                                    msg.match.nw_dst = a.protosrc
                                    event.connection.send(msg)
                        else:
                            log.debug("%i %i learned %s", dpid, inport,
                                      a.protosrc)
                        self.arpTable[dpid][a.protosrc] = Entry(
                            inport, packet.src)

                        # Send any waiting packets...
                        self._send_lost_buffers(dpid, a.protosrc, packet.src,
                                                inport)

                        if a.opcode == arp.REQUEST:
                            # Maybe we can answer

                            if a.protodst in self.arpTable[dpid]:
                                # We have an answer...

                                if not self.arpTable[dpid][
                                        a.protodst].isExpired():
                                    # .. and it's relatively current, so we'll reply ourselves

                                    r = arp()
                                    r.hwtype = a.hwtype
                                    r.prototype = a.prototype
                                    r.hwlen = a.hwlen
                                    r.protolen = a.protolen
                                    r.opcode = arp.REPLY
                                    r.hwdst = a.hwsrc
                                    r.protodst = a.protosrc
                                    r.protosrc = a.protodst
                                    r.hwsrc = self.arpTable[dpid][
                                        a.protodst].mac
                                    e = ethernet(type=packet.type,
                                                 src=dpid_to_mac(dpid),
                                                 dst=a.hwsrc)
                                    e.set_payload(r)
                                    log.debug("%i %i answering ARP for %s" %
                                              (dpid, inport, r.protosrc))
                                    msg = of.ofp_packet_out()
                                    msg.data = e.pack()
                                    msg.actions.append(
                                        of.ofp_action_output(
                                            port=of.OFPP_IN_PORT))
                                    msg.in_port = inport
                                    event.connection.send(msg)
                                    return

            # Didn't know how to answer or otherwise handle this ARP, so just flood it
            log.debug("%i %i flooding ARP %s %s => %s" % (dpid, inport, {
                arp.REQUEST: "request",
                arp.REPLY: "reply"
            }.get(a.opcode, 'op:%i' % (a.opcode, )), a.protosrc, a.protodst))

            msg = of.ofp_packet_out(
                in_port=inport,
                data=event.ofp,
                action=of.ofp_action_output(port=of.OFPP_FLOOD))
            event.connection.send(msg)
Ejemplo n.º 59
0
    def ARP_Handler(self, packet, packet_in):
        log.debug("ARP FRAME RECEIVED FROM %s" % packet_in.in_port)

        if packet.payload.opcode == arp.REQUEST:
            log.debug("IT'S AN ARP REQUEST!")

            arp_payload = packet.payload
            arp_request_ip = str(arp_payload.protodst)
            if arp_request_ip in self.arp_table:

                arp_reply = arp()
                arp_reply.opcode = arp.REPLY
                arp_reply.hwsrc = EthAddr(self.arp_table[arp_request_ip])
                arp_reply.hwdst = arp_payload.hwsrc
                arp_reply.protosrc = arp_payload.protodst
                arp_reply.protodst = arp_payload.protosrc

                ether = ethernet()
                ether.type = ether.ARP_TYPE
                ether.src = EthAddr(self.arp_table[arp_request_ip])
                ether.dst = arp_payload.hwsrc
                ether.payload = arp_reply

                self.resend_packet(ether, packet_in.in_port)
                log.debug("ARP REPLY SENT!")

        elif packet.payload.opcode == arp.REPLY:
            log.debug("IT'S AN ARP REPLY!")

            arp_payload = packet.payload
            hwsrc = str(arp_payload.hwsrc)
            srcip = str(arp_payload.protosrc)
            if srcip not in self.arp_table:
                self.arp_table[srcip] = hwsrc
                self.mac_to_port[hwsrc] = packet_in.in_port
                log.debug("%s %s INSTALLED TO CAM TABLE" % (srcip, hwsrc))

            # If there are packets in buffer waiting to be sent out
            if srcip in self.buffer.keys():
                print 'YES!'
                out_port = self.routing_table[self.buffer[srcip]
                                              ['DestinationNetwork']]['Port']
                ip_packet = self.buffer[srcip]['IP_Packet']
                etherFrame = ethernet()
                etherFrame.type = etherFrame.IP_TYPE
                etherFrame.src = EthAddr(self.arp_table[self.routing_table[
                    self.buffer[srcip]['DestinationNetwork']]
                                                        ['RouterInterface']])
                etherFrame.dst = EthAddr(self.arp_table[srcip])
                etherFrame.payload = ip_packet
                self.resend_packet(etherFrame, out_port)

                msg = of.ofp_flow_mod()
                print self.buffer[srcip]['DestinationNetwork']
                msg.priority = 10
                msg.match.dl_type = ethernet.IP_TYPE
                msg.match.nw_proto = ipv4.ICMP_PROTOCOL
                msg.match.set_nw_dst(self.buffer[srcip]['DestinationNetwork'])
                # msg.match.nw_dst = IPAddr(srcip)
                msg.actions.append(
                    of.ofp_action_dl_addr.set_src(
                        EthAddr(self.arp_table[self.routing_table[
                            self.buffer[srcip]['DestinationNetwork']]
                                               ['RouterInterface']])))
                msg.actions.append(
                    of.ofp_action_dl_addr.set_dst(
                        EthAddr(self.arp_table[srcip])))
                msg.actions.append(of.ofp_action_output(port=out_port))
                self.connection.send(msg)
                log.debug("Flow mod for destination network %s sent!",
                          self.buffer[srcip]['DestinationNetwork'])
                self.buffer.pop(srcip)
Ejemplo n.º 60
0
    def _handle_PacketIn(self, event):
        """
        Handles packet in messages from the switch.
        """
        etherFrame = event.parsed  # This is the parsed packet data.
        packet_in = event.ofp  # The actual ofp_packet_in message.

        # Incomplete frames
        if not etherFrame.parsed:
            log.warning("Ignoring incomplete packet")
            return

        # LLDP
        if etherFrame.type == ethernet.LLDP_TYPE:
            log.warning("Ignoring LLDP")
            return

        # Add the new MAC into CAM table
        if str(etherFrame.src) not in self.mac_to_port:
            self.mac_to_port[str(etherFrame.src)] = packet_in.in_port
            log.debug('%s Adding %s into CAM' %
                      (self.dpid, str(etherFrame.src)))

        # Switchable?
        if str(etherFrame.dst) in self.mac_to_port:
            self.resend_packet(etherFrame,
                               self.mac_to_port[str(etherFrame.dst)])
            log.debug("%s Frame can be switched!" % self.dpid)

        else:
            # ARP
            if etherFrame.type == ethernet.ARP_TYPE:
                log.debug('RECEIVED: EtherType -> ARP')
                self.ARP_Handler(etherFrame, packet_in)

            # IP
            elif etherFrame.type == ethernet.IP_TYPE:
                log.debug('%s RECEIVED: EtherType -> IP' % self.dpid)

                # Extract IP Packet from Ethernet Frame
                ip_packet = etherFrame.payload
                destination_ip = str(ip_packet.dstip)

                # For Router?
                if destination_ip in self.interfaces:
                    log.debug('%s ICMP ECHO -> ROUTER INTERFACE' % self.dpid)
                    self.ICMP_Handler(etherFrame, packet_in)
                else:
                    routable = False
                    for netaddr in list(self.routing_table.keys()):
                        destination_network = netaddr
                        if IPAddress(destination_ip) in IPNetwork(
                                destination_network):
                            routable = True
                            log.debug('%s Packet can be routed!' % self.dpid)
                            break

                    local = False
                    if not routable:
                        for netaddr in list(self.interfaces.keys()):
                            destination_network = self.interfaces[netaddr][
                                'Network']
                            if IPAddress(destination_ip) in IPNetwork(
                                    destination_network):
                                local = True
                                log.debug('%s Packet forwarded locally!' %
                                          self.dpid)
                                break

                    if local:
                        if destination_ip not in self.arp_table:
                            # ARP for the Next Hop
                            arp_request = arp()
                            arp_request.opcode = arp.REQUEST
                            arp_request.protosrc = IPAddr(netaddr)
                            arp_request.protodst = IPAddr(destination_ip)
                            arp_request.hwsrc = EthAddr(
                                self.interfaces[netaddr]['MAC'])
                            arp_request.hwdst = EthAddr('00:00:00:00:00:00')

                            ether = ethernet()
                            ether.type = ethernet.ARP_TYPE
                            ether.src = EthAddr(
                                self.interfaces[netaddr]['MAC'])
                            ether.dst = EthAddr('FF:FF:FF:FF:FF:FF')
                            ether.payload = arp_request

                            msg = of.ofp_packet_out()
                            msg.data = ether
                            msg.actions.append(
                                of.ofp_action_output(port=of.OFPP_FLOOD))
                            self.connection.send(msg)
                        if destination_ip in self.arp_table:
                            etherFrame.src = etherFrame.dst
                            etherFrame.dst = EthAddr(
                                self.arp_table[destination_ip])
                            self.resend_packet(
                                etherFrame, self.mac_to_port[
                                    self.arp_table[destination_ip]])

                    elif routable:
                        next_hop = self.routing_table[destination_network][
                            'Next Hop']
                        if next_hop not in self.arp_table:
                            # ARP for the Next Hop
                            arp_request = arp()
                            arp_request.opcode = arp.REQUEST
                            arp_request.protosrc = IPAddr(
                                self.routing_table[destination_network]
                                ['Connected'])
                            arp_request.protodst = IPAddr(next_hop)
                            arp_request.hwsrc = EthAddr(self.interfaces[
                                self.routing_table[destination_network]
                                ['Connected']]['MAC'])
                            arp_request.hwdst = EthAddr('00:00:00:00:00:00')

                            ether = ethernet()
                            ether.type = ethernet.ARP_TYPE
                            ether.src = EthAddr(self.interfaces[
                                self.routing_table[destination_network]
                                ['Connected']]['MAC'])
                            ether.dst = EthAddr('FF:FF:FF:FF:FF:FF')
                            ether.payload = arp_request

                            msg = of.ofp_packet_out()
                            msg.data = ether
                            msg.actions.append(
                                of.ofp_action_output(port=of.OFPP_FLOOD))
                            self.connection.send(msg)
                        if next_hop in self.arp_table:
                            etherFrame.src = EthAddr(self.interfaces[
                                self.routing_table[destination_network]
                                ['Connected']]['MAC'])
                            etherFrame.dst = EthAddr(self.arp_table[next_hop])
                            self.resend_packet(
                                etherFrame,
                                self.mac_to_port[self.arp_table[next_hop]])
                            log.debug('%s Packet forwarded to next hop!' %
                                      self.dpid)