Ejemplo n.º 1
0
    def _create_test_dhcp6_packet(self, zero_time=False):
        ret_pkt = packet.Packet()
        ret_pkt.add_protocol(
            ethernet.ethernet(
                ethertype=ether_types.ETH_TYPE_IPV6,
                dst='33:33:00:01:00:02',
                src=self.port_info['mac_address']))
        ret_pkt.add_protocol(
            ipv6.ipv6(
                src='fe80::f816:3eff:fe60:714b',
                dst='ff02::1:2',
                nxt=inet.IPPROTO_UDP))
        ret_pkt.add_protocol(
            udp.udp(
                src_port=constants.DHCPV6_RESPONSE_PORT,
                dst_port=constants.DHCPV6_CLIENT_PORT))

        options = [dhcp6.option(
            code=1,
            data=b"\x00\x01\x00\x01",
            length=4)]
        if zero_time:
            options.append(dhcp6.option(
                code=3,
                data=b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
                length=12))
        else:
            options.append(dhcp6.option(
                code=3,
                data=b"\x01\x02\x03\x04\x05\x06\x07\x08\x0a\x0b\x0c\x0d",
                length=12))
        ret_pkt.add_protocol(dhcp6.dhcp6(
            dhcp6.DHCPV6_REQUEST, dhcp6.options(option_list=options)))
        return ret_pkt
Ejemplo n.º 2
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
Ejemplo n.º 3
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
Ejemplo n.º 4
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
Ejemplo n.º 5
0
    def create_packet(self, primary_ip_address, vlan_id=None):
        """Prepare a VRRP packet.

        Returns a newly created os_ken.lib.packet.packet.Packet object
        with appropriate protocol header objects added by add_protocol().
        It's caller's responsibility to serialize().
        The serialized packet would looks like the ones described in
        the following sections.

        * RFC 3768 5.1. VRRP Packet Format
        * RFC 5798 5.1. VRRP Packet Format

        ================== ====================
        Argument           Description
        ================== ====================
        primary_ip_address Source IP address
        vlan_id            VLAN ID.  None for no VLAN.
        ================== ====================
        """
        if self.is_ipv6:
            traffic_class = 0xc0        # set tos to internetwork control
            flow_label = 0
            payload_length = ipv6.ipv6._MIN_LEN + len(self)     # XXX _MIN_LEN
            e = ethernet.ethernet(VRRP_IPV6_DST_MAC_ADDRESS,
                                  vrrp_ipv6_src_mac_address(self.vrid),
                                  ether.ETH_TYPE_IPV6)
            ip = ipv6.ipv6(6, traffic_class, flow_label, payload_length,
                           inet.IPPROTO_VRRP, VRRP_IPV6_HOP_LIMIT,
                           primary_ip_address, VRRP_IPV6_DST_ADDRESS)
        else:
            header_length = ipv4.ipv4._MIN_LEN // 4      # XXX _MIN_LEN
            total_length = 0
            tos = 0xc0  # set tos to internetwork control
            identification = self.get_identification()
            e = ethernet.ethernet(VRRP_IPV4_DST_MAC_ADDRESS,
                                  vrrp_ipv4_src_mac_address(self.vrid),
                                  ether.ETH_TYPE_IP)
            ip = ipv4.ipv4(4, header_length, tos, total_length, identification,
                           0, 0, VRRP_IPV4_TTL, inet.IPPROTO_VRRP, 0,
                           primary_ip_address, VRRP_IPV4_DST_ADDRESS)

        p = packet.Packet()
        p.add_protocol(e)
        if vlan_id is not None:
            vlan_ = vlan.vlan(0, 0, vlan_id, e.ethertype)
            e.ethertype = ether.ETH_TYPE_8021Q
            p.add_protocol(vlan_)
        p.add_protocol(ip)
        p.add_protocol(self)
        return p
Ejemplo n.º 6
0
    def get_ret_packet(self, packet_in, port_info, req_type):
        ip_info = self.get_port_ip(port_info,
                                   ip_version=constants.IP_VERSION_6)
        if not ip_info:
            return
        gateway_ip = ip_info['gateway_ip']
        mac = port_info['mac_address']

        header_eth = packet_in.get_protocol(ethernet.ethernet)
        header_ipv6 = packet_in.get_protocol(ipv6.ipv6)
        header_dhcp = packet_in.get_protocol(dhcp6.dhcp6)

        if req_type == 'CONFIRM':
            options = self.get_reply_dhcp_options(
                mac,
                message="all addresses still on link",
                req_options=header_dhcp.options.option_list)
        if req_type == 'RELEASE':
            options = self.get_reply_dhcp_options(
                mac,
                message="release received",
                req_options=header_dhcp.options.option_list)
        else:
            options = self.get_dhcp_options(mac, ip_info,
                                            header_dhcp.options.option_list,
                                            req_type)

        ret_pkt = packet.Packet()
        ret_pkt.add_protocol(
            ethernet.ethernet(ethertype=header_eth.ethertype,
                              dst=header_eth.src,
                              src=self.hw_addr))
        ret_pkt.add_protocol(
            ipv6.ipv6(src=gateway_ip,
                      dst=header_ipv6.src,
                      nxt=inet.IPPROTO_UDP))
        ret_pkt.add_protocol(
            udp.udp(src_port=constants.DHCPV6_RESPONSE_PORT,
                    dst_port=constants.DHCPV6_CLIENT_PORT))

        ret_type = self.get_ret_type(req_type)

        ret_pkt.add_protocol(
            dhcp6.dhcp6(ret_type,
                        options,
                        transaction_id=header_dhcp.transaction_id))

        return ret_pkt
Ejemplo n.º 7
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])
Ejemplo n.º 8
0
def decode(nfa):
    """This function analyses nflog packet by using os-ken packet library."""

    prefix = ffi.string(libnflog.nflog_get_prefix(nfa))
    packet_hdr = libnflog.nflog_get_msg_packet_hdr(nfa)
    hw_proto = socket.ntohs(packet_hdr.hw_protocol)

    msg = ''
    msg_packet_hwhdr = libnflog.nflog_get_msg_packet_hwhdr(nfa)
    if msg_packet_hwhdr != ffi.NULL:
        packet_hwhdr = ffi.string(msg_packet_hwhdr)
        if len(packet_hwhdr) >= 12:
            dst, src = struct.unpack_from('!6s6s', packet_hwhdr)
            # Dump ethernet packet to get mac addresses
            eth = ethernet.ethernet(addrconv.mac.bin_to_text(dst),
                                    addrconv.mac.bin_to_text(src),
                                    ethertype=hw_proto)
            msg = str(eth)

    # Dump IP packet
    pkt = _payload(nfa)
    if hw_proto == ether_types.ETH_TYPE_IP:
        ip_pkt, proto, data = ipv4.ipv4().parser(pkt)
        msg += str(ip_pkt)
        proto_pkt, a, b = proto.parser(data)
        msg += str(proto_pkt)
    elif hw_proto == ether_types.ETH_TYPE_IPV6:
        ip_pkt, proto, data = ipv6.ipv6().parser(pkt)
        proto_pkt, a, b = proto.parser(data)
        msg += str(proto_pkt)
    elif hw_proto == ether_types.ETH_TYPE_ARP:
        ip_pkt, proto, data = arp.arp().parser(pkt)
        msg += str(ip_pkt)
    else:
        msg += "Does not support hw_proto: " + str(hw_proto)

    return {
        'prefix': encodeutils.safe_decode(prefix),
        'msg': encodeutils.safe_decode(msg)
    }
Ejemplo n.º 9
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
Ejemplo n.º 10
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
Ejemplo n.º 11
0
    def test_serialize(self):
        src_ip = '2001:db8:2000::1'
        dst_ip = vrrp.VRRP_IPV6_DST_ADDRESS
        prev = ipv6.ipv6(6, 0, 0, 0, inet.IPPROTO_VRRP,
                         vrrp.VRRP_IPV6_HOP_LIMIT, src_ip, dst_ip)

        type_ = vrrp.VRRP_TYPE_ADVERTISEMENT
        vrid = 5
        priority = 10
        max_adver_int = 30
        ip_address = '2001:db8:2000::2'
        ip_addresses = [ip_address]

        vrrp_ = vrrp.vrrpv3.create(type_, vrid, priority, max_adver_int,
                                   ip_addresses)

        buf = vrrp_.serialize(bytearray(), prev)
        print(len(buf), type(buf), buf)
        pack_str = vrrp.vrrpv3._PACK_STR + '16s'
        pack_len = struct.calcsize(pack_str)
        res = struct.unpack(pack_str, six.binary_type(buf))
        eq_(res[0], vrrp.vrrp_to_version_type(vrrp.VRRP_VERSION_V3, type_))
        eq_(res[1], vrid)
        eq_(res[2], priority)
        eq_(res[3], len(ip_addresses))
        eq_(res[4], max_adver_int)
        # res[5] is checksum
        eq_(res[6], addrconv.ipv6.text_to_bin(ip_address))
        eq_(len(buf), pack_len)
        print(res)

        # checksum
        ph = struct.pack('!16s16sI3xB', addrconv.ipv6.text_to_bin(src_ip),
                         addrconv.ipv6.text_to_bin(dst_ip), pack_len,
                         inet.IPPROTO_VRRP)
        s = packet_utils.checksum(ph + buf)
        eq_(0, s)
Ejemplo n.º 12
0
 def _gen_ipv6(self, nxt, src=None, dst=None):
     return ipv6.ipv6(
         src=(src or SRC_IPV6_1),
         dst=(dst or DST_IPV6_1),
         nxt=nxt,
     )