Example #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
Example #2
0
def nd_advert(vid, eth_src, eth_dst, src_ip, dst_ip):
    """Return IPv6 neighbor avertisement 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.
    Returns:
        ryu.lib.packet.ethernet: Serialized IPv6 neighbor discovery packet.
    """
    pkt = build_pkt_header(vid, eth_src, eth_dst, valve_of.ether.ETH_TYPE_IPV6)
    ipv6_icmp6 = ipv6.ipv6(src=src_ip,
                           dst=dst_ip,
                           nxt=valve_of.inet.IPPROTO_ICMPV6,
                           hop_limit=IPV6_MAX_HOP_LIM)
    pkt.add_protocol(ipv6_icmp6)
    icmpv6_nd_advert = icmpv6.icmpv6(
        type_=icmpv6.ND_NEIGHBOR_ADVERT,
        data=icmpv6.nd_neighbor(dst=src_ip,
                                option=icmpv6.nd_option_tla(hw_src=eth_src),
                                res=7))
    pkt.add_protocol(icmpv6_nd_advert)
    pkt.serialize()
    return pkt
Example #3
0
def nd_request(vid, eth_src, eth_dst, src_ip, dst_ip):
    """Return IPv6 neighbor discovery request packet.

    Args:
        vid (int or None): VLAN VID to use (or None).
        eth_src (str): source Ethernet MAC address.
        eth_dst (str): Ethernet destination address.
        src_ip (ipaddress.IPv6Address): source IPv6 address.
        dst_ip (ipaddress.IPv6Address): requested IPv6 address.
    Returns:
        ryu.lib.packet.ethernet: Serialized IPv6 neighbor discovery packet.
    """
    if mac_addr_is_unicast(eth_dst):
        nd_mac = eth_dst
        nd_ip = dst_ip
    else:
        nd_mac = ipv6_link_eth_mcast(dst_ip)
        nd_ip = ipv6_solicited_node_from_ucast(dst_ip)
    pkt = build_pkt_header(vid, eth_src, nd_mac, valve_of.ether.ETH_TYPE_IPV6)
    ipv6_pkt = ipv6.ipv6(src=str(src_ip),
                         dst=nd_ip,
                         nxt=valve_of.inet.IPPROTO_ICMPV6)
    pkt.add_protocol(ipv6_pkt)
    icmpv6_pkt = icmpv6.icmpv6(
        type_=icmpv6.ND_NEIGHBOR_SOLICIT,
        data=icmpv6.nd_neighbor(dst=dst_ip,
                                option=icmpv6.nd_option_sla(hw_src=eth_src)))
    pkt.add_protocol(icmpv6_pkt)
    pkt.serialize()
    return pkt
Example #4
0
 def packet_in_handler(self, event):
     if event.msg.match['in_port'] != FAKEPORT:
         return
     pkt = packet.Packet(event.msg.data)
     eth_protocol = pkt.get_protocol(ethernet.ethernet)
     vlan_protocol = pkt.get_protocol(vlan.vlan)
     ipv6_protocol = pkt.get_protocol(ipv6.ipv6)
     icmpv6_protocol = pkt.get_protocol(icmpv6.icmpv6)
     if not (eth_protocol and vlan_protocol and ipv6_protocol
             and icmpv6_protocol):
         return
     if icmpv6_protocol.type_ != icmpv6.ND_NEIGHBOR_SOLICIT:
         return
     if int(ipaddress.ip_address(ipv6_protocol.src)) == 0:
         return
     src_ip = ipaddress.ip_address(icmpv6_protocol.data.dst)
     if src_ip.is_reserved:
         return
     eth_dst = eth_protocol.src
     dst_ip = ipv6_protocol.src
     eth_src = FAKECLIENTMAC
     vid = vlan_protocol.vid
     reply = packet.Packet()
     for protocol in (ethernet.ethernet(eth_dst, eth_src,
                                        ether.ETH_TYPE_8021Q),
                      vlan.vlan(vid=vid, ethertype=ether.ETH_TYPE_IPV6),
                      ipv6.ipv6(src=src_ip,
                                dst=dst_ip,
                                nxt=socket.IPPROTO_ICMPV6,
                                hop_limit=255),
                      icmpv6.icmpv6(
                          type_=icmpv6.ND_NEIGHBOR_ADVERT,
                          data=icmpv6.nd_neighbor(
                              dst=src_ip,
                              option=icmpv6.nd_option_tla(hw_src=eth_src),
                              res=7))):
         reply.add_protocol(protocol)
     reply.serialize()
     out = parser.OFPPacketOut(datapath=event.msg.datapath,
                               buffer_id=ofp.OFP_NO_BUFFER,
                               in_port=ofp.OFPP_CONTROLLER,
                               actions=[parser.OFPActionOutput(FAKEPORT)],
                               data=reply.data)
     self.send_mods(event.msg.datapath, [out])
Example #5
0
    def test_smoke_packet_in(self):
        nd_solicit = packet.Packet()
        eth_src = '01:02:03:04:05:06'
        eth_dst = 'ff:ff:ff:ff:ff:ff'
        src_ip = 'fc00::1'
        dst_ip = 'fc00::2'
        vid = 2
        for protocol in (ethernet.ethernet(eth_dst, eth_src,
                                           ether.ETH_TYPE_8021Q),
                         vlan.vlan(vid=vid, ethertype=ether.ETH_TYPE_IPV6),
                         ipv6.ipv6(src=src_ip,
                                   dst=dst_ip,
                                   nxt=socket.IPPROTO_ICMPV6,
                                   hop_limit=255),
                         icmpv6.icmpv6(
                             type_=icmpv6.ND_NEIGHBOR_SOLICIT,
                             data=icmpv6.nd_neighbor(
                                 dst=src_ip,
                                 option=icmpv6.nd_option_tla(hw_src=eth_src),
                                 res=7))):
            nd_solicit.add_protocol(protocol)
        nd_solicit.serialize()

        fake_dp = FakeDP()
        fake_pipette = Pipette(dpset={})

        class FakeMsg:
            def __init__(self):
                self.datapath = fake_dp
                self.match = {'in_port': FAKEPORT}
                self.data = nd_solicit.data

        class FakePiEv:
            def __init__(self):
                self.msg = FakeMsg()

        fake_pipette = Pipette(dpset={})
        fake_pipette.packet_in_handler(FakePiEv())
        assert fake_dp.msgs
Example #6
0
def router_advert(vid, eth_src, eth_dst, src_ip, dst_ip, vips, pi_flags=0x6):
    """Return IPv6 ICMP Router Advert.

    Args:
        vid (int or None): VLAN VID to use (or None).
        eth_src (str): source Ethernet MAC address.
        eth_dst (str): dest Ethernet MAC address.
        src_ip (ipaddress.IPv6Address): source IPv6 address.
        vips (list): prefixes (ipaddress.IPv6Address) to advertise.
        pi_flags (int): flags to set in prefix information field (default set A and L)
    Returns:
        ryu.lib.packet.ethernet: Serialized IPv6 ICMP RA packet.
    """
    pkt = build_pkt_header(vid, eth_src, eth_dst, valve_of.ether.ETH_TYPE_IPV6)
    ipv6_pkt = ipv6.ipv6(src=src_ip,
                         dst=dst_ip,
                         nxt=valve_of.inet.IPPROTO_ICMPV6,
                         hop_limit=IPV6_MAX_HOP_LIM)
    pkt.add_protocol(ipv6_pkt)
    options = []
    for vip in vips:
        options.append(
            icmpv6.nd_option_pi(
                prefix=vip.network.network_address,
                pl=vip.network.prefixlen,
                res1=pi_flags,
                val_l=86400,
                pre_l=14400,
            ))
    options.append(icmpv6.nd_option_sla(hw_src=eth_src))
    # https://tools.ietf.org/html/rfc4861#section-4.6.2
    icmpv6_ra_pkt = icmpv6.icmpv6(type_=icmpv6.ND_ROUTER_ADVERT,
                                  data=icmpv6.nd_router_advert(
                                      rou_l=1800,
                                      ch_l=IPV6_RA_HOP_LIM,
                                      options=options))
    pkt.add_protocol(icmpv6_ra_pkt)
    pkt.serialize()
    return pkt