Beispiel #1
0
def icmpv6_echo_reply(vid, eth_src, eth_dst, src_ip, dst_ip, hop_limit,
                      id_, seq, data):
    r"""Return IPv6 ICMP echo reply packet.

        Args:
            vid (int or None): VLAN VID to use (or None).
            eth_src (str): source Ethernet MAC address.
            eth_dst (str): destination Ethernet MAC address.
            src_ip (ipaddress.IPv6Address): source IPv6 address.
            dst_ip (ipaddress.IPv6Address): destination IPv6 address.
            hop_limit (int): IPv6 hop limit.
            id_ (int): identifier for echo reply.
            seq (int): sequence number for echo reply.
            data (str): payload for echo reply.
        Returns:
            ryu.lib.packet.ethernet: Serialized IPv6 ICMP echo reply packet.
    """
    pkt = build_pkt_header(
        vid, eth_src, eth_dst, valve_of.ether.ETH_TYPE_IPV6)
    ipv6_reply = ipv6.ipv6(
        src=src_ip,
        dst=dst_ip,
        nxt=valve_of.inet.IPPROTO_ICMPV6,
        hop_limit=hop_limit)
    pkt.add_protocol(ipv6_reply)
    icmpv6_reply = icmpv6.icmpv6(
        type_=icmpv6.ICMPV6_ECHO_REPLY,
        data=icmpv6.echo(id_=id_, seq=seq, data=data))
    pkt.add_protocol(icmpv6_reply)
    pkt.serialize()
    return pkt
Beispiel #2
0
def icmpv6_echo_reply(eth_src, eth_dst, vid, src_ip, dst_ip, hop_limit,
                      id_, seq, data):
    """Return IPv6 ICMP echo reply packet.

    Args:
        eth_src (str): source Ethernet MAC address.
        eth_dst (str): destination Ethernet MAC address.
        vid (int or None): VLAN VID to use (or None).
        src_ip (ipaddr.IPv6Address): source IPv6 address.
        dst_ip (ipaddr.IPv6Address): destination IPv6 address.
        hop_limit (int): IPv6 hop limit.
        id_ (int): identifier for echo reply.
        seq (int): sequence number for echo reply.
        data (str): payload for echo reply.
    Returns:
        ryu.lib.packet.ethernet: Serialized IPv6 ICMP echo reply packet.
    """
    pkt = build_pkt_header(
        eth_src, eth_dst, vid, ether.ETH_TYPE_IPV6)
    ipv6_reply = ipv6.ipv6(
        src=src_ip,
        dst=dst_ip,
        nxt=inet.IPPROTO_ICMPV6,
        hop_limit=hop_limit)
    pkt.add_protocol(ipv6_reply)
    icmpv6_reply = icmpv6.icmpv6(
        type_=icmpv6.ICMPV6_ECHO_REPLY,
        data=icmpv6.echo(id_=id_, seq=seq, data=data))
    pkt.add_protocol(icmpv6_reply)
    pkt.serialize()
    return pkt
Beispiel #3
0
    def test_to_string(self):
        ec = icmpv6.echo(self.id_, self.seq, self.data)
        ic = icmpv6.icmpv6(self.type_, self.code, self.csum, ec)

        echo_values = {'id': self.id_, 'seq': self.seq, 'data': self.data}
        _echo_str = ','.join([
            '%s=%s' % (k, repr(echo_values[k]))
            for k, v in inspect.getmembers(ec) if k in echo_values
        ])
        echo_str = '%s(%s)' % (icmpv6.echo.__name__, _echo_str)

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

        eq_(str(ic), ic_str)
        eq_(repr(ic), ic_str)
Beispiel #4
0
    def control_plane_icmpv6_handler(self, in_port, vlan, eth_src,
                                     ipv6_pkt, icmpv6_pkt):
        flowmods = []
        pkt = self.build_ethernet_pkt(
            eth_src, in_port, vlan, ether.ETH_TYPE_IPV6)

        if icmpv6_pkt.type_ == icmpv6.ND_NEIGHBOR_SOLICIT:
            dst = icmpv6_pkt.data.dst
            ipv6_reply = ipv6.ipv6(
                src=dst,
                dst=ipv6_pkt.src,
                nxt=inet.IPPROTO_ICMPV6,
                hop_limit=ipv6_pkt.hop_limit)
            pkt.add_protocol(ipv6_reply)
            icmpv6_reply = icmpv6.icmpv6(
                type_=icmpv6.ND_NEIGHBOR_ADVERT,
                data=icmpv6.nd_neighbor(
                    dst=dst,
                    option=icmpv6.nd_option_tla(hw_src=self.FAUCET_MAC),
                        res=7))
            pkt.add_protocol(icmpv6_reply)
            pkt.serialize()
            flowmods.extend([self.valve_packetout(in_port, pkt.data)])
        elif icmpv6_pkt.type_ == icmpv6.ND_NEIGHBOR_ADVERT:
            resolved_ip_gw = ipaddr.IPv6Address(icmpv6_pkt.data.dst)
            self.logger.info('ND response %s for %s', eth_src, resolved_ip_gw)
            is_updated = None
            if resolved_ip_gw in vlan.nd_cache:
                cached_eth_dst = vlan.nd_cache[resolved_ip_gw].eth_src
                if cached_eth_dst != eth_src:
                    is_updated = True
            else:
                is_updated = False
            for ip_dst, ip_gw in vlan.ipv6_routes.iteritems():
                if ip_gw == resolved_ip_gw:
                    flowmods.extend(
                        self.add_resolved_route(
                            ether.ETH_TYPE_IPV6, vlan, vlan.nd_cache,
                            ip_gw, ip_dst, eth_src,is_updated))
        elif icmpv6_pkt.type_ == icmpv6.ICMPV6_ECHO_REQUEST:
            dst = ipv6_pkt.dst
            ipv6_reply = ipv6.ipv6(
                src=dst,
                dst=ipv6_pkt.src,
                nxt=inet.IPPROTO_ICMPV6,
                hop_limit=ipv6_pkt.hop_limit)
            pkt.add_protocol(ipv6_reply)
            icmpv6_reply = icmpv6.icmpv6(
                type_=icmpv6.ICMPV6_ECHO_REPLY,
                data=icmpv6.echo(
                    id_=icmpv6_pkt.data.id,
                    seq=icmpv6_pkt.data.seq,
                    data=icmpv6_pkt.data.data))
            pkt.add_protocol(icmpv6_reply)
            pkt.serialize()
            flowmods.extend([self.valve_packetout(in_port, pkt.data)])

        return flowmods
Beispiel #5
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)
Beispiel #6
0
    def control_plane_icmpv6_handler(self, in_port, vlan, eth_src,
                                     ipv6_pkt, icmpv6_pkt):
        flowmods = []
        pkt = self.build_ethernet_pkt(
            eth_src, in_port, vlan, ether.ETH_TYPE_IPV6)

        if icmpv6_pkt.type_ == icmpv6.ND_NEIGHBOR_SOLICIT:
            dst = icmpv6_pkt.data.dst
            ipv6_reply = ipv6.ipv6(
                src=dst,
                dst=ipv6_pkt.src,
                nxt=inet.IPPROTO_ICMPV6,
                hop_limit=ipv6_pkt.hop_limit)
            pkt.add_protocol(ipv6_reply)
            icmpv6_reply = icmpv6.icmpv6(
                type_=icmpv6.ND_NEIGHBOR_ADVERT,
                data=icmpv6.nd_neighbor(
                    dst=dst,
                    option=icmpv6.nd_option_tla(hw_src=self.FAUCET_MAC),
                        res=7))
            pkt.add_protocol(icmpv6_reply)
            pkt.serialize()
            flowmods.extend([self.valve_packetout(in_port, pkt.data)])
        elif icmpv6_pkt.type_ == icmpv6.ND_NEIGHBOR_ADVERT:
            resolved_ip_gw = ipaddr.IPv6Address(icmpv6_pkt.data.dst)
            for ip_dst, ip_gw in vlan.ipv6_routes.iteritems():
                if ip_gw == resolved_ip_gw:
                    self.logger.info('ND response %s for %s',
                        eth_src, resolved_ip_gw)
                    flowmods.extend(
                        self.add_resolved_route(
                            ether.ETH_TYPE_IPV6, vlan, vlan.nd_cache,
                            ip_gw, ip_dst, eth_src))
        elif icmpv6_pkt.type_ == icmpv6.ICMPV6_ECHO_REQUEST:
            dst = ipv6_pkt.dst
            ipv6_reply = ipv6.ipv6(
                src=dst,
                dst=ipv6_pkt.src,
                nxt=inet.IPPROTO_ICMPV6,
                hop_limit=ipv6_pkt.hop_limit)
            pkt.add_protocol(ipv6_reply)
            icmpv6_reply = icmpv6.icmpv6(
                type_=icmpv6.ICMPV6_ECHO_REPLY,
                data=icmpv6.echo(
                    id_=icmpv6_pkt.data.id,
                    seq=icmpv6_pkt.data.seq,
                    data=icmpv6_pkt.data.data))
            pkt.add_protocol(icmpv6_reply)
            pkt.serialize()
            flowmods.extend([self.valve_packetout(in_port, pkt.data)])

        return flowmods
Beispiel #7
0
    def ping_connected_hosts(self, datapath, wan_port):
        """
        This function will send an ICMPv6 ECHO REQUEST message to all the nodes of protected network.
        That will in turn, trigger a Neighbor Solicitation message to be received and the IPv6 destination
        address, will be the randomly generated LLU address of Janus.
        :param datapath: The datapath (represents the device used as a traffic normaliser (Janus))
        :param wan_port:  The port to send a message from. Use this as the in_port, to exclude from multicast
        """
        # Construct L2 header
        src_mac = generate_random_mac(
        )  # Generated randomly (can be seen that it is not factory default)
        dst_mac = '33:33:ff:ff:ff:ff'  # This is a multicast L2 address
        self.temporary_mac_id = "33:33:ff" + src_mac[-9:]
        layer2 = ethernet.ethernet(dst=dst_mac,
                                   src=src_mac,
                                   ethertype=ether_types.ETH_TYPE_IPV6)

        # Construct L3 header
        ip6_dst = 'ff02::1'  # well known multicast L3 address, as defined by IANA
        ip6_src = generate_llu_ipv6(src_mac)  # IPv6 Link Local Unicast address
        layer3 = ipv6.ipv6(nxt=inet.IPPROTO_ICMPV6, src=ip6_src, dst=ip6_dst)

        # Construct l4 header
        icmpv6_type = icmpv6.ICMPV6_ECHO_REQUEST
        layer4 = icmpv6.icmpv6(type_=icmpv6_type,
                               code=0,
                               csum=0,
                               data=icmpv6.echo())

        # Create packet
        pkt = packet.Packet()
        # layer 1 is automatically generated when packet.serialize() is called
        pkt.add_protocol(layer2)
        pkt.add_protocol(layer3)
        pkt.add_protocol(layer4)

        # Send packet to multicast addresses in protected network
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        pkt.serialize()
        data = pkt.data
        actions = [parser.OFPActionOutput(ofproto.OFPP_FLOOD)]
        out = parser.OFPPacketOut(datapath=datapath,
                                  buffer_id=ofproto.OFP_NO_BUFFER,
                                  actions=actions,
                                  data=data,
                                  in_port=wan_port)

        datapath.send_msg(out)
Beispiel #8
0
    def test_default_args(self):
        prev = ipv6(nxt=inet.IPPROTO_ICMPV6)
        ic = icmpv6.icmpv6(type_=icmpv6.ICMPV6_ECHO_REPLY, data=icmpv6.echo())
        prev.serialize(ic, None)
        buf = ic.serialize(bytearray(), prev)
        res = struct.unpack(icmpv6.icmpv6._PACK_STR, str(buf[:4]))

        eq_(res[0], icmpv6.ICMPV6_ECHO_REPLY)
        eq_(res[1], 0)
        eq_(res[2], icmpv6_csum(prev, buf))

        res = struct.unpack(icmpv6.echo._PACK_STR, str(buf[4:]))

        eq_(res[0], 0)
        eq_(res[1], 0)
    def test_default_args(self):
        prev = ipv6(nxt=inet.IPPROTO_ICMPV6)
        ic = icmpv6.icmpv6(
            type_=icmpv6.ICMPV6_ECHO_REPLY, data=icmpv6.echo())
        prev.serialize(ic, None)
        buf = ic.serialize(bytearray(), prev)
        res = struct.unpack(icmpv6.icmpv6._PACK_STR, str(buf[:4]))

        eq_(res[0], icmpv6.ICMPV6_ECHO_REPLY)
        eq_(res[1], 0)
        eq_(res[2], icmpv6_csum(prev, buf))

        res = struct.unpack(icmpv6.echo._PACK_STR, str(buf[4:]))

        eq_(res[0], 0)
        eq_(res[1], 0)
Beispiel #10
0
    def _test_serialize(self, echo_data=None):
        buf = self.buf + str(echo_data or "")
        src_ipv6 = netaddr.IPAddress("3ffe:507:0:1:200:86ff:fe05:80da").packed
        dst_ipv6 = netaddr.IPAddress("3ffe:501:0:1001::2").packed
        prev = ipv6(6, 0, 0, len(buf), 64, 255, src_ipv6, dst_ipv6)
        echo_csum = icmpv6_csum(prev, buf)

        echo = icmpv6.echo(self.id_, self.seq, echo_data)
        icmp = icmpv6.icmpv6(self.type_, self.code, 0, echo)
        buf = buffer(icmp.serialize(bytearray(), prev))

        (type_, code, csum) = struct.unpack_from(icmp._PACK_STR, buf, 0)
        (id_, seq) = struct.unpack_from(echo._PACK_STR, buf, icmp._MIN_LEN)
        data = buf[(icmp._MIN_LEN + echo._MIN_LEN) :]
        data = data if len(data) != 0 else None

        eq_(type_, self.type_)
        eq_(code, self.code)
        eq_(csum, echo_csum)
        eq_(id_, self.id_)
        eq_(seq, self.seq)
        eq_(data, echo_data)
Beispiel #11
0
    def _test_serialize(self, echo_data=None):
        buf = self.buf + str(echo_data or '')
        src_ipv6 = netaddr.IPAddress('3ffe:507:0:1:200:86ff:fe05:80da').packed
        dst_ipv6 = netaddr.IPAddress('3ffe:501:0:1001::2').packed
        prev = ipv6(6, 0, 0, len(buf), 64, 255, src_ipv6, dst_ipv6)
        echo_csum = icmpv6_csum(prev, buf)

        echo = icmpv6.echo(self.id_, self.seq, echo_data)
        icmp = icmpv6.icmpv6(self.type_, self.code, 0, echo)
        buf = buffer(icmp.serialize(bytearray(), prev))

        (type_, code, csum) = struct.unpack_from(icmp._PACK_STR, buf, 0)
        (id_, seq) = struct.unpack_from(echo._PACK_STR, buf, icmp._MIN_LEN)
        data = buf[(icmp._MIN_LEN + echo._MIN_LEN):]
        data = data if len(data) != 0 else None

        eq_(type_, self.type_)
        eq_(code, self.code)
        eq_(csum, echo_csum)
        eq_(id_, self.id_)
        eq_(seq, self.seq)
        eq_(data, echo_data)
Beispiel #12
0
    def test_to_string(self):
        ec = icmpv6.echo(self.id_, self.seq, self.data)
        ic = icmpv6.icmpv6(self.type_, self.code, self.csum, ec)

        echo_values = {'id': self.id_,
                       'seq': self.seq,
                       'data': self.data}
        _echo_str = ','.join(['%s=%s' % (k, repr(echo_values[k]))
                              for k, v in inspect.getmembers(ec)
                              if k in echo_values])
        echo_str = '%s(%s)' % (icmpv6.echo.__name__, _echo_str)

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

        eq_(str(ic), ic_str)
        eq_(repr(ic), ic_str)
Beispiel #13
0
 def test_init(self):
     echo = icmpv6.echo(0, 0)
     eq_(echo.id, 0)
     eq_(echo.seq, 0)
     eq_(echo.data, None)
Beispiel #14
0
 def test_init(self):
     echo = icmpv6.echo(0, 0)
     eq_(echo.id, 0)
     eq_(echo.seq, 0)
     eq_(echo.data, None)