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 ""
Example #2
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
    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
Example #4
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)
Example #5
0
    def test_default_args(self):
        ec = icmp.echo()
        buf = ec.serialize()
        res = struct.unpack(icmp.echo._PACK_STR, six.binary_type(buf))

        eq_(res[0], 0)
        eq_(res[1], 0)
Example #6
0
    def test_default_args(self):
        ec = icmp.echo()
        buf = ec.serialize()
        res = struct.unpack(icmp.echo._PACK_STR, six.binary_type(buf))

        eq_(res[0], 0)
        eq_(res[1], 0)
Example #7
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)
Example #8
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 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 ""
Example #10
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)
    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
Example #12
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)
Example #13
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)
Example #14
0
 def setUp(self):
     self.id_ = 13379
     self.seq = 1
     self.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.echo = icmp.echo(self.id_, self.seq, self.data)
     self.buf = struct.pack('!HH', self.id_, self.seq)
     self.buf += self.data
Example #15
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)
Example #16
0
 def setUp(self):
     self.id_ = 13379
     self.seq = 1
     self.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.echo = icmp.echo(
         self.id_, self.seq, self.data)
     self.buf = struct.pack('!HH', self.id_, self.seq)
     self.buf += self.data
Example #17
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
Example #18
0
 def setUp(self):
     self.id_ = 13379
     self.seq = 1
     self.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.echo = icmp.echo(self.id_, self.seq, self.data)
     self.buf = struct.pack("!HH", self.id_, self.seq)
     self.buf += self.data
    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,) )  
Example #20
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
Example #21
0
    def packet_in_handler(self, ev):
        msg = ev.msg
        dp = msg.datapath

        pkt = packet.Packet(array.array('B', msg.data))
        p_arp = self._find_protocol(pkt, "arp")
        p_icmp = self._find_protocol(pkt, "icmp")
        p_ipv4 = self._find_protocol(pkt, "ipv4")

        if p_arp:
            src_ip = str(netaddr.IPAddress(p_arp.src_ip))
            dst_ip = str(netaddr.IPAddress(p_arp.dst_ip))
            if p_arp.opcode == arp.ARP_REQUEST:
                LOG.debug("--- PacketIn: ARP_Request: %s->%s", src_ip, dst_ip)
                if p_arp.dst_ip == self.RYU_IP:
                    LOG.debug("--- send Pkt: ARP_Reply")
                    data = self._arp_reply()
                    self._send_msg(dp, data)
                elif p_arp.dst_ip == self.HOST_IP:
                    LOG.debug("    PacketIn: GARP")
                    LOG.debug("--- send Pkt: ARP_Request")
                    data = self._arp_request()
                    self._send_msg(dp, data)
            elif p_arp.opcode == arp.ARP_REPLY:
                LOG.debug("--- PacketIn: ARP_Reply: %s->%s", src_ip, dst_ip)
                LOG.debug("--- send Pkt: Echo_Request")
                echo = icmp.echo(id_=66, seq=1)
                data = self._echo_request(echo)
                self._send_msg(dp, data)

        if p_icmp:
            src = str(netaddr.IPAddress(p_ipv4.src))
            dst = str(netaddr.IPAddress(p_ipv4.dst))
            if p_icmp.type == icmp.ICMP_ECHO_REQUEST:
                LOG.debug("--- PacketIn: Echo_Request: %s->%s", src, dst)
                if p_ipv4.dst == self.RYU_IP:
                    LOG.debug("--- send Pkt: Echo_Reply")
                    echo = p_icmp.data
                    echo.data = bytearray(echo.data)
                    data = self._echo_reply(echo)
                    self._send_msg(dp, data)
            elif p_icmp.type == icmp.ICMP_ECHO_REPLY:
                LOG.debug("--- PacketIn: Echo_Reply: %s->%s", src, dst)
    def packet_in_handler(self, ev):
        msg = ev.msg
        dp = msg.datapath

        pkt = packet.Packet(array.array('B', msg.data))
        p_arp = self._find_protocol(pkt, "arp")
        p_icmp = self._find_protocol(pkt, "icmp")
        p_ipv4 = self._find_protocol(pkt, "ipv4")

        if p_arp:
            src_ip = str(netaddr.IPAddress(p_arp.src_ip))
            dst_ip = str(netaddr.IPAddress(p_arp.dst_ip))
            if p_arp.opcode == arp.ARP_REQUEST:
                LOG.debug("--- PacketIn: ARP_Request: %s->%s", src_ip, dst_ip)
                if p_arp.dst_ip == self.RYU_IP:
                    LOG.debug("--- send Pkt: ARP_Reply")
                    data = self._arp_reply()
                    self._send_msg(dp, data)
                elif p_arp.dst_ip == self.HOST_IP:
                    LOG.debug("    PacketIn: GARP")
                    LOG.debug("--- send Pkt: ARP_Request")
                    data = self._arp_request()
                    self._send_msg(dp, data)
            elif p_arp.opcode == arp.ARP_REPLY:
                LOG.debug("--- PacketIn: ARP_Reply: %s->%s", src_ip, dst_ip)
                LOG.debug("--- send Pkt: Echo_Request")
                echo = icmp.echo(id_=66, seq=1)
                data = self._echo_request(echo)
                self._send_msg(dp, data)

        if p_icmp:
            src = str(netaddr.IPAddress(p_ipv4.src))
            dst = str(netaddr.IPAddress(p_ipv4.dst))
            if p_icmp.type == icmp.ICMP_ECHO_REQUEST:
                LOG.debug("--- PacketIn: Echo_Request: %s->%s", src, dst)
                if p_ipv4.dst == self.RYU_IP:
                    LOG.debug("--- send Pkt: Echo_Reply")
                    echo = p_icmp.data
                    echo.data = bytearray(echo.data)
                    data = self._echo_reply(echo)
                    self._send_msg(dp, data)
            elif p_icmp.type == icmp.ICMP_ECHO_REPLY:
                LOG.debug("--- PacketIn: Echo_Reply: %s->%s", src, dst)
Example #23
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)
Example #24
0
    def setUp_with_echo(self):
        self.echo_id = 13379
        self.echo_seq = 1
        self.echo_data = '\x30\x0e\x09\x00\x00\x00\x00\x00' \
            + '\x10\x11\x12\x13\x14\x15\x16\x17' \
            + '\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f' \
            + '\x20\x21\x22\x23\x24\x25\x26\x27' \
            + '\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f' \
            + '\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 = 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)
Example #25
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)
Example #26
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
    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)
Example #28
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)
Example #29
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)
    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
Example #31
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
Example #32
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)