def assert_nothing_captured(self, remark=None, filter_out_fn=is_ipv6_misc): """ Assert that nothing unfiltered was captured on interface :param remark: remark printed into debug logs :param filter_out_fn: filter applied to each packet, packets for which the filter returns True are removed from capture """ if os.path.isfile(self.out_path): try: capture = self.get_capture(0, remark=remark, filter_out_fn=filter_out_fn) if capture: if len(capture.res) == 0: # junk filtered out, we're good return self.test.logger.error( ppc("Unexpected packets captured:", capture)) except: pass if remark: raise AssertionError( "Non-empty capture file present for interface %s(%s)" % (self.name, remark)) else: raise AssertionError( "Non-empty capture file present for interface %s" % self.name)
def get_capture(self, expected_count=None, remark=None, timeout=1, filter_out_fn=is_ipv6_misc): """ Get captured packets :param expected_count: expected number of packets to capture, if None, then self.test.packet_count_for_dst_pg_idx is used to lookup the expected count :param remark: remark printed into debug logs :param timeout: how long to wait for packets :param filter_out_fn: filter applied to each packet, packets for which the filter returns True are removed from capture :returns: iterable packets """ remaining_time = timeout capture = None name = self.name if remark is None else "%s (%s)" % (self.name, remark) based_on = "based on provided argument" if expected_count is None: expected_count = \ self.test.get_packet_count_for_if_idx(self.sw_if_index) based_on = "based on stored packet_infos" if expected_count == 0: raise Exception( "Internal error, expected packet count for %s is 0!" % name) self.test.logger.debug("Expecting to capture %s (%s) packets on %s" % (expected_count, based_on, name)) while remaining_time > 0: before = time.time() capture = self._get_capture(remaining_time, filter_out_fn) elapsed_time = time.time() - before if capture: if len(capture.res) == expected_count: # bingo, got the packets we expected return capture elif len(capture.res) > expected_count: self.test.logger.error( ppc("Unexpected packets captured:", capture)) break else: self.test.logger.debug("Partial capture containing %s " "packets doesn't match expected " "count %s (yet?)" % (len(capture.res), expected_count)) elif expected_count == 0: # bingo, got None as we expected - return empty capture return PacketList() remaining_time -= elapsed_time if capture: self.generate_debug_aid("count-mismatch") raise Exception("Captured packets mismatch, captured %s packets, " "expected %s packets on %s" % (len(capture.res), expected_count, name)) else: raise Exception("No packets captured on %s" % name)
def get_capture(self, expected_count=None, remark=None, timeout=1, filter_out_fn=is_ipv6_misc): """ Get captured packets :param expected_count: expected number of packets to capture, if None, then self.test.packet_count_for_dst_pg_idx is used to lookup the expected count :param remark: remark printed into debug logs :param timeout: how long to wait for packets :param filter_out_fn: filter applied to each packet, packets for which the filter returns True are removed from capture :returns: iterable packets """ remaining_time = timeout capture = None name = self.name if remark is None else "%s (%s)" % (self.name, remark) based_on = "based on provided argument" if expected_count is None: expected_count = \ self.test.get_packet_count_for_if_idx(self.sw_if_index) based_on = "based on stored packet_infos" if expected_count == 0: raise Exception( "Internal error, expected packet count for %s is 0!" % name) self.test.logger.debug("Expecting to capture %s (%s) packets on %s" % ( expected_count, based_on, name)) while remaining_time > 0: before = time.time() capture = self._get_capture(remaining_time, filter_out_fn) elapsed_time = time.time() - before if capture: if len(capture.res) == expected_count: # bingo, got the packets we expected return capture elif len(capture.res) > expected_count: self.test.logger.error( ppc("Unexpected packets captured:", capture)) break else: self.test.logger.debug("Partial capture containing %s " "packets doesn't match expected " "count %s (yet?)" % (len(capture.res), expected_count)) elif expected_count == 0: # bingo, got None as we expected - return empty capture return PacketList() remaining_time -= elapsed_time if capture: self.generate_debug_aid("count-mismatch") raise Exception("Captured packets mismatch, captured %s packets, " "expected %s packets on %s" % (len(capture.res), expected_count, name)) else: raise Exception("No packets captured on %s" % name)
def test_ipsec_nat_tun(self): """IPSec/NAT tunnel test case""" p = self.ipv4_params scapy_tun_sa = SecurityAssociation( ESP, spi=p.scapy_tun_spi, crypt_algo=p.crypt_algo, crypt_key=p.crypt_key, auth_algo=p.auth_algo, auth_key=p.auth_key, tunnel_header=IP(src=self.pg1.remote_ip4, dst=self.tun_if.remote_ip4), nat_t_header=UDP(sport=4500, dport=4500), ) # in2out - from private network to public pkts = self.create_stream_plain( self.pg1.remote_mac, self.pg1.local_mac, self.pg1.remote_ip4, self.tun_if.remote_ip4, ) self.pg1.add_stream(pkts) self.pg_enable_capture(self.pg_interfaces) self.pg_start() capture = self.tun_if.get_capture(len(pkts)) self.verify_capture_encrypted(capture, scapy_tun_sa) vpp_tun_sa = SecurityAssociation( ESP, spi=p.vpp_tun_spi, crypt_algo=p.crypt_algo, crypt_key=p.crypt_key, auth_algo=p.auth_algo, auth_key=p.auth_key, tunnel_header=IP(src=self.tun_if.remote_ip4, dst=self.pg1.remote_ip4), nat_t_header=UDP(sport=4500, dport=4500), ) # out2in - from public network to private pkts = self.create_stream_encrypted( self.tun_if.remote_mac, self.tun_if.local_mac, self.tun_if.remote_ip4, self.pg1.remote_ip4, vpp_tun_sa, ) self.logger.info(ppc("Sending packets:", pkts)) self.tun_if.add_stream(pkts) self.pg_enable_capture(self.pg_interfaces) self.pg_start() capture = self.pg1.get_capture(len(pkts)) self.verify_capture_plain(capture)
def verify_tunneled_vlano4(self, src_if, capture, sent, tunnel_src, tunnel_dst, vlan): try: self.assertEqual(len(capture), len(sent)) except: ppc("Unexpected packets captured:", capture) raise for i in range(len(capture)): try: tx = sent[i] rx = capture[i] tx_ip = tx[IP] rx_ip = rx[IP] self.assertEqual(rx_ip.src, tunnel_src) self.assertEqual(rx_ip.dst, tunnel_dst) rx_gre = rx[GRE] rx_l2 = rx_gre[Ether] rx_vlan = rx_l2[Dot1Q] rx_ip = rx_l2[IP] self.assertEqual(rx_vlan.vlan, vlan) tx_gre = tx[GRE] tx_l2 = tx_gre[Ether] tx_ip = tx_l2[IP] self.assertEqual(rx_ip.src, tx_ip.src) self.assertEqual(rx_ip.dst, tx_ip.dst) # bridged, not L3 forwarded, so no TTL decrement self.assertEqual(rx_ip.ttl, tx_ip.ttl) except: self.logger.error(ppp("Rx:", rx)) self.logger.error(ppp("Tx:", tx)) raise
def verify_tunneled_vlano4(self, src_if, capture, sent, tunnel_src, tunnel_dst, vlan): try: self.assertEqual(len(capture), len(sent)) except: ppc("Unexpected packets captured:", capture) raise for i in range(len(capture)): try: tx = sent[i] rx = capture[i] tx_ip = tx[IP] rx_ip = rx[IP] self.assertEqual(rx_ip.src, tunnel_src) self.assertEqual(rx_ip.dst, tunnel_dst) rx_gre = rx[GRE] rx_l2 = rx_gre[Ether] rx_vlan = rx_l2[Dot1Q] rx_ip = rx_l2[IP] self.assertEqual(rx_vlan.vlan, vlan) tx_gre = tx[GRE] tx_l2 = tx_gre[Ether] tx_ip = tx_l2[IP] self.assertEqual(rx_ip.src, tx_ip.src) self.assertEqual(rx_ip.dst, tx_ip.dst) # bridged, not L3 forwarded, so no TTL decrement self.assertEqual(rx_ip.ttl, tx_ip.ttl) except: self.logger.error(ppp("Rx:", rx)) self.logger.error(ppp("Tx:", tx)) raise
def assert_nothing_captured(self, remark=None): if os.path.isfile(self.out_path): try: capture = self.get_capture(remark=remark) self.test.logger.error( ppc("Unexpected packets captured:", capture)) except: pass if remark: raise AssertionError( "Capture file present for interface %s(%s)" % (self.name, remark)) else: raise AssertionError("Capture file present for interface %s" % self.name)
def test_ipsec_nat_tun(self): """ IPSec/NAT tunnel test case """ p = self.ipv4_params scapy_tun_sa = SecurityAssociation(ESP, spi=p.scapy_tun_spi, crypt_algo=p.crypt_algo, crypt_key=p.crypt_key, auth_algo=p.auth_algo, auth_key=p.auth_key, tunnel_header=IP( src=self.pg1.remote_ip4, dst=self.tun_if.remote_ip4), nat_t_header=UDP( sport=4500, dport=4500)) # in2out - from private network to public pkts = self.create_stream_plain( self.pg1.remote_mac, self.pg1.local_mac, self.pg1.remote_ip4, self.tun_if.remote_ip4) self.pg1.add_stream(pkts) self.pg_enable_capture(self.pg_interfaces) self.pg_start() capture = self.tun_if.get_capture(len(pkts)) self.verify_capture_encrypted(capture, scapy_tun_sa) vpp_tun_sa = SecurityAssociation(ESP, spi=p.vpp_tun_spi, crypt_algo=p.crypt_algo, crypt_key=p.crypt_key, auth_algo=p.auth_algo, auth_key=p.auth_key, tunnel_header=IP( src=self.tun_if.remote_ip4, dst=self.pg1.remote_ip4), nat_t_header=UDP( sport=4500, dport=4500)) # out2in - from public network to private pkts = self.create_stream_encrypted( self.tun_if.remote_mac, self.tun_if.local_mac, self.tun_if.remote_ip4, self.pg1.remote_ip4, vpp_tun_sa) self.logger.info(ppc("Sending packets:", pkts)) self.tun_if.add_stream(pkts) self.pg_enable_capture(self.pg_interfaces) self.pg_start() capture = self.pg1.get_capture(len(pkts)) self.verify_capture_plain(capture)
def test_ipsec_nat_tun(self): """ IPSec/NAT tunnel test case """ local_tun_sa = SecurityAssociation(ESP, spi=0x000003e9, crypt_algo='AES-CBC', crypt_key='JPjyOWBeVEQiMe7h', auth_algo='HMAC-SHA1-96', auth_key='C91KUR9GYMm5GfkEvNjX', tunnel_header=IP( src=self.pg1.remote_ip4, dst=self.pg0.remote_ip4), nat_t_header=UDP(sport=4500, dport=4500)) # in2out - from private network to public pkts = self.create_stream_plain(self.pg1.remote_mac, self.pg1.local_mac, self.pg1.remote_ip4, self.pg0.remote_ip4) self.pg1.add_stream(pkts) self.pg_enable_capture(self.pg_interfaces) self.pg_start() capture = self.pg0.get_capture(len(pkts)) self.verify_capture_encrypted(capture, local_tun_sa) remote_tun_sa = SecurityAssociation(ESP, spi=0x000003e8, crypt_algo='AES-CBC', crypt_key='JPjyOWBeVEQiMe7h', auth_algo='HMAC-SHA1-96', auth_key='C91KUR9GYMm5GfkEvNjX', tunnel_header=IP( src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4), nat_t_header=UDP(sport=4500, dport=4500)) # out2in - from public network to private pkts = self.create_stream_encrypted(self.pg0.remote_mac, self.pg0.local_mac, self.pg0.remote_ip4, self.pg1.remote_ip4, remote_tun_sa) self.logger.info(ppc("Sending packets:", pkts)) self.pg0.add_stream(pkts) self.pg_enable_capture(self.pg_interfaces) self.pg_start() capture = self.pg1.get_capture(len(pkts)) self.verify_capture_plain(capture)
def assert_nothing_captured(self, timeout=.25): packets = [] now = time() deadline = now + timeout while now < deadline: r, w, e = select([self.uds], [], [self.uds], deadline - now) if self.uds in r: x = self.uds.recv(1024 * 1024) packets.append(Ether(x[VPP_PUNT_HEADER_SIZE:])) if self.uds in e: raise Exception("select() indicates error on UDS socket") now = time() if len(packets) > 0: self.testcase.logger.error( ppc("Unexpected packets captured:", packets)) raise Exception("Unexpected packet count received, got %s packets," " expected no packets" % len(packets))