Ejemplo n.º 1
0
    def test_encap(self):
        """Packet Tracer Filter Test with encap"""

        # the packet we are trying to match
        p = (
            Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
            / IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4)
            / UDP()
            / VXLAN()
            / Ether()
            / IP()
            / UDP()
            / GENEVE(vni=1234)
            / Ether()
            / IP(src="192.168.4.167")
            / UDP()
            / Raw("\xa5" * 100)
        )

        #
        # compute filter mask & value
        # we compute it by XOR'ing a template packet with a modified packet
        # we need to set checksums to 0 to make sure scapy will not recompute
        # them
        #
        tmpl = (
            Ether()
            / IP(chksum=0)
            / UDP(chksum=0)
            / VXLAN()
            / Ether()
            / IP(chksum=0)
            / UDP(chksum=0)
            / GENEVE(vni=0)
            / Ether()
            / IP(src="0.0.0.0", chksum=0)
        )
        ori = raw(tmpl)

        # the mask
        tmpl[GENEVE].vni = 0xFFFFFF
        user = tmpl[GENEVE].payload
        user[IP].src = "255.255.255.255"
        new = raw(tmpl)
        mask = "".join(("{:02x}".format(o ^ n) for o, n in zip(ori, new)))

        # this does not match (wrong vni)
        tmpl[GENEVE].vni = 1
        user = tmpl[GENEVE].payload
        user[IP].src = "192.168.4.167"
        new = raw(tmpl)
        match = "".join(("{:02x}".format(o ^ n) for o, n in zip(ori, new)))
        self.assert_classify(mask, match, [p] * 11, 0)

        # this must match
        tmpl[GENEVE].vni = 1234
        new = raw(tmpl)
        match = "".join(("{:02x}".format(o ^ n) for o, n in zip(ori, new)))
        self.assert_classify(mask, match, [p] * 17)
Ejemplo n.º 2
0
 def encap_mcast(self, pkt, src_ip, src_mac, vni):
     """
     Encapsulate the original payload frame by adding GENEVE header with its
     UDP, IP and Ethernet fields
     """
     return (Ether(src=src_mac, dst=self.mcast_mac) /
             IP(src=src_ip, dst=self.mcast_ip4) /
             UDP(sport=self.dport, dport=self.dport, chksum=0) /
             GENEVE(vni=vni) / pkt)
Ejemplo n.º 3
0
 def encapsulate(self, pkt, vni):
     """
     Encapsulate the original payload frame by adding GENEVE header with its
     UDP, IP and Ethernet fields
     """
     return (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
             IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) /
             UDP(sport=self.dport, dport=self.dport, chksum=0) /
             GENEVE(vni=vni) / pkt)
Ejemplo n.º 4
0
    def test_l3_packet(self):
        vni = 1234
        r = self.vapi.add_node_next(node_name="geneve4-input",
                                    next_name="ethernet-input")
        r = self.vapi.geneve_add_del_tunnel2(
            is_add=1,
            local_address=self.pg0.local_ip4,
            remote_address=self.pg0.remote_ip4,
            vni=vni,
            l3_mode=1,
            decap_next_index=r.next_index,
        )

        self.vapi.sw_interface_add_del_address(sw_if_index=r.sw_if_index,
                                               prefix="10.0.0.1/24")

        pkt = (Ether(src=self.pg0.remote_mac, dst="d0:0b:ee:d0:00:00") /
               IP(src="10.0.0.2", dst="10.0.0.1") / ICMP())

        encap = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
                 IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4) /
                 UDP(sport=6081, dport=6081, chksum=0) / GENEVE(vni=vni))

        arp = Ether(src=self.pg0.remote_mac, dst="d0:0b:ee:d0:00:00") / ARP(
            op="is-at",
            hwsrc=self.pg0.remote_mac,
            hwdst="d0:0b:ee:d0:00:00",
            psrc="10.0.0.2",
            pdst="10.0.0.1",
        )

        rx = self.send_and_expect(self.pg0, encap / pkt * 1, self.pg0)
        rx = self.send_and_assert_no_replies(self.pg0, encap / arp * 1,
                                             self.pg0)
        rx = self.send_and_expect(self.pg0, encap / pkt * 1, self.pg0)
        self.assertEqual(rx[0][ICMP].type, 0)  # echo reply

        r = self.vapi.geneve_add_del_tunnel2(
            is_add=0,
            local_address=self.pg0.local_ip4,
            remote_address=self.pg0.remote_ip4,
            vni=vni,
        )
Ejemplo n.º 5
0
    def define_packets(self):
        """Defines the packets to be sent from the traffic generator.

        Packet definition: | ETH | IP | UDP |

        :returns: Packets to be sent from the traffic generator.
        :rtype: tuple
        """
        p1_src_start_ip_int = int(IPv4Address(self.p1_src_start_ip))
        p1_dst_start_ip_int = int(IPv4Address(self.p1_dst_start_ip))
        p2_inner_src_start_ip_int = int(IPv4Address(
            self.p2_inner_src_start_ip))
        p2_inner_dst_start_ip_int = int(IPv4Address(
            self.p2_inner_dst_start_ip))

        # Direction 0 --> 1
        base_pkt_a = (
            Ether() /
            IP(src=self.p1_src_start_ip, dst=self.p1_dst_start_ip, proto=61))
        # Direction 1 --> 0
        base_pkt_b = (
            Ether() /
            IP(src=self.p2_outer_src_ip, dst=self.p2_outer_dst_ip, proto=17) /
            UDP(sport=self.p2_udp_sport_start, dport=self.p2_udp_dport) /
            GENEVE(vni=self.p2_geneve_start_vni) /
            Ether(dst=self.p2_inner_dst_mac) /
            IP(src=self.p2_inner_src_start_ip,
               dst=self.p2_inner_dst_start_ip,
               proto=61))
        base_pkt_b /= Raw(load=self._gen_payload(110 - len(base_pkt_b)))
        # Direction 0 --> 1
        vm1 = STLScVmRaw([
            STLVmFlowVar(name=u"ip_src",
                         min_value=p1_src_start_ip_int,
                         max_value=p1_src_start_ip_int + self.n_tunnels * 256 -
                         1,
                         size=4,
                         op=u"inc"),
            STLVmWrFlowVar(fv_name=u"ip_src", pkt_offset=u"IP.src"),
            STLVmFlowVar(name=u"ip_dst",
                         min_value=p1_dst_start_ip_int,
                         max_value=p1_dst_start_ip_int + self.n_tunnels * 256 -
                         1,
                         size=4,
                         op=u"inc"),
            STLVmWrFlowVar(fv_name=u"ip_dst", pkt_offset=u"IP.dst"),
            STLVmFixIpv4(offset=u"IP")
        ])
        # Direction 1 --> 0
        vm2 = STLScVmRaw([
            STLVmFlowVar(name=u"ip",
                         min_value=0,
                         max_value=self.n_tunnels * 256 - 1,
                         size=4,
                         op=u"inc"),
            STLVmWrMaskFlowVar(fv_name=u"ip",
                               pkt_cast_size=4,
                               mask=0xffffffff,
                               add_value=p2_inner_src_start_ip_int,
                               pkt_offset=u"IP:1.src"),
            STLVmWrMaskFlowVar(fv_name=u"ip",
                               pkt_cast_size=4,
                               mask=0xffffffff,
                               add_value=p2_inner_dst_start_ip_int,
                               pkt_offset=u"IP:1.dst"),
            STLVmWrMaskFlowVar(fv_name=u"ip",
                               pkt_cast_size=2,
                               mask=0xffff,
                               add_value=self.p2_udp_sport_start,
                               pkt_offset=u"UDP.sport"),
            STLVmWrMaskFlowVar(fv_name=u"ip",
                               pkt_cast_size=4,
                               mask=0xffffff00,
                               add_value=(self.p2_geneve_start_vni << 8),
                               pkt_offset=u"GENEVE.vni"),
            STLVmWrMaskFlowVar(
                fv_name=u"ip",
                pkt_cast_size=4,
                mask=0xffffff,
                shift=-8,
                offset_fixup=2,
                add_value=c_int(
                    int(self.p2_inner_dst_mac.replace(u":", u"")[6:12], 16) <<
                    8).value,
                pkt_offset=u"Ether:1.dst"),
            STLVmFixIpv4(offset=u"IP:1"),
            STLVmFixIpv4(offset=u"IP"),
            STLVmFixChecksumHw(l3_offset=u"IP",
                               l4_offset=u"UDP",
                               l4_type=CTRexVmInsFixHwCs.L4_TYPE_UDP)
        ])

        return base_pkt_a, base_pkt_b, vm1, vm2
Ejemplo n.º 6
0
def main():
    """Send and receive GENEVE packets."""

    args = TrafficScriptArg(
        [
            u"tx_src_mac", u"tx_dst_mac", u"rx_src_mac", u"rx_dst_mac",
            u"tun_local_ip", u"tun_remote_ip", u"tun_vni", u"tun_src_ip",
            u"tun_dst_ip"
        ]
    )

    tx_txq = TxQueue(args.get_arg(u"tx_if"))
    tx_rxq = RxQueue(args.get_arg(u"tx_if"))
    rx_txq = TxQueue(args.get_arg(u"rx_if"))
    rx_rxq = RxQueue(args.get_arg(u"rx_if"))

    rx_src_mac = args.get_arg(u"rx_src_mac")
    rx_dst_mac = args.get_arg(u"rx_dst_mac")
    tx_src_mac = args.get_arg(u"tx_src_mac")
    tx_dst_mac = args.get_arg(u"tx_dst_mac")

    tun_local_ip = args.get_arg(u"tun_local_ip")
    tun_remote_ip = args.get_arg(u"tun_remote_ip")
    tun_vni = args.get_arg(u"tun_vni")
    tun_src_ip = args.get_arg(u"tun_src_ip")
    tun_dst_ip = args.get_arg(u"tun_dst_ip")

    geneve_tunnel_mac = u"d0:0b:ee:d0:00:00"
    geneve_udp_dport = 6081

    tx_sent_packets = list()
    src_ip = ip_address(tun_src_ip)
    dst_ip = ip_address(tun_dst_ip)
    ip_layer = IP if src_ip.version == 4 else IPv6
    tx_ip_pkt = ip_layer(src=src_ip, dst=dst_ip, proto=61) \
        if ip_layer == IP else ip_layer(src=src_ip, dst=dst_ip)
    tx_pkt_send = (Ether(src=tx_src_mac, dst=tx_dst_mac) / tx_ip_pkt)
    tx_pkt_send /= Raw()
    size_limit = 78 if ip_layer == IPv6 else 60
    if len(tx_pkt_send) < size_limit:
        tx_pkt_send[Raw].load += b"\0" * (size_limit - len(tx_pkt_send))

    tx_sent_packets.append(tx_pkt_send)
    tx_txq.send(tx_pkt_send)

    while True:
        rx_pkt_recv = rx_rxq.recv(2)

        if rx_pkt_recv is None:
            raise RuntimeError(f"GENEVE packet Rx timeout")

        if rx_pkt_recv.haslayer(ICMPv6ND_NS):
            # read another packet in the queue if the current one is ICMPv6ND_NS
            continue
        else:
            # otherwise process the current packet
            break

    check_geneve(
        rx_pkt_recv, ip_layer, rx_src_mac, rx_dst_mac, geneve_tunnel_mac,
        rx_dst_mac, tun_local_ip, tun_remote_ip, str(src_ip), str(dst_ip),
        geneve_udp_dport, int(tun_vni)
    )

    rx_inner_ip_pkt = IP(
        src=rx_pkt_recv[Ether:2][IP].dst,
        dst=rx_pkt_recv[Ether:2][IP].src,
        proto=61
    ) if isinstance(rx_pkt_recv[Ether:2][1], IP) else IPv6(
        src=rx_pkt_recv[Ether:2][IPv6].dst,
        dst=rx_pkt_recv[Ether:2][IPv6].src
    )
    rx_inner_ip_pkt /= Raw()
    rx_inner_pkt = (
        Ether(src=rx_pkt_recv[4].dst, dst=rx_pkt_recv[4].src) /
        rx_inner_ip_pkt
    )
    size_limit = 78 if isinstance(rx_pkt_recv[Ether:2][1], IPv6) else 60
    if len(rx_inner_pkt) < size_limit:
        rx_inner_pkt[Raw].load += b"\0" * (size_limit - len(rx_inner_pkt))

    rx_outer_ip_pkt = IP(
        src=rx_pkt_recv[Ether:1][IP].dst,
        dst=rx_pkt_recv[Ether:1][IP].src
    ) if isinstance(rx_pkt_recv[Ether:1][1], IP) else IPv6(
        src=rx_pkt_recv[Ether:1][IPv6].dst,
        dst=rx_pkt_recv[Ether:1][IPv6].src
    )
    rx_pkt_send = (
        Ether(src=rx_pkt_recv[Ether:1].dst, dst=rx_pkt_recv[Ether:1].src) /
        rx_outer_ip_pkt /
        UDP(sport=6081, dport=6081) /
        GENEVE(vni=rx_pkt_recv[GENEVE].vni) /
        rx_inner_pkt
    )
    rx_txq.send(rx_pkt_send)

    while True:
        tx_pkt_recv = tx_rxq.recv(2, ignore=tx_sent_packets)
        ip_layer = IP

        if tx_pkt_recv is None:
            raise RuntimeError(f"{ip_layer.__name__} packet Rx timeout")

        if tx_pkt_recv.haslayer(ICMPv6ND_NS):
            # read another packet in the queue if the current one is ICMPv6ND_NS
            continue
        else:
            # otherwise process the current packet
            break

    check_ip(
        tx_pkt_recv, ip_layer, tx_dst_mac, tx_src_mac, str(dst_ip), str(src_ip)
    )

    sys.exit(0)
Ejemplo n.º 7
0
def craft_pkt(_types, _dicts):

    pkt = None
    for i in range(len(_types)):
        _type = _types[i]
        _dict = _dicts[i]
        logging.debug("type: {}, dict: {}".format(_type, _dict))

        if _type == "Ether":
            if 'smac' not in _dict.keys() or \
               'dmac' not in _dict.keys():
                raise Exception('Ether: smac and/or dmac not found')
            else:
                if pkt:
                    pkt = pkt / Ether(src=_dict['smac'], dst=_dict['dmac'])
                else:
                    pkt = Ether(src=_dict['smac'], dst=_dict['dmac'])

        elif _type == "Dot1Q":
            if 'vlan' not in _dict.keys():
                raise Exception('Dot1Q: vlan not found')
            else:
                pkt = pkt / Dot1Q(vlan=int(_dict['vlan']))

        elif _type == "IP":
            if 'sip' not in _dict.keys() or \
               'dip' not in _dict.keys():
                raise Exception('IP: sip and/or dip not found')
            else:
                pkt = pkt / IP(src=_dict['sip'], dst=_dict['dip'], id=0)
            if 'flags' in _dict.keys():
                pkt.getlayer('IP').flags = _dict['flags']
            if 'ttl' in _dict.keys():
                pkt.getlayer('IP').ttl = _dict['ttl']

        elif _type == "UDP":
            if 'sport' not in _dict.keys() or \
               'dport' not in _dict.keys():
                raise Exception('UDP: sport and/or dport not found')
            else:
                pkt = pkt / UDP(sport=int(_dict['sport']),
                                dport=int(_dict['dport']))

        elif _type == "TCP":
            if 'sport' not in _dict.keys() or \
               'dport' not in _dict.keys():
                raise Exception('TCP: sport and/or dport not found')
            elif 'flags' in _dict.keys():
                pkt = pkt / TCP(sport=int(_dict['sport']),
                                dport=int(_dict['dport']),
                                flags=_dict['flags'])
            else:
                pkt = pkt / TCP(sport=int(_dict['sport']),
                                dport=int(_dict['dport']))

        elif _type == "ICMP":
            if 'icmp_type' not in _dict.keys() or \
               'icmp_code' not in _dict.keys():
                raise Exception('ICMP: icmp_type and/or icmp_code not found')
            else:
                pkt = pkt / ICMP(type=int(_dict['icmp_type']),
                                 code=int(_dict['icmp_code']))

        elif _type == "MPLS":
            if 'label' not in _dict.keys() or \
               's' not in _dict.keys():
                raise Exception('MPLS: label and/or s not found')
            else:
                pkt = pkt / MPLS(label=int(_dict['label']), s=int(_dict['s']))

        elif _type == "GENEVE":
            if 'vni' not in _dict.keys() or \
               'options' not in _dict.keys():
                raise Exception('GENEVE: vni and/or options not found')
            else:
                pkt = pkt / GENEVE(vni=int(_dict['vni']),
                                   options=_dict['options'])
    return pkt
Ejemplo n.º 8
0
        TCP(sport=0x03e8, dport=0x2710, flags='S') / payload
dump_pkt(ipv4_tcp)

print('H2S L2 TCP EXP S')
payload = 'abcdefghijlkmnopqrstuvwzxyabcdefghijlkmnopqrstuvwzxy'

opt_src_slot_id='\x00\x00\x21\x01\x00\x10\x20\x30'
opt_dst_slot_id='\x00\x00\x22\x01\x00\x01\x23\x52'

geneve_options=opt_src_slot_id + opt_dst_slot_id

geneve_ipv4_tcp_exp = Ether(dst='00:06:07:08:09:0A', src='00:01:02:03:04:05') / \
        Dot1Q(vlan=2) / \
        IP(dst='1.2.3.4', src='4.3.2.1', id=0, ttl=64) / \
        UDP(sport=0x0, chksum=0) / \
        GENEVE(vni=0xA0B0C0, options=geneve_options) / \
        Ether(dst='00:00:F1:D0:D1:D0', src='00:00:00:40:08:01') / \
        IP(dst='192.0.2.1', src='2.0.0.1', id=0, ttl=64) / \
        TCP(sport=0x03e8, dport=0x2710, flags='S') / payload

dump_pkt(geneve_ipv4_tcp_exp)

print('S2H L2 TCP INJ SA')
payload = 'abcdefghijlkmnopqrstuvwzxyabcdefghijlkmnopqrstuvwzxy'

opt_src_slot_id='\x00\x00\x21\x01\x00\x10\x20\x30'
opt_dst_slot_id='\x00\x00\x22\x01\x00\x01\x23\x52'

geneve_options=opt_src_slot_id + opt_dst_slot_id

geneve_ipv4_tcp_inj = Ether(dst='00:01:02:03:04:05', src='00:06:07:08:09:0A') / \