def send_icmp(self, tp, code, dest_ip, dest_mac, dest_port, orig_packet):
        # Should be able to send echo reply (tp=0,code=0),
        # destination unreachable (tp=3,code=0(network unreachable)/1(host unreachable)/3(port unreachable)),
        # TTL expired (tp=11,code=0)

        msg = None
        if tp == 0:
            p = orig_packet.payload
            while p is not None and not isinstance(p, echo):
                p = p.next
            if p is None:
                return
            r = echo(id=p.id, seq=p.seq)
            r.set_payload(p.next)
            msg = icmp(type=0, code=0)
            msg.set_payload(r)
        elif tp == 3:
            msg = icmp()
            msg.type = 3
            msg.code = code
            d = orig_packet.payload.pack()
            d = d[:orig_packet.payload.hl * 4 + 8]
            d = struct.pack("!HH", 0, 0) + d
            msg.payload = d
        elif tp == 11:
            msg = icmp()
            msg.type = 11
            msg.code = 0
            d = orig_packet.payload.pack()
            d = d[:orig_packet.payload.hl * 4 + 8]
            d = struct.pack("!HH", 0, 0) + d
            msg.payload = d

        # Make the IP packet around it
        ipp = ipv4()
        ipp.protocol = ipp.ICMP_PROTOCOL
        ipp.srcip = IPAddr(dest_port.ip)
        ipp.dstip = IPAddr(dest_ip)

        # Ethernet around that...
        e = ethernet()
        e.src = EthAddr(dest_port.mac)
        e.dst = EthAddr(dest_mac)
        e.type = e.IP_TYPE

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

        # send this packet to the switch
        log.debug('router {}; Sending ICMP TYPE {}; code {}; dest_ip {}; output_port {}'.format(self.connection.dpid, tp, code, dest_ip, dest_port.id))
        self.send_packet(None, e, dest_port.id, of.OFPP_NONE)
Ejemplo n.º 2
0
    def _handle_icmp_reply(self, dpid, p, srcip, dstip, icmp_type):
        p_icmp = icmp()
        p_icmp.type = icmp_type
        if icmp_type == pkt.TYPE_ECHO_REPLY:
            p_icmp.payload = p.find('icmp').payload
        elif icmp_type == pkt.TYPE_DEST_UNREACH:
            orig_ip = p.find('ipv4')
            d = orig_ip.pack()
            d = d[:orig_ip.hl * 4 + 8]
            d = struct.pack("!HH", 0, 0) + d 
            p_icmp.payload = d
        
        p_ip = ipv4()
        p_ip.protocol = p_ip.ICMP_PROTOCOL
        p_ip.srcip = dstip 
        p_ip.dstip = srcip
        

        e = ethernet()
        e.src = p.dst
        e.dst = p.src
        e.type = e.IP_TYPE
        
        p_ip.payload = p_icmp
        e.payload = p_ip
        
        msg = of.ofp_packet_out()
        msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))
        msg.data = e.pack()
        msg.in_port = self.routingTable[dpid][srcip]
        self.connections[dpid].send(msg)
        log.debug('DPID : IP %s pings router at %s, send icmp reply'% (str(srcip), str(dstip)))
Ejemplo n.º 3
0
    def handleIcmpRequest(self, dpid, p, srcip, dstip, icmpType):
        pIcmp = icmp()
        pIcmp.type = icmpType
        if icmpType == pkt.TYPE_ECHO_REPLY:
            pIcmp.payload = p.find('icmp').payload
        elif icmpType == pkt.TYPE_DEST_UNREACH:
            oriIp = p.find('ipv4')
            d = oriIp.pack()
            d = d[:oriIp.hl * 4 + 8]
            d = struct.pack("!HH", 0, 0) + d
            pIcmp.payload = d
        pIp = ipv4()
        pIp.protocol = pIp.ICMP_PROTOCOL
        pIp.srcip = dstip
        pIp.dstip = srcip
        e = ethernet()
        e.src = p.dst
        e.dst = p.src
        e.type = e.IP_TYPE
        pIp.payload = pIcmp
        e.payload = pIp

        msg = of.ofp_packet_out()
        msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT))
        msg.data = e.pack()
        msg.in_port = self.routingTable[dpid][srcip]
        self.connections[dpid].send(msg)
        log.debug("dpid %d: IP %s ping router at %s" %
                  (dpid, str(srcip), str(dstip)))
Ejemplo n.º 4
0
	def handle_icmp(self,event):
		print "Replying to Ping: ",event.dpid
		packet = event.parsed
		icmp_reply = icmp()
		icmp_reply.type = pkt.TYPE_ECHO_REPLY
		icmp_reply.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_reply
		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)
Ejemplo n.º 5
0
    def icmp_unreach(self, dpid, packet, inport):
        icmp_pkt = icmp()
        #icmp_pkt = pkt.unreach()
        #icmp_pkt.payload = packet.find("icmp").payload
        #print str(icmp_pkt.payload.pack().encode('hex'))
        icmp_pkt.type = 3
        icmp_pkt.code = 0

        orig_ip = packet.find('ipv4')
        d = orig_ip.pack()
        d = d[:orig_ip.hl * 4 + 8]

        d = struct.pack("!HH", 0, 0) + d
        icmp_pkt.payload = d
        #print str(d.encode('hex'))

        ip_pkt = ipv4()
        srcip = IPAddr(self.fakeways[dpid - 1][0])
        ip_pkt.srcip = IPAddr(self.fakeways[dpid - 1][0])
        ip_pkt.dstip = packet.payload.srcip
        ip_pkt.protocol = ip_pkt.ICMP_PROTOCOL
        ip_pkt.set_payload(icmp_pkt)
        #print str(ip_pkt.payload)
        e = ethernet(type=ethernet.IP_TYPE,
                     src=self.arpTable[dpid][srcip].mac,
                     dst=packet.src)
        #print str(self.arpTable[dpid][ip_pkt.srcip].mac)
        e.set_payload(ip_pkt)
        action = of.ofp_action_output(port=inport)
        po = of.ofp_packet_out(actions=action, data=e.pack())
        core.openflow.sendToDPID(dpid, po)
Ejemplo n.º 6
0
    def handle_icmp(self, event):
        print "Replying to Ping: ", event.dpid
        packet = event.parsed
        icmp_reply = icmp()
        icmp_reply.type = pkt.TYPE_ECHO_REPLY
        icmp_reply.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_reply
        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)
Ejemplo n.º 7
0
  def handle_ICMP_packets (self, packet, packet_in):
    """
    Controller may receive ICMP echo (ping) requests for the router, which it should respond to.
    """
    ppacket = packet.payload

    icmp_request_packet = ppacket.payload
    
    # make new icmp reply to the received icmp request
    if icmp_request_packet.type == 8: # (8 type number is for icmp request)

      icmp_echo_reply_packet = icmp()
      icmp_echo_reply_packet.code = 0
      icmp_echo_reply_packet.type = 0 # (0 type number is for icmp reply)
      icmp_echo_reply_packet.payload = icmp_request_packet.payload

      # make ipv4 header
      ip = ipv4()

      # set it's fields
      ip.srcip = ppacket.dstip
      ip.dstip = ppacket.srcip
      ip.protocol = ipv4.ICMP_PROTOCOL
      ip.payload = icmp_echo_reply_packet

      # make the new packet to send
      newPacket = ethernet()

      # set it's fields
      newPacket.type = ethernet.IP_TYPE
      newPacket.src = ethernet_frame.dst
      newPacket.dst = ethernet_frame.src
      newPacket.payload = ip

      self.resend_packet(newPacket, packet_in.in_port)
Ejemplo n.º 8
0
  def icmp_message(self, dpid, p, srcip, dstip, icmp_type,event):
    p_icmp = icmp()
    p_icmp.type = icmp_type
    if icmp_type == pkt.TYPE_ECHO_REPLY:
      p_icmp.payload = p.find('icmp').payload
    elif icmp_type == pkt.TYPE_DEST_UNREACH:
            #print dir(p.next)
      orig_ip = p.find('ipv4')
      d = orig_ip.pack()
      d = d[:orig_ip.hl * 4 + 8]
      d = struct.pack("!HH", 0, 0) + d # network, unsigned short, unsigned short
      p_icmp.payload = d

            #print dir(p)
            #print type(p.payload)

    p_ip = ipv4()
    p_ip.protocol = p_ip.ICMP_PROTOCOL
    p_ip.srcip = dstip  # srcip, dstip in the argument is from the ping
    p_ip.dstip = srcip


    e = ethernet()
    e.src = p.dst
    e.dst = p.src
    e.type = e.IP_TYPE

    p_ip.payload = p_icmp
    e.payload = p_ip

    msg = of.ofp_packet_out()
    msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))
    msg.data = e.pack()
    msg.in_port = self.routing[dpid][srcip]
    event.connection.send(msg)
Ejemplo n.º 9
0
  def sendICMP(self,type_,code,ip,packet):
    icm = icmp()
    icm.type=type_
    icm.code=code
    d = packet.next.pack()
    d = d[:packet.next.hl * 4+8]
    d = struct.pack("!HH", 0,0) + d
    icm.payload = d
    # icmp.type = pkt.TYPE_DEST_UNREACH

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

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

    # Hook them up...
    ipp.set_payload(icm)
    e.set_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 = self.event_port
    self.connection.send(msg)
  def _handle_ICMP_Reply(self, dpid, ethernet_packet, srcip, dstip, icmpType):
    ICMP_packet = icmp()
    ICMP_packet.type = icmpType
    if icmpType == pkt.TYPE_ECHO_REPLY:
      ICMP_packet.payload = ethernet_packet.find('icmp').payload
    elif icmpType == pkt.TYPE_DEST_UNREACH:
      oriIp = ethernet_packet.find('ipv4')
      d = oriIp.pack()
      d = d[:oriIp.hl * 4 + 8]
      d = struct.pack("!HH", 0, 0) + d
      ICMP_packet.payload = d

    IP_packet = ipv4()
    IP_packet.protocol = IP_packet.ICMP_PROTOCOL
    IP_packet.srcip = dstip
    IP_packet.dstip = srcip
    IP_packet.payload = ICMP_packet

    e = ethernet()
    e.src = ethernet_packet.dst
    if (srcip in subnet1 and self.routerIP[dpid] in subnet1) or (srcip in subnet2 and self.routerIP[dpid] in subnet2) or (srcip in subnet2 and self.routerIP[dpid] in subnet):
        e.dst = ethernet_packet.src
    else:
        gatewayIP = IPAddr(self._find_gatewayIP(IP_packet.dstip))
        e.dst = self.arpTable[dpid][gatewayIP]
    e.type = e.IP_TYPE
    e.payload = IP_packet

    msg = of.ofp_packet_out()
    msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT))
    msg.data = e.pack()
    msg.in_port = self.routingTable[dpid][srcip]
    self.connections[dpid].send(msg)
    log.debug("Router {0}: {1} ping router at {2}".format(dpid, srcip, dstip))
Ejemplo n.º 11
0
    def sendICMP(self, type_, code, ip, packet):
        icm = icmp()
        icm.type = type_
        icm.code = code
        d = packet.next.pack()
        d = d[:packet.next.hl * 4 + 8]
        d = struct.pack("!HH", 0, 0) + d
        icm.payload = d
        # icmp.type = pkt.TYPE_DEST_UNREACH

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

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

        # Hook them up...
        ipp.set_payload(icm)
        e.set_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 = self.event_port
        self.connection.send(msg)
Ejemplo n.º 12
0
    def ICMP_Handler(self, packet, packet_in):
        ethernet_frame = packet
        ip_packet = packet.payload

        icmp_request_packet = ip_packet.payload

        # ICMP Echo Request (8) -> ICMP Echo Reply (0)
        if icmp_request_packet.type == 8:
            icmp_echo_reply_packet = icmp()
            icmp_echo_reply_packet.code = 0
            icmp_echo_reply_packet.type = 0
            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("%s ICMP ECHO REPLY SENT!" % self.dpid)
Ejemplo n.º 13
0
    def reply_icmp_error(self, event, icmp_type, code):
        print "Replying Host Unreachable from ", event.dpid
        packet = event.parsed
        icmp_reply = icmp()
        icmp_reply.type = icmp_type
        icmp_reply.code = code
        # icmp_reply.payload = packet.find("icmp").payload
        d = packet.next.pack()
        d = d[:packet.next.hl * 4 + 8]
        d = struct.pack("!HH", 0, 0) + d
        icmp_reply.payload = d

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

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

        # Hook them up...
        ipp.payload = icmp_reply
        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
        print "Sending to (fromIP, toIP, fromMAC, toMAC) : ", ipp.srcip, ipp.dstip, e.src, e.dst
        event.connection.send(msg)
Ejemplo n.º 14
0
	def reply_icmp_error(self, event, icmp_type, code):
		print "Replying Host Unreachable from ", event.dpid
		packet = event.parsed
		icmp_reply = icmp()
		icmp_reply.type = icmp_type
		icmp_reply.code = code
		# icmp_reply.payload = packet.find("icmp").payload
		d = packet.next.pack()
		d = d[:packet.next.hl*4+8]
		d = struct.pack("!HH", 0, 0) + d
		icmp_reply.payload = d

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

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

		# Hook them up...
		ipp.payload = icmp_reply
		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
		print "Sending to (fromIP, toIP, fromMAC, toMAC) : ", ipp.srcip, ipp.dstip, e.src, e.dst
		event.connection.send(msg)
    def _handle_ICMP(self, IP_packet, inport, org_packet):
        if IP_packet.payload.type == pkt.TYPE_ECHO_REQUEST:
            log.debug("A ICMP REQUEST packet")

            dst_ip = IP_packet.dstip
            # find dst_ip in routing table
            if dst_ip in self.my_port_to_ip:
                # to one of switch port
                log.debug("not ")

                p = icmp()
                p.type = pkt.TYPE_ECHO_REPLY
                p.payload = IP_packet.payload.payload
                IP_packet.srcip, IP_packet.dstip = IP_packet.dstip, IP_packet.srcip
                IP_packet.payload = p
                self._send_frame(IP_packet, ethernet.IP_TYPE,
                                 self.port_list[inport].mac, org_packet.src,
                                 inport)
                pass

            elif dst_ip not in self.ip_to_port:
                # unreachable
                log.debug("The ip address {0} is not reachable".format(dst_ip))
                p = self._create_icmp_unreachable(IP_packet, inport)
                self._send_frame(p, ethernet.IP_TYPE,
                                 self.port_list[inport].mac, org_packet.src,
                                 inport)

            else:
                outport = self.ip_to_port[dst_ip]
                # ip packet enqueue/list? with identifier?: dst_ip
                self.arp_cache.add(IP_packet)
                # send arp request to that port
                arp_rq = self._create_arp_packet(arp.REQUEST,
                                                 EthAddr("ff:ff:ff:ff:ff:ff"),
                                                 dst_ip, outport)
                self._send_frame(arp_rq, ethernet.ARP_TYPE,
                                 self.port_list[outport].mac,
                                 EthAddr("ff:ff:ff:ff:ff:ff"), outport)

        elif IP_packet.payload.type == pkt.TYPE_ECHO_REPLY:
            log.debug("A ICMP REPLY packet")
            log.debug(IP_packet)

            out_port = self.ip_to_port[IP_packet.dstip]
            log.debug(self.ip_to_mac)
            dst_mac = self.ip_to_mac[IP_packet.dstip]
            self._send_frame(IP_packet, ethernet.IP_TYPE,
                             self.port_list[out_port].mac, dst_mac, out_port)

        pass
Ejemplo n.º 16
0
  def _create_icmp_unreachable(self, ip_packet, inport):
    p = icmp()
    p.type = pkt.TYPE_DEST_UNREACH
    data = ip_packet.pack()
    data = data[:ip_packet.hl * 4 + 8]
    data = struct.pack("!HH", 0, 0) + data
    p.payload = data

    p_ip = ipv4()
    p_ip.protocol = p_ip.ICMP_PROTOCOL
    p_ip.srcip = self.port_list[inport].ip
    p_ip.dstip = ip_packet.srcip

    p_ip.payload = p
    return p_ip
  def isValidIpPacket(self,event):
    # ipv4_packet = event.parsed.find("ipv4")
    ipv4_packet = event.parsed.find("ipv4")
    # Do more processing of the IPv4 packet
    src_ip = ipv4_packet.srcip
    dst_ip = ipv4_packet.dstip
    if(ipv4_packet.csum!=ipv4_packet.checksum()):
  	  print "Ip packet checksum not macthing"
  	  return False
    if(ipv4_packet.ttl<=1):
      if(dst_ip==self.IPAddr or dst_ip.toStr()=='255.255.255.255'):
        print "My Packet accept at ",self.IPAddr
        print ipv4_packet
        if(packet.payload.protocol==packet.payload.ICMP_PROTOCOL):
          self.handle_icmp(event)
        return False  
      print "TTL Invalid"
      icmp_rep = icmp()
      icmp_rep.type = 11 # TYPE_TIME_EXCEED
      #icmp_rep.code=0
      icmp_rep.next=unreach()

      # icmp_rep.next.seq=packet.payload.next.next.seq
      # icmp_rep.next.id=packet.payload.next.next.id
      # icmp_rep.next.raw=packet.payload.next.next.raw

      # Show the client that it's actually the me
      rep=ipv4()
      rep.srcip=self.IPAddr
      rep.dstip=ipv4_packet.srcip
      rep.next=icmp_rep
      rep.protocol=ipv4_packet.ICMP_PROTOCOL
      eth = ethernet()
      eth.dst = event.parsed.src
      eth.src = self.EthAddr
      eth.set_payload(rep)
      eth.type = ethernet.IP_TYPE
      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
      self.connection.send(msg)
      return False		
    if(ipv4_packet.iplen<20):
  	  print "Length Invalid"
  	  return False	
    # len > min_len
    return True
Ejemplo n.º 18
0
    def ICMP_Request_Router_local(self, packet, packet_in):
        icmp_reply = icmp()
        icmp_reply.code = 0
        icmp_reply.type = 0
        icmp_reply.payload = packet.payload.payload.payload
        ip_reply = ipv4()
        ip_reply.srcip = packet.payload.dstip
        ip_reply.dstip = packet.payload.srcip
        ip_reply.protocol = ipv4.ICMP_PROTOCOL
        ip_reply.payload = icmp_reply
        ether_packet = ethernet()
        ether_packet.type = ethernet.IP_TYPE
        ether_packet.src = packet.dst
        ether_packet.dst = packet.src
        ether_packet.payload = ip_reply

        self.resend_packet(ether_packet, packet_in.in_port)
        log.debug('ICMP/TCP/UDP reply has sent')
Ejemplo n.º 19
0
    def ICMP_Unreachable(self, packet, packet_in):
        icmp_reply_unreachable = icmp()
        icmp_reply_unreachable.code = 0
        icmp_reply_unreachable.type = 3
        icmp_reply_unreachable.payload = packet.payload.payload.payload
        ip_reply_unreachable = ipv4()
        ip_reply_unreachable.srcip = packet.payload.dstip
        ip_reply_unreachable.dstip = packet.payload.srcip
        ip_reply_unreachable.protocol = ipv4.ICMP_PROTOCOL
        ip_reply_unreachable.payload = icmp_reply_unreachable
        ether_packet = ethernet()
        ether_packet.type = ethernet.IP_TYPE
        ether_packet.src = packet.dst
        ether_packet.dst = packet.src
        ether_packet.payload = ip_reply_unreachable

        self.resend_packet(ether_packet, packet_in.in_port)
        log.debug('ICMP reply for unreachable packet has sent')
  def handle_icmp(self,event):
    print "ICMP Packet Arrived"
    packet=event.parsed
    src_mac = packet.src
    dst_mac = packet.dst
    ipv4_packet = event.parsed.find("ipv4")
    src_ip = ipv4_packet.srcip
    dst_ip = ipv4_packet.dstip

    if packet.payload.next.type==8:
		print "handing"
		icmp_rep = icmp()
		# icmp_rep.type = 3
		icmp_rep.next=echo()
		icmp_rep.next.seq=packet.payload.next.next.seq
		icmp_rep.next.id=packet.payload.next.next.id
		icmp_rep.next.raw=packet.payload.next.next.raw

		# Show the client that it's actually the me
		rep=ipv4()
		rep.srcip=self.IPAddr
		rep.dstip=src_ip
		rep.next=icmp_rep
		rep.protocol=packet.payload.ICMP_PROTOCOL
		eth = ethernet()
		eth.dst = packet.src
		eth.src = self.EthAddr
		eth.set_payload(rep)
		eth.type = ethernet.IP_TYPE
		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
		self.connection.send(msg)
		print "done handing"
		return

    if packet.payload.next.type==3:
      if packet.payload.next.code==1:
        print "Destination Host Unreachable"
      if packet.payload.next.code==0:
        print "Destination Network Unreachable"
    return
Ejemplo n.º 21
0
    def _generate_icmp_reply(self, dpid, p, srcip, dstip, icmp_type):
        p_icmp = icmp()
        p_icmp.type = icmp_type
        if icmp_type == pkt.TYPE_ECHO_REPLY:
            p_icmp.payload = p.find('icmp').payload
        elif icmp_type == pkt.TYPE_DEST_UNREACH:
            #print dir(p.next)
            orig_ip = p.find('ipv4')
            d = orig_ip.pack()
            d = d[:orig_ip.hl * 4 + 8]
            d = struct.pack("!HH", 0,
                            0) + d  # network, unsigned short, unsigned short
            p_icmp.payload = d

        p_ip = ipv4()
        p_ip.protocol = p_ip.ICMP_PROTOCOL
        p_ip.srcip = dstip  # srcip, dstip in the argument is from the ping
        p_ip.dstip = srcip

        e = ethernet()
        e.src = p.dst
        if is_same_subnet(srcip, self.routerIP[dpid]):
            e.dst = p.src
        else:
            gatewayip = dpid_to_ip(3 - dpid)
            e.dst = self.arpTable[dpid][gatewayip]

        e.type = e.IP_TYPE

        p_ip.payload = p_icmp
        e.payload = p_ip

        msg = of.ofp_packet_out()
        msg.actions.append(of.ofp_action_output(port=of.OFPP_IN_PORT))
        msg.data = e.pack()
        msg.in_port = self.routingTable[dpid][srcip]
        self.connections[dpid].send(msg)
        log.debug(
            'DPID %d: IP %s pings router at %s, generating icmp reply with code %d...',
            dpid, str(srcip), str(dstip), icmp_type)
Ejemplo n.º 22
0
    def _generate_icmp_reply(self, dpid, p, srcip, dstip, icmp_type):
        p_icmp = icmp()
        p_icmp.type = icmp_type
        if icmp_type == pkt.TYPE_ECHO_REPLY:
            p_icmp.payload = p.find('icmp').payload
        elif icmp_type == pkt.TYPE_DEST_UNREACH:
            #print dir(p.next)
            orig_ip = p.find('ipv4')
            d = orig_ip.pack()
            d = d[:orig_ip.hl * 4 + 8]
            d = struct.pack("!HH", 0, 0) + d # network, unsigned short, unsigned short
            p_icmp.payload = d

        
        p_ip = ipv4()
        p_ip.protocol = p_ip.ICMP_PROTOCOL
        p_ip.srcip = dstip  # srcip, dstip in the argument is from the ping
        p_ip.dstip = srcip
        

        e = ethernet()
        e.src = p.dst
        if is_same_subnet(srcip, self.routerIP[dpid]):
            e.dst = p.src
        else:
            gatewayip = dpid_to_ip( 3-dpid )
            e.dst = self.arpTable[dpid][gatewayip]

        e.type = e.IP_TYPE
        
        p_ip.payload = p_icmp
        e.payload = p_ip
        
        msg = of.ofp_packet_out()
        msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))
        msg.data = e.pack()
        msg.in_port = self.routingTable[dpid][srcip]
        self.connections[dpid].send(msg)
        log.debug('DPID %d: IP %s pings router at %s, generating icmp reply with code %d...', dpid, str(srcip), str(dstip), icmp_type)
Ejemplo n.º 23
0
    def _handle_icmp_reply(self, dpid, p, srcip, dstip, icmp_type):
        pic = icmp()
        pic.type = icmp_type
        if icmp_type == pkt.TYPE_ECHO_REPLY:
            pic.payload = p.find('icmp').payload
        elif icmp_type == pkt.TYPE_DEST_UNREACH:
            orig_ip = p.find('ipv4')
            d = orig_ip.pack()
            d = d[:orig_ip.hl * 4 + 8]
            d = struct.pack("!HH", 0, 0) + d 
            pic.payload = d

        
        #p_ip = ipv4()
        ipv4().protocol = ipv4().ICMP_PROTOCOL
        ipv4().srcip = dstip  
        ipv4().dstip = srcip
        

        e = ethernet()
        e.src = p.dst
        if (srcip in Subnet1 and self.routerIP[dpid] in Subnet1) or (srcip in Subnet2 and self.routerIP[dpid] in Subnet2):
            e.dst = p.src
        else:
            gatewayip = IPAddr('10.0.%d.1' % (3-dpid))
            e.dst = self.arpTable[dpid][gatewayip]

        e.type = e.IP_TYPE
        
        p_ip.payload = p_icmp
        e.payload = p_ip
        
        msg = of.ofp_packet_out()
        msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))
        msg.data = e.pack()
        msg.in_port = self.routingTable[dpid][srcip]
        self.connections[dpid].send(msg)
        log.debug('DPID %d: IP %s pings router at %s, generating icmp reply', dpid, str(srcip), str(dstip))
Ejemplo n.º 24
0
	def _router_handle_icmp(self, event):
		# NOTE handles ECHO messages for now only
		packet = event.parsed
		ipPacket = packet.next
		icmpPacket = ipPacket.next
		replied = False
		if icmpPacket.type == TYPE_ECHO_REQUEST:
			for port in self.ports:
				if port.ip == ipPacket.dstip:
					# ping reply
					reply = icmp()
					reply.type = TYPE_ECHO_REPLY
					reply.payload = icmpPacket.payload # seq, id, etc.
					# ip packet
					i = ipv4()
					i.protocol = i.ICMP_PROTOCOL
					i.srcip = ipPacket.dstip
					i.dstip = ipPacket.srcip
					i.payload = reply
					# ethernet
					e = ethernet(type = ethernet.IP_TYPE,
								 src = packet.dst,
								 dst = packet.src)
					e.payload = i
					# openflow msg
					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
					self.connection.send(msg)
					# break the for-loop
					replied = True
					break
		if not replied:
			# this must be other's ping
			self._router_handle_ipv4(event)
Ejemplo n.º 25
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 +
                      ' FROM SRCIP ' + source_ip)

            routable, destination_network = self.checkRoutableDestination(
                destination_ip)

            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)

                    elif ip_packet.protocol == 0x11:
                        log.debug('UDP PACKET DETECTED!')

                        udp_packet = ip_packet.payload
                        print "\nRECEIVED UDP PACKET IN PORT NUMBER : " + str(
                            udp_packet.dstport)

                        if udp_packet.dstport == 9999:
                            print "\nUDP PAYLOAD : " + str(udp_packet.payload)
                            self.handleBandwidthRequest(udp_packet.payload)

                # 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
                        }

                        self.ARPResolve(destination_ip, destination_network,
                                        output_port)

                    if destination_ip in self.arp_table:
                        if destination_ip == "10.0.2.100":
                            print "\n--DETECTED NEW PACKET TO APPLY QOS FLOW. PROCEEDING ...--"
                        else:
                            print "\n--DETECTED NEW PACKET TO APPLY NORMAL FLOW. PROCEEDING ...--"
                        self.buffer[destination_ip] = {
                            'IP_Packet': ip_packet,
                            'DestinationNetwork': destination_network
                        }
                        self.push_flow_label(source_ip, destination_ip,
                                             output_port)
                        print "\n--FLOW LABEL SUCCESSFULLY PUSHED FOR NEWLY DETECTED PACKET!--"

                        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:
                #if source_ip != '0.0.0.0':
                log.debug('PACKET IS NOT ROUTABLE for IPdest' +
                          str(ip_packet.dstip) + ' from IPsrc ' +
                          str(ip_packet.srcip))
                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")
                log.debug("Ignoring packet with src ip 0.0.0.0")
Ejemplo n.º 26
0
  def custom_switch(self,packet,packet_in):
    """
    Implement switch-like behavior.
    """
    self.mac_to_port[packet.src]=self.event_port

    ip=packet.find('ipv4')

    if self.is_router():
      if isinstance(packet.next,arp):
        a=packet.next
        if packet.payload.opcode==arp.REQUEST:
          if not a.protosrc.inNetwork(self.network,netmask=24):
            log.debug("dropping ARP request from separate subnet")

          elif not a.protodst.inNetwork(self.network,netmask=24):
            r = arp()
            r.hwtype = a.hwtype
            r.prototype = a.prototype
            r.hwlen = a.hwlen
            r.protolen = a.protolen
            r.opcode = arp.REPLY
            r.hwdst = a.hwsrc
            r.protodst = a.protosrc
            r.protosrc = a.protodst
            r.hwsrc = self.mac
            e = ethernet(type=packet.type, src=dpid_to_mac(self.dpid),
                           dst=a.hwsrc)
            e.set_payload(r)
            log.debug("ARP request to different network replying my IP")
            msg = of.ofp_packet_out()
            msg.data = e.pack()
            msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))
            msg.in_port = self.event_port
            self.connection.send(msg)
          else:
            log.debug("ARP Request from same network dropping packet")

        elif packet.payload.opcode==arp.REPLY :
          log.debug("arp reply arrived with %s > %s and my ip=%s"%
            (a.protosrc,a.protodst,self.ip))
          # if a.protodst == self.ip:
            ##send all waiting packets to that mac address through the port
          for waiting_packet in self.arpBuffer[a.protosrc]:

            e = ethernet(type=ethernet.IP_TYPE, 
                      src=dpid_to_mac(self.dpid),
                      dst=a.hwsrc)

            e.set_payload(waiting_packet.payload)
            msg = of.ofp_packet_out()
            msg.data = e.pack()
            msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT ))
            msg.in_port = self.event_port
            self.connection.send(msg)

            # self.resend_packet(waiting_packet,of.OFPP_IN_PORT)
          self.arpBuffer[a.protosrc]=[]

      elif ip is not None:

        if ip.csum == ip.checksum() and ip.iplen >= ipv4.MIN_LEN :
          pass
        else:
          print 'Garbled packet'
          return

        ip.ttl-=1
        if(ip.ttl<=0):
          print 'TTL 0 throwing packet'
          # return
          #ICMP packet
          # Make the ping reply
          icm = icmp()
          icm.type=11
          icm.code=0
          d = packet.next.pack()
          d = d[:packet.next.hl * 4+8]
          d = struct.pack("!HH", 0,0) + d
          icm.payload = d
          # icmp.type = pkt.TYPE_DEST_UNREACH

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

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

          # Hook them up...
          ipp.set_payload(icm)
          e.set_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 = self.event_port
          self.connection.send(msg)
          return

        ip.csum=ip.checksum()
        ip_net = IPAddr(ip.dstip.toUnsigned() & ~((1 << (32-24))-1))
        print ip_net
        if ip.dstip not in self.routeTable and ip_net not in self.routeTable and not ip.dstip.inNetwork(self.network,netmask=24):
          #send icmp unreachable
          # print self.routeTable
          log.debug("Unreacheable %s",(ip.dstip))

          ##ICMP packet
          # Make the ping reply
          icm = icmp()
          icm.type=3
          icm.code=0
          d = packet.next.pack()
          d = d[:packet.next.hl * 4+8]
          d = struct.pack("!HH", 0,0) + d
          icm.payload = d
          # icmp.type = pkt.TYPE_DEST_UNREACH

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

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

          # Hook them up...
          ipp.payload = icm
          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 = self.event_port
          self.connection.send(msg)

        elif ip.dstip.inNetwork(self.network,netmask=24) and ip.dstip not in self.routeTable:
          #ICMP host unreachable
          self.sendICMP(3,1,ip,packet)


        else:
          if ip.dstip in self.routeTable:
            dpid = self.routeTable[ip.dstip]
          else:
            dpid = self.routeTable[ip_net]

          if dpid==50:
            #host ip send ARP
            if not ip.dstip in self.arpBuffer:
              self.arpBuffer[ip.dstip]=[]

            self.arpBuffer[ip.dstip].append(packet)

            r = arp()
            r.hwsrc = self.mac
            r.hwdst = ETHER_BROADCAST
            r.opcode = arp.REQUEST
            r.protodst = ip.dstip
            r.protosrc = self.ip
            
            e = ethernet(type=ethernet.ARP_TYPE, 
                      src=dpid_to_mac(self.dpid),
                      dst=ETHER_BROADCAST)


            e.set_payload(r)
            log.debug("ARP request to find host ")
            msg = of.ofp_packet_out()
            msg.data = e.pack()
            msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD ))
            msg.in_port = self.event_port
            self.connection.send(msg)


          else:
            # print self.mac,self.mac_to_port
            if dpid_to_mac(dpid) in self.mac_to_port:
              self.resend_packet(packet.pack(),
                self.mac_to_port[ dpid_to_mac(dpid) ])
            else:
              self.act_like_hub(packet, packet_in)

    else:
      # self.act_like_hub(packet,packet_in)
      self.addEntryOrFlood(packet,packet_in)
Ejemplo n.º 27
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)

                    elif ip_packet.protocol == 0x11:
                        log.debug('UDP PACKET DETECTED!')
                        handleBandwidthRequest(ip_packet)
                        udp_packet = ip_packet.payload
                        print "\nRECEIVED UDP PACKET IN PORT NUMBER : " + str(
                            udp_packet.dstport)
                        print "\nUDP PAYLOAD : " + str(udp_packet.payload)

                # 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:
                        if destination_ip == "10.0.4.100" and source_ip not in self.allocated_bandwidths.keys(
                        ):
                            print "\n--DETECTED NEW PACKET TO APPLY QOS FLOW. PROCEEDING ...--"
                            self.buffer[destination_ip] = {
                                'IP_Packet': ip_packet,
                                'DestinationNetwork': destination_network
                            }
                            self.push_flow_label(source_ip, destination_ip,
                                                 output_port)
                            print "\n--QOS SUCCESSFULLY PUSHED FOR NEWLY DETECTED PACKET!--"
                        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.º 28
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)

            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.º 29
0
    def custom_switch(self, packet, packet_in):
        """
    Implement switch-like behavior.
    """
        self.mac_to_port[packet.src] = self.event_port

        ip = packet.find('ipv4')

        if self.is_router():
            if isinstance(packet.next, arp):
                a = packet.next
                if packet.payload.opcode == arp.REQUEST:
                    if not a.protosrc.inNetwork(self.network, netmask=24):
                        log.debug("dropping ARP request from separate subnet")

                    elif not a.protodst.inNetwork(self.network, netmask=24):
                        r = arp()
                        r.hwtype = a.hwtype
                        r.prototype = a.prototype
                        r.hwlen = a.hwlen
                        r.protolen = a.protolen
                        r.opcode = arp.REPLY
                        r.hwdst = a.hwsrc
                        r.protodst = a.protosrc
                        r.protosrc = a.protodst
                        r.hwsrc = self.mac
                        e = ethernet(type=packet.type,
                                     src=dpid_to_mac(self.dpid),
                                     dst=a.hwsrc)
                        e.set_payload(r)
                        log.debug(
                            "ARP request to different network replying my IP")
                        msg = of.ofp_packet_out()
                        msg.data = e.pack()
                        msg.actions.append(
                            of.ofp_action_output(port=of.OFPP_IN_PORT))
                        msg.in_port = self.event_port
                        self.connection.send(msg)
                    else:
                        log.debug(
                            "ARP Request from same network dropping packet")

                elif packet.payload.opcode == arp.REPLY:
                    log.debug("arp reply arrived with %s > %s and my ip=%s" %
                              (a.protosrc, a.protodst, self.ip))
                    # if a.protodst == self.ip:
                    ##send all waiting packets to that mac address through the port
                    for waiting_packet in self.arpBuffer[a.protosrc]:

                        e = ethernet(type=ethernet.IP_TYPE,
                                     src=dpid_to_mac(self.dpid),
                                     dst=a.hwsrc)

                        e.set_payload(waiting_packet.payload)
                        msg = of.ofp_packet_out()
                        msg.data = e.pack()
                        msg.actions.append(
                            of.ofp_action_output(port=of.OFPP_IN_PORT))
                        msg.in_port = self.event_port
                        self.connection.send(msg)

                        # self.resend_packet(waiting_packet,of.OFPP_IN_PORT)
                    self.arpBuffer[a.protosrc] = []

            elif ip is not None:

                if ip.csum == ip.checksum() and ip.iplen >= ipv4.MIN_LEN:
                    pass
                else:
                    print 'Garbled packet'
                    return

                ip.ttl -= 1
                if (ip.ttl <= 0):
                    print 'TTL 0 throwing packet'
                    # return
                    #ICMP packet
                    # Make the ping reply
                    icm = icmp()
                    icm.type = 11
                    icm.code = 0
                    d = packet.next.pack()
                    d = d[:packet.next.hl * 4 + 8]
                    d = struct.pack("!HH", 0, 0) + d
                    icm.payload = d
                    # icmp.type = pkt.TYPE_DEST_UNREACH

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

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

                    # Hook them up...
                    ipp.set_payload(icm)
                    e.set_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 = self.event_port
                    self.connection.send(msg)
                    return

                ip.csum = ip.checksum()
                ip_net = IPAddr(ip.dstip.toUnsigned()
                                & ~((1 << (32 - 24)) - 1))
                print ip_net
                if ip.dstip not in self.routeTable and ip_net not in self.routeTable and not ip.dstip.inNetwork(
                        self.network, netmask=24):
                    #send icmp unreachable
                    # print self.routeTable
                    log.debug("Unreacheable %s", (ip.dstip))

                    ##ICMP packet
                    # Make the ping reply
                    icm = icmp()
                    icm.type = 3
                    icm.code = 0
                    d = packet.next.pack()
                    d = d[:packet.next.hl * 4 + 8]
                    d = struct.pack("!HH", 0, 0) + d
                    icm.payload = d
                    # icmp.type = pkt.TYPE_DEST_UNREACH

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

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

                    # Hook them up...
                    ipp.payload = icm
                    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 = self.event_port
                    self.connection.send(msg)

                elif ip.dstip.inNetwork(
                        self.network,
                        netmask=24) and ip.dstip not in self.routeTable:
                    #ICMP host unreachable
                    self.sendICMP(3, 1, ip, packet)

                else:
                    if ip.dstip in self.routeTable:
                        dpid = self.routeTable[ip.dstip]
                    else:
                        dpid = self.routeTable[ip_net]

                    if dpid == 50:
                        #host ip send ARP
                        if not ip.dstip in self.arpBuffer:
                            self.arpBuffer[ip.dstip] = []

                        self.arpBuffer[ip.dstip].append(packet)

                        r = arp()
                        r.hwsrc = self.mac
                        r.hwdst = ETHER_BROADCAST
                        r.opcode = arp.REQUEST
                        r.protodst = ip.dstip
                        r.protosrc = self.ip

                        e = ethernet(type=ethernet.ARP_TYPE,
                                     src=dpid_to_mac(self.dpid),
                                     dst=ETHER_BROADCAST)

                        e.set_payload(r)
                        log.debug("ARP request to find host ")
                        msg = of.ofp_packet_out()
                        msg.data = e.pack()
                        msg.actions.append(
                            of.ofp_action_output(port=of.OFPP_FLOOD))
                        msg.in_port = self.event_port
                        self.connection.send(msg)

                    else:
                        # print self.mac,self.mac_to_port
                        if dpid_to_mac(dpid) in self.mac_to_port:
                            self.resend_packet(
                                packet.pack(),
                                self.mac_to_port[dpid_to_mac(dpid)])
                        else:
                            self.act_like_hub(packet, packet_in)

        else:
            # self.act_like_hub(packet,packet_in)
            self.addEntryOrFlood(packet, packet_in)
Ejemplo n.º 30
0
  def _handle_PacketIn (self, event):
    """
    Handles packet in messages from the switch.
    """

    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.

    # Add the new MAC to mac_to_port table
    if str(packet.src) not in self.mac_to_port:
    log.debug("mac_to_port table was updated by mac: {} -> port: {}".format(packet.src, hwsrc))
    self.mac_to_port[str(packet.src)] = packet_in.in_port

    # ARP
    if packet.type == ethernet.ARP_TYPE:
      log.debug("in _handle_PacketIn func: an ARP requeset received.")
      # send to it's function
      self.handle_ARP_requests(packet, packet_in)

    # Static Routing -> handle all ipv4 traffic that comes through the router
    # by forwarding it to the correct subnet.
    elif packet.type == ethernet.IP_TYPE:
      log.debug("in _handle_PacketIn func: an IPv4 packet received.")

      ppayload = packet.payload
      dst_ip = str(ppayload.dstip)
      routable, dst_network = isRoutable (dst_ip)

      if routable:
        # Check if our router's routing_table knows the dst_network
        # and the dst_ip is match to dst_network
        if self.routing_table[str(dst_network)]['interfaceAddr'] == dst_ip:

          if ip_packet.protocol == ipv4.ICMP_PROTOCOL:
            self.handle_ICMP_packets(packet, packet_in)

        else:
          # Route the packet to it's port
          output_port = self.routing_table[dst_network]['Port']
          # ARP if host MAC Address is not present
          if dst_ip not in self.arp_table:
            # Push frame to buffer
            self.buffer[dst_ip] = {'IP_Packet': ppayload, 'DestinationNetwork': dst_network}

            # Construct ARP Packet
            arp_request = arp()

            # now set ARP structure fields
            arp_request.hwdst = EthAddr('00:00:00:00:00:00')
            RouterInterfaceAddr = self.routing_table[dst_network]['interfaceAddr']
            arp_request.hwsrc = EthAddr(self.arp_table[RouterInterfaceAddr])
            arp_request.protodst = IPAddr(dst_ip)
            arp_request.protosrc = IPAddr(self.routing_table[dst_network]['interfaceAddr'])
            arp_request.opcode = arp.REQUEST

            # make the new pavket to send
            newPacket = ethernet()

            # set it's fields
            newPacket.type = newPacket.ARP_TYPE
            newPacket.src = EthAddr(self.arp_table[RouterInterfaceAddr])
            newPacket.dst = EthAddr('FF:FF:FF:FF:FF:FF')
            newPacket.payload = arp_request

            # send the packet
            self.resend_packet(newPacket, output_port)

          if dst_ip in self.arp_table:
            packet.src = EthAddr(self.arp_table[self.routing_table[dst_network]['interfaceAddr']])
            packet.dst = EthAddr(self.arp_table[dst_ip])
            self.resend_packet(packet, output_port)

      # message of ICMP destination unreachable
      else:
        ethernet_frame = packet
        ppacket = packet.payload
        icmp_request_packet = ppacket.payload

        # make an icmp packet
        icmp_echo_reply_packet = icmp()
        icmp_echo_reply_packet.code = 0
        icmp_echo_reply_packet.type = 3 # (3 type number is for icmp destination unreachable)
        icmp_echo_reply_packet.payload = icmp_request_packet.payload

        # make ipv4 header
        ip = ipv4()

        # set it's fields
        ip.srcip = ppacket.dstip
        ip.dstip = ppacket.srcip
        ip.protocol = ipv4.ICMP_PROTOCOL
        ip.payload = icmp_echo_reply_packet

        # make the new packet to send
        newPacket = ethernet()

        # set it's fields
        newPacket.type = ethernet.IP_TYPE
        newPacket.src = ethernet_frame.dst
        newPacket.dst = ethernet_frame.src
        newPacket.payload = ip

        self.resend_packet(newPacket, packet_in.in_port)


  def isRoutable (dst_ip):
    """
    Check if the destination ip address wanted in packet
    is in our routing table or not.
    """

    for r in self.routing_table:
      dst_network = r

      if IPAddress(dst_ip) in IPNetwork(dst_network):
        log.debug("packet is routable!")
        return True, dst_network

    log.debug("packet is not routable!")
    return False, null
  def handle_ipPacket(self,event): # handle broad cast ip also 
    # print "IP packet Received at R"+str(event.dpid)

    packet=event.parsed
    if(packet is None):
    	print "error"
    	print event
    src_mac = packet.src
    dst_mac = packet.dst

    ipv4_packet = event.parsed.next
    if(ipv4_packet is None):
      print "error"
      print event
    # Do more processing of the IPv4 packet
    src_ip = ipv4_packet.srcip
    dst_ip = ipv4_packet.dstip
    global _hello_tos, _lsu_tos
    if ipv4_packet.tos == _hello_tos:
      print "HELLO at R"+str(event.dpid)+" from "+src_ip.toStr()
      self.neighbours[event.port]=src_ip
      self.times[event.port]=time.time()
      self.G.add_edge(self.IPAddr,src_ip)
      self.send_lsu()
      return

    if ipv4_packet.tos == _lsu_tos:
      if src_ip==self.IPAddr:
        return
      print "LSU at R"+str(event.dpid)+" from "+src_ip.toStr()
      self.times2[src_ip]=time.time()
      pl=ipv4_packet.next
      lst=pl.split(':')[:-1]
      if src_ip in self.seqnum.keys() and self.seqnum[src_ip]>=int(pl[0]):
      	return
      self.seqnum[src_ip]=int(pl[0])
      ed=[i for i in self.G.edges() if i[0]==src_ip]
      try:
        self.G.remove_edges_from(ed)
      except:
        pass
      for i in lst[1:]:
      	self.G.add_edge(src_ip,IPAddr(i))
      eth = ethernet()
      eth.src = self.EthAddr
      eth.set_payload(ipv4_packet)
      eth.type = ethernet.IP_TYPE
      msg = of.ofp_packet_out()
      msg.data = eth.pack()
      msg.actions.append(of.ofp_action_output(port = of.OFPP_ALL))
      self.connection.send(msg)
      return

    if dst_mac!=self.EthAddr and dst_mac!=EthAddr('ff:ff:ff:ff:ff:ff'):
      return
    
    if(not self.isValidIpPacket(event)):
      return

    if(dst_ip==self.IPAddr or dst_ip.toStr()=='255.255.255.255'):
      if(packet.payload.protocol==packet.payload.ICMP_PROTOCOL):
      	self.handle_icmp(event)
    else:   
      nxt=self.FindNextHopInterface(dst_ip.toStr())
      if(nxt[0]==-1):   # need to send an icmp packet 
        # print "No Route to Host"
        # Create ARP reply
        icmp_rep = icmp()
        icmp_rep.type = 3
        icmp_rep.code= nxt[2]
        icmp_rep.next=unreach()

        # icmp_rep.next.seq=packet.payload.next.next.seq
        # icmp_rep.next.id=packet.payload.next.next.id
        # icmp_rep.next.raw=packet.payload.next.next.raw

        # Show the client that it's actually the me
        rep=ipv4()
        rep.srcip=self.IPAddr
        rep.dstip=src_ip
        rep.next=icmp_rep
        rep.protocol=packet.payload.ICMP_PROTOCOL
        eth = ethernet()
        eth.dst = packet.src
        eth.src = self.EthAddr
        eth.set_payload(rep)
        eth.type = ethernet.IP_TYPE
        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
        self.connection.send(msg)
        print "icmp reply DONE"

      else:
        NextHopIP=nxt[0]
        Interface=nxt[1][-1]

        payload=packet.payload.payload # payload of IP packet
        # create a empty IP packet

        ipv4_packet_out=ipv4_packet
        ipv4_packet_out.ttl=ipv4_packet_out.ttl-1
        # Create the Ethernet packet

        eth = ethernet()
        eth.type = ethernet.IP_TYPE
        if IPAddr(NextHopIP) in self.arp_table: 
          eth.dst = self.arp_table[IPAddr(NextHopIP)]
          eth.src = self.EthAddr
          eth.set_payload(ipv4_packet_out)

          # 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 = int(Interface)))
          msg.in_port = event.port
          self.connection.send(msg)
        else:
          arp_rep = arp()
          arp_rep.opcode = arp.REQUEST

          # Show the client that it's actually the me
          arp_rep.hwsrc = self.EthAddr
          arp_rep.hwdst = EthAddr('ff:ff:ff:ff:ff:ff')
          #arp_rep.hwdst = 'ff:ff:ff:ff:ff:ff'
          arp_rep.protosrc = self.IPAddr
          arp_rep.protodst = IPAddr(NextHopIP)

          # Create the Ethernet packet
          eth1 = ethernet()
          eth1.type = ethernet.ARP_TYPE
          eth1.dst = EthAddr('ff:ff:ff:ff:ff:ff')
          eth1.src = self.EthAddr
          eth1.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 = eth1.pack()
          msg.actions.append(of.ofp_action_output(port = int(Interface)))
          msg.in_port = event.port
          self.connection.send(msg)
          eth.src = self.EthAddr
          eth.set_payload(ipv4_packet_out)
          self.que.append((eth,int(Interface),event.port))
  def handle_ipPacket(self,event): # handle broad cast ip also 
    print "IP packet Received at R"+str(event.dpid)
    packet=event.parsed
    src_mac = packet.src
    dst_mac = packet.dst

    if dst_mac!=self.EthAddr and dst_mac!=EthAddr('ff:ff:ff:ff:ff:ff'):
      return
    
    if(not self.isValidIpPacket(event)):
      return

    ipv4_packet = event.parsed.find("ipv4")
    # Do more processing of the IPv4 packet
    src_ip = ipv4_packet.srcip
    dst_ip = ipv4_packet.dstip

    if(dst_ip==self.IPAddr or dst_ip.toStr()=='255.255.255.255'):
      print "My Packet accept at ",self.IPAddr
      print ipv4_packet
      if(packet.payload.protocol==packet.payload.ICMP_PROTOCOL):
      	self.handle_icmp(event)
    else:   
      nxt=self.FindNextHopInterface(dst_ip.toStr())
      if(nxt[0]==-1):   # need to send an icmp packet 
        # print "No Route to Host"
        # Create ARP reply
        icmp_rep = icmp()
        icmp_rep.type = 3
        icmp_rep.code= nxt[2]
        icmp_rep.next=unreach()

        # icmp_rep.next.seq=packet.payload.next.next.seq
        # icmp_rep.next.id=packet.payload.next.next.id
        # icmp_rep.next.raw=packet.payload.next.next.raw

        # Show the client that it's actually the me
        rep=ipv4()
        rep.srcip=self.IPAddr
        rep.dstip=src_ip
        rep.next=icmp_rep
        rep.protocol=packet.payload.ICMP_PROTOCOL
        eth = ethernet()
        eth.dst = packet.src
        eth.src = self.EthAddr
        eth.set_payload(rep)
        eth.type = ethernet.IP_TYPE
        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
        self.connection.send(msg)
        print "icmp reply DONE"

      else:
        NextHopIP=nxt[0]
        Interface=nxt[1][-1]

        # payload=packet.payload.pa/yload # payload of IP packet
        # create a empty IP packet

        # ipv4_packet_out=ipv4_packet
        ipv4_packet.ttl=ipv4_packet.ttl-1
        # Create the Ethernet packet

        eth = ethernet()
        eth.type = ethernet.IP_TYPE
        if IPAddr(NextHopIP) in self.arp_table: 
          eth.dst = self.arp_table[IPAddr(NextHopIP)]
          eth.src = self.EthAddr
          eth.set_payload(ipv4_packet)

          # 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 = int(Interface)))
          msg.in_port = event.port
          self.connection.send(msg)
        else:
          arp_rep = arp()
          arp_rep.opcode = arp.REQUEST

          # Show the client that it's actually the me
          arp_rep.hwsrc = self.EthAddr
          arp_rep.hwdst = EthAddr('ff:ff:ff:ff:ff:ff')
          #arp_rep.hwdst = 'ff:ff:ff:ff:ff:ff'
          arp_rep.protosrc = self.IPAddr
          arp_rep.protodst = IPAddr(NextHopIP)

          # Create the Ethernet packet
          eth1 = ethernet()
          eth1.type = ethernet.ARP_TYPE
          eth1.dst = EthAddr('ff:ff:ff:ff:ff:ff')
          eth1.src = self.EthAddr
          eth1.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 = eth1.pack()
          msg.actions.append(of.ofp_action_output(port = int(Interface)))
          msg.in_port = event.port
          self.connection.send(msg)
          eth.src = self.EthAddr
          eth.set_payload(ipv4_packet_out)
          self.que.append((eth,int(Interface),event.port))