Ejemplo n.º 1
0
    def _ping(self,
              dp,
              port_out,
              ip_src=DISCOVERY_IP_SRC,
              ip_dst=DISCOVERY_IP_DST,
              eth_src='02:b0:00:00:00:b5',
              eth_dst='02:bb:bb:bb:bb:bb',
              icmp_type=8,
              icmp_code=0):
        ofp = dp.ofproto
        parser = dp.ofproto_parser
        pkt = packet.Packet()
        pkt.add_protocol(
            ethernet.ethernet(ethertype=0x0800, dst=eth_dst, src=eth_src))

        pkt.add_protocol(ipv4.ipv4(dst=ip_dst, src=ip_src, proto=1))

        pkt.add_protocol(
            icmp.icmp(type_=icmp_type,
                      code=icmp_code,
                      csum=0,
                      data=icmp.echo(
                          1, 1, "{'dpid' : " + str(dp.id) + ",'port_out' : " +
                          str(port_out) + "}")))
        pkt.serialize()
        data = pkt.data
        actions = [parser.OFPActionOutput(port_out, 0)]
        out = parser.OFPPacketOut(datapath=dp,
                                  buffer_id=ofp.OFP_NO_BUFFER,
                                  in_port=ofp.OFPP_CONTROLLER,
                                  actions=actions,
                                  data=data)
        dp.send_msg(out)
Ejemplo n.º 2
0
    def _handle_icmp(self, ev, subname):
        msg = ev.msg
        datapath = msg.datapath
        pkt = packet.Packet(data=msg.data)
        pkt_ethernet = pkt.get_protocol(ethernet.ethernet)
        pkt_ipv4 = pkt.get_protocol(ipv4.ipv4)
        pkt_icmp = pkt.get_protocol(icmp.icmp)
        in_port = msg.match['in_port']
         
        # ignore icmp of other than icmp_echo_request
        if pkt_icmp.type != icmp.ICMP_ECHO_REQUEST:
            return
        # make packet object to return
        this_subnet=self.subnet[datapath.id][subname]
        pkt = packet.Packet()
        pkt.add_protocol(ethernet.ethernet(ethertype=pkt_ethernet.ethertype,
            dst=pkt_ethernet.src,
            src=this_subnet['mac']))
#             if vid != None:
#             pkt.add_protocol(vlan.vlan(vid=vid, ethertype = 0x0800))
        pkt.add_protocol(ipv4.ipv4(dst=pkt_ipv4.src,
            src=this_subnet['ip'],
            proto=pkt_ipv4.proto))
        pkt.add_protocol(icmp.icmp(type_=icmp.ICMP_ECHO_REPLY,
            code=icmp.ICMP_ECHO_REPLY_CODE,
            csum=0,
            data=pkt_icmp.data))
        self._send_packet(datapath, in_port, pkt)
        self.logger.info("icmp reply is sent: %s-%s via port=%s" % (pkt_ethernet.src, pkt_ipv4.src, in_port) )      
    def test_Packet_in_2_icmpEcho1(self):
        print "*** Case2: HOST2のMAC未学習の時、HOST1からICMP Echoを受信 ***"

        sr = SimpleForward()
        dstMac = ROUTER_MACADDR1
        srcMac = HOST_MACADDR1
        srcIp = HOST_IPADDR1
        dstIp = HOST_IPADDR2
        targetMac = dstMac
        targetIp = dstIp
        ttl = 64

        datapath = _Datapath()
        e = ethernet(dstMac, srcMac, ether.ETH_TYPE_IP)

        iph = ipv4(4, 5, 0, 0, 0, 2, 0, ttl, 1, 0, srcIp, dstIp)
        echo = icmp.echo(1, 1, 'unit test')
        icmph = icmp.icmp(8, 0, 0, echo)

        p = Packet()
        p.add_protocol(e)
        p.add_protocol(iph)
        p.add_protocol(icmph)
        p.serialize()

        packetIn = OFPPacketIn(datapath, match=OFPMatch(in_port=1), data=buffer(p.data))

        ev = ofp_event.EventOFPPacketIn(packetIn)

        result = sr.packet_in_handler(ev)
        self.assertEqual(result, 1)
        print ""
Ejemplo n.º 4
0
    def  receive_icmp(self, datapath, packet, port):
   
        ip_packet = packet.get_protocol(ipv4.ipv4)
        icmp_packet = packet.get_protocol(icmp.icmp)
        
        if icmp_packet.type == 8: # Echo request
	   dst_mac = self.arpcache.get_mac(ip_packet.src, port)
	   
	   ip_data =  self.ports.get_ip(ip_packet.dst)
           if (ip_data == None):
	     LOG.debug("ICMP not for router")
	     return 0
	   
	   (ip_addr,mask,mac_addr) = self.ports.get_port(port) # Routing
           
           e =  ethernet.ethernet(dst_mac, mac_addr, ether.ETH_TYPE_IP)
           ip = ipv4.ipv4(src= ip_packet.dst, dst=ip_packet.src, proto= inet.IPPROTO_ICMP,ttl=64)
	   echo_new = icmp.echo(icmp_packet.data.id, icmp_packet.data.seq, icmp_packet.data.data)
	   icmp_new = icmp.icmp(type_=0, code=0, data=echo_new)
           p = Packet()
           p.add_protocol(e)
           p.add_protocol(ip)
           p.add_protocol(icmp_new)
           
           self.send_packet(datapath,port, p)
           LOG.debug("ICMP for router")
           return 1
        return 0
Ejemplo n.º 5
0
    def _ping(self, dp, port_out):
        ofp = dp.ofproto
        parser = dp.ofproto_parser
        pkt = packet.Packet()
        pkt.add_protocol(
            ethernet.ethernet(ethertype=0x0800,
                              dst='ff:ff:ff:ff:ff:ff',
                              src='aa:aa:aa:aa:aa:aa'))

        pkt.add_protocol(ipv4.ipv4(dst='0.0.0.2', src='0.0.0.1', proto=1))

        pkt.add_protocol(
            icmp.icmp(type_=8,
                      code=0,
                      csum=0,
                      data=icmp.echo(
                          1, 1, "{'dpid' : " + str(dp.id) + ",'port_out' : " +
                          str(port_out) + "}")))
        pkt.serialize()
        data = pkt.data
        actions = [parser.OFPActionOutput(port_out, 0)]
        out = parser.OFPPacketOut(datapath=dp,
                                  buffer_id=ofp.OFP_NO_BUFFER,
                                  in_port=ofp.OFPP_CONTROLLER,
                                  actions=actions,
                                  data=data)
        dp.send_msg(out)
Ejemplo n.º 6
0
 def _handle_icmp(self, datapath, port, pkt_ethernet, pkt_ipv4, pkt_icmp):
     """
     依据传入的 eth, ip, icmp 生成 packet包
     :param datapath:
     :param port:
     :param pkt_ethernet:
     :param pkt_ipv4:
     :param pkt_icmp:
     :return:
     """
     if pkt_icmp.type != icmp.ICMP_ECHO_REQUEST:
         return
     pkt = packet.Packet()
     pkt.add_protocol(
         ethernet.ethernet(ethertype=pkt_ethernet.ethertype,
                           dst=pkt_ethernet.src,
                           src=self.hw_addr))
     pkt.add_protocol(
         ipv4.ipv4(dst=pkt_ipv4.src, src=self.ip_addr,
                   proto=pkt_ipv4.proto))
     pkt.add_protocol(
         icmp.icmp(type_=icmp.ICMP_ECHO_REPLY,
                   code=icmp.ICMP_ECHO_REPLY_CODE,
                   csum=0,
                   data=pkt_icmp.data))
     self._send_packet(datapath, port, pkt)
Ejemplo n.º 7
0
    def send_ping_packet(self, switch, ip):
        datapath = switch.dp
        dpid = datapath.id
        mac_dst = self.arp_table[ip]
        out_port = self.mac_to_port[dpid][mac_dst]
        actions = [datapath.ofproto_parser.OFPActionOutput(out_port)]

        pkt = packet.Packet()
        pkt.add_protocol(
            ethernet.ethernet(ethertype=ether_types.ETH_TYPE_IP,
                              src=self.controller_mac,
                              dst=self.arp_table[ip]))
        pkt.add_protocol(
            ipv4.ipv4(proto=in_proto.IPPROTO_ICMP,
                      src=self.controller_ip,
                      dst=ip))
        echo_payload = '%d;%s;%f' % (dpid, ip, time.time())
        payload = icmp.echo(data=echo_payload)
        pkt.add_protocol(icmp.icmp(data=payload))
        pkt.serialize()

        out = datapath.ofproto_parser.OFPPacketOut(
            datapath=datapath,
            buffer_id=datapath.ofproto.OFP_NO_BUFFER,
            data=pkt.data,
            in_port=datapath.ofproto.OFPP_CONTROLLER,
            actions=actions)

        datapath.send_msg(out)
Ejemplo n.º 8
0
    def send_icmp(self,
                  datapath,
                  srcMac,
                  srcIp,
                  dstMac,
                  dstIp,
                  outPort,
                  seq,
                  data,
                  id=1,
                  type=8,
                  ttl=64):

        e = ethernet(dstMac, srcMac, ether.ETH_TYPE_IP)
        iph = ipv4(4, 5, 0, 0, 0, 2, 0, ttl, 1, 0, srcIp, dstIp)
        echo = icmp.echo(id, seq, data)
        icmph = icmp.icmp(type, 0, 0, echo)

        p = Packet()
        p.add_protocol(e)
        p.add_protocol(iph)
        p.add_protocol(icmph)
        p.serialize()

        actions = [datapath.ofproto_parser.OFPActionOutput(outPort, 0)]
        out = datapath.ofproto_parser.OFPPacketOut(
            datapath=datapath,
            buffer_id=0xffffffff,
            in_port=datapath.ofproto.OFPP_CONTROLLER,
            actions=actions,
            data=p.data)
        datapath.send_msg(out)
        return 0
Ejemplo n.º 9
0
 def _handle_icmp(self, datapath, port, pkt_ethernet, pkt_ipv4, pkt_icmp,
                  SrcGroup):
     # パケットがICMP ECHOリクエストでなかった場合はすぐに返す
     # 自分のゲートウェイIPアドレスをもっているグループでなかったら終了
     print('ICMP : ', pkt_ipv4.src, ' > ', pkt_ipv4.dst)
     if pkt_icmp.type != icmp.ICMP_ECHO_REQUEST or pkt_ipv4.dst != self.group_mac[
             SrcGroup][0][0]:
         return
     # ICMPを作成して返す
     pkt = packet.Packet()
     pkt.add_protocol(
         ethernet.ethernet(ethertype=pkt_ethernet.ethertype,
                           dst=pkt_ethernet.src,
                           src=self.gateway_mac))  # ゲートウェイのmac
     pkt.add_protocol(
         ipv4.ipv4(
             dst=pkt_ipv4.src,
             src=self.group_mac[SrcGroup][0][0],  # ゲートウェイのIP
             proto=pkt_ipv4.proto))
     pkt.add_protocol(
         icmp.icmp(type_=icmp.ICMP_ECHO_REPLY,
                   code=icmp.ICMP_ECHO_REPLY_CODE,
                   csum=0,
                   data=pkt_icmp.data))
     self._send_packet(datapath, port, pkt)
Ejemplo n.º 10
0
 def _handle_icmp(self, msg, port, data):
     # パケットがICMP ECHOリクエストでなかった場合はすぐに返す
     # 自分のゲートウェイIPアドレスをもっているグループでなかったら終了
     pkt = packet.Packet(data)
     pkt_icmp = pkt.get_protocol(icmp.icmp)
     pkt_ethernet = pkt.get_protocol(ethernet.ethernet)
     pkt_ipv4 = pkt.get_protocol(ipv4.ipv4)
     if pkt_ipv4:
         pass
     else:
         return
     if pkt_icmp.type != icmp.ICMP_ECHO_REQUEST or pkt_ipv4.dst != self.gateway_ip:
         return
     src_mac = self.gateway_mac
     src_ip = self.gateway_ip
     dst_mac = pkt_ethernet.src
     dst_ip = pkt_ipv4.src
     print('ICMP : ', src_ip, ' >> ', dst_ip)
     # ICMPを作成して返す
     pkt = packet.Packet()
     pkt.add_protocol(
         ethernet.ethernet(ethertype=pkt_ethernet.ethertype,
                           dst=dst_mac,
                           src=src_mac))  # ゲートウェイのmac
     pkt.add_protocol(
         ipv4.ipv4(
             dst=dst_ip,
             src=src_ip,  # ゲートウェイのIP
             proto=pkt_ipv4.proto))
     pkt.add_protocol(
         icmp.icmp(type_=icmp.ICMP_ECHO_REPLY,
                   code=icmp.ICMP_ECHO_REPLY_CODE,
                   csum=0,
                   data=pkt_icmp.data))
     self._send_packet(port, pkt, self.datapath.ofproto.OFP_NO_BUFFER)
Ejemplo n.º 11
0
    def send_icmp_reply(self, datapath, old_pkt, output):

        pkt = packet.Packet()

        for protocol in old_pkt:
            if protocol.protocol_name == 'ethernet':
                e = ethernet.ethernet(src=protocol.dst, dst=protocol.src, ethertype=ether_types.ETH_TYPE_IP)
                pkt.add_protocol(e)
            elif protocol.protocol_name == 'ipv4':
                ip = ipv4.ipv4(version=protocol.version, header_length=protocol.header_length, tos=protocol.tos,
                               total_length=0, identification=protocol.identification,
                               flags=protocol.flags, offset=0, ttl=protocol.ttl, proto=protocol.proto, csum=0,
                               src=protocol.dst, dst=protocol.src, option=protocol.option)
                pkt.add_protocol(ip)
                dst_ip = ip.dst
            elif protocol.protocol_name == 'icmp':
                icm = icmp.icmp(type_=icmp.ICMP_ECHO_REPLY, code=icmp.ICMP_ECHO_REPLY_CODE, csum=0, data=protocol.data)
                pkt.add_protocol(icm)

        pkt.serialize()

        actions = [datapath.ofproto_parser.OFPActionOutput(output, 0)]

        ofp = datapath.ofproto
        ofp_parser = datapath.ofproto_parser

        res = ofp_parser.OFPPacketOut(datapath=datapath, buffer_id=ofp.OFP_NO_BUFFER,
                                      in_port=datapath.ofproto.OFPP_CONTROLLER, actions=actions, data=pkt.data)

        LOG.info('Sending ICMP echo response for %s', dst_ip)
        datapath.send_msg(res)
Ejemplo n.º 12
0
    def test_Packet_in_2_icmpEcho1(self):
        print "*** Case2: HOST2のMAC未学習の時、HOST1からICMP Echoを受信 ***"

        sr = SimpleForward()
        dstMac = ROUTER_MACADDR1
        srcMac = HOST_MACADDR1
        srcIp = HOST_IPADDR1
        dstIp = HOST_IPADDR2
        targetMac = dstMac
        targetIp = dstIp
        ttl = 64

        datapath = _Datapath()
        e = ethernet(dstMac, srcMac, ether.ETH_TYPE_IP)

        iph = ipv4(4, 5, 0, 0, 0, 2, 0, ttl, 1, 0, srcIp, dstIp)
        echo = icmp.echo(1, 1, 'unit test')
        icmph = icmp.icmp(8, 0, 0, echo)

        p = Packet()
        p.add_protocol(e)
        p.add_protocol(iph)
        p.add_protocol(icmph)
        p.serialize()

        packetIn = OFPPacketIn(datapath,
                               match=OFPMatch(in_port=1),
                               data=buffer(p.data))

        ev = ofp_event.EventOFPPacketIn(packetIn)

        result = sr.packet_in_handler(ev)
        self.assertEqual(result, 1)
        print ""
Ejemplo n.º 13
0
    def send_ping_packet(self, s1, s2):
        '''
            Send a ping/ICMP packet between two switches.
            Uses ryu's packet library.
            Uses a fake MAC and IP address only known to controller.
        '''
        datapath = self.datapath_list[int(s1.dpid)]
        dst_mac = self.ping_mac
        dst_ip = self.ping_ip
        out_port = s1.port_no
        actions = [datapath.ofproto_parser.OFPActionOutput(out_port)]

        pkt = packet.Packet()
        pkt.add_protocol(
            ethernet.ethernet(ethertype=ether_types.ETH_TYPE_IP,
                              src=self.controller_mac,
                              dst=dst_mac))
        pkt.add_protocol(
            ipv4.ipv4(proto=in_proto.IPPROTO_ICMP,
                      src=self.controller_ip,
                      dst=dst_ip))
        echo_payload = '%s;%s;%f' % (s1.dpid, s2.dpid, time.time())
        payload = icmp.echo(data=echo_payload)
        pkt.add_protocol(icmp.icmp(data=payload))
        pkt.serialize()

        out = datapath.ofproto_parser.OFPPacketOut(
            datapath=datapath,
            buffer_id=datapath.ofproto.OFP_NO_BUFFER,
            data=pkt.data,
            in_port=datapath.ofproto.OFPP_CONTROLLER,
            actions=actions)

        datapath.send_msg(out)
Ejemplo n.º 14
0
    def _build_pkt(self, fields, ops):
        pkt_out = packet.Packet()
        pkt_ipv4 = pkt_out.get_protocol(ipv4.ipv4)
        pkt_icmp = pkt_out.get_protocol(icmp.icmp)

        def addIPv4(pkt_out, fields):
            pkt_out.add_protocol(
                ipv4.ipv4(dst=fields['dstip'],
                          src=fields['srcip'],
                          proto=fields['proto']))
            return pkt_out

        pkt_out.add_protocol(
            ethernet.ethernet(ethertype=fields['ethtype'],
                              dst=fields['dstmac'],
                              src=fields['srcmac']))
        # Add if ARP
        if 'arp' in fields['ptype']:
            pkt_out.add_protocol(
                arp.arp(opcode=arp.ARP_REPLY,
                        src_mac=fields['srcmac'],
                        src_ip=fields['srcip'],
                        dst_mac=fields['dstmac'],
                        dst_ip=fields['dstip']))
        # Add if IPv4
        if 'ipv4' in fields['ptype']:
            pkt_out = addIPv4(pkt_out, fields)

        # Add if ICMP
        if 'icmp' in fields['ptype']:
            pkt_out = addIPv4(pkt_out, fields)

            pkt_out.add_protocol(
                icmp.icmp(type_=icmp.ICMP_ECHO_REPLY,
                          code=icmp.ICMP_ECHO_REPLY_CODE,
                          csum=0,
                          data=None))
        # Add if UDP
        if 'udp' in fields['ptype']:
            pkt_out = addIPv4(pkt_out, fields)
            pkt_out.add_protocol(
                udp.udp(dst_port=fields['dstport'],
                        bits=fields['bits'],
                        option=fields['opt'],
                        src_port=fields['srcport']))
        # Add if TCP
        if 'tcp' in fields['ptype']:
            pkt_out = addIPv4(pkt_out, fields)
            pkt_out.add_protocol(
                tcp.tcp(dst_port=fields['dstport'],
                        bits=fields['bits'],
                        option=fields['opt'],
                        src_port=fields['srcport']))
        #Add covert channel information
        if fields['com'] != None:
            pkt_out.add_protocol(fields['com'])

        #Send crafted packet
        self._send_packet(fields['dp'], ops['newport'], pkt_out)
Ejemplo n.º 15
0
def icmp_packet_gen():
    pkt = packet.Packet()
    pkt.protocols.append(
        ethernet.ethernet("ff:ff:ff:ff:ff:ff", "ff:ff:ff:ff:ff:ff", IPV4))
    pkt.protocols.append(ipv4.ipv4(proto=ICMP_PROTO))
    pkt.protocols.append(icmp.icmp(0, 0, 0))

    return pkt
Ejemplo n.º 16
0
    def test_default_args(self):
        ic = icmp.icmp()
        buf = ic.serialize(bytearray(), None)
        res = struct.unpack(icmp.icmp._PACK_STR, six.binary_type(buf[:4]))

        eq_(res[0], 8)
        eq_(res[1], 0)
        eq_(buf[4:], b'\x00\x00\x00\x00')

        # with data
        ic = icmp.icmp(type_=icmp.ICMP_DEST_UNREACH, data=icmp.dest_unreach())
        buf = ic.serialize(bytearray(), None)
        res = struct.unpack(icmp.icmp._PACK_STR, six.binary_type(buf[:4]))

        eq_(res[0], 3)
        eq_(res[1], 0)
        eq_(buf[4:], b'\x00\x00\x00\x00')
Ejemplo n.º 17
0
    def test_default_args(self):
        ic = icmp.icmp()
        buf = ic.serialize(bytearray(), None)
        res = struct.unpack(icmp.icmp._PACK_STR, six.binary_type(buf[:4]))

        eq_(res[0], 8)
        eq_(res[1], 0)
        eq_(buf[4:], b'\x00\x00\x00\x00')

        # with data
        ic = icmp.icmp(type_=icmp.ICMP_DEST_UNREACH, data=icmp.dest_unreach())
        buf = ic.serialize(bytearray(), None)
        res = struct.unpack(icmp.icmp._PACK_STR, six.binary_type(buf[:4]))

        eq_(res[0], 3)
        eq_(res[1], 0)
        eq_(buf[4:], b'\x00\x00\x00\x00')
Ejemplo n.º 18
0
    def _handle_icmp(self, msg, pkt, icmp_pkt):
        """
            reply to ICMP_ECHO_REQUEST(i.e. ping);
            may handle other types of ICMP msg in the future;
            return True if send a response
        """
        LOG.debug('Handling ICMP packet %s', icmp_pkt)

        if icmp_pkt.type != icmp.ICMP_ECHO_REQUEST:
            return False

        in_port_no = msg.in_port
        switch = self.dpid_to_switch[msg.datapath.id]
        ipv4_layer = self.find_packet(pkt, 'ipv4')
        ip_src = netaddr.IPAddress(ipv4_layer.src)
        ip_dst = netaddr.IPAddress(ipv4_layer.dst)

        if ip_dst == netaddr.IPAddress(util.bgper_config['local_ipv4']):
            self.write_to_tap(pkt.data, modifyMacAddress=True)
            LOG.debug('Forward ICMP packet to tap port.')
            return True

        need_reply = False
        for _k, p in switch.ports.iteritems():
            if p.gateway and p.gateway.gw_ip == ip_dst:
                need_reply = True
                break
        if not need_reply:
            return False

        echo_id = icmp_pkt.data.id
        echo_seq = icmp_pkt.data.seq
        echo_data = bytearray(icmp_pkt.data.data)

        icmp_data = icmp.echo(id_=echo_id, seq=echo_seq, data=echo_data)

        #send a echo reply packet
        ether_layer = self.find_packet(pkt, 'ethernet')
        ether_dst = ether_layer.src
        ether_src = str(switch.ports[in_port_no].hw_addr)
        e = ethernet.ethernet(ether_dst, ether_src, ether.ETH_TYPE_IP)
        #csum calculation should be paid attention to
        i = ipv4.ipv4(version=4, header_length=5, tos=0, total_length=0,
            identification=0, flags=0x000, offset=0, ttl=64, proto=1, csum=0,
            src=str(ip_dst), dst=str(ip_src), option=None)
        ic = icmp.icmp(type_=0, code=0, csum=0, data=icmp_data)
        p = packet.Packet()
        p.add_protocol(e)
        p.add_protocol(i)
        p.add_protocol(ic)
        p.serialize()
        datapath = msg.datapath
        datapath.send_packet_out(in_port=ofproto_v1_0.OFPP_NONE,
                actions=[datapath.ofproto_parser.OFPActionOutput(in_port_no)],
                data=p.data)
        LOG.debug('Ping replied %s -> %s', ip_dst, ip_src)
        return True
Ejemplo n.º 19
0
    def _send_gossip_message_now(self, dp):
        """being called from GossipMonitor. Sending ICMP messages an measuring RTT.
		The response is then catched at packet_in_handler to derive the RTT"""

        if dp.id != self.tables.ovsk_dpid:
            # only sending gossip messages from ovsk to ovsk_server
            return

        dpid = dp.id
        parser = dp.ofproto_parser
        ofproto = dp.ofproto

        # creating the ICMP Request
        for port in self.tables.datapaths_ports[dpid]:
            if port == ofproto.OFPP_LOCAL:
                # omitting OFPP_LOCAL
                continue

            ping = packet.Packet()

            ping.add_protocol(
                ethernet.ethernet(
                    ethertype=ether_types.ETH_TYPE_IP,
                    dst=self.tables.ovsk_out_port_and_dest_mac[port],
                    src=self.tables.ovsk_mac))

            ping.add_protocol(
                ipv4.ipv4(dst=self.tables.ovsk_server_ip,
                          src=self.tables.ovsk_ip,
                          proto=ip_proto.IPPROTO_ICMP))

            ping.add_protocol(
                icmp.icmp(type_=icmp.ICMP_ECHO_REQUEST,
                          code=self.icmp_codes_per_out_port[port],
                          csum=0,
                          data=icmp.echo(
                              id_=self.icmp_codes_per_out_port[port],
                              seq=0,
                              data=None)))

            # sending the message

            ping.serialize()
            # print "--->[%s] Sending gossip ICMP packet:\n\t--->%s\n" % (dp.id, ping)
            data = ping.data

            actions = [parser.OFPActionOutput(port=port)]

            out = parser.OFPPacketOut(datapath=dp,
                                      actions=actions,
                                      in_port=ofproto.OFPP_CONTROLLER,
                                      buffer_id=ofproto.OFP_NO_BUFFER,
                                      data=data)

            self.request_reply_delay[self.icmp_codes_per_out_port[
                port]] = datetime.now().microsecond
            dp.send_msg(out)
Ejemplo n.º 20
0
    def send_icmp(self, datapath, dst_ip, src_mac, icmp_type, icmp_code,
                  ip_ihl, icmp_data):
        self.logger.debug("Sending ICMP")
        proto = datapath.ofproto
        parser = datapath.ofproto_parser
        dpid = dpid_to_str(datapath.id)

        pkt = packet.Packet()

        out_port, hop_ip = self.get_route(dpid, dst_ip)
        out_mac = self.mac_from_port(dpid, out_port)
        dst_mac = src_mac
        self.logger.debug(
            "Router {} sending ICMP to {} with target MAC {} (from port {} hopping to {})"
            .format(dpid, dst_ip, dst_mac, out_port, hop_ip))

        for interface in self.interface_table.get(dpid):
            if interface.get("port") == out_port:
                src_ip = interface.get("ip")

        offset = 14 + 8 + (ip_ihl * 4)
        payload = icmp_data[14:offset]

        if icmp_type == 3:
            self.logger.debug("TYPE 3 ICMP")
            payload = icmp.dest_unreach(data=payload)

        if icmp_type == 11:
            self.logger.debug("TYPE 11 ICMP")
            payload = icmp.TimeExceeded(data=payload)

        ## pkt.add_protocol(...)
        ## https://ryu.readthedocs.io/en/latest/library_packet_ref/packet_icmp.html

        pkt.add_protocol(
            ethernet.ethernet(dst=dst_mac,
                              src=out_mac,
                              ethertype=ethernet.ether.ETH_TYPE_IP))
        pkt.add_protocol(
            ipv4.ipv4(dst=dst_ip,
                      src=src_ip,
                      ttl=64,
                      proto=ipv4.inet.IPPROTO_ICMP))
        pkt.add_protocol(
            icmp.icmp(type_=icmp_type, code=icmp_code, data=payload))

        pkt.serialize()
        data = pkt.data
        actions = [datapath.ofproto_parser.OFPActionOutput(port=out_port)]
        out = datapath.ofproto_parser.OFPPacketOut(
            datapath=datapath,
            buffer_id=proto.OFP_NO_BUFFER,
            in_port=proto.OFPP_ANY,
            actions=actions,
            data=data)
        datapath.send_msg(out)
Ejemplo n.º 21
0
 def _handle_icmp(self, datapath, port, pkt_ethernet, pkt_ipv4, pkt_icmp):
     pkt = packet.Packet()
     pkt.add_protocol(ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.src,src=self.hw_addr))
     pkt.add_protocol(ipv4.ipv4(dst=pkt_ipv4.src,src=self.ip_addr,proto=pkt_ipv4.proto))
     dpid = datapath.id
     #pkt.add_protocol(icmp.icmp(type_=icmp.ICMP_TIME_EXCEEDED,
     pkt.add_protocol(icmp.icmp(type_=icmp.ICMP_TIME_EXCEEDED,code=(10*dpid/256 +dpid%256),csum=0))
     self.logger.info("packet-in 0x%x, %d" %(dpid,(10*dpid/256+dpid%256)))
     #pkt.add_protocol(icmp.icmp(type_=icmp.ICMP_ECHO_REPLY,code=icmp.ICMP_ECHO_REPLY_CODE,csum=0))
     self._send_packet(datapath, port, pkt)
Ejemplo n.º 22
0
 def _handle_icmp(self, datapath, port, pkt_ethernet, pkt_ipv4, pkt_icmp):
     if pkt_icmp.type != icmp.ICMP_ECHO_REQUEST:
         return
     pkt = packet.Packet()
     pkt.add_protocol(ethernet.ethernet(ethertype=pkt_ethernet.ethertype, dst=pkt_ethernet.src, src=self.hw_addr))
     pkt.add_protocol(ipv4.ipv4(dst=pkt_ipv4.src, src=self.ip_addr, proto=pkt_ipv4.proto))
     pkt.add_protocol(
         icmp.icmp(type_=icmp.ICMP_ECHO_REPLY, code=icmp.ICMP_ECHO_REPLY_CODE, csum=0, data=pkt_icmp.data)
     )
     self._send_packet(datapath, port, pkt)
Ejemplo n.º 23
0
    def send_icmp(self,
                  in_port,
                  icmp_type,
                  icmp_code,
                  datapath,
                  ipv4_header=None,
                  ethernet_header=None,
                  icmp_data=None,
                  msg_data=None,
                  src_ip=None):
        # Generate ICMP reply packet
        csum = 0
        offset = ethernet.ethernet._MIN_LEN

        ether_proto = ether.ETH_TYPE_IP

        eth = ethernet_header
        e = ethernet.ethernet(eth.src, eth.dst, ether_proto)

        if icmp_data is None and msg_data is not None:
            ip_datagram = msg_data[offset:]
            if icmp_type == icmp.ICMP_DEST_UNREACH:
                icmp_data = icmp.dest_unreach(data_len=len(ip_datagram),
                                              data=ip_datagram)
            elif icmp_type == icmp.ICMP_TIME_EXCEEDED:
                icmp_data = icmp.TimeExceeded(data_len=len(ip_datagram),
                                              data=ip_datagram)

        ic = icmp.icmp(icmp_type, icmp_code, csum, data=icmp_data)

        ip = ipv4_header
        if src_ip is None:
            src_ip = ip.dst
        ip_total_length = ip.header_length * 4 + ic._MIN_LEN
        if ic.data is not None:
            ip_total_length += ic.data._MIN_LEN
            if ic.data.data is not None:
                ip_total_length += +len(ic.data.data)
        i = ipv4.ipv4(ip.version, ip.header_length, ip.tos, ip_total_length,
                      ip.identification, ip.flags, ip.offset, DEFAULT_TTL,
                      inet.IPPROTO_ICMP, csum, src_ip, ip.src)

        pkt = packet.Packet()
        pkt.add_protocol(e)

        pkt.add_protocol(i)
        pkt.add_protocol(ic)
        pkt.serialize()

        # Send packet out
        self.send_packet_out(datapath,
                             in_port,
                             datapath.ofproto.OFPP_IN_PORT,
                             pkt.data,
                             data_str=str(pkt))
Ejemplo n.º 24
0
    def setUp(self):
        self.type_ = icmp.ICMP_ECHO_REQUEST
        self.code = 0
        self.csum = 0
        self.data = None

        self.ic = icmp.icmp(self.type_, self.code, self.csum, self.data)

        self.buf = bytearray(struct.pack(icmp.icmp._PACK_STR, self.type_, self.code, self.csum))
        self.csum_calc = packet_utils.checksum(self.buf)
        struct.pack_into("!H", self.buf, 2, self.csum_calc)
Ejemplo n.º 25
0
 def icmp(self, imsi='001010000000013',
          src_mac='00:00:00:00:00:00', src_ip='192.168.70.2',
          dst_mac='ff:ff:ff:ff:ff:ff', dst_ip='192.168.70.3'):
     """
     Send an ICMP packet through the magma switch and display which tabled
     caused a drop (-1 if the packet wasn't dropped by any table)
     """
     pkt = ethernet.ethernet(src=src_mac, dst=dst_mac) / \
           ipv4.ipv4(src=src_ip, dst=dst_ip, proto=1) / \
           icmp.icmp()
     pkt.serialize()
     self.raw(data=pkt.data, imsi=imsi)
Ejemplo n.º 26
0
def build_pkt(pkt):
    """Build and return a packet and eth type from a dict."""
    layers = []
    assert 'eth_dst' in pkt and 'eth_src' in pkt
    ethertype = None
    if 'arp_source_ip' in pkt and 'arp_target_ip' in pkt:
        ethertype = ether.ETH_TYPE_ARP
        layers.append(
            arp.arp(src_ip=pkt['arp_source_ip'], dst_ip=pkt['arp_target_ip']))
    elif 'ipv6_src' in pkt and 'ipv6_dst' in pkt:
        ethertype = ether.ETH_TYPE_IPV6
        if 'neighbor_solicit_ip' in pkt:
            layers.append(
                icmpv6.icmpv6(
                    type_=icmpv6.ND_NEIGHBOR_SOLICIT,
                    data=icmpv6.nd_neighbor(
                        dst=pkt['neighbor_solicit_ip'],
                        option=icmpv6.nd_option_sla(hw_src=pkt['eth_src']))))
        elif 'echo_request_data' in pkt:
            layers.append(
                icmpv6.icmpv6(type_=icmpv6.ICMPV6_ECHO_REQUEST,
                              data=icmpv6.echo(id_=1,
                                               seq=1,
                                               data=pkt['echo_request_data'])))
        layers.append(
            ipv6.ipv6(src=pkt['ipv6_src'],
                      dst=pkt['ipv6_dst'],
                      nxt=inet.IPPROTO_ICMPV6))
    elif 'ipv4_src' in pkt and 'ipv4_dst' in pkt:
        ethertype = ether.ETH_TYPE_IP
        proto = inet.IPPROTO_IP
        if 'echo_request_data' in pkt:
            echo = icmp.echo(id_=1, seq=1, data=pkt['echo_request_data'])
            layers.append(icmp.icmp(type_=icmp.ICMP_ECHO_REQUEST, data=echo))
            proto = inet.IPPROTO_ICMP
        net = ipv4.ipv4(src=pkt['ipv4_src'], dst=pkt['ipv4_dst'], proto=proto)
        layers.append(net)
    assert ethertype is not None, pkt
    if 'vid' in pkt:
        tpid = ether.ETH_TYPE_8021Q
        layers.append(vlan.vlan(vid=pkt['vid'], ethertype=ethertype))
    else:
        tpid = ethertype
    eth = ethernet.ethernet(dst=pkt['eth_dst'],
                            src=pkt['eth_src'],
                            ethertype=tpid)
    layers.append(eth)
    layers = [layer for layer in reversed(layers)]
    result = packet.Packet()
    for layer in layers:
        result.add_protocol(layer)
    result.serialize()
    return (result, ethertype)
def generate(icmp_type, icmp_code, msg_data, src_ip=None, pkt=None):
    """Generate ICMP error message

    :param icmp_type: The icmp type of packet
    :param icmp_code: The icmp code of packet
    :param msg_data: The original data that cause this ICMP error packet
    :param src_ip: The source ip of the packet
    :param pkt: The original packet that cause this ICMP error
    :returns: An ryu.lib.packet.packet.Packet instance, which is an ICMP packet
    """
    if not pkt:
        pkt = packet.Packet(msg_data)

    e_pkt = pkt.get_protocol(ethernet.ethernet)
    ipv4_pkt = pkt.get_protocol(ipv4.ipv4)
    if not src_ip:
        src_ip = ipv4_pkt.dst

    # Create ICMP data
    offset = ethernet.ethernet._MIN_LEN
    # Copy 128 bytes data according to RFC 4884
    end_of_data = offset + len(ipv4_pkt) + 128
    ip_datagram = bytearray()
    ip_datagram += msg_data[offset:end_of_data]
    data_len = int(len(ip_datagram) / 4)
    length_modulus = int(len(ip_datagram) % 4)
    # Zero pad to the next 32 bit boundary, according to RFC 4884
    if length_modulus:
        data_len += 1
        ip_datagram += bytearray([0] * (4 - length_modulus))

    icmp_data = _create_icmp_data(icmp_type, data_len, ip_datagram)
    ic_pkt = icmp.icmp(icmp_type, icmp_code, 0, data=icmp_data)

    # Create IPv4 data
    ip_total_length = ipv4_pkt.header_length * 4 + ic_pkt._MIN_LEN
    ip_total_length += ic_pkt.data._MIN_LEN
    ip_total_length += len(ic_pkt.data.data)
    ipv4_pkt.total_length = ip_total_length
    # Default ttl
    ipv4_pkt.ttl = 64
    ipv4_pkt.proto = inet.IPPROTO_ICMP
    ipv4_pkt.csum = 0
    ipv4_pkt.src, ipv4_pkt.dst = src_ip, ipv4_pkt.src

    # Create ethernet data
    e_pkt.src, e_pkt.dst = e_pkt.dst, e_pkt.src

    pkt_reply = packet.Packet()
    pkt_reply.add_protocol(e_pkt)
    pkt_reply.add_protocol(ipv4_pkt)
    pkt_reply.add_protocol(ic_pkt)
    return pkt_reply
Ejemplo n.º 28
0
    def setUp(self):
        self.type_ = icmp.ICMP_ECHO_REQUEST
        self.code = 0
        self.csum = 0
        self.data = None

        self.ic = icmp.icmp(self.type_, self.code, self.csum, self.data)

        self.buf = bytearray(
            struct.pack(icmp.icmp._PACK_STR, self.type_, self.code, self.csum))
        self.csum_calc = packet_utils.checksum(six.binary_type(self.buf))
        struct.pack_into('!H', self.buf, 2, self.csum_calc)
Ejemplo n.º 29
0
 def send_several_packet(self, middleware, chain, node):
     type_pkt = chain['detect_type']
     dst_ip = node['manage_ip']
     dst_mac = node['set_eth']
     src_ip = cm.Communal().randomIP(dst_ip)
     src_mac = cm.src_mac[0]
     content = 'abcdefghijklmnopqrstuvwabcdefghi'
     # detect in port or out port
     if type_pkt == 'tcp':
         dport = chain['detect_port']
         if middleware.has_key('in_device_id') and middleware['in_device_id']:
             node_poet = (self.etcd_port[middleware['in_device_id']]
                          if self.etcd_port.has_key(middleware['in_device_id'])
                          else None)
             if node_poet and self.datapaths.has_key(node_poet['forwarder']):
                 datapath = self.datapaths[node_poet['forwarder']]
                 vlanid = node_poet['vlan_id']
                 port = node_poet['port']
                 self.send_tcp_pke(datapath, port, vlanid, dst_ip, src_ip,
                                   src_mac, dst_mac, dport)
                 pkt = self.assemble_tcp(content, vlanid, dst_ip, dst_mac,
                                         src_ip, src_mac, dport)
             self._send_packet(datapath, pkt, port)
         if middleware.has_key('out_device_id') and middleware['out_device_id']:
             node_poet = (self.etcd_port[middleware['out_device_id']]
                          if self.etcd_port.has_key(middleware['out_device_id'])
                          else None)
             if node_poet and self.datapaths.has_key(node_poet['forwarder']):
                 datapath = self.datapaths[node_poet['forwarder']]
                 vlanid = node_poet['vlan_id']
                 port = node_poet['port']
                 self.send_tcp_pke(datapath, port, vlanid, dst_ip, src_ip,
                                   src_mac, dst_mac, dport)
                 pkt = self.assemble_tcp(content, vlanid, dst_ip, dst_mac,
                                         src_ip, src_mac, dport)
                 self._send_packet(datapath, pkt, port)
     elif type_pkt == 'icmp':
         self._send_packet(datapath, pkt, port)
         if middleware.has_key('out_device_id') and middleware['out_device_id']:
             node_poet = (self.etcd_port[middleware['out_device_id']]
                          if self.etcd_port.has_key(middleware['out_device_id'])
                          else None)
             if node_poet and self.datapaths.has_key(node_poet['forwarder']):
                 datapath = self.datapaths[node_poet['forwarder']]
                 vlanid = node_poet['vlan_id']
                 port = node_poet['port']
                 pkt = self.assemble_icmp(vlanid, dst_ip, dst_mac, src_ip,
                                          src_mac, (csum + 2), (identification - 1))
                 pkt.add_protocol(icmp.icmp(type_=icmp.ICMP_ECHO_REQUEST,
                                            code=icmp.ICMP_ECHO_REPLY_CODE,
                                            data=icmp.echo(id_=1, seq=rand + 2, data=content)))
                 self._send_packet(datapath, pkt, port)
Ejemplo n.º 30
0
    def _handle_icmp(self, datapath, port, pkt_ethernet, pkt_ipv4, pkt_icmp):
        pkt = packet.Packet()
        pkt.add_protocol(ethernet.ethernet(ethertype=pkt_ethernet.ethertype,
                                           dst=pkt_ethernet.src,
                                           src=self.hw_addr))
        pkt.add_protocol(ipv4.ipv4(dst=pkt_ipv4.src,
                                   src=pkt_ipv4.dst,
                                   proto=pkt_ipv4.proto))
        pkt.add_protocol(icmp.icmp(type_=icmp.ICMP_ECHO_REPLY,
                                   code=icmp.ICMP_ECHO_REPLY_CODE,
                                   csum=0,
                                   data=pkt_icmp.data))      
	self._send_packet(datapath, port, pkt)
Ejemplo n.º 31
0
    def send_ping(self, ip_dst):
        pkt = packet.Packet()
        if ip_dst in self.arp_table:
            mac_dst = self.arp_table[ip_dst]
        else:
            return
        pkt.add_protocol(ethernet.ethernet(ethertype=0x800,dst=mac_dst,\
                                                           src=self.hw_addr))

        pkt.add_protocol(ipv4.ipv4(dst= ip_dst, src=self.ip_addr,proto=1))
        pkt.add_protocol(icmp.icmp(type_= 8, code=0, csum=0))#Not sure about echo
        print("Ping packet sent")
        self._flood_packet(pkt)
Ejemplo n.º 32
0
    def setUp_with_TimeExceeded(self):
        self.te_data = b"abc"
        self.te_data_len = len(self.te_data)
        self.data = icmp.TimeExceeded(data_len=self.te_data_len, data=self.te_data)

        self.type_ = icmp.ICMP_TIME_EXCEEDED
        self.code = 0
        self.ic = icmp.icmp(self.type_, self.code, self.csum, self.data)

        self.buf = bytearray(struct.pack(icmp.icmp._PACK_STR, self.type_, self.code, self.csum))
        self.buf += self.data.serialize()
        self.csum_calc = packet_utils.checksum(self.buf)
        struct.pack_into("!H", self.buf, 2, self.csum_calc)
Ejemplo n.º 33
0
    def _handle_icmp(self, msg, pkt, icmp_pkt):
        '''
            reply to ICMP_ECHO_REQUEST(i.e. ping);
            may handle other types of ICMP msg in the future;
            return True if send a responce
        '''
        #print 'icmp', icmp_pkt
        if icmp_pkt.type != icmp.ICMP_ECHO_REQUEST:
            return False

        in_port_no = msg.in_port
        switch = self.dpid_to_switch[msg.datapath.id]
        ipv4_layer = self.find_packet(pkt, 'ipv4')
        ip_src = ipv4_layer.src
        ip_dst = ipv4_layer.dst

        need_reply = False
        for _k, p in switch.ports.iteritems():
            if p.gateway and p.gateway.gw_ip == ip_dst:
                need_reply = True
                break
        if not need_reply:
            return False

        echo_id = icmp_pkt.data.id
        echo_seq = icmp_pkt.data.seq
        echo_data = bytearray(icmp_pkt.data.data)

        icmp_data = icmp.echo(id_=echo_id,seq=echo_seq,data=echo_data)

        #send a echo reply packet
        ether_layer = self.find_packet(pkt, 'ethernet')
        ether_dst = ether_layer.src
        ether_src = switch.ports[in_port_no].hw_addr
        e = ethernet.ethernet(ether_dst,ether_src,ether.ETH_TYPE_IP)
        #csum calculation should be paied attention
        i = ipv4.ipv4(version=4,header_length=5,tos=0,total_length=0,
            identification=0,flags=0x000,offset=0,ttl=64,proto=1,csum=0,
            src=ip_dst,dst=ip_src,option=None)
        ic = icmp.icmp(type_= 0,code=0,csum=0,data=icmp_data)
        p = packet.Packet()
        p.add_protocol(e)
        p.add_protocol(i)
        p.add_protocol(ic)
        p.serialize()
        datapath = msg.datapath
        datapath.send_packet_out(in_port=ofproto_v1_0.OFPP_NONE,
                actions=[datapath.ofproto_parser.OFPActionOutput(in_port_no)],
                data=p.data)
        print 'send a ping replay'
        return True
Ejemplo n.º 34
0
    def _build_pkt(self, fields, ops):
        pkt_out = packet.Packet()
        pkt_ipv4 = pkt_out.get_protocol(ipv4.ipv4)
        pkt_icmp = pkt_out.get_protocol(icmp.icmp)

        def addIPv4(pkt_out, fields):
            pkt_out.add_protocol(ipv4.ipv4(dst=fields['dstip'],
                                 src=fields['srcip'],
                                 proto=fields['proto']))
            return pkt_out

        pkt_out.add_protocol(ethernet.ethernet(ethertype=fields['ethtype'],
                                               dst=fields['dstmac'],
                                               src=fields['srcmac']))
        # Add if ARP                                           
        if 'arp' in fields['ptype']:
            pkt_out.add_protocol(arp.arp(opcode=arp.ARP_REPLY,
                                 src_mac=fields['srcmac'],
                                 src_ip=fields['srcip'],
                                 dst_mac=fields['dstmac'],
                                 dst_ip=fields['dstip']))
        # Add if IPv4
        if 'ipv4' in fields['ptype']:
            pkt_out = addIPv4(pkt_out,fields)
            
        # Add if ICMP
        if 'icmp' in fields['ptype']:
            pkt_out = addIPv4(pkt_out,fields)
            
            pkt_out.add_protocol(icmp.icmp(type_=icmp.ICMP_ECHO_REPLY,
                                 code=icmp.ICMP_ECHO_REPLY_CODE,
                                 csum=0,
                                 data=None))
        # Add if UDP    
        if 'udp' in fields['ptype']:
            pkt_out = addIPv4(pkt_out,fields)
            pkt_out.add_protocol(udp.udp(dst_port=fields['dstport'],
				bits=fields['bits'],option=fields['opt'],
                                src_port=fields['srcport']))
        # Add if TCP                         	 
        if 'tcp' in fields['ptype']:
            pkt_out = addIPv4(pkt_out,fields)
            pkt_out.add_protocol(tcp.tcp(dst_port=fields['dstport'],
				bits=fields['bits'],option=fields['opt'],
                                src_port=fields['srcport']))
        #Add covert channel information                    
        if fields['com'] != None:
            pkt_out.add_protocol(fields['com'])
            
        #Send crafted packet            
        self._send_packet(fields['dp'], ops['newport'], pkt_out)
Ejemplo n.º 35
0
    def _handle_icmp(self, datapath, port, pkt_ethernet, pkt_ipv4, pkt_icmp):
        if pkt_icmp.type != icmp.ICMP_ECHO_REQUEST:
            return
        if pkt_ipv4.dst in self.arp_table1:
           # index = self.ip_addr.index(pkt_ipv4.dst)

            pkt = packet.Packet()
            pkt.add_protocol(ethernet.ethernet(ethertype=pkt_ethernet.ethertype,
                                           dst=pkt_ethernet.src, src=self.arp_table1[pkt_ipv4.dst]))
            pkt.add_protocol(ipv4.ipv4(dst=pkt_ipv4.src, src=pkt_ipv4.dst,
                                       proto=pkt_ipv4.proto))
            pkt.add_protocol(icmp.icmp(type_=icmp.ICMP_ECHO_REPLY,
                                       code=icmp.ICMP_ECHO_CODE, csum=0, datapath=pkt_icmp.data))
            self._send_packet(datapath, port, pkt)
Ejemplo n.º 36
0
    def _build_echo(self, _type, echo):
        e = self._build_ether(ether.ETH_TYPE_IP)
        ip = ipv4.ipv4(version=4, header_length=5, tos=0, total_length=84,
                       identification=0, flags=0, offset=0, ttl=64,
                       proto=inet.IPPROTO_ICMP, csum=0,
                       src=self.RYU_IP, dst=self.HOST_IP)
        ping = icmp.icmp(_type, code=0, csum=0, data=echo)

        p = packet.Packet()
        p.add_protocol(e)
        p.add_protocol(ip)
        p.add_protocol(ping)
        p.serialize()
        return p
Ejemplo n.º 37
0
    def setUp_with_dest_unreach(self):
        self.unreach_mtu = 10
        self.unreach_data = b"abc"
        self.unreach_data_len = len(self.unreach_data)
        self.data = icmp.dest_unreach(data_len=self.unreach_data_len, mtu=self.unreach_mtu, data=self.unreach_data)

        self.type_ = icmp.ICMP_DEST_UNREACH
        self.code = icmp.ICMP_HOST_UNREACH_CODE
        self.ic = icmp.icmp(self.type_, self.code, self.csum, self.data)

        self.buf = bytearray(struct.pack(icmp.icmp._PACK_STR, self.type_, self.code, self.csum))
        self.buf += self.data.serialize()
        self.csum_calc = packet_utils.checksum(self.buf)
        struct.pack_into("!H", self.buf, 2, self.csum_calc)
Ejemplo n.º 38
0
    def _build_echo(self, _type, echo):
        e = self._build_ether(ether.ETH_TYPE_IP)
        ip = ipv4.ipv4(version=4, header_length=5, tos=0, total_length=84,
                       identification=0, flags=0, offset=0, ttl=64,
                       proto=inet.IPPROTO_ICMP, csum=0,
                       src=self.RYU_IP, dst=self.HOST_IP)
        ping = icmp.icmp(_type, code=0, csum=0, data=echo)

        p = packet.Packet()
        p.add_protocol(e)
        p.add_protocol(ip)
        p.add_protocol(ping)
        p.serialize()
        return p
Ejemplo n.º 39
0
 def _handle_icmp(self, datapath, port, pkt_ethernet, pkt_ipv4, pkt_icmp):
     if pkt_icmp.type != icmp.ICMP_ECHO_REQUEST:
         return
     pkt = packet.Packet()
     pkt.add_protocol(ethernet.ethernet(ethertype=pkt_ethernet.ethertype,
                                        dst=pkt_ethernet.src,
                                        src=ROUTER_MACADDR1))
     pkt.add_protocol(ipv4.ipv4(dst=pkt_ipv4.src,
                                src=ROUTER_IPADDR1,
                                proto=pkt_ipv4.proto))
     pkt.add_protocol(icmp.icmp(type_=icmp.ICMP_ECHO_REPLY,
                                code=icmp.ICMP_ECHO_REPLY_CODE,
                                csum=0,
                                data=pkt_icmp.data))
     self._send_packet(datapath, port, pkt)
Ejemplo n.º 40
0
    def setUp_with_TimeExceeded(self):
        self.te_data = 'abc'
        self.te_data_len = len(self.te_data)
        self.data = icmp.TimeExceeded(data_len=self.te_data_len,
                                      data=self.te_data)

        self.type_ = icmp.ICMP_TIME_EXCEEDED
        self.code = 0
        self.ic = icmp.icmp(self.type_, self.code, self.csum, self.data)

        self.buf = struct.pack(icmp.icmp._PACK_STR, self.type_, self.code,
                               self.csum)
        self.buf += self.data.serialize()
        self.csum_calc = packet_utils.checksum(str(self.buf))
        struct.pack_into('!H', self.buf, 2, self.csum_calc)
 def createPacketIpv4(self, datapath, port, pkt_ethernet, pkt_ipv, pkt_icmp):
     # create send packet
     sendpkt = packet.Packet()
     sendpkt.add_protocol(ethernet.ethernet(ethertype=pkt_ethernet.ethertype,
                                       dst=pkt_ethernet.dst,
                                        src=pkt_ethernet.src))
     sendpkt.add_protocol(ipv4.ipv4(dst=pkt_ipv.src,
                                src=pkt_ethernet.src,
                                proto=pkt_ipv.proto))
     sendpkt.add_protocol(icmp.icmp(type_=icmp.ICMP_ECHO_REPLY,
                                code=icmp.ICMP_ECHO_REPLY_CODE,
                                csum=0,
                                data=pkt_icmp.data))
     sendpkt.serialize()
     return sendpkt
Ejemplo n.º 42
0
    def send_ping(self, datapath, src_mac, dst_mac, src_ip, dst_ip, outport=1, seq=0):
        ttl = 64

        e = ethernet.ethernet(dst_mac, src_mac, ether.ETH_TYPE_IP)
        iph = ipv4.ipv4(4, 5, 0, 0, 0, 2, 0, ttl, 1, 0, src_ip, dst_ip)
        echo = icmp.echo(1, seq, data=None)
        icmph = icmp.icmp(8, 0, 0, echo)
        
        pkt = packet.Packet()
        pkt.add_protocol(e)
        pkt.add_protocol(iph)
        pkt.add_protocol(icmph)
        
        self._send_packet(datapath, outport, pkt)
        self.logger.info("icmp echo req is sent: to %s" % (dst_ip,) )  
Ejemplo n.º 43
0
    def send_icmp(self, datapath, srcMac, srcIp, dstMac, dstIp, outPort, seq, data, id=1, type=8, ttl=64):
        e = ethernet.ethernet(dstMac, srcMac, ether.ETH_TYPE_IP) #Construye el protocolo ethernet
        iph = ipv4.ipv4(4, 5, 0, 0, 0, 2, 0, ttl, 1, 0, srcIp, dstIp) #Construye la parte del protocolo IP
        echo = icmp.echo(id, seq, data) #Construye la parte del echo que se añadirá al protocolo icmp
        icmph = icmp.icmp(type, 0, 0, echo) #Construye la parte del icmp

        p = Packet() #Crea el paquete
        p.add_protocol(e) #Añade el protocolo ethernet
        p.add_protocol(iph) #Añade el protocolo ip
        p.add_protocol(icmph) #Añade el protocolo icmp
        p.serialize() #Serializa todo

        actions = [datapath.ofproto_parser.OFPActionOutput(outPort, 0)] #Enviar por el puerto outPort
        #Mensaje a enviar
        out = datapath.ofproto_parser.OFPPacketOut(datapath=datapath, buffer_id=0xffffffff, in_port=datapath.ofproto.OFPP_CONTROLLER, actions=actions, data=p.data)
        datapath.send_msg(out) #Enviar mensaje
Ejemplo n.º 44
0
    def setUp_with_dest_unreach(self):
        self.unreach_mtu = 10
        self.unreach_data = 'abc'
        self.unreach_data_len = len(self.unreach_data)
        self.data = icmp.dest_unreach(data_len=self.unreach_data_len,
                                      mtu=self.unreach_mtu,
                                      data=self.unreach_data)

        self.type_ = icmp.ICMP_DEST_UNREACH
        self.code = icmp.ICMP_HOST_UNREACH_CODE
        self.ic = icmp.icmp(self.type_, self.code, self.csum, self.data)

        self.buf = struct.pack(icmp.icmp._PACK_STR, self.type_, self.code,
                               self.csum)
        self.buf += self.data.serialize()
        self.csum_calc = packet_utils.checksum(str(self.buf))
        struct.pack_into('!H', self.buf, 2, self.csum_calc)
Ejemplo n.º 45
0
class Test_icmp_dest_unreach(unittest.TestCase):

    type_ = icmp.ICMP_DEST_UNREACH
    code = icmp.ICMP_HOST_UNREACH_CODE
    csum = 0

    mtu = 10
    data = 'abc'
    data_len = len(data)
    dst_unreach = icmp.dest_unreach(data_len=data_len, mtu=mtu, data=data)

    ic = icmp.icmp(type_, code, csum, data=dst_unreach)

    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_to_string(self):
        data_values = {
            'data': self.data,
            'data_len': self.data_len,
            'mtu': self.mtu
        }
        _data_str = ','.join([
            '%s=%s' % (k, repr(data_values[k]))
            for k, v in inspect.getmembers(self.dst_unreach)
            if k in data_values
        ])
        data_str = '%s(%s)' % (icmp.dest_unreach.__name__, _data_str)

        icmp_values = {
            'type': repr(self.type_),
            'code': repr(self.code),
            'csum': repr(self.csum),
            'data': data_str
        }
        _ic_str = ','.join([
            '%s=%s' % (k, icmp_values[k])
            for k, v in inspect.getmembers(self.ic) if k in icmp_values
        ])
        ic_str = '%s(%s)' % (icmp.icmp.__name__, _ic_str)

        eq_(str(self.ic), ic_str)
        eq_(repr(self.ic), ic_str)
Ejemplo n.º 46
0
    def control_plane_icmp_handler(self, in_port, vlan, eth_src,
                                   ipv4_pkt, icmp_pkt):
        ofmsgs = []

        if icmp_pkt is not None:
            pkt = self.build_ethernet_pkt(
                eth_src, in_port, vlan, ether.ETH_TYPE_IP)
            ipv4_pkt = ipv4.ipv4(
                dst=ipv4_pkt.src, src=ipv4_pkt.dst, proto=ipv4_pkt.proto)
            icmp_pkt = icmp.icmp(
                type_=icmp.ICMP_ECHO_REPLY, code=icmp.ICMP_ECHO_REPLY_CODE,
                data=icmp_pkt.data)
            pkt.add_protocol(ipv4_pkt)
            pkt.add_protocol(icmp_pkt)
            pkt.serialize()
            ofmsgs.append(self.valve_packetout(in_port, pkt.data))

        return ofmsgs
Ejemplo n.º 47
0
    def ICMPPacket(self, datapath, in_port, pkt_ethernet, pkt_ipv4, pkt_icmp):
      if pkt_icmp.type == icmp.ICMP_ECHO_REQUEST:
	eer=ethernet.ethernet(ethertype=pkt_ethernet.ethertype,
						dst=pkt_ethernet.src,
						src=self.ip_mac_port[in_port][1])
						
	iper=ipv4.ipv4(dst=pkt_ipv4.src,
				    src=self.ip_mac_port[in_port][2],
				    proto=pkt_ipv4.proto)
				    
	icmper=icmp.icmp(type_=icmp.ICMP_ECHO_REPLY,
				    code=icmp.ICMP_ECHO_REPLY_CODE,
				    csum=0,
				    data=pkt_icmp.data)
	p = packet.Packet()
	p.add_protocol(eer)
	p.add_protocol(iper)
	p.add_protocol(icmper)
	
	self.send_packet(datapath, in_port, p)
Ejemplo n.º 48
0
 def handleIcmpPacket(self, datapath, in_port, pkt_ethernet, pkt_ipv4, pkt_icmp):
     #This function builds an ICMP echo reply for the echo request received
     if pkt_icmp.type == icmp.ICMP_ECHO_REQUEST:
         eer=ethernet.ethernet(ethertype=pkt_ethernet.ethertype,
                     dst=pkt_ethernet.src,
                     src=self.interfaces_virtuales[self.tabla_vlan[in_port]][0])
                     
         iper=ipv4.ipv4(dst=pkt_ipv4.src,
                 src=self.interfaces_virtuales[self.tabla_vlan[in_port]][2],
                 proto=pkt_ipv4.proto)
                 
         icmper=icmp.icmp(type_=icmp.ICMP_ECHO_REPLY,
                 code=icmp.ICMP_ECHO_REPLY_CODE,
                 csum=0,
                 data=pkt_icmp.data)
         p = packet.Packet()
         p.add_protocol(eer)
         p.add_protocol(iper)
         p.add_protocol(icmper)
 
         self.sendPacket(datapath, in_port, p)
Ejemplo n.º 49
0
    def setUp_with_echo(self):
        self.echo_id = 13379
        self.echo_seq = 1
        self.echo_data = b'\x30\x0e\x09\x00\x00\x00\x00\x00' \
            + b'\x10\x11\x12\x13\x14\x15\x16\x17' \
            + b'\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f' \
            + b'\x20\x21\x22\x23\x24\x25\x26\x27' \
            + b'\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f' \
            + b'\x30\x31\x32\x33\x34\x35\x36\x37'
        self.data = icmp.echo(
            id_=self.echo_id, seq=self.echo_seq, data=self.echo_data)

        self.type_ = icmp.ICMP_ECHO_REQUEST
        self.code = 0
        self.ic = icmp.icmp(self.type_, self.code, self.csum, self.data)

        self.buf = bytearray(struct.pack(
            icmp.icmp._PACK_STR, self.type_, self.code, self.csum))
        self.buf += self.data.serialize()
        self.csum_calc = packet_utils.checksum(self.buf)
        struct.pack_into('!H', self.buf, 2, self.csum_calc)
Ejemplo n.º 50
0
 def _virtual_ip_icmp_reply(self, datapath, in_port, pkt):
     eth_hd = pkt.get_protocol(ethernet.ethernet)
     ipv4_hd = pkt.get_protocol(ipv4.ipv4)
     icmp_hd = pkt.get_protocol(icmp.icmp)
     if icmp_hd.type == icmp.ICMP_ECHO_REQUEST:
         vir_ip = ipv4_hd.dst
         if vir_ip not in self.virtual_ip:
             print ("WARNING: could be virtual ip routing table config err")
             return
         vir_mac = self.virtual_ip[vir_ip]
         icmp_reply = packet.Packet()
         icmp_reply.add_protocol(ethernet.ethernet(ethertype=eth_hd.ethertype,
                                                   dst=eth_hd.src,
                                                   src=vir_mac))
         icmp_reply.add_protocol(ipv4.ipv4(dst=ipv4_hd.src,
                                           src=vir_ip,
                                           proto=ipv4_hd.proto))
         icmp_reply.add_protocol(icmp.icmp(type_=icmp.ICMP_ECHO_REPLY,
                                           code=icmp.ICMP_ECHO_REPLY_CODE,
                                           data=icmp_hd.data))
         self._send_packet_port(datapath, in_port, icmp_reply)
Ejemplo n.º 51
0
def _icmp_send(dp, port_out, ip_src=DISCOVERY_IP_SRC, ip_dst=DISCOVERY_IP_DST, 
               eth_src='02:b0:00:00:00:b5', eth_dst='02:bb:bb:bb:bb:bb',
               icmp_type=8, icmp_code=0):
    """
    Generates ICMP packet and sends it out of 'port_out' on forwarder 'dp'
 
    Keyword arguments:
        dp -- Datapath
        port_out -- Port on forwarder (dp) used to spit out packet
        ip_src -- IP address of sender
        ip_dst  -- IP address of recipient
        eth_src -- Ethernet address of source (Default is 02:b0:00:00:00:b5 because none wanted to have 0xb00b5 as experimenter ID)
        eth_dst -- Ethernet destiation address (probably to be reworked)
        icmp_type -- ICMP type, default is 8 which is Echo
        icmp_code -- ICMP code, default is 0 which is No Code

    """

    ofp = dp.ofproto
    parser = dp.ofproto_parser
    pkt = packet.Packet()
    pkt.add_protocol(ethernet.ethernet(ethertype=0x0800,
                                       dst=eth_dst,
                                       src=eth_src))

    pkt.add_protocol(ipv4.ipv4(dst=ip_dst,
                               src=ip_src,
                               proto=1))

    ##TODO: Rework payload and codes to properly work with Fragmentation needed
    pkt.add_protocol(icmp.icmp(type_=icmp_type,
                               code=icmp_code,
                               csum=0,
                               data=icmp.echo(1,1,"{'dpid' : "+str(dp.id)+",'port_out' : "+str(port_out)+"}")))
    pkt.serialize()
    data=pkt.data
    actions=[parser.OFPActionOutput(port_out,0)]
    out=parser.OFPPacketOut(datapath=dp, buffer_id=ofp.OFP_NO_BUFFER, in_port=ofp.OFPP_CONTROLLER, actions=actions, data=data)
    dp.send_msg(out)
Ejemplo n.º 52
0
    def send_icmp(self, datapath, srcMac, srcIp, dstMac, dstIp, outPort, seq, data, id=1, type=8, ttl=64):

        e = ethernet(dstMac, srcMac, ether.ETH_TYPE_IP)
        iph = ipv4(4, 5, 0, 0, 0, 2, 0, ttl, 1, 0, srcIp, dstIp)
        echo = icmp.echo(id, seq, data)
        icmph = icmp.icmp(type, 0, 0, echo)

        p = Packet()
        p.add_protocol(e)
        p.add_protocol(iph)
        p.add_protocol(icmph)
        p.serialize()

        actions = [datapath.ofproto_parser.OFPActionOutput(outPort, 0)]
        out = datapath.ofproto_parser.OFPPacketOut(
            datapath=datapath,
            buffer_id=0xffffffff,
            in_port=datapath.ofproto.OFPP_CONTROLLER,
            actions=actions,
            data=p.data)
        datapath.send_msg(out)
        return 0
Ejemplo n.º 53
0
def echo_reply(eth_src, eth_dst, vid, src_ip, dst_ip, data):
    """Return an ICMP echo reply packet.

    Args:
        eth_src (str): Ethernet source address.
        eth_dst (str): destination Ethernet MAC address.
        vid (int or None): VLAN VID to use (or None).
        src_ip (ipaddr.IPv4Address): source IPv4 address.
        dst_ip (ipaddr.IPv4Address): destination IPv4 address.
    Returns:
        ryu.lib.packet.icmp: serialized ICMP echo reply packet.
    """
    pkt = build_pkt_header(eth_src, eth_dst, vid, ether.ETH_TYPE_IP)
    ipv4_pkt = ipv4.ipv4(
        dst=dst_ip, src=src_ip, proto=inet.IPPROTO_ICMP)
    pkt.add_protocol(ipv4_pkt)
    icmp_pkt = icmp.icmp(
        type_=icmp.ICMP_ECHO_REPLY, code=icmp.ICMP_ECHO_REPLY_CODE,
        data=data)
    pkt.add_protocol(icmp_pkt)
    pkt.serialize()
    return pkt
Ejemplo n.º 54
0
    def _ping(self, dp, port_out):
        ofp = dp.ofproto
        parser = dp.ofproto_parser
        pkt = packet.Packet()
        pkt.add_protocol(ethernet.ethernet(ethertype=0x0800, dst="ff:ff:ff:ff:ff:ff", src="aa:aa:aa:aa:aa:aa"))

        pkt.add_protocol(ipv4.ipv4(dst="0.0.0.2", src="0.0.0.1", proto=1))

        pkt.add_protocol(
            icmp.icmp(
                type_=8,
                code=0,
                csum=0,
                data=icmp.echo(1, 1, "{'dpid' : " + str(dp.id) + ",'port_out' : " + str(port_out) + "}"),
            )
        )
        pkt.serialize()
        data = pkt.data
        actions = [parser.OFPActionOutput(port_out, 0)]
        out = parser.OFPPacketOut(
            datapath=dp, buffer_id=ofp.OFP_NO_BUFFER, in_port=ofp.OFPP_CONTROLLER, actions=actions, data=data
        )
        dp.send_msg(out)
    def _ping(self, dp, port_out, ip_src=DISCOVERY_IP_SRC, ip_dst=DISCOVERY_IP_DST, 
              eth_src='02:b0:00:00:00:b5', eth_dst='02:bb:bb:bb:bb:bb',
              icmp_type=8, icmp_code=0):
        ofp = dp.ofproto
        parser = dp.ofproto_parser
        pkt = packet.Packet()
        pkt.add_protocol(ethernet.ethernet(ethertype=0x0800,
                                           dst=eth_dst,
                                           src=eth_src))

        pkt.add_protocol(ipv4.ipv4(dst=ip_dst,
                                   src=ip_src,
                                   proto=1))

        pkt.add_protocol(icmp.icmp(type_=icmp_type,
                                   code=icmp_code,
                                   csum=0,
                                   data=icmp.echo(1,1,"{'dpid' : "+str(dp.id)+",'port_out' : "+str(port_out)+"}")))
        pkt.serialize()
        data=pkt.data
        actions=[parser.OFPActionOutput(port_out,0)]
        out=parser.OFPPacketOut(datapath=dp, buffer_id=ofp.OFP_NO_BUFFER, in_port=ofp.OFPP_CONTROLLER, actions=actions, data=data)
        dp.send_msg(out)
Ejemplo n.º 56
0
    def trigger_host_discovery(self):
        # In order to enable active host discovery
        # net.ipv4.icmp_echo_ignore_broadcasts should be set to 0
        icmp_packet = packet.Packet()
        icmp_packet.add_protocol(ethernet.ethernet(
            src=HOST_DIS_ETH_SRC,
            dst=HOST_DIS_ETH_DST))
        icmp_packet.add_protocol(ipv4.ipv4(
            dst=HOST_DIS_IP_DST,
            src=HOST_DIS_IP_SRC,
            proto=inet.IPPROTO_ICMP))
        icmp_packet.add_protocol(icmp.icmp(data=icmp.echo()))
        icmp_packet.serialize()

        for dpid, out_port in self.get_flood_ports():
            dp = self.dpset.get(dpid)
            actions = [dp.ofproto_parser.OFPActionOutput(out_port)]
            out = dp.ofproto_parser.OFPPacketOut(
                    datapath=dp,
                    buffer_id=dp.ofproto.OFP_NO_BUFFER,
                    in_port=dp.ofproto.OFPP_CONTROLLER,
                    actions=actions,
                    data=icmp_packet.data)
            dp.send_msg(out)
Ejemplo n.º 57
0
 def handle_icmp(self,msg,pkt,icmp_pkt):
     dpid = msg.datapath.id
     datapath = msg.datapath
     if icmp_pkt.type != ICMP_ECHO_REQUEST:
        # need forward packet
        return
     eth_layer = self.find_packet(pkt, 'ethernet')
     print vars(eth_layer) 
     ip_layer = self.find_packet(pkt,'ipv4')
     ipDestAddr = netaddr.IPAddress(ip_layer.dst)
     port_in = msg.match['in_port']
     if self.routers[dpid].ports[port_in].ip_addr == str(ipDestAddr):
        
        pkt = packet.Packet()
        print self.routers[dpid].ports[port_in].mac_addr
        print eth_layer.src
        pkt.add_protocol(ethernet.ethernet(ethertype=eth_layer.ethertype,
                                      dst=eth_layer.src,
                                      src=self.routers[dpid].ports[port_in].mac_addr))
        pkt.add_protocol(ipv4.ipv4(dst=ip_layer.src,
                              src=self.routers[dpid].ports[port_in].ip_addr,
                              proto=ip_layer.proto))
        pkt.add_protocol(icmp.icmp(type_=icmp.ICMP_ECHO_REPLY,
                              code=icmp.ICMP_ECHO_REPLY_CODE,
                              csum=0,
                              data=icmp_pkt.data))
        pkt.serialize()
        data = pkt.data
        actions = [datapath.ofproto_parser.OFPActionOutput(port_in)]
        out = datapath.ofproto_parser.OFPPacketOut(datapath=datapath,
                             buffer_id=datapath.ofproto.OFP_NO_BUFFER,
                             in_port=datapath.ofproto.OFPP_CONTROLLER,
                             actions=actions,
                             data=data)  
        datapath.send_msg(out)
        logger.info('send reply icmp to : %s ',ip_layer.src)
Ejemplo n.º 58
0
                               in_port=ofproto.OFPP_CONTROLLER,
                               actions=actions,
                               data=data)
                     datapath.send_msg(out)
                     
 def ICMPPacket(self, datapath, in_port, pkt_ethernet, pkt_ipv4, pkt_icmp):
     if pkt_icmp.type == icmp.ICMP_ECHO_REQUEST:
         eer=ethernet.ethernet(ethertype=pkt_ethernet.ethertype,
                     dst=pkt_ethernet.src,
                     src=self.interfaces_virtuales[self.tabla_vlan[in_port]][0])
                     
         iper=ipv4.ipv4(dst=pkt_ipv4.src,
                 src=self.interfaces_virtuales[self.tabla_vlan[in_port]][2],
                 proto=pkt_ipv4.proto)
                 
         icmper=icmp.icmp(type_=icmp.ICMP_ECHO_REPLY,
                 code=icmp.ICMP_ECHO_REPLY_CODE,
                 csum=0,
                 data=pkt_icmp.data)
         p = packet.Packet()
         p.add_protocol(eer)
         p.add_protocol(iper)
         p.add_protocol(icmper)
 
         self.send_packet(datapath, in_port, p)
         
 def paquete_para_enrutar(self, ev):
   
     msg = ev.msg               # Objeto que representa la estuctura de datos PacketIn.
     datapath = msg.datapath    # Identificador del datapath correspondiente al switch.
     ofproto = datapath.ofproto # Protocolo utilizado que se fija en una etapa 
Ejemplo n.º 59
0
    def _packet_in_handler(self, ev):
        msg = ev.msg
        in_port  = msg.in_port
        datapath = msg.datapath
        ofproto = datapath.ofproto
        dpid = datapath.id
        print 'mac_to_port',self.mac_to_port,'\n'       
        self.mac_to_port.setdefault(dpid, {})
        print 'mac_to_port',self.mac_to_port,'\n'
       
        dst, src, _eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0)
        LOG.info("packet in %s %s %s %s",
                 dpid, haddr_to_str(src), haddr_to_str(dst), msg.in_port)

        if _eth_type == ether.ETH_TYPE_ARP:
            #if dst in self.port_to_switch_mac[dpid]:
            arp_pkt = self.find_packet(msg,'arp')
            if arp_pkt != None:
                dst_ip = arp_pkt.dst_ip
                src_ip = arp_pkt.src_ip
                
                self.port_to_ip.setdefault(dpid,{})
                self.port_to_ip[dpid][in_port] = (src_ip & 0Xffffff00) + 0xfe

                if dst_ip == self.port_to_ip[dpid][in_port]:
                    src_mac = self.port_to_switch_mac[dpid][in_port]
                
                    e = ethernet.ethernet(src,self.port_to_switch_mac[dpid][in_port],ether.ETH_TYPE_ARP)
                    if arp_pkt.opcode == arp.ARP_REQUEST:
                        opcode = arp.ARP_REPLY 
                    #else:
                        #opcode = arp.ARP_REV_REPLY
                    a = arp.arp(hwtype = 1,proto = 0x0800, hlen = 6, plen = 4, opcode = opcode,
                        src_mac = src_mac,src_ip = arp_pkt.dst_ip,
                        dst_mac = arp_pkt.src_mac, dst_ip = arp_pkt.src_ip)
                    p = Packet()
                    p.add_protocol(e)
                    p.add_protocol(a) 
                    p.serialize()             
                                    
                    datapath.send_packet_out(in_port=ofproto_v1_0.OFPP_NONE,actions=[datapath.ofproto_parser.OFPActionOutput(in_port)],data=p.data)

                    print "arp request packet's dst_mac is ",haddr_to_str(self.port_to_switch_mac[dpid][in_port])
                    


        
        if _eth_type == ether.ETH_TYPE_IP:
            ip_pkt = self.find_packet(msg,'ipv4')
            #to judge if the ip packet contains icmp protocol
            #print 'lee 0'
            if ip_pkt.proto == 1:
                icmp_pkt = self.find_packet(msg,'icmp')
                if icmp_pkt.type == icmp.ICMP_ECHO_REQUEST:
                    ip_src = ip_pkt.src
                    ip_dst = ip_pkt.dst

                    echo_id = icmp_pkt.data.id
                    echo_seq = icmp_pkt.data.seq
                    echo_data = bytearray(icmp_pkt.data.data)

                    icmp_data = icmp.echo(id_=echo_id,seq=echo_seq,data=echo_data)
                    
                    self.port_to_ip.setdefault(dpid, {})
                    #mask is 24 bit
                    self.port_to_ip[dpid][in_port] = (ip_src & 0Xffffff00) + 0xfe
                    #print 'lee 1'
                    if self.port_to_ip[dpid][in_port] == ip_dst:
                        #send a echo reply packet  
                        ether_dst = src
                        ether_src = self.port_to_switch_mac[dpid][in_port]
                        e = ethernet.ethernet(ether_dst,ether_src,ether.ETH_TYPE_IP)
                        #csum calculation should be paied attention
                        #ic = icmp.icmp(type_= 0,code=0,csum=0,data=icmp_pkt.data)
                        i = ipv4.ipv4(version=4,header_length=5,tos=0,total_length=0,
                            identification=0,flags=0x000,offset=0,ttl=64,proto=1,csum=0,src=ip_dst,
                            dst=ip_src,option=None)

                        ic = icmp.icmp(type_= 0,code=0,csum=0,data=icmp_data)
                        p = Packet()
                        p.add_protocol(e)
                        p.add_protocol(i)
                        p.add_protocol(ic) 
                        p.serialize()                       
                        datapath.send_packet_out(in_port=ofproto_v1_0.OFPP_NONE,actions=[datapath.ofproto_parser.OFPActionOutput(in_port)],data=p.data)
                        print 'send a ping replay'                        
                    else:
                        pass
        
        if _eth_type == ether.ETH_TYPE_IPV6:
            ipv6_pkt = self.find_packet(msg,'ipv6')
            #don't care about ipv6's extention header
            icmpv6_pkt = self.find_packet(msg,'icmpv6')
            if icmpv6_pkt != None:
                if icmpv6_pkt.type_ == icmpv6.ND_NEIGHBOR_SOLICIT:

                    self.port_to_ipv6.setdefault(dpid,{})
                    #self.port_to_ipv6[dpid][in_port]=hexlify(((ipv6_pkt.src & (1<<128))-(1<<64)) + (1<<64) - 2)
                    self.port_to_ipv6[dpid][in_port]=struct.pack('!4I',0x100000,0x0,0xffffffff,0xfffffffd)
                    
                    if icmpv6_pkt.data.dst == self.port_to_ipv6[dpid][in_port]:
                           
                        #send a ND_NEIGHBOR_REPLY packet
                        ether_dst = src
                        ether_src = self.port_to_switch_mac[dpid][in_port]
                        e = ethernet.ethernet(ether_dst,ether_src,ether.ETH_TYPE_IPV6)
                        
                        ic6_data_data = icmpv6.nd_option_la(hw_src=self.port_to_switch_mac[dpid][in_port],data=None)
                        #res = 3 or 7
                        ic6_data = icmpv6.nd_neighbor(res=3,dst=icmpv6_pkt.data.dst,type_=icmpv6.nd_neighbor.ND_OPTION_TLA,length=1,data=ic6_data_data)
                        ic6 = icmpv6.icmpv6(type_=icmpv6.ND_NEIGHBOR_ADVERT,code=0,csum=0,data=ic6_data)  
                        #payload_length
                        i6 = ipv6.ipv6(version= 6,traffic_class=0,flow_label=0,payload_length=32,nxt=58,hop_limit=255,
                            src=icmpv6_pkt.data.dst,dst=ipv6_pkt.src) 
                        p = Packet()
                        p.add_protocol(e)
                        p.add_protocol(i6)
                        p.add_protocol(ic6) 
                        p.serialize() 
                        datapath.send_packet_out(in_port=ofproto_v1_0.OFPP_NONE,actions=[datapath.ofproto_parser.OFPActionOutput(in_port)],data=p.data)
                        print 'send a NA packet'
                        
                
                if icmpv6_pkt.type_ == icmpv6.ICMPV6_ECHO_REQUEST:
                    if self.port_to_ipv6[dpid].has_key(in_port):
                       
                    #print hexlify(self.port_to_ipv6[dpid][in_port])
                    #print 'ipv6_pkt.dst is',hexlify(ipv6_pkt.dst)
                    #print 'ipv6_pkt.dst is',hexlify(ipv6_pkt.dst)                  
                        if ipv6_pkt.dst == self.port_to_ipv6[dpid][in_port]:
                            ether_dst = src
                            ether_src = self.port_to_switch_mac[dpid][in_port]
                            e = ethernet.ethernet(ether_dst,ether_src,ether.ETH_TYPE_IPV6)
                            ic6_data = icmpv6_pkt.data
                            ic6 = icmpv6.icmpv6(type_=icmpv6.ICMPV6_ECHO_REPLY,code=0,csum=0,data=ic6_data)
                            i6 = ipv6.ipv6(version= 6,traffic_class=0,flow_label=0,payload_length=64,nxt=58,hop_limit=64,
                                src=ipv6_pkt.dst,dst=ipv6_pkt.src)
                            p = Packet()
                            p.add_protocol(e)
                            p.add_protocol(i6)
                            p.add_protocol(ic6) 
                            p.serialize() 
                            datapath.send_packet_out(in_port=ofproto_v1_0.OFPP_NONE,actions=[datapath.ofproto_parser.OFPActionOutput(in_port)],data=p.data)
                            print 'send a ping6 reply packet'


                                        
                    

        # learn a mac address to avoid FLOOD next time.
        self.mac_to_port[dpid][src] = msg.in_port

        if dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][dst]
        else:
            out_port = ofproto.OFPP_FLOOD

        actions = [datapath.ofproto_parser.OFPActionOutput(out_port)]
        if out_port != ofproto.OFPP_FLOOD:
            if _eth_type == ether.ETH_TYPE_IP:
                self.add_flow(datapath, msg.in_port, dst, actions)        
            #add a ipv6 flow table pay attention ipv6_flow entry only be added once when ipv4 flow entry is added       
            elif _eth_type == ether.ETH_TYPE_IPV6:

                '''
                # judge if src and dst addr is special 
                # eg: src [0,0,0,0] dst begin with 0xff01 or 0x ff02 
                if ipv6_src == [0,0,0,0] or ipv6_dst[0]&0xff010000 == 0xff010000 or ipv6_dst[0]&0xff020000 == 0xff020000:
                    print 'ipv6 reserved address\n' 
                #elif ipv6_dst[0]&0xfe800000 == 0xfe800000:
                #    print 'ipv6 dst address is Link-Local address'
                else:
                '''     
                
                ipv6_pkt = self.find_packet(msg,'ipv6')
                #ipv6_src=struct.pack('!4I',self._binary_to_ipv6_format(ipv6_packet.src))
                #ipv6_dst=struct.pack('!4I',self._binary_to_ipv6_format(ipv6_packet.dst))
                ipv6_src = convert.bin_to_ipv6_arg_list(ipv6_pkt.src)
                ipv6_dst = convert.bin_to_ipv6_arg_list(ipv6_pkt.dst)
                """
                ipv6_src = struct.pack('!4I',int(hexlify(ipv6_pkt.src)[0:8],16),int(hexlify(ipv6_pkt.src)[8:16],16),int(hexlify(ipv6_pkt.src)[16:24],16),int(hexlify(ipv6_pkt.src)[24:32],16))
                ipv6_dst = struct.pack('!4I',int(hexlify(ipv6_pkt.dst)[0:8],16),int(hexlify(ipv6_pkt.dst)[8:16],16),int(hexlify(ipv6_pkt.dst)[16:24],16),int(hexlify(ipv6_pkt.dst)[24:32],16))
                """   
                rule={'ipv6_src':ipv6_src,'ipv6_dst':ipv6_dst}
                self.nx_ipv6_add_flow(datapath,rule,actions)
                print 'add a ipv6 flow entry'  
            else:
                pass
          
        out = datapath.ofproto_parser.OFPPacketOut(
            datapath=datapath, buffer_id=msg.buffer_id, in_port=msg.in_port,
            actions=actions)
        datapath.send_msg(out)