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) ]
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)
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")
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)
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)
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)
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)
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)
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)
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)
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)
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)
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()
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)
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)
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)
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."
def bcast_icmp6(): """ Send broadcast IP6 ping """ send(IPv6(dst="ff02::1") / ICMPv6EchoRequest() / "whosthere")
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)
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)
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)
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)
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
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)