Example #1
0
 def gen_encrypt_pkts6(self,
                       sa,
                       sw_intf,
                       src,
                       dst,
                       count=1,
                       payload_size=54):
     return [
         Ether(src=sw_intf.remote_mac, dst=sw_intf.local_mac) / sa.encrypt(
             IPv6(src=src, dst=dst) /
             ICMPv6EchoRequest(id=0, seq=1, data='X' * payload_size))
         for i in range(count)
     ]
Example #2
0
 def _l4_hdr(self):
     if self.stream.l4 is not None:
         l4_header = self.stream.l4.__dict__
     proto = self.stream.get_l4_proto()
     if proto == 'tcp':
         return TCP(**l4_header)
     elif proto == 'udp':
         return UDP(**l4_header)
     elif proto == 'icmp':
         return ICMP(**l4_header)
     elif proto == 'icmpv6':
         return ICMPv6EchoRequest()
     else:
         log.error("Unsupported L4 protocol %s." % proto)
Example #3
0
    def test_map_t_spoof_icmp_id_psid_ip6_to_ip4(self):
        """ MAP-T spoof ICMP id psid IPv6 -> IPv4 """

        eth = Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac)
        ip = IPv6(src=self.ipv6_cpe_address, dst=self.ipv6_map_address)
        icmp = ICMPv6EchoRequest()
        icmp.id = self.ipv6_udp_or_tcp_spoof_port
        payload = "H" * 10
        tx_pkt = eth / ip / icmp / payload

        self.pg_send(self.pg1, tx_pkt * 1)

        self.pg0.get_capture(0, timeout=1)
        self.pg0.assert_nothing_captured("Should drop IPv6 spoof port PSID")
Example #4
0
    def test_vrrp6_accept_mode_enabled(self):
        """ IPv6 Master VR replies for VIP w/ accept mode on """

        # A prio 255 VR cannot be preempted so the prio has to be lower and
        # we have to wait for it to take over
        vr_id = 100
        prio = 100
        intvl = self._default_adv
        vip = self.pg0.remote_hosts[4].ip6
        flags = (self._default_flags | VRRP_VR_FLAG_ACCEPT)
        vr = VppVRRPVirtualRouter(self,
                                  self.pg0,
                                  vr_id,
                                  prio=prio,
                                  intvl=intvl,
                                  flags=flags,
                                  vips=[vip])
        self._vrs.append(vr)
        vr.add_vpp_config()

        # After adding the VR, it should be in the init state
        vr.assert_state_equals(VRRP_VR_STATE_INIT)

        # start VR
        vr.start_stop(is_start=1)
        vr.assert_state_equals(VRRP_VR_STATE_BACKUP)

        # wait for VR to take over as master
        end_time = vr.start_time() + vr.master_down_seconds()
        sleep_s = end_time - time.time()
        time.sleep(sleep_s)
        vr.assert_state_equals(VRRP_VR_STATE_MASTER)

        # send an ICMP echo to the VR virtual IP address
        echo = (Ether(dst=vr.virtual_mac(), src=self.pg0.remote_mac) /
                IPv6(dst=vip, src=self.pg0.remote_ip6) /
                ICMPv6EchoRequest(seq=1, id=self.pg0.sw_if_index))
        self.pg_send(self.pg0, [echo])

        # wait for an echo reply.
        time.sleep(1)
        rx_pkts = self.pg0.get_capture(expected_count=1,
                                       timeout=1,
                                       filter_out_fn=is_not_echo_reply)

        self.assertEqual(rx_pkts[0][IPv6].src, vip)
        self.assertEqual(rx_pkts[0][IPv6].dst, self.pg0.remote_ip6)
        self.assertEqual(rx_pkts[0][ICMPv6EchoReply].seq, 1)
        self.assertEqual(rx_pkts[0][ICMPv6EchoReply].id, self.pg0.sw_if_index)
Example #5
0
def fragment_covert_channel(src, dst):

    payload1 = ''
    for i in range(1280):
        payload1 = payload1 + '0'
        
    payload2 = ''
    for i in range(1280):
        payload2 = payload2 + '0'
        
    # Create IPv6 Packet
    ip6 = IPv6()
    ip6.dst = dst
    ip6.src = src
    
    # Create ICMPv6 Packet
    icmpv6 = ICMPv6EchoRequest(cksum=0x7b57, data=payload1)
    
    # Create Fragments
    frg_hdr1 = IPv6ExtHdrFragment()  # offset=0, m=1, id=511, nh=58
    frg_hdr1.offset = 0
    frg_hdr1.m = 1
    frg_hdr1.id = 511
    frg_hdr1.nh = 44

    frg_hdr2 = IPv6ExtHdrFragment()  # offset=162, m=0, id=511, nh=6
    frg_hdr2.offset = 162
    frg_hdr2.m = 0
    frg_hdr2.id = 511
    frg_hdr2.nh = 6

    tcp_hdr = TCP()
    tcp_hdr.source_port = 1055
    tcp_hdr.destination_port = 8080

    # Create Packet for sending
    pkt1 = ip6/frg_hdr1/icmpv6
    pkt2 = ip6/frg_hdr2/tcp_hdr/payload2

    pkt1.show()
    pkt2.show()
    # Send Packets
    send(pkt1)
    send(pkt2)
Example #6
0
    def test_map_t_echo_request_ip6_to_ip4(self):
        """ MAP-T echo request IPv6 -> IPv4 """

        eth = Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac)
        ip = IPv6(src=self.ipv6_cpe_address, dst=self.ipv6_map_address)
        icmp = ICMPv6EchoRequest()
        icmp.id = self.ipv6_udp_or_tcp_map_port
        payload = "H" * 10
        tx_pkt = eth / ip / icmp / payload

        self.pg_send(self.pg1, tx_pkt * 1)

        rx_pkts = self.pg0.get_capture(1)
        rx_pkt = rx_pkts[0]

        self.assertEqual(rx_pkt[IP].proto, IP(proto="icmp").proto)
        self.assertEqual(rx_pkt[ICMP].type, ICMP(type="echo-request").type)
        self.assertEqual(rx_pkt[ICMP].code, 0)
        self.assertEqual(rx_pkt[ICMP].id, self.ipv6_udp_or_tcp_map_port)
Example #7
0
def tcp_fragment():
    payload1 = ''
    for i in range(1280):
        payload1 = payload1 + 'A'
    payload2 = ''
    for i in range(1280):
        payload2 = payload2 + 'B'
    # source = str(RandIP6())
    packet_1 = IPv6(dst=destination, src=source) / IPv6ExtHdrFragment(
        offset=0, m=1, id=511, nh=58) / ICMPv6EchoRequest(cksum=0x7b57,
                                                          data=payload1)
    packet_2 = IPv6(dst=destination, src=source) / IPv6ExtHdrFragment(
        offset=162, m=0, id=511, nh=6) / TCP(sport=s_port,
                                             dport=d_port) / payload2
    # packet_1=ip6/frag1/icmpv6
    # packet_2=ip6/frag2/tcpheader/payload2
    # Send Packets
    send(packet_1)
    send(packet_2)
Example #8
0
    def sourcenat_test_icmp_echo6_conf(self):
        sports = [1234, 1235]
        dports = [6661, 6662]

        for nbr, remote_host in enumerate(self.pg1.remote_hosts):
            client_addr = self.pg0.remote_hosts[0].ip6
            remote_addr = self.pg1.remote_hosts[nbr].ip6
            src_nat_addr = self.pg2.remote_hosts[0].ip6

            # ping from pods to outside network
            p1 = (
                Ether(dst=self.pg0.local_mac,
                      src=self.pg0.remote_hosts[0].mac) /
                IPv6(src=client_addr, dst=remote_addr) /
                ICMPv6EchoRequest(id=0xfeed) /
                Raw())

            rxs = self.send_and_expect(
                self.pg0,
                p1 * N_PKTS,
                self.pg1)

            for rx in rxs:
                self.assertEqual(rx[IPv6].src, src_nat_addr)
                self.assert_packet_checksums_valid(rx)

            received_id = rx[0][ICMPv6EchoRequest].id
            # ping reply from outside to pods
            p2 = (
                Ether(dst=self.pg1.local_mac,
                      src=self.pg1.remote_hosts[nbr].mac) /
                IPv6(src=remote_addr, dst=src_nat_addr) /
                ICMPv6EchoReply(id=received_id))
            rxs = self.send_and_expect(
                self.pg1,
                p2 * N_PKTS,
                self.pg0)

            for rx in rxs:
                self.assert_packet_checksums_valid(rx)
                self.assertEqual(rx[IPv6].src, remote_addr)
                self.assertEqual(rx[ICMPv6EchoReply].id, 0xfeed)
Example #9
0
    def test_map_t_echo_request_ip4_to_ip6(self):
        """ MAP-T echo request IPv4 -> IPv6 """

        eth = Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac)
        ip = IP(src=self.pg0.remote_ip4, dst=self.ipv4_map_address)
        icmp = ICMP(type="echo-request", id=self.ipv6_udp_or_tcp_map_port)
        payload = "H" * 10
        tx_pkt = eth / ip / icmp / payload

        self.pg_send(self.pg0, tx_pkt * 1)

        rx_pkts = self.pg1.get_capture(1)
        rx_pkt = rx_pkts[0]

        self.assertEqual(rx_pkt[IPv6].nh, IPv6(nh="ICMPv6").nh)
        self.assertEqual(rx_pkt[ICMPv6EchoRequest].type,
                         ICMPv6EchoRequest(type="Echo Request").type)
        self.assertEqual(rx_pkt[ICMPv6EchoRequest].code, 0)
        self.assertEqual(rx_pkt[ICMPv6EchoRequest].id,
                         self.ipv6_udp_or_tcp_map_port)
Example #10
0
    def test_vrrp6_accept_mode_disabled(self):
        """ IPv6 Master VR does not reply for VIP w/ accept mode off """

        # accept mode only matters when prio < 255, so it will have to
        # come up as a backup and take over as master after the timeout
        vr_id = 100
        prio = 100
        intvl = self._default_adv
        vip = self.pg0.remote_hosts[4].ip6
        vr = VppVRRPVirtualRouter(self,
                                  self.pg0,
                                  vr_id,
                                  prio=prio,
                                  intvl=intvl,
                                  flags=self._default_flags,
                                  vips=[vip])
        self._vrs.append(vr)
        vr.add_vpp_config()

        # After adding the VR, it should be in the init state
        vr.assert_state_equals(VRRP_VR_STATE_INIT)

        # start VR
        vr.start_stop(is_start=1)
        vr.assert_state_equals(VRRP_VR_STATE_BACKUP)

        # wait for VR to take over as master
        end_time = vr.start_time() + vr.master_down_seconds()
        sleep_s = end_time - time.time()
        time.sleep(sleep_s)
        vr.assert_state_equals(VRRP_VR_STATE_MASTER)

        # send an ICMPv6 echo to the VR virtual IP address
        echo = (Ether(dst=vr.virtual_mac(), src=self.pg0.remote_mac) /
                IPv6(dst=vip, src=self.pg0.remote_ip6) /
                ICMPv6EchoRequest(seq=1, id=self.pg0.sw_if_index))
        self.pg_send(self.pg0, [echo])

        # wait for an echo reply. none should be received
        time.sleep(1)
        self.pg0.assert_nothing_captured(filter_out_fn=is_not_echo_reply)
Example #11
0
def send_too_big_multiprocess(addr, data, index, str_f, mtu=1280):
    """Send too big packet ICMPv6 packet.

    Arguments:
        addr {str} -- target address
        data {str} -- payload
        index {int} -- number of current handling IP prefix
        str_f {list(str)} -- a list of strings that store the log

    Keyword Arguments:
        mtu {int} -- mtu value in the packet too big ICMPv6 Packet (default: {1280})
    """
    str_f.append('==> Sending TBT to IP #%d, MTU = %d' % (index, mtu))
    src = IPv6(dst=addr).src
    base = IPv6(src=addr, dst=src, plen=len(data) + 8)

    too_big_extension = ICMPv6PacketTooBig(mtu=mtu) / \
        (base / ICMPv6EchoRequest(data=data[:mtu - 96], seq=0))

    base = IPv6(dst=addr)

    too_big_packet = base / too_big_extension

    send(too_big_packet, verbose=False)
Example #12
0
def main():
    args = TrafficScriptArg(['src_mac', 'dst_mac', 'src_ip', 'dst_ip'])

    rxq = RxQueue(args.get_arg('rx_if'))
    txq = TxQueue(args.get_arg('tx_if'))

    src_mac = args.get_arg('src_mac')
    dst_mac = args.get_arg('dst_mac')
    src_ip = args.get_arg('src_ip')
    dst_ip = args.get_arg('dst_ip')
    echo_id = 0xa
    echo_seq = 0x1

    sent_packets = []

    # send ICMPv6 neighbor advertisement message
    pkt_send = (Ether(src=src_mac, dst='ff:ff:ff:ff:ff:ff') /
                IPv6(src=src_ip, dst='ff02::1:ff00:2') /
                ICMPv6ND_NA(tgt=src_ip, R=0) /
                ICMPv6NDOptDstLLAddr(lladdr=src_mac))
    sent_packets.append(pkt_send)
    txq.send(pkt_send)

    # send ICMPv6 echo request
    pkt_send = (Ether(src=src_mac, dst=dst_mac) /
                IPv6(src=src_ip, dst=dst_ip) /
                ICMPv6EchoRequest(id=echo_id, seq=echo_seq))
    sent_packets.append(pkt_send)
    txq.send(pkt_send)

    # receive ICMPv6 echo reply
    while True:
        ether = rxq.recv(2, sent_packets)
        if ether is None:
            raise RuntimeError('ICMPv6 echo reply Rx timeout')

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

    if not ether.haslayer(IPv6):
        raise RuntimeError(
            'Unexpected packet with no IPv6 received {0}'.format(
                ether.__repr__()))

    ipv6 = ether[IPv6]

    if not ipv6.haslayer(ICMPv6EchoReply):
        raise RuntimeError('Unexpected packet with no ICMPv6 echo reply '
                           'received {0}'.format(ipv6.__repr__()))

    icmpv6 = ipv6[ICMPv6EchoReply]

    # check identifier and sequence number
    if icmpv6.id != echo_id or icmpv6.seq != echo_seq:
        raise RuntimeError('Invalid ICMPv6 echo reply received ID {0} seq {1} '
                           'should be ID {2} seq {3}'.format(
                               icmpv6.id, icmpv6.seq, echo_id, echo_seq))

    # verify checksum
    cksum = icmpv6.cksum
    del icmpv6.cksum
    tmp = ICMPv6EchoReply(str(icmpv6))
    if not checksum_equal(tmp.cksum, cksum):
        raise RuntimeError('Invalid checksum {0} should be {1}'.format(
            cksum, tmp.cksum))

    sys.exit(0)
Example #13
0
    def test_dslite_ce(self):
        """ Test DS-Lite CE """

        # TODO: add message to retrieve dslite config
        # nat_config = self.vapi.nat_show_config()
        # self.assertEqual(1, nat_config.dslite_ce)

        b4_ip4 = '192.0.0.2'
        b4_ip6 = '2001:db8:62aa::375e:f4c1:1'
        self.vapi.dslite_set_b4_addr(ip4_addr=b4_ip4, ip6_addr=b4_ip6)

        aftr_ip4 = '192.0.0.1'
        aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
        aftr_ip6_n = socket.inet_pton(socket.AF_INET6, aftr_ip6)
        self.vapi.dslite_set_aftr_addr(ip4_addr=aftr_ip4, ip6_addr=aftr_ip6)

        r1 = VppIpRoute(self, aftr_ip6, 128,
                        [VppRoutePath(self.pg1.remote_ip6,
                                      self.pg1.sw_if_index)])
        r1.add_vpp_config()

        # UDP encapsulation
        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             IP(dst=self.pg1.remote_ip4, src=self.pg0.remote_ip4) /
             UDP(sport=10000, dport=20000))
        self.pg0.add_stream(p)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        capture = self.pg1.get_capture(1)
        capture = capture[0]
        self.assertEqual(capture[IPv6].src, b4_ip6)
        self.assertEqual(capture[IPv6].dst, aftr_ip6)
        self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
        self.assertEqual(capture[IP].dst, self.pg1.remote_ip4)
        self.assertEqual(capture[UDP].sport, 10000)
        self.assertEqual(capture[UDP].dport, 20000)
        self.assert_packet_checksums_valid(capture)

        # UDP decapsulation
        p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
             IPv6(dst=b4_ip6, src=aftr_ip6) /
             IP(dst=self.pg0.remote_ip4, src=self.pg1.remote_ip4) /
             UDP(sport=20000, dport=10000))
        self.pg1.add_stream(p)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        capture = self.pg0.get_capture(1)
        capture = capture[0]
        self.assertFalse(capture.haslayer(IPv6))
        self.assertEqual(capture[IP].src, self.pg1.remote_ip4)
        self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
        self.assertEqual(capture[UDP].sport, 20000)
        self.assertEqual(capture[UDP].dport, 10000)
        self.assert_packet_checksums_valid(capture)

        # ping DS-Lite B4 tunnel endpoint address
        p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
             IPv6(src=self.pg1.remote_hosts[0].ip6, dst=b4_ip6) /
             ICMPv6EchoRequest())
        self.pg1.add_stream(p)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        capture = self.pg1.get_capture(1)
        capture = capture[0]
        self.assertEqual(capture[IPv6].src, b4_ip6)
        self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
        self.assertTrue(capture.haslayer(ICMPv6EchoReply))
    def test_nd_mirror_proxy(self):
        """ Interface (Mirror) Proxy ND """

        #
        # When VPP has an interface whose address is also applied to a TAP
        # interface on the host, then VPP's TAP interface will be unnumbered
        # to the 'real' interface and do proxy ND from the host.
        # the curious aspect of this setup is that ND requests from the host
        # will come from the VPP's own address.
        #
        addr = self.pg0.remote_ip6
        nsma = in6_getnsma(inet_pton(socket.AF_INET6, addr))
        d = inet_ntop(socket.AF_INET6, nsma)

        # Make pg1 un-numbered to pg0
        #
        self.pg1.unconfig_ip6()
        self.pg1.set_unnumbered(self.pg0.sw_if_index)

        #
        # Enable ND proxy on pg1
        #
        self.vapi.ip6nd_proxy_enable_disable(sw_if_index=self.pg1.sw_if_index,
                                             is_enable=1)
        #
        # Send the ND request with an originating address that
        # is VPP's own address
        #
        nd_req_from_host = (
            Ether(src=self.pg1.remote_mac, dst=in6_getnsmac(nsma)) /
            IPv6(dst=d, src=self.pg0.local_ip6) / ICMPv6ND_NS(tgt=addr) /
            ICMPv6NDOptSrcLLAddr(lladdr=self.pg1.remote_mac))

        rx = self.send_and_expect(self.pg1, [nd_req_from_host], self.pg1)
        self.assertEqual(rx[0][Ether].src, self.pg1.local_mac)
        self.assertEqual(rx[0][Ether].dst, self.pg1.remote_mac)
        self.assertEqual(rx[0][IPv6].src, self.pg0.remote_ip6)
        self.assertEqual(rx[0][IPv6].dst, self.pg0.local_ip6)
        self.assertEqual(ipv6nh[rx[0][IPv6].nh], "ICMPv6")
        self.assertEqual(rx[0][ICMPv6ND_NA].tgt, self.pg0.remote_ip6)
        self.assertTrue(rx[0].haslayer(ICMPv6NDOptDstLLAddr))
        self.assertEqual(rx[0][ICMPv6NDOptDstLLAddr].lladdr,
                         self.pg1.local_mac)

        #
        # Send the unicast ND request
        #
        unicast_nd_req_from_host = (
            Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) /
            IPv6(dst=self.pg0.remote_ip6, src=self.pg1.remote_ip6_ll) /
            ICMPv6ND_NS(tgt=self.pg0.remote_ip6) /
            ICMPv6NDOptSrcLLAddr(lladdr=self.pg1.remote_mac))

        rx = self.send_and_expect(self.pg1, [unicast_nd_req_from_host],
                                  self.pg0)
        self.assertEqual(rx[0][Ether].src, self.pg0.local_mac)
        self.assertEqual(rx[0][Ether].dst, in6_getnsmac(nsma))
        self.assertEqual(rx[0][IPv6].src, self.pg0.local_ip6)
        self.assertEqual(rx[0][IPv6].dst, d)
        self.assertEqual(ipv6nh[rx[0][IPv6].nh], "ICMPv6")
        self.assertEqual(rx[0][ICMPv6ND_NS].tgt, self.pg0.remote_ip6)
        self.assertTrue(rx[0].haslayer(ICMPv6NDOptSrcLLAddr))
        self.assertEqual(rx[0][ICMPv6NDOptSrcLLAddr].lladdr,
                         self.pg0.local_mac)

        # Resolve the NDs on the uplink
        self.pg0.resolve_ndp()

        #
        # Again send the unicast ND request, this time dst address should be
        # in local cache
        #
        rx = self.send_and_expect(self.pg1, [unicast_nd_req_from_host],
                                  self.pg1)
        self.assertEqual(rx[0][Ether].src, self.pg1.local_mac)
        self.assertEqual(rx[0][Ether].dst, self.pg1.remote_mac)
        self.assertEqual(rx[0][IPv6].src, self.pg0.remote_ip6)
        self.assertEqual(in6_ptop(rx[0][IPv6].dst),
                         in6_ptop(self.pg1.remote_ip6_ll))
        self.assertEqual(ipv6nh[rx[0][IPv6].nh], "ICMPv6")
        self.assertEqual(rx[0][ICMPv6ND_NA].tgt, self.pg0.remote_ip6)
        self.assertTrue(rx[0].haslayer(ICMPv6NDOptDstLLAddr))
        self.assertEqual(rx[0][ICMPv6NDOptDstLLAddr].lladdr,
                         self.pg1.local_mac)

        #
        # Send the Echo Request from host to remote (of uplink)
        #
        id = self.pg1.sw_if_index
        seq = 0x1
        echo_request = (
            Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
            IPv6(dst=self.pg0.remote_ip6, src=self.pg0.local_ip6) /
            ICMPv6EchoRequest(seq=seq, id=id))

        rx = self.send_and_expect(self.pg1, [echo_request], self.pg0)
        self.assertEqual(rx[0][Ether].src, self.pg0.local_mac)
        self.assertEqual(rx[0][Ether].dst, self.pg0.remote_mac)
        self.assertEqual(rx[0][IPv6].src, self.pg0.local_ip6)
        self.assertEqual(rx[0][IPv6].dst, self.pg0.remote_ip6)
        self.assertEqual(ipv6nh[rx[0][IPv6].nh], "ICMPv6")
        self.assertTrue(rx[0].haslayer(ICMPv6EchoRequest))
        self.assertEqual(rx[0][ICMPv6EchoRequest].id, id)
        self.assertEqual(rx[0][ICMPv6EchoRequest].seq, seq)

        #
        # setup a punt redirect so packets from the uplink go to the tap
        #
        redirect = VppIpPuntRedirect(self, self.pg0.sw_if_index,
                                     self.pg1.sw_if_index, self.pg0.local_ip6)
        redirect.add_vpp_config()

        echo_reply = (Ether(dst=self.pg0.remote_mac, src=self.pg0.local_mac) /
                      IPv6(dst=self.pg0.local_ip6, src=self.pg0.remote_ip6) /
                      ICMPv6EchoReply(seq=1, id=id))

        rx = self.send_and_expect(self.pg0, [echo_reply], self.pg1)
        self.assertEqual(rx[0][Ether].src, self.pg1.local_mac)
        self.assertEqual(rx[0][Ether].dst, self.pg1.remote_mac)
        self.assertEqual(rx[0][IPv6].src, self.pg0.remote_ip6)
        self.assertEqual(rx[0][IPv6].dst, self.pg0.local_ip6)
        self.assertEqual(ipv6nh[rx[0][IPv6].nh], "ICMPv6")
        self.assertTrue(rx[0].haslayer(ICMPv6EchoReply))
        self.assertEqual(rx[0][ICMPv6EchoReply].id, id)
        self.assertEqual(rx[0][ICMPv6EchoReply].seq, seq)

        #
        # cleanup
        #
        self.vapi.ip6nd_proxy_enable_disable(sw_if_index=self.pg1.sw_if_index,
                                             is_enable=0)
        redirect.remove_vpp_config()
Example #15
0
    def test_static(self):
        """1:1 NAT66 test"""
        flags = self.config_flags.NAT_IS_INSIDE
        self.vapi.nat66_add_del_interface(is_add=1,
                                          flags=flags,
                                          sw_if_index=self.pg0.sw_if_index)
        self.vapi.nat66_add_del_interface(is_add=1,
                                          sw_if_index=self.pg1.sw_if_index)
        self.vapi.nat66_add_del_static_mapping(
            local_ip_address=self.pg0.remote_ip6,
            external_ip_address=self.nat_addr,
            is_add=1,
        )

        # in2out
        pkts = []
        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) / TCP())
        pkts.append(p)
        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) / UDP())
        pkts.append(p)
        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) /
             ICMPv6EchoRequest())
        pkts.append(p)
        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             IPv6(src=self.pg0.remote_ip6, dst=self.pg1.remote_ip6) / GRE() /
             IP() / TCP())
        pkts.append(p)
        self.pg0.add_stream(pkts)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        capture = self.pg1.get_capture(len(pkts))

        for packet in capture:
            try:
                self.assertEqual(packet[IPv6].src, self.nat_addr)
                self.assertEqual(packet[IPv6].dst, self.pg1.remote_ip6)
                self.assert_packet_checksums_valid(packet)
            except:
                self.logger.error(ppp("Unexpected or invalid packet:", packet))
                raise

        # out2in
        pkts = []
        p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
             IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) / TCP())
        pkts.append(p)
        p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
             IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) / UDP())
        pkts.append(p)
        p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
             IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) /
             ICMPv6EchoReply())
        pkts.append(p)
        p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
             IPv6(src=self.pg1.remote_ip6, dst=self.nat_addr) / GRE() / IP() /
             TCP())
        pkts.append(p)
        self.pg1.add_stream(pkts)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        capture = self.pg0.get_capture(len(pkts))
        for packet in capture:
            try:
                self.assertEqual(packet[IPv6].src, self.pg1.remote_ip6)
                self.assertEqual(packet[IPv6].dst, self.pg0.remote_ip6)
                self.assert_packet_checksums_valid(packet)
            except:
                self.logger.error(ppp("Unexpected or invalid packet:", packet))
                raise

        sm = self.vapi.nat66_static_mapping_dump()
        self.assertEqual(len(sm), 1)
        self.assertEqual(sm[0].total_pkts, 8)
Example #16
0
def main():
    # start_size - start size of the ICMPv6 echo data
    # end_size - end size of the ICMPv6 echo data
    # step - increment step
    args = TrafficScriptArg([
        'src_mac', 'dst_mac', 'src_ip', 'dst_ip', 'start_size', 'end_size',
        'step'
    ])

    rxq = RxQueue(args.get_arg('rx_if'))
    txq = TxQueue(args.get_arg('tx_if'))

    src_mac = args.get_arg('src_mac')
    dst_mac = args.get_arg('dst_mac')
    src_ip = args.get_arg('src_ip')
    dst_ip = args.get_arg('dst_ip')
    start_size = int(args.get_arg('start_size'))
    end_size = int(args.get_arg('end_size'))
    step = int(args.get_arg('step'))
    echo_id = 0xa
    # generate some random data buffer
    data = bytearray(os.urandom(end_size))

    # send ICMPv6 neighbor advertisement message
    sent_packets = []
    pkt_send = (Ether(src=src_mac, dst=dst_mac) /
                IPv6(src=src_ip, dst=dst_ip) / ICMPv6ND_NA(tgt=src_ip, R=0) /
                ICMPv6NDOptDstLLAddr(lladdr=src_mac))
    sent_packets.append(pkt_send)
    txq.send(pkt_send)

    # send ICMPv6 echo request with incremented data length and receive ICMPv6
    # echo reply
    for echo_seq in range(start_size, end_size + 1, step):
        pkt_send = (
            Ether(src=src_mac, dst=dst_mac) / IPv6(src=src_ip, dst=dst_ip) /
            ICMPv6EchoRequest(id=echo_id, seq=echo_seq, data=data[0:echo_seq]))
        sent_packets.append(pkt_send)
        txq.send(pkt_send)

        ether = rxq.recv(ignore=sent_packets)
        if ether is None:
            raise RuntimeError(
                'ICMPv6 echo reply seq {0} Rx timeout'.format(echo_seq))

        if not ether.haslayer(IPv6):
            raise RuntimeError(
                'Unexpected packet with no IPv6 received {0}'.format(
                    ether.__repr__()))

        ipv6 = ether['IPv6']

        if not ipv6.haslayer(ICMPv6EchoReply):
            raise RuntimeError(
                'Unexpected packet with no IPv6 ICMP received {0}'.format(
                    ipv6.__repr__()))

        icmpv6 = ipv6['ICMPv6 Echo Reply']

        if icmpv6.id != echo_id or icmpv6.seq != echo_seq:
            raise RuntimeError(
                'Invalid ICMPv6 echo reply received ID {0} seq {1} should be '
                'ID {2} seq {3}, {0}'.format(icmpv6.id, icmpv6.seq, echo_id,
                                             echo_seq))

        cksum = icmpv6.cksum
        del icmpv6.cksum
        tmp = ICMPv6EchoReply(str(icmpv6))
        if not checksum_equal(tmp.cksum, cksum):
            raise RuntimeError('Invalid checksum {0} should be {1}'.format(
                cksum, tmp.cksum))

        sent_packets.remove(pkt_send)

    sys.exit(0)
def main():
    """Send IP ICMP packet from one traffic generator interface to the other."""
    args = TrafficScriptArg([
        'tg_src_mac', 'tg_dst_mac', 'src_ip', 'dst_ip', 'dut_if1_mac',
        'dut_if2_mac'
    ], [
        'encaps_tx', 'vlan_tx', 'vlan_outer_tx', 'encaps_rx', 'vlan_rx',
        'vlan_outer_rx'
    ])

    tx_src_mac = args.get_arg('tg_src_mac')
    tx_dst_mac = args.get_arg('dut_if1_mac')
    rx_dst_mac = args.get_arg('tg_dst_mac')
    rx_src_mac = args.get_arg('dut_if2_mac')
    src_ip = args.get_arg('src_ip')
    dst_ip = args.get_arg('dst_ip')
    tx_if = args.get_arg('tx_if')
    rx_if = args.get_arg('rx_if')

    encaps_tx = args.get_arg('encaps_tx')
    vlan_tx = args.get_arg('vlan_tx')
    vlan_outer_tx = args.get_arg('vlan_outer_tx')
    encaps_rx = args.get_arg('encaps_rx')
    vlan_rx = args.get_arg('vlan_rx')
    vlan_outer_rx = args.get_arg('vlan_outer_rx')

    rxq = RxQueue(rx_if)
    txq = TxQueue(tx_if)
    sent_packets = []
    ip_format = ''
    pkt_raw = Ether(src=tx_src_mac, dst=tx_dst_mac)
    if encaps_tx == 'Dot1q':
        pkt_raw /= Dot1Q(vlan=int(vlan_tx))
    elif encaps_tx == 'Dot1ad':
        pkt_raw.type = 0x88a8
        pkt_raw /= Dot1Q(vlan=vlan_outer_tx)
        pkt_raw /= Dot1Q(vlan=vlan_tx)
    if valid_ipv4(src_ip) and valid_ipv4(dst_ip):
        pkt_raw /= IP(src=src_ip, dst=dst_ip)
        pkt_raw /= ICMP()
        ip_format = IP
    elif valid_ipv6(src_ip) and valid_ipv6(dst_ip):
        pkt_raw /= IPv6(src=src_ip, dst=dst_ip)
        pkt_raw /= ICMPv6EchoRequest()
        ip_format = IPv6
    else:
        raise ValueError("IP not in correct format")

    sent_packets.append(pkt_raw)
    txq.send(pkt_raw)
    if tx_if == rx_if:
        ether = rxq.recv(2, ignore=sent_packets)
    else:
        ether = rxq.recv(2)

    if ether is None:
        raise RuntimeError("ICMP echo Rx timeout")

    if rx_dst_mac == ether[Ether].dst and rx_src_mac == ether[Ether].src:
        logger.trace("MAC matched")
    else:
        raise RuntimeError("Matching packet unsuccessful: {0}".format(
            ether.__repr__()))

    if encaps_rx == 'Dot1q':
        if ether[Dot1Q].vlan == int(vlan_rx):
            logger.trace("VLAN matched")
        else:
            raise RuntimeError('Ethernet frame with wrong VLAN tag ({}-'
                               'received, {}-expected):\n{}'.format(
                                   ether[Dot1Q].vlan, vlan_rx,
                                   ether.__repr__()))
        ip = ether[Dot1Q].payload
    elif encaps_rx == 'Dot1ad':
        raise NotImplementedError()
    else:
        ip = ether.payload

    if not isinstance(ip, ip_format):
        raise RuntimeError("Not an IP packet received {0}".format(
            ip.__repr__()))

    # Compare data from packets
    if src_ip == ip.src:
        logger.trace("Src IP matched")
    else:
        raise RuntimeError("Matching Src IP unsuccessful: {} != {}".format(
            src_ip, ip.src))

    if dst_ip == ip.dst:
        logger.trace("Dst IP matched")
    else:
        raise RuntimeError("Matching Dst IP unsuccessful: {} != {}".format(
            dst_ip, ip.dst))

    sys.exit(0)
Example #18
0
def main():
    """Send 100 IP ICMP packets traffic and check if it is divided into
    two paths."""
    args = TrafficScriptArg(
        ['src_ip', 'dst_ip', 'tg_if1_mac', 'dut_if1_mac', 'dut_if2_mac',
         'path_1_mac', 'path_2_mac'])

    src_ip = args.get_arg('src_ip')
    dst_ip = args.get_arg('dst_ip')
    tg_if1_mac = args.get_arg('tg_if1_mac')
    dut_if1_mac = args.get_arg('dut_if1_mac')
    dut_if2_mac = args.get_arg('dut_if2_mac')
    path_1_mac = args.get_arg('path_1_mac')
    path_2_mac = args.get_arg('path_2_mac')
    tx_if = args.get_arg('tx_if')
    rx_if = args.get_arg('rx_if')
    path_1_counter = 0
    path_2_counter = 0

    rxq = RxQueue(rx_if)
    txq = TxQueue(tx_if)
    sent_packets = []
    ip_format = ''
    pkt_raw = ''
    separator = ''

    if valid_ipv4(src_ip):
        separator = '.'
    elif valid_ipv6(src_ip):
        separator = ':'
    else:
        raise ValueError("Source address not in correct format")

    src_ip_base = (src_ip.rsplit(separator, 1))[0] + separator

    for i in range(1, 101):
        if valid_ipv4(src_ip) and valid_ipv4(dst_ip):
            pkt_raw = (Ether(src=tg_if1_mac, dst=dut_if1_mac) /
                       IP(src=src_ip_base+str(i), dst=dst_ip) /
                       ICMP())
            ip_format = 'IP'
        elif valid_ipv6(src_ip) and valid_ipv6(dst_ip):
            pkt_raw = (Ether(src=tg_if1_mac, dst=dut_if1_mac) /
                       IPv6(src=src_ip_base+str(i), dst=dst_ip) /
                       ICMPv6EchoRequest())
            ip_format = 'IPv6'
        else:
            raise ValueError("IP not in correct format")

        sent_packets.append(pkt_raw)
        txq.send(pkt_raw)
        ether = rxq.recv(2)

        if ether is None:
            raise RuntimeError("ICMP echo Rx timeout")
        if not ether.haslayer(ip_format):
            raise RuntimeError("Not an IP packet received {0}"
                               .format(ether.__repr__()))

        if ether['Ethernet'].src != dut_if2_mac:
            raise RuntimeError("Source MAC address error")

        if ether['Ethernet'].dst == path_1_mac:
            path_1_counter += 1
        elif ether['Ethernet'].dst == path_2_mac:
            path_2_counter += 1
        else:
            raise RuntimeError("Destination MAC address error")

    if (path_1_counter + path_2_counter) != 100:
        raise RuntimeError("Packet loss: recevied only {} packets of 100 "
                           .format(path_1_counter + path_2_counter))

    if path_1_counter == 0:
        raise RuntimeError("Path 1 error!")

    if path_2_counter == 0:
        raise RuntimeError("Path 2 error!")

    print "Path_1 counter: {}".format(path_1_counter)
    print "Path_2 counter: {}".format(path_2_counter)

    sys.exit(0)
Example #19
0
def main():
    """Send IP ICMP packet from one traffic generator interface to the other.

    :raises RuntimeError: If the received packet is not correct."""

    args = TrafficScriptArg([
        u"tg_src_mac", u"tg_dst_mac", u"src_ip", u"dst_ip", u"dut_if1_mac",
        u"dut_if2_mac", u"src_rloc", u"dst_rloc"
    ], [u"ot_mode"])

    tx_src_mac = args.get_arg(u"tg_src_mac")
    tx_dst_mac = args.get_arg(u"dut_if1_mac")
    rx_dst_mac = args.get_arg(u"tg_dst_mac")
    rx_src_mac = args.get_arg(u"dut_if2_mac")
    src_ip = args.get_arg(u"src_ip")
    dst_ip = args.get_arg(u"dst_ip")
    src_rloc = args.get_arg(u"src_rloc")
    dst_rloc = args.get_arg(u"dst_rloc")
    tx_if = args.get_arg(u"tx_if")
    rx_if = args.get_arg(u"rx_if")
    ot_mode = args.get_arg(u"ot_mode")

    rxq = RxQueue(rx_if)
    txq = TxQueue(tx_if)

    pkt_raw = Ether(src=tx_src_mac, dst=tx_dst_mac)

    if valid_ipv4(src_ip) and valid_ipv4(dst_ip):
        pkt_raw /= IP(src=src_ip, dst=dst_ip)
        pkt_raw /= ICMP()
        ip_format = IP
    elif valid_ipv6(src_ip) and valid_ipv6(dst_ip):
        pkt_raw /= IPv6(src=src_ip, dst=dst_ip)
        pkt_raw /= ICMPv6EchoRequest()
        ip_format = IPv6
    else:
        raise ValueError(u"IP not in correct format")

    bind_layers(UDP, LispGPEHeader, dport=4341)

    pkt_raw /= Raw()
    sent_packets = list()
    sent_packets.append(pkt_raw)
    txq.send(pkt_raw)

    while True:
        if tx_if == rx_if:
            ether = rxq.recv(2, ignore=sent_packets)
        else:
            ether = rxq.recv(2)

        if ether is None:
            raise RuntimeError(u"ICMP echo Rx timeout")

        if ether.haslayer(ICMPv6ND_NS):
            # read another packet in the queue if the current one is ICMPv6ND_NS
            continue
        if ether.haslayer(ICMPv6ND_RA):
            # read another packet in the queue if the current one is ICMPv6ND_RA
            continue
        elif ether.haslayer(ICMPv6MLReport2):
            # read another packet in the queue if the current one is
            # ICMPv6MLReport2
            continue

        # otherwise process the current packet
        break

    if rx_dst_mac == ether[Ether].dst and rx_src_mac == ether[Ether].src:
        print(u"MAC addresses match.")
    else:
        raise RuntimeError(f"Matching packet unsuccessful: {ether!r}")

    ip = ether.payload

    if ot_mode == u"6to4":
        if not isinstance(ip, IP):
            raise RuntimeError(f"Not an IP packet received {ip!r}")
    elif ot_mode == u"4to6":
        if not isinstance(ip, IPv6):
            raise RuntimeError(f"Not an IP packet received {ip!r}")
    elif not isinstance(ip, ip_format):
        raise RuntimeError(f"Not an IP packet received {ip!r}")

    lisp = ether.getlayer(LispGPEHeader).underlayer
    if not lisp:
        raise RuntimeError(u"Lisp layer not present or parsing failed.")

    # Compare data from packets
    if src_ip == lisp.src:
        print(u"Source IP matches source EID.")
    else:
        raise RuntimeError(
            f"Matching Src IP unsuccessful: {src_ip} != {lisp.src}")

    if dst_ip == lisp.dst:
        print(u"Destination IP matches destination EID.")
    else:
        raise RuntimeError(
            f"Matching Dst IP unsuccessful: {dst_ip} != {lisp.dst}")

    if src_rloc == ip.src:
        print(u"Source RLOC matches configuration.")
    else:
        raise RuntimeError(
            f"Matching Src RLOC unsuccessful: {src_rloc} != {ip.src}")

    if dst_rloc == ip.dst:
        print(u"Destination RLOC matches configuration.")
    else:
        raise RuntimeError(
            f"Matching dst RLOC unsuccessful: {dst_rloc} != {ip.dst}")

    sys.exit(0)
def ipv6_ping(src_if, dst_if, src_mac, dst_mac, proxy_to_src_mac,
              proxy_to_dst_mac, src_ip, dst_ip):
    """Sends ICMPv6 Echo Request, receive it and send a reply.

    :param src_if: First TG interface on link to DUT.
    :param dst_if: Second TG interface on link to DUT.
    :param src_mac: MAC address of first interface.
    :param dst_mac: MAC address of second interface.
    :param proxy_to_src_mac: MAC address of first proxy interface on DUT.
    :param proxy_to_dst_mac: MAC address of second proxy interface on DUT.
    :param src_ip: IP address of first interface.
    :param dst_ip: IP address of second interface.
    :type src_if: str
    :type dst_if: str
    :type src_mac: str
    :type dst_mac: str
    :type proxy_to_src_mac: str
    :type proxy_to_dst_mac: str
    :type src_ip: str
    :type dst_ip: str
    :raises RuntimeError: If a received packet is not correct.
    """
    rxq = RxQueue(dst_if)
    txq = TxQueue(src_if)

    icmpv6_ping_pkt = (Ether(src=src_mac, dst=proxy_to_src_mac) /
                       IPv6(src=src_ip, dst=dst_ip) / ICMPv6EchoRequest())

    txq.send(icmpv6_ping_pkt)

    ether = None
    while True:
        ether = rxq.recv(3)
        if not ether:
            continue
        if ether.haslayer(ICMPv6ND_NS):
            # read another packet in the queue in case of ICMPv6ND_NS packet
            continue
        else:
            # otherwise process the current packet
            break

    if ether is None:
        raise RuntimeError('ICMPv6 Echo Request timeout.')
    try:
        ether[IPv6]["ICMPv6 Echo Request"]
    except KeyError:
        raise RuntimeError("Received packet is not an ICMPv6 Echo Request.")
    print "ICMP Echo: OK."

    rxq = RxQueue(src_if)
    txq = TxQueue(dst_if)

    icmpv6_ping_pkt = (Ether(src=dst_mac, dst=proxy_to_dst_mac) /
                       IPv6(src=dst_ip, dst=src_ip) / ICMPv6EchoReply())

    txq.send(icmpv6_ping_pkt)

    ether = None
    while True:
        ether = rxq.recv(3)
        if not ether:
            continue
        if ether.haslayer(ICMPv6ND_NS):
            # read another packet in the queue in case of ICMPv6ND_NS packet
            continue
        else:
            # otherwise process the current packet
            break

    if ether is None:
        raise RuntimeError('DHCPv6 SOLICIT timeout')
    try:
        ether[IPv6]["ICMPv6 Echo Reply"]
    except KeyError:
        raise RuntimeError("Received packet is not an ICMPv6 Echo Reply.")

    print "ICMP Reply: OK."
Example #21
0
def bcast_icmp6():
    """
       Send broadcast IP6 ping
    """
    send(IPv6(dst="ff02::1") / ICMPv6EchoRequest() / "whosthere")
Example #22
0
def main():
    """Send a simple L2 or ICMP packet from one TG interface to DUT, then
    receive a copy of the packet on the second TG interface, and a copy of
    the ICMP reply."""
    args = TrafficScriptArg(
        ['tg_src_mac', 'src_ip', 'dst_ip', 'dut_if1_mac', 'ptype'])

    src_mac = args.get_arg('tg_src_mac')
    dst_mac = args.get_arg('dut_if1_mac')
    src_ip = args.get_arg('src_ip')
    dst_ip = args.get_arg('dst_ip')
    tx_if = args.get_arg('tx_if')
    rx_if = args.get_arg('rx_if')
    ptype = args.get_arg('ptype')

    rxq_mirrored = RxQueue(rx_if)
    rxq_tx = RxQueue(tx_if)
    txq = TxQueue(tx_if)

    sent = []

    if ptype == "ARP":
        pkt_raw = (Ether(src=src_mac, dst=dst_mac) /
                   ARP(hwsrc=src_mac,
                       hwdst="00:00:00:00:00:00",
                       psrc=src_ip,
                       pdst=dst_ip,
                       op="who-has"))
    elif ptype == "ICMP":
        if valid_ipv4(src_ip) and valid_ipv4(dst_ip):
            pkt_raw = (Ether(src=src_mac, dst=dst_mac) /
                       IP(src=src_ip, dst=dst_ip) / ICMP(type="echo-request"))
        else:
            raise ValueError("IP addresses not in correct format")
    elif ptype == "ICMPv6":
        if valid_ipv6(src_ip) and valid_ipv6(dst_ip):
            pkt_raw = (Ether(src=src_mac, dst=dst_mac) /
                       IPv6(src=src_ip, dst=dst_ip) / ICMPv6EchoRequest())
        else:
            raise ValueError("IPv6 addresses not in correct format")
    else:
        raise RuntimeError("Unexpected payload type.")

    txq.send(pkt_raw)
    sent.append(auto_pad(pkt_raw))
    ether = rxq_mirrored.recv(2)

    # Receive copy of Rx packet.
    if ether is None:
        raise RuntimeError("Rx timeout of mirrored Rx packet")
    pkt = auto_pad(pkt_raw)
    if str(ether) != str(pkt):
        print("Mirrored Rx packet doesn't match the original Rx packet.")
        if ether.src != src_mac or ether.dst != dst_mac:
            raise RuntimeError("MAC mismatch in mirrored Rx packet.")
        if ptype == "ARP":
            if not ether.haslayer(ARP):
                raise RuntimeError("Mirrored Rx packet is not an ARP packet.")
            if ether['ARP'].op != 1:  # 1=who-has
                raise RuntimeError("Mirrored Rx packet is not an ARP request.")
            if ether['ARP'].hwsrc != src_mac or ether['ARP'].hwdst != dst_mac:
                raise RuntimeError("MAC mismatch in mirrored Rx ARP packet.")
            if ether['ARP'].psrc != src_ip or ether['ARP'].pdst != dst_ip:
                raise RuntimeError("IP address mismatch in mirrored "
                                   "Rx ARP packet.")
        elif ptype == "ICMP":
            if not ether.haslayer(IP):
                raise RuntimeError("Mirrored Rx packet is not an IPv4 packet.")
            if ether['IP'].src != src_ip or ether['IP'].dst != dst_ip:
                raise RuntimeError("IP address mismatch in mirrored "
                                   "Rx IPv4 packet.")
            if not ether.haslayer(ICMP):
                raise RuntimeError("Mirrored Rx packet is not an ICMP packet.")
            if ether['ICMP'].type != 8:  # 8=echo-request
                raise RuntimeError("Mirrored Rx packet is not an ICMP "
                                   "echo request.")
        elif ptype == "ICMPv6":
            if not ether.haslayer(IPv6):
                raise RuntimeError("Mirrored Rx packet is not an IPv6 packet.")
            if ether['IPv6'].src != src_ip or ether['IPv6'].dst != dst_ip:
                raise RuntimeError("IP address mismatch in mirrored "
                                   "Rx IPv6 packet.")
            if not ether.haslayer(ICMPv6EchoRequest):
                raise RuntimeError("Mirrored Rx packet is not an ICMPv6 "
                                   "echo request.")
    print("Mirrored Rx packet check OK.\n")

    # Receive reply on TG Tx port.
    ether_repl = rxq_tx.recv(2, sent)
    if ether_repl is None:
        raise RuntimeError("Reply not received on TG Tx port.")
    else:
        print("Reply received on TG Tx port.\n")

    # Receive copy of Tx packet.
    ether = rxq_mirrored.recv(2)
    if ether is None:
        raise RuntimeError("Rx timeout of mirrored Tx packet")
    if str(ether) != str(ether_repl):
        print("Mirrored Tx packet doesn't match the received Tx packet.")
        if ether.src != ether_repl.src or ether.dst != ether_repl.dst:
            raise RuntimeError("MAC mismatch in mirrored Tx packet.")
        if ptype == "ARP":
            if not ether.haslayer(ARP):
                raise RuntimeError("Mirrored Tx packet is not an ARP packet.")
            if ether['ARP'].op != ether_repl['ARP'].op:  # 2=is_at
                raise RuntimeError("ARP operational code mismatch "
                                   "in mirrored Tx packet.")
            if ether['ARP'].hwsrc != ether_repl['ARP'].hwsrc\
                    or ether['ARP'].hwdst != ether_repl['ARP'].hwdst:
                raise RuntimeError("MAC mismatch in mirrored Tx ARP packet.")
            if ether['ARP'].psrc != ether_repl['ARP'].psrc\
                    or ether['ARP'].pdst != ether_repl['ARP'].pdst:
                raise RuntimeError("IP address mismatch in mirrored "
                                   "Tx ARP packet.")
        elif ptype == "ICMP":
            if not ether.haslayer(IP):
                raise RuntimeError("Mirrored Tx packet is not an IPv4 packet.")
            if ether['IP'].src != ether_repl['IP'].src\
                    or ether['IP'].dst != ether_repl['IP'].dst:
                raise RuntimeError("IP address mismatch in mirrored "
                                   "Tx IPv4 packet.")
            if not ether.haslayer(ICMP):
                raise RuntimeError("Mirrored Tx packet is not an ICMP packet.")
            if ether['ICMP'].type != ether_repl['ICMP'].type:  # 0=echo-reply
                raise RuntimeError("ICMP packet type mismatch "
                                   "in mirrored Tx packet.")
        elif ptype == "ICMPv6":
            if not ether.haslayer(IPv6):
                raise RuntimeError("Mirrored Tx packet is not an IPv6 packet.")
            if ether['IPv6'].src != ether_repl['IPv6'].src\
                    or ether['IPv6'].dst != ether_repl['IPv6'].dst:
                raise RuntimeError("IP address mismatch in mirrored "
                                   "Tx IPv6 packet.")
            if ether[2].name != ether_repl[2].name:
                raise RuntimeError("ICMPv6 message type mismatch "
                                   "in mirrored Tx packet.")
    print("Mirrored Tx packet check OK.\n")
    sys.exit(0)
def ipv6_ping(src_if, dst_if, src_mac, dst_mac, proxy_to_src_mac,
              proxy_to_dst_mac, src_ip, dst_ip):
    """Sends ICMPv6 Echo Request, receive it and send a reply.

    :param src_if: First TG interface on link to DUT.
    :param dst_if: Second TG interface on link to DUT.
    :param src_mac: MAC address of first interface.
    :param dst_mac: MAC address of second interface.
    :param proxy_to_src_mac: MAC address of first proxy interface on DUT.
    :param proxy_to_dst_mac: MAC address of second proxy interface on DUT.
    :param src_ip: IP address of first interface.
    :param dst_ip: IP address of second interface.
    :type src_if: str
    :type dst_if: str
    :type src_mac: str
    :type dst_mac: str
    :type proxy_to_src_mac: str
    :type proxy_to_dst_mac: str
    :type src_ip: str
    :type dst_ip: str
    :raises RuntimeError: If a received packet is not correct.
    """
    rxq = RxQueue(dst_if)
    txq = TxQueue(src_if)

    icmpv6_ping_pkt = \
        Ether(src=src_mac, dst=proxy_to_src_mac) / \
        IPv6(src=src_ip, dst=dst_ip) / \
        ICMPv6EchoRequest()

    txq.send(icmpv6_ping_pkt)

    ether = None
    for _ in range(5):
        pkt = rxq.recv(3)
        if pkt is not None:
            ether = pkt
            break

    if ether is None:
        raise RuntimeError('ICMPv6 Echo Request timeout.')
    try:
        ether["IPv6"]["ICMPv6 Echo Request"]
    except KeyError:
        raise RuntimeError("Received packet is not an ICMPv6 Echo Request.")
    print "ICMP Echo: OK."

    rxq = RxQueue(src_if)
    txq = TxQueue(dst_if)

    icmpv6_ping_pkt = \
        Ether(src=dst_mac, dst=proxy_to_dst_mac) / \
        IPv6(src=dst_ip, dst=src_ip) / \
        ICMPv6EchoReply()

    txq.send(icmpv6_ping_pkt)

    ether = None
    for _ in range(5):
        pkt = rxq.recv(3)
        if pkt is not None:
            ether = pkt
            break

    if ether is None:
        raise RuntimeError('DHCPv6 SOLICIT timeout')
    try:
        ether["IPv6"]["ICMPv6 Echo Reply"]
    except KeyError:
        raise RuntimeError("Received packet is not an ICMPv6 Echo Reply.")

    print "ICMP Reply: OK."
def main():
    args = TrafficScriptArg([
        'src_mac', 'dst_mac', 'src_nh_mac', 'dst_nh_mac', 'src_ip', 'dst_ip',
        'h_num'
    ])

    src_rxq = RxQueue(args.get_arg('rx_if'))
    src_txq = TxQueue(args.get_arg('rx_if'))
    dst_rxq = RxQueue(args.get_arg('tx_if'))
    dst_txq = TxQueue(args.get_arg('tx_if'))

    src_mac = args.get_arg('src_mac')
    dst_mac = args.get_arg('dst_mac')
    src_nh_mac = args.get_arg('src_nh_mac')
    dst_nh_mac = args.get_arg('dst_nh_mac')
    src_ip = args.get_arg('src_ip')
    dst_ip = args.get_arg('dst_ip')
    hop_num = int(args.get_arg('h_num'))
    hop_limit = 64
    echo_id = 0xa
    echo_seq = 0x1

    src_sent_packets = []
    dst_sent_packets = []

    # send ICMPv6 neighbor advertisement message
    pkt_send = (Ether(src=src_mac, dst='ff:ff:ff:ff:ff:ff') /
                IPv6(src=src_ip, dst='ff02::1:ff00:2') /
                ICMPv6ND_NA(tgt=src_ip, R=0) /
                ICMPv6NDOptDstLLAddr(lladdr=src_mac))
    src_sent_packets.append(pkt_send)
    src_txq.send(pkt_send)
    pkt_send = (Ether(src=dst_mac, dst='ff:ff:ff:ff:ff:ff') /
                IPv6(src=dst_ip, dst='ff02::1:ff00:2') /
                ICMPv6ND_NA(tgt=dst_ip, R=0) /
                ICMPv6NDOptDstLLAddr(lladdr=dst_mac))
    dst_sent_packets.append(pkt_send)
    dst_txq.send(pkt_send)

    # send ICMPv6 echo request from first TG interface
    pkt_send = (Ether(src=src_mac, dst=src_nh_mac) /
                IPv6(src=src_ip, dst=dst_ip, hlim=hop_limit) /
                ICMPv6EchoRequest(id=echo_id, seq=echo_seq))
    src_sent_packets.append(pkt_send)
    src_txq.send(pkt_send)

    # receive ICMPv6 echo request on second TG interface
    ether = dst_rxq.recv(2, dst_sent_packets)
    if ether is None:
        raise RuntimeError('ICMPv6 echo reply Rx timeout')

    if not ether.haslayer(IPv6):
        raise RuntimeError(
            'Unexpected packet with no IPv6 received {0}'.format(
                ether.__repr__()))

    ipv6 = ether['IPv6']

    # verify hop limit processing
    if ipv6.hlim != (hop_limit - hop_num):
        raise RuntimeError('Invalid hop limit {0} should be {1}'.format(
            ipv6.hlim, hop_limit - hop_num))

    if not ipv6.haslayer(ICMPv6EchoRequest):
        raise RuntimeError(
            'Unexpected packet with no IPv6 ICMP received {0}'.format(
                ipv6.__repr__()))

    icmpv6 = ipv6['ICMPv6 Echo Request']

    # check identifier and sequence number
    if icmpv6.id != echo_id or icmpv6.seq != echo_seq:
        raise RuntimeError(
            'Invalid ICMPv6 echo reply received ID {0} seq {1} should be ' \
            'ID {2} seq {3}'.format(icmpv6.id, icmpv6.seq, echo_id, echo_seq))

    # verify checksum
    cksum = icmpv6.cksum
    del icmpv6.cksum
    tmp = ICMPv6EchoRequest(str(icmpv6))
    if not checksum_equal(tmp.cksum, cksum):
        raise RuntimeError('Invalid checksum {0} should be {1}'.format(
            cksum, tmp.cksum))

    # send ICMPv6 echo reply from second TG interface
    pkt_send = (Ether(src=dst_mac, dst=dst_nh_mac) /
                IPv6(src=dst_ip, dst=src_ip) /
                ICMPv6EchoReply(id=echo_id, seq=echo_seq))
    dst_sent_packets.append(pkt_send)
    dst_txq.send(pkt_send)

    # receive ICMPv6 echo reply on first TG interface
    ether = src_rxq.recv(2, src_sent_packets)
    if ether is None:
        raise RuntimeError('ICMPv6 echo reply Rx timeout')

    if not ether.haslayer(IPv6):
        raise RuntimeError(
            'Unexpected packet with no IPv6 received {0}'.format(
                ether.__repr__()))

    ipv6 = ether['IPv6']

    # verify hop limit processing
    if ipv6.hlim != (hop_limit - hop_num):
        raise RuntimeError('Invalid hop limit {0} should be {1}'.format(
            ipv6.hlim, hop_limit - hop_num))

    if not ipv6.haslayer(ICMPv6EchoReply):
        raise RuntimeError(
            'Unexpected packet with no IPv6 ICMP received {0}'.format(
                ipv6.__repr__()))

    icmpv6 = ipv6['ICMPv6 Echo Reply']

    # check identifier and sequence number
    if icmpv6.id != echo_id or icmpv6.seq != echo_seq:
        raise RuntimeError(
            'Invalid ICMPv6 echo reply received ID {0} seq {1} should be ' \
            'ID {2} seq {3}'.format(icmpv6.id, icmpv6.seq, echo_id, echo_seq))

    # verify checksum
    cksum = icmpv6.cksum
    del icmpv6.cksum
    tmp = ICMPv6EchoReply(str(icmpv6))
    if not checksum_equal(tmp.cksum, cksum):
        raise RuntimeError('Invalid checksum {0} should be {1}'.format(
            cksum, tmp.cksum))

    sys.exit(0)
Example #25
0
    def test_dslite(self):
        """ Test DS-Lite """
        nat_config = self.vapi.nat_show_config()
        self.assertEqual(0, nat_config.dslite_ce)

        self.vapi.dslite_add_del_pool_addr_range(start_addr=self.nat_addr,
                                                 end_addr=self.nat_addr,
                                                 is_add=1)
        aftr_ip4 = '192.0.0.1'
        aftr_ip6 = '2001:db8:85a3::8a2e:370:1'
        self.vapi.dslite_set_aftr_addr(ip4_addr=aftr_ip4, ip6_addr=aftr_ip6)
        self.vapi.syslog_set_sender(self.pg2.local_ip4, self.pg2.remote_ip4)

        # UDP
        p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
             IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[0].ip6) /
             IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
             UDP(sport=20000, dport=10000))
        self.pg1.add_stream(p)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        capture = self.pg0.get_capture(1)
        capture = capture[0]
        self.assertFalse(capture.haslayer(IPv6))
        self.assertEqual(capture[IP].src, self.nat_addr)
        self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
        self.assertNotEqual(capture[UDP].sport, 20000)
        self.assertEqual(capture[UDP].dport, 10000)
        self.assert_packet_checksums_valid(capture)
        out_port = capture[UDP].sport
        capture = self.pg2.get_capture(1)
        self.verify_syslog_apmadd(capture[0][Raw].load, '192.168.1.1',
                                  20000, self.nat_addr, out_port,
                                  self.pg1.remote_hosts[0].ip6, IP_PROTOS.udp)

        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
             UDP(sport=10000, dport=out_port))
        self.pg0.add_stream(p)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        capture = self.pg1.get_capture(1)
        capture = capture[0]
        self.assertEqual(capture[IPv6].src, aftr_ip6)
        self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[0].ip6)
        self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
        self.assertEqual(capture[IP].dst, '192.168.1.1')
        self.assertEqual(capture[UDP].sport, 10000)
        self.assertEqual(capture[UDP].dport, 20000)
        self.assert_packet_checksums_valid(capture)

        # TCP
        p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
             IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
             IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
             TCP(sport=20001, dport=10001))
        self.pg1.add_stream(p)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        capture = self.pg0.get_capture(1)
        capture = capture[0]
        self.assertFalse(capture.haslayer(IPv6))
        self.assertEqual(capture[IP].src, self.nat_addr)
        self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
        self.assertNotEqual(capture[TCP].sport, 20001)
        self.assertEqual(capture[TCP].dport, 10001)
        self.assert_packet_checksums_valid(capture)
        out_port = capture[TCP].sport

        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
             TCP(sport=10001, dport=out_port))
        self.pg0.add_stream(p)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        capture = self.pg1.get_capture(1)
        capture = capture[0]
        self.assertEqual(capture[IPv6].src, aftr_ip6)
        self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
        self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
        self.assertEqual(capture[IP].dst, '192.168.1.1')
        self.assertEqual(capture[TCP].sport, 10001)
        self.assertEqual(capture[TCP].dport, 20001)
        self.assert_packet_checksums_valid(capture)

        # ICMP
        p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
             IPv6(dst=aftr_ip6, src=self.pg1.remote_hosts[1].ip6) /
             IP(dst=self.pg0.remote_ip4, src='192.168.1.1') /
             ICMP(id=4000, type='echo-request'))
        self.pg1.add_stream(p)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        capture = self.pg0.get_capture(1)
        capture = capture[0]
        self.assertFalse(capture.haslayer(IPv6))
        self.assertEqual(capture[IP].src, self.nat_addr)
        self.assertEqual(capture[IP].dst, self.pg0.remote_ip4)
        self.assertNotEqual(capture[ICMP].id, 4000)
        self.assert_packet_checksums_valid(capture)
        out_id = capture[ICMP].id

        p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
             IP(dst=self.nat_addr, src=self.pg0.remote_ip4) /
             ICMP(id=out_id, type='echo-reply'))
        self.pg0.add_stream(p)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        capture = self.pg1.get_capture(1)
        capture = capture[0]
        self.assertEqual(capture[IPv6].src, aftr_ip6)
        self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
        self.assertEqual(capture[IP].src, self.pg0.remote_ip4)
        self.assertEqual(capture[IP].dst, '192.168.1.1')
        self.assertEqual(capture[ICMP].id, 4000)
        self.assert_packet_checksums_valid(capture)

        # ping DS-Lite AFTR tunnel endpoint address
        p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) /
             IPv6(src=self.pg1.remote_hosts[1].ip6, dst=aftr_ip6) /
             ICMPv6EchoRequest())
        self.pg1.add_stream(p)
        self.pg_enable_capture(self.pg_interfaces)
        self.pg_start()
        capture = self.pg1.get_capture(1)
        capture = capture[0]
        self.assertEqual(capture[IPv6].src, aftr_ip6)
        self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6)
        self.assertTrue(capture.haslayer(ICMPv6EchoReply))

        b4s = self.statistics.get_counter('/dslite/total-b4s')
        self.assertEqual(b4s[0][0], 2)
        sessions = self.statistics.get_counter('/dslite/total-sessions')
        self.assertEqual(sessions[0][0], 3)
def main():
    """Send ICMP echo request and wait for ICMP echo reply. It ignores all other
    packets."""
    args = TrafficScriptArg(
        ['dst_mac', 'src_mac', 'dst_ip', 'src_ip', 'timeout'])

    dst_mac = args.get_arg('dst_mac')
    src_mac = args.get_arg('src_mac')
    dst_ip = args.get_arg('dst_ip')
    src_ip = args.get_arg('src_ip')
    tx_if = args.get_arg('tx_if')
    rx_if = args.get_arg('rx_if')
    timeout = int(args.get_arg('timeout'))
    wait_step = 1

    rxq = RxQueue(rx_if)
    txq = TxQueue(tx_if)
    sent_packets = []

    # Create empty ip ICMP packet
    if valid_ipv4(src_ip) and valid_ipv4(dst_ip):
        icmp_request = (Ether(src=src_mac, dst=dst_mac) /
                        IP(src=src_ip, dst=dst_ip) / ICMP())
        ip_format = {
            'IPType': 'IP',
            'ICMP_req': 'ICMP',
            'ICMP_rep': 'ICMP',
            'Type': 0
        }
    elif valid_ipv6(src_ip) and valid_ipv6(dst_ip):
        icmp_request = (Ether(src=src_mac, dst=dst_mac) /
                        IPv6(src=src_ip, dst=dst_ip) / ICMPv6EchoRequest())
        ip_format = {
            'IPType': 'IPv6',
            'ICMP_req': 'ICMPv6 Echo Request',
            'ICMP_rep': 'ICMPv6 Echo Reply',
            'Type': 129
        }
    else:
        raise ValueError("IP not in correct format")

    # Send created packet on the interface
    sent_packets.append(icmp_request)
    txq.send(icmp_request)

    for _ in range(1000):
        while True:
            icmp_reply = rxq.recv(wait_step, ignore=sent_packets)
            if icmp_reply is None:
                timeout -= wait_step
                if timeout < 0:
                    raise RuntimeError("ICMP echo Rx timeout")

            elif icmp_reply.haslayer(ICMPv6ND_NS):
                # read another packet in the queue in case of ICMPv6ND_NS packet
                continue
            else:
                # otherwise process the current packet
                break

        if is_icmp_reply(icmp_reply, ip_format):
            if address_check(icmp_request, icmp_reply, ip_format):
                break
    else:
        raise RuntimeError("Max packet count limit reached")

    print "ICMP echo reply received."

    sys.exit(0)
Example #27
0
def main():
    """Send IP ICMPv4/ICMPv6 packet from one traffic generator interface to
    the other one. Dot1q or Dot1ad tagging of the ethernet frame can be set.
    """
    args = TrafficScriptArg(['src_mac', 'dst_mac', 'src_ip', 'dst_ip'],
                            ['encaps', 'vlan1', 'vlan2', 'encaps_rx',
                             'vlan1_rx', 'vlan2_rx'])

    src_mac = args.get_arg('src_mac')
    dst_mac = args.get_arg('dst_mac')
    src_ip = args.get_arg('src_ip')
    dst_ip = args.get_arg('dst_ip')

    encaps = args.get_arg('encaps')
    vlan1 = args.get_arg('vlan1')
    vlan2 = args.get_arg('vlan2')
    encaps_rx = args.get_arg('encaps_rx')
    vlan1_rx = args.get_arg('vlan1_rx')
    vlan2_rx = args.get_arg('vlan2_rx')

    tx_if = args.get_arg('tx_if')
    rx_if = args.get_arg('rx_if')

    rxq = RxQueue(rx_if)
    txq = TxQueue(tx_if)

    sent_packets = []
    ip_format = ''
    icmp_format = ''
    # Create empty ip ICMP packet and add padding before sending
    if valid_ipv4(src_ip) and valid_ipv4(dst_ip):
        if encaps == 'Dot1q':
            pkt_raw = (Ether(src=src_mac, dst=dst_mac) /
                       Dot1Q(vlan=int(vlan1)) /
                       IP(src=src_ip, dst=dst_ip) /
                       ICMP())
        elif encaps == 'Dot1ad':
            pkt_raw = (Ether(src=src_mac, dst=dst_mac, type=0x88A8) /
                       Dot1Q(vlan=int(vlan1), type=0x8100) /
                       Dot1Q(vlan=int(vlan2)) /
                       IP(src=src_ip, dst=dst_ip) /
                       ICMP())
        else:
            pkt_raw = (Ether(src=src_mac, dst=dst_mac) /
                       IP(src=src_ip, dst=dst_ip) /
                       ICMP())
        ip_format = IP
        icmp_format = ICMP
    elif valid_ipv6(src_ip) and valid_ipv6(dst_ip):
        if encaps == 'Dot1q':
            pkt_raw = (Ether(src=src_mac, dst=dst_mac) /
                       Dot1Q(vlan=int(vlan1)) /
                       IPv6(src=src_ip, dst=dst_ip) /
                       ICMPv6EchoRequest())
        elif encaps == 'Dot1ad':
            pkt_raw = (Ether(src=src_mac, dst=dst_mac, type=0x88A8) /
                       Dot1Q(vlan=int(vlan1), type=0x8100) /
                       Dot1Q(vlan=int(vlan2)) /
                       IPv6(src=src_ip, dst=dst_ip) /
                       ICMPv6EchoRequest())
        else:
            pkt_raw = (Ether(src=src_mac, dst=dst_mac) /
                       IPv6(src=src_ip, dst=dst_ip) /
                       ICMPv6EchoRequest())
        ip_format = IPv6
        icmp_format = ICMPv6EchoRequest
    else:
        raise ValueError("IP(s) not in correct format")

    # Send created packet on one interface and receive on the other
    sent_packets.append(pkt_raw)
    txq.send(pkt_raw)

    # Receive ICMP / ICMPv6 echo reply
    while True:
        ether = rxq.recv(2,)
        if ether is None:
            raise RuntimeError('ICMP echo Rx timeout')

        if ether.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 whether received packet contains layers IP/IPv6 and
    # ICMP/ICMPv6EchoRequest
    if encaps_rx:
        if encaps_rx == 'Dot1q':
            if not vlan1_rx:
                vlan1_rx = vlan1
            if not ether.haslayer(Dot1Q):
                raise RuntimeError('Not VLAN tagged Eth frame received:\n{0}'.
                                   format(ether.__repr__()))
            elif ether[Dot1Q].vlan != int(vlan1_rx):
                raise RuntimeError('Ethernet frame with wrong VLAN tag ({}) '
                                   'received ({} expected):\n{}'.
                                   format(ether[Dot1Q].vlan, vlan1_rx,
                                          ether.__repr__()))
        elif encaps_rx == 'Dot1ad':
            if not vlan1_rx:
                vlan1_rx = vlan1
            if not vlan2_rx:
                vlan2_rx = vlan2
            # TODO
            raise RuntimeError('Encapsulation {0} not implemented yet.'.
                               format(encaps_rx))
        else:
            raise RuntimeError('Unsupported encapsulation expected: {0}'.
                               format(encaps_rx))

    if not ether.haslayer(ip_format):
        raise RuntimeError('Not an IP/IPv6 packet received:\n{0}'.
                           format(ether.__repr__()))

    if not ether.haslayer(icmp_format):
        raise RuntimeError('Not an ICMP/ICMPv6EchoRequest packet received:\n'
                           '{0}'.format(ether.__repr__()))

    sys.exit(0)
Example #28
0
def main():
    args = TrafficScriptArg([
        'src_mac', 'dst_mac', 'src_nh_mac', 'dst_nh_mac', 'src_ip', 'dst_ip',
        'h_num'
    ], ['is_dst_tg'])

    src_rxq = RxQueue(args.get_arg('tx_if'))
    src_txq = TxQueue(args.get_arg('tx_if'))

    src_mac = args.get_arg('src_mac')
    dst_mac = args.get_arg('dst_mac')
    src_nh_mac = args.get_arg('src_nh_mac')
    dst_nh_mac = args.get_arg('dst_nh_mac')
    src_ip = args.get_arg('src_ip')
    dst_ip = args.get_arg('dst_ip')
    hop_num = int(args.get_arg('h_num'))

    is_dst_tg = True if args.get_arg('is_dst_tg') in ['True', ''] else False
    dst_rxq = RxQueue(args.get_arg('rx_if')) if is_dst_tg else None
    dst_txq = TxQueue(args.get_arg('rx_if')) if is_dst_tg else None

    hop_limit = 64
    echo_id = 0xa
    echo_seq = 0x1

    src_sent_packets = []
    dst_sent_packets = []

    # send ICMPv6 neighbor advertisement message
    pkt_send = (Ether(src=src_mac, dst='ff:ff:ff:ff:ff:ff') /
                IPv6(src=src_ip, dst='ff02::1:ff00:2') /
                ICMPv6ND_NA(tgt=src_ip, R=0) /
                ICMPv6NDOptDstLLAddr(lladdr=src_mac))
    src_sent_packets.append(pkt_send)
    src_txq.send(pkt_send)

    if is_dst_tg:
        # send ICMPv6 neighbor advertisement message
        pkt_send = (Ether(src=dst_mac, dst='ff:ff:ff:ff:ff:ff') /
                    IPv6(src=dst_ip, dst='ff02::1:ff00:2') /
                    ICMPv6ND_NA(tgt=dst_ip, R=0) /
                    ICMPv6NDOptDstLLAddr(lladdr=dst_mac))
        dst_sent_packets.append(pkt_send)
        dst_txq.send(pkt_send)

    # send ICMPv6 echo request from first TG interface
    pkt_send = (Ether(src=src_mac, dst=src_nh_mac) /
                IPv6(src=src_ip, dst=dst_ip, hlim=hop_limit) /
                ICMPv6EchoRequest(id=echo_id, seq=echo_seq))
    src_sent_packets.append(pkt_send)
    src_txq.send(pkt_send)

    if is_dst_tg:
        # receive ICMPv6 echo request on second TG interface
        while True:
            ether = dst_rxq.recv(2, dst_sent_packets)
            if ether is None:
                raise RuntimeError('ICMPv6 echo reply Rx timeout')

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

        if not ether.haslayer(IPv6):
            raise RuntimeError(
                'Unexpected packet with no IPv6 received: {0}'.format(
                    ether.__repr__()))

        ipv6 = ether[IPv6]

        # verify hop limit processing
        if ipv6.hlim != (hop_limit - hop_num):
            raise RuntimeError('Invalid hop limit {0} should be {1}'.format(
                ipv6.hlim, hop_limit - hop_num))

        if not ipv6.haslayer(ICMPv6EchoRequest):
            raise RuntimeError('Unexpected packet with no IPv6 ICMP received '
                               '{0}'.format(ipv6.__repr__()))

        icmpv6 = ipv6[ICMPv6EchoRequest]

        # check identifier and sequence number
        if icmpv6.id != echo_id or icmpv6.seq != echo_seq:
            raise RuntimeError('Invalid ICMPv6 echo reply received ID {0} '
                               'seq {1} should be ID {2} seq {3}'.format(
                                   icmpv6.id, icmpv6.seq, echo_id, echo_seq))

        # verify checksum
        cksum = icmpv6.cksum
        del icmpv6.cksum
        tmp = ICMPv6EchoRequest(str(icmpv6))
        if not checksum_equal(tmp.cksum, cksum):
            raise RuntimeError('Invalid checksum {0} should be {1}'.format(
                cksum, tmp.cksum))

        # send ICMPv6 echo reply from second TG interface
        pkt_send = (Ether(src=dst_mac, dst=dst_nh_mac) /
                    IPv6(src=dst_ip, dst=src_ip, hlim=(ipv6.hlim - 1)) /
                    ICMPv6EchoReply(id=echo_id, seq=echo_seq))
        dst_sent_packets.append(pkt_send)
        dst_txq.send(pkt_send)

    # receive ICMPv6 echo reply on first TG interface
    while True:
        ether = src_rxq.recv(2, src_sent_packets)
        if ether is None:
            raise RuntimeError('ICMPv6 echo reply Rx timeout')

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

    if not ether.haslayer(IPv6):
        raise RuntimeError(
            'Unexpected packet with no IPv6 layer received {0}'.format(
                ether.__repr__()))

    ipv6 = ether[IPv6]

    # verify hop limit processing; destination node decrements hlim by one in
    # outgoing ICMPv6 Echo Reply
    directions = 2 if is_dst_tg else 1
    hop_limit_reply = hop_limit - directions * hop_num - 1
    if ipv6.hlim != hop_limit_reply:
        raise RuntimeError('Invalid hop limit {0} should be {1}'.format(
            ipv6.hlim, hop_limit_reply))

    if not ipv6.haslayer(ICMPv6EchoReply):
        raise RuntimeError(
            'Unexpected packet with no IPv6 ICMP received {0}'.format(
                ipv6.__repr__()))

    icmpv6 = ipv6[ICMPv6EchoReply]

    # check identifier and sequence number
    if icmpv6.id != echo_id or icmpv6.seq != echo_seq:
        raise RuntimeError('Invalid ICMPv6 echo reply received ID {0} '
                           'seq {1} should be ID {2} seq {3}'.format(
                               icmpv6.id, icmpv6.seq, echo_id, echo_seq))

    # verify checksum
    cksum = icmpv6.cksum
    del icmpv6.cksum
    tmp = ICMPv6EchoReply(str(icmpv6))
    if not checksum_equal(tmp.cksum, cksum):
        raise RuntimeError('Invalid checksum {0} should be {1}'.format(
            cksum, tmp.cksum))

    sys.exit(0)
Example #29
0
    def create_stream(
        self,
        src_if,
        packet_sizes,
        traffic_type=0,
        ipv6=0,
        proto=-1,
        ports=0,
        fragments=False,
        pkt_raw=True,
        etype=-1,
    ):
        """
        Create input packet stream for defined interface using hosts or
        deleted_hosts list.

        :param object src_if: Interface to create packet stream for.
        :param list packet_sizes: List of required packet sizes.
        :param traffic_type: 1: ICMP packet, 2: IPv6 with EH, 0: otherwise.
        :return: Stream of packets.
        """
        pkts = []
        if self.flows.__contains__(src_if):
            src_hosts = self.hosts_by_pg_idx[src_if.sw_if_index]
            for dst_if in self.flows[src_if]:
                dst_hosts = self.hosts_by_pg_idx[dst_if.sw_if_index]
                n_int = len(dst_hosts) * len(src_hosts)
                for i in range(0, n_int):
                    dst_host = dst_hosts[i // len(src_hosts)]
                    src_host = src_hosts[i % len(src_hosts)]
                    pkt_info = self.create_packet_info(src_if, dst_if)
                    if ipv6 == 1:
                        pkt_info.ip = 1
                    elif ipv6 == 0:
                        pkt_info.ip = 0
                    else:
                        pkt_info.ip = random.choice([0, 1])
                    if proto == -1:
                        pkt_info.proto = random.choice(self.proto[self.IP])
                    else:
                        pkt_info.proto = proto
                    payload = self.info_to_payload(pkt_info)
                    p = Ether(dst=dst_host.mac, src=src_host.mac)
                    if etype > 0:
                        p = Ether(dst=dst_host.mac, src=src_host.mac, type=etype)
                    if pkt_info.ip:
                        p /= IPv6(dst=dst_host.ip6, src=src_host.ip6)
                        if fragments:
                            p /= IPv6ExtHdrFragment(offset=64, m=1)
                    else:
                        if fragments:
                            p /= IP(
                                src=src_host.ip4, dst=dst_host.ip4, flags=1, frag=64
                            )
                        else:
                            p /= IP(src=src_host.ip4, dst=dst_host.ip4)
                    if traffic_type == self.ICMP:
                        if pkt_info.ip:
                            p /= ICMPv6EchoRequest(
                                type=self.icmp6_type, code=self.icmp6_code
                            )
                        else:
                            p /= ICMP(type=self.icmp4_type, code=self.icmp4_code)
                    else:
                        p /= self.create_upper_layer(i, pkt_info.proto, ports)
                    if pkt_raw:
                        p /= Raw(payload)
                        pkt_info.data = p.copy()
                    if pkt_raw:
                        size = random.choice(packet_sizes)
                        self.extend_packet(p, size)
                    pkts.append(p)
        return pkts
Example #30
0
def main():
    """Send IP ICMP packet from one traffic generator interface to the other.

    :raises RuntimeError: If the received packet is not correct."""

    args = TrafficScriptArg([
        'tg_src_mac', 'tg_dst_mac', 'src_ip', 'dst_ip', 'dut_if1_mac',
        'dut_if2_mac', 'src_rloc', 'dst_rloc'
    ])

    tx_src_mac = args.get_arg('tg_src_mac')
    tx_dst_mac = args.get_arg('dut_if1_mac')
    rx_dst_mac = args.get_arg('tg_dst_mac')
    rx_src_mac = args.get_arg('dut_if2_mac')
    src_ip = args.get_arg('src_ip')
    dst_ip = args.get_arg('dst_ip')
    src_rloc = args.get_arg("src_rloc")
    dst_rloc = args.get_arg("dst_rloc")
    tx_if = args.get_arg('tx_if')
    rx_if = args.get_arg('rx_if')

    rxq = RxQueue(rx_if)
    txq = TxQueue(tx_if)
    sent_packets = []
    pkt_raw = Ether(src=tx_src_mac, dst=tx_dst_mac)

    if valid_ipv4(src_ip) and valid_ipv4(dst_ip):
        pkt_raw /= IP(src=src_ip, dst=dst_ip)
        pkt_raw /= ICMP()
        ip_format = IP
    elif valid_ipv6(src_ip) and valid_ipv6(dst_ip):
        pkt_raw /= IPv6(src=src_ip, dst=dst_ip)
        pkt_raw /= ICMPv6EchoRequest()
        ip_format = IPv6
    else:
        raise ValueError("IP not in correct format")

    bind_layers(UDP, LispGPEHeader, dport=4341)

    sent_packets.append(pkt_raw)
    txq.send(pkt_raw)

    if tx_if == rx_if:
        ether = rxq.recv(2, ignore=sent_packets)
    else:
        ether = rxq.recv(2)

    if ether is None:
        raise RuntimeError("ICMP echo Rx timeout")

    if rx_dst_mac == ether[Ether].dst and rx_src_mac == ether[Ether].src:
        print("MAC addresses match.")
    else:
        raise RuntimeError("Matching packet unsuccessful: {0}".format(
            ether.__repr__()))

    ip = ether.payload

    if not isinstance(ip, ip_format):
        raise RuntimeError("Not an IP packet received {0}".format(
            ip.__repr__()))

    lisp = ether.getlayer(LispGPEHeader).underlayer
    if not lisp:
        raise RuntimeError("Lisp layer not present or parsing failed.")

    # Compare data from packets
    if src_ip == lisp.src:
        print("Source IP matches source EID.")
    else:
        raise RuntimeError("Matching Src IP unsuccessful: {} != {}".format(
            src_ip, lisp.src))

    if dst_ip == lisp.dst:
        print("Destination IP matches destination EID.")
    else:
        raise RuntimeError("Matching Dst IP unsuccessful: {} != {}".format(
            dst_ip, lisp.dst))

    if src_rloc == ip.src:
        print("Source RLOC matches configuration.")
    else:
        raise RuntimeError("Matching Src RLOC unsuccessful: {} != {}".format(
            src_rloc, ip.src))

    if dst_rloc == ip.dst:
        print("Destination RLOC matches configuration.")
    else:
        raise RuntimeError("Matching dst RLOC unsuccessful: {} != {}".format(
            dst_rloc, ip.dst))

    sys.exit(0)