xref: /illumos-gate/usr/src/test/os-tests/tests/mac/mac_cksum.c (revision 1f8b8a0145321ca42ee324565958ceb82a14ee7a)
13d6ee46bSPatrick Mooney /*
23d6ee46bSPatrick Mooney  * This file and its contents are supplied under the terms of the
33d6ee46bSPatrick Mooney  * Common Development and Distribution License ("CDDL"), version 1.0.
43d6ee46bSPatrick Mooney  * You may only use this file in accordance with the terms of version
53d6ee46bSPatrick Mooney  * 1.0 of the CDDL.
63d6ee46bSPatrick Mooney  *
73d6ee46bSPatrick Mooney  * A full copy of the text of the CDDL should have accompanied this
83d6ee46bSPatrick Mooney  * source.  A copy of the CDDL is also available via the Internet at
93d6ee46bSPatrick Mooney  * http://www.illumos.org/license/CDDL.
103d6ee46bSPatrick Mooney  */
113d6ee46bSPatrick Mooney 
123d6ee46bSPatrick Mooney /*
133d6ee46bSPatrick Mooney  * Copyright 2025 Oxide Computer Compnay
143d6ee46bSPatrick Mooney  */
153d6ee46bSPatrick Mooney 
163d6ee46bSPatrick Mooney /*
173d6ee46bSPatrick Mooney  * Executor for mac_sw_cksum() ktests.
183d6ee46bSPatrick Mooney  *
193d6ee46bSPatrick Mooney  * This program builds up the packed nvlist payloads expected by the ktest for
203d6ee46bSPatrick Mooney  * mac_sw_cksum().  The caller provides a snoop(1) with one or more packets
213d6ee46bSPatrick Mooney  * bearing valid checksums.  Along with the checksum types selected (via option
223d6ee46bSPatrick Mooney  * flags), it is passed into the ktest, where it is stripped of its checksums
233d6ee46bSPatrick Mooney  * and then run through mac_sw_cksum().  The resulting mblk is compared
243d6ee46bSPatrick Mooney  * byte-for-byte with the original input to determine if the emulation generated
253d6ee46bSPatrick Mooney  * the correct checksums.
263d6ee46bSPatrick Mooney  */
273d6ee46bSPatrick Mooney 
283d6ee46bSPatrick Mooney #include <stdio.h>
293d6ee46bSPatrick Mooney #include <stdlib.h>
303d6ee46bSPatrick Mooney #include <fcntl.h>
313d6ee46bSPatrick Mooney #include <unistd.h>
323d6ee46bSPatrick Mooney #include <err.h>
333d6ee46bSPatrick Mooney #include <errno.h>
343d6ee46bSPatrick Mooney #include <strings.h>
353d6ee46bSPatrick Mooney #include <netinet/in.h>
363d6ee46bSPatrick Mooney #include <sys/mman.h>
373d6ee46bSPatrick Mooney #include <sys/dlpi.h>
383d6ee46bSPatrick Mooney #include <sys/types.h>
393d6ee46bSPatrick Mooney #include <sys/types32.h>
403d6ee46bSPatrick Mooney #include <sys/stat.h>
413d6ee46bSPatrick Mooney #include <sys/sysmacros.h>
42*1f8b8a01SPatrick Mooney #include <sys/ethernet.h>
433d6ee46bSPatrick Mooney 
443d6ee46bSPatrick Mooney #include <libnvpair.h>
453d6ee46bSPatrick Mooney #include <libktest.h>
463d6ee46bSPatrick Mooney 
473d6ee46bSPatrick Mooney typedef struct snoop_pkt_hdr {
483d6ee46bSPatrick Mooney 	uint_t			sph_origlen;
493d6ee46bSPatrick Mooney 	uint_t			sph_msglen;
503d6ee46bSPatrick Mooney 	uint_t			sph_totlen;
513d6ee46bSPatrick Mooney 	uint_t			sph_drops;
523d6ee46bSPatrick Mooney #if defined(_LP64)
533d6ee46bSPatrick Mooney 	struct timeval32	sph_timestamp;
543d6ee46bSPatrick Mooney #else
553d6ee46bSPatrick Mooney #error	"ktest is expected to be 64-bit for now"
563d6ee46bSPatrick Mooney #endif
573d6ee46bSPatrick Mooney } snoop_pkt_hdr_t;
583d6ee46bSPatrick Mooney 
593d6ee46bSPatrick Mooney typedef struct snoop_file_hdr {
603d6ee46bSPatrick Mooney 	char		sfh_magic[8];
613d6ee46bSPatrick Mooney 	uint32_t	sfh_vers;
623d6ee46bSPatrick Mooney 	uint32_t	sfh_mac_type;
633d6ee46bSPatrick Mooney } snoop_file_hdr_t;
643d6ee46bSPatrick Mooney 
653d6ee46bSPatrick Mooney static const char snoop_magic[8] = "snoop\0\0\0";
663d6ee46bSPatrick Mooney static const uint_t snoop_acceptable_vers = 2;
673d6ee46bSPatrick Mooney 
683d6ee46bSPatrick Mooney typedef struct pkt_cap_iter {
693d6ee46bSPatrick Mooney 	int		pci_fd;
703d6ee46bSPatrick Mooney 	const char	*pci_base;
713d6ee46bSPatrick Mooney 	size_t		pci_map_sz;
723d6ee46bSPatrick Mooney 	size_t		pci_sz;
733d6ee46bSPatrick Mooney 	size_t		pci_offset;
743d6ee46bSPatrick Mooney } pkt_cap_iter_t;
753d6ee46bSPatrick Mooney 
763d6ee46bSPatrick Mooney static pkt_cap_iter_t *
pkt_cap_open(int fd)773d6ee46bSPatrick Mooney pkt_cap_open(int fd)
783d6ee46bSPatrick Mooney {
793d6ee46bSPatrick Mooney 	struct stat info;
803d6ee46bSPatrick Mooney 	if (fstat(fd, &info) != 0) {
813d6ee46bSPatrick Mooney 		return (NULL);
823d6ee46bSPatrick Mooney 	}
833d6ee46bSPatrick Mooney 	if (info.st_size < sizeof (snoop_file_hdr_t)) {
843d6ee46bSPatrick Mooney 		errno = EINVAL;
853d6ee46bSPatrick Mooney 		return (NULL);
863d6ee46bSPatrick Mooney 	}
873d6ee46bSPatrick Mooney 
883d6ee46bSPatrick Mooney 	const size_t page_sz = (size_t)sysconf(_SC_PAGESIZE);
893d6ee46bSPatrick Mooney 	const size_t map_sz = P2ROUNDUP(info.st_size, page_sz);
903d6ee46bSPatrick Mooney 	void *map = mmap(NULL, map_sz, PROT_READ, MAP_PRIVATE, fd, 0);
913d6ee46bSPatrick Mooney 	if (map == NULL) {
923d6ee46bSPatrick Mooney 		return (NULL);
933d6ee46bSPatrick Mooney 	}
943d6ee46bSPatrick Mooney 
953d6ee46bSPatrick Mooney 	const snoop_file_hdr_t *hdr = (const snoop_file_hdr_t *)map;
963d6ee46bSPatrick Mooney 	if (bcmp(&hdr->sfh_magic, snoop_magic, sizeof (hdr->sfh_magic)) != 0 ||
973d6ee46bSPatrick Mooney 	    ntohl(hdr->sfh_vers) != snoop_acceptable_vers ||
983d6ee46bSPatrick Mooney 	    ntohl(hdr->sfh_mac_type) != DL_ETHER) {
993d6ee46bSPatrick Mooney 		(void) munmap(map, map_sz);
1003d6ee46bSPatrick Mooney 		errno = EINVAL;
1013d6ee46bSPatrick Mooney 		return (NULL);
1023d6ee46bSPatrick Mooney 	}
1033d6ee46bSPatrick Mooney 
1043d6ee46bSPatrick Mooney 	struct pkt_cap_iter *iter = malloc(sizeof (struct pkt_cap_iter));
1053d6ee46bSPatrick Mooney 	if (iter == NULL) {
1063d6ee46bSPatrick Mooney 		(void) munmap(map, map_sz);
1073d6ee46bSPatrick Mooney 		errno = ENOMEM;
1083d6ee46bSPatrick Mooney 		return (NULL);
1093d6ee46bSPatrick Mooney 	}
1103d6ee46bSPatrick Mooney 
1113d6ee46bSPatrick Mooney 	iter->pci_fd = fd;
1123d6ee46bSPatrick Mooney 	iter->pci_base = (const char *)map;
1133d6ee46bSPatrick Mooney 	iter->pci_map_sz = map_sz;
1143d6ee46bSPatrick Mooney 	iter->pci_sz = info.st_size;
1153d6ee46bSPatrick Mooney 	iter->pci_offset = sizeof (*hdr);
1163d6ee46bSPatrick Mooney 
1173d6ee46bSPatrick Mooney 	return (iter);
1183d6ee46bSPatrick Mooney }
1193d6ee46bSPatrick Mooney 
1203d6ee46bSPatrick Mooney static void
pkt_cap_close(pkt_cap_iter_t * iter)1213d6ee46bSPatrick Mooney pkt_cap_close(pkt_cap_iter_t *iter)
1223d6ee46bSPatrick Mooney {
1233d6ee46bSPatrick Mooney 	(void) munmap((void *)iter->pci_base, iter->pci_map_sz);
1243d6ee46bSPatrick Mooney 	(void) close(iter->pci_fd);
1253d6ee46bSPatrick Mooney 	free(iter);
1263d6ee46bSPatrick Mooney }
1273d6ee46bSPatrick Mooney 
1283d6ee46bSPatrick Mooney static bool
pkt_cap_next(pkt_cap_iter_t * iter,const void ** pkt_buf,uint_t * sizep)1293d6ee46bSPatrick Mooney pkt_cap_next(pkt_cap_iter_t *iter, const void **pkt_buf, uint_t *sizep)
1303d6ee46bSPatrick Mooney {
1313d6ee46bSPatrick Mooney 	size_t remain = iter->pci_sz - iter->pci_offset;
1323d6ee46bSPatrick Mooney 
1333d6ee46bSPatrick Mooney 	if (remain < sizeof (snoop_pkt_hdr_t)) {
1343d6ee46bSPatrick Mooney 		return (false);
1353d6ee46bSPatrick Mooney 	}
1363d6ee46bSPatrick Mooney 
1373d6ee46bSPatrick Mooney 	const snoop_pkt_hdr_t *hdr =
1383d6ee46bSPatrick Mooney 	    (const snoop_pkt_hdr_t *)&iter->pci_base[iter->pci_offset];
1393d6ee46bSPatrick Mooney 
1403d6ee46bSPatrick Mooney 	const uint_t msg_sz = ntohl(hdr->sph_msglen);
1413d6ee46bSPatrick Mooney 	const uint_t total_sz = ntohl(hdr->sph_totlen);
1423d6ee46bSPatrick Mooney 	if (remain < total_sz || remain < msg_sz) {
1433d6ee46bSPatrick Mooney 		return (false);
1443d6ee46bSPatrick Mooney 	}
1453d6ee46bSPatrick Mooney 
1463d6ee46bSPatrick Mooney 	*pkt_buf = (const void *)&hdr[1];
1473d6ee46bSPatrick Mooney 	*sizep = msg_sz;
1483d6ee46bSPatrick Mooney 	iter->pci_offset += total_sz;
1493d6ee46bSPatrick Mooney 	return (true);
1503d6ee46bSPatrick Mooney }
1513d6ee46bSPatrick Mooney 
1523d6ee46bSPatrick Mooney static ktest_hdl_t *kthdl = NULL;
1533d6ee46bSPatrick Mooney const char *mac_cksum_cmd = "";
1543d6ee46bSPatrick Mooney 
1553d6ee46bSPatrick Mooney struct payload_opts {
1563d6ee46bSPatrick Mooney 	uint_t		po_padding;
1573d6ee46bSPatrick Mooney 	boolean_t	po_cksum_partial;
1583d6ee46bSPatrick Mooney 	boolean_t	po_cksum_full;
1593d6ee46bSPatrick Mooney 	boolean_t	po_cksum_ipv4;
160*1f8b8a01SPatrick Mooney 	boolean_t	po_split_ether;
161*1f8b8a01SPatrick Mooney 	uint_t		po_split_manual;
1623d6ee46bSPatrick Mooney };
1633d6ee46bSPatrick Mooney 
1643d6ee46bSPatrick Mooney static char *
build_payload(const void * pkt_buf,uint_t pkt_sz,const struct payload_opts * popts,size_t * payload_sz)1653d6ee46bSPatrick Mooney build_payload(const void *pkt_buf, uint_t pkt_sz,
1663d6ee46bSPatrick Mooney     const struct payload_opts *popts, size_t *payload_sz)
1673d6ee46bSPatrick Mooney {
1683d6ee46bSPatrick Mooney 	nvlist_t *payload = fnvlist_alloc();
1693d6ee46bSPatrick Mooney 	fnvlist_add_byte_array(payload, "pkt_bytes",
1703d6ee46bSPatrick Mooney 	    (uchar_t *)pkt_buf, pkt_sz);
1713d6ee46bSPatrick Mooney 	if (popts->po_padding) {
1723d6ee46bSPatrick Mooney 		fnvlist_add_uint32(payload, "padding", popts->po_padding);
1733d6ee46bSPatrick Mooney 	}
1743d6ee46bSPatrick Mooney 	if (popts->po_cksum_partial) {
1753d6ee46bSPatrick Mooney 		fnvlist_add_boolean(payload, "cksum_partial");
1763d6ee46bSPatrick Mooney 	}
1773d6ee46bSPatrick Mooney 	if (popts->po_cksum_full) {
1783d6ee46bSPatrick Mooney 		fnvlist_add_boolean(payload, "cksum_full");
1793d6ee46bSPatrick Mooney 	}
1803d6ee46bSPatrick Mooney 	if (popts->po_cksum_ipv4) {
1813d6ee46bSPatrick Mooney 		fnvlist_add_boolean(payload, "cksum_ipv4");
1823d6ee46bSPatrick Mooney 	}
1833d6ee46bSPatrick Mooney 
184*1f8b8a01SPatrick Mooney 	uint_t nsplit = 0;
185*1f8b8a01SPatrick Mooney 	uint32_t splits[2];
186*1f8b8a01SPatrick Mooney 	if (popts->po_split_ether) {
187*1f8b8a01SPatrick Mooney 		splits[nsplit++] = sizeof (struct ether_header);
188*1f8b8a01SPatrick Mooney 	}
189*1f8b8a01SPatrick Mooney 	if (popts->po_split_manual != 0) {
190*1f8b8a01SPatrick Mooney 		splits[nsplit++] = popts->po_split_manual;
191*1f8b8a01SPatrick Mooney 	}
192*1f8b8a01SPatrick Mooney 	if (nsplit > 0) {
193*1f8b8a01SPatrick Mooney 		fnvlist_add_uint32_array(payload, "cksum_splits", splits,
194*1f8b8a01SPatrick Mooney 		    nsplit);
195*1f8b8a01SPatrick Mooney 	}
196*1f8b8a01SPatrick Mooney 
1973d6ee46bSPatrick Mooney 	char *packed = fnvlist_pack(payload, payload_sz);
1983d6ee46bSPatrick Mooney 	nvlist_free(payload);
1993d6ee46bSPatrick Mooney 
2003d6ee46bSPatrick Mooney 	return (packed);
2013d6ee46bSPatrick Mooney }
2023d6ee46bSPatrick Mooney 
2033d6ee46bSPatrick Mooney static void
mac_cksum_usage(void)2043d6ee46bSPatrick Mooney mac_cksum_usage(void)
2053d6ee46bSPatrick Mooney {
2063d6ee46bSPatrick Mooney 	(void) fprintf(stderr, "usage: %s [flags] [opts] <cap_file>\n\n"
2073d6ee46bSPatrick Mooney 	    "Flags:\n"
2083d6ee46bSPatrick Mooney 	    "\t-4\temulate HCK_IPV4_HDRCKSUM\n"
2093d6ee46bSPatrick Mooney 	    "\t-f\temulate HCK_FULLCKSUM\t(cannot be used with -p)\n"
2103d6ee46bSPatrick Mooney 	    "\t-p\temulate HCK_PARTIALCKSUM\t(cannot be used with -f)\n"
211*1f8b8a01SPatrick Mooney 	    "\t-e\tsplit mblk after Ethernet header\n"
2123d6ee46bSPatrick Mooney 	    "Options:\n"
2133d6ee46bSPatrick Mooney 	    "\t-b <len>\tpad mblk with <len> bytes (must be even)\n"
214*1f8b8a01SPatrick Mooney 	    "\t-s <len>\tsplit mblk after len bytes (must be even)\n"
215*1f8b8a01SPatrick Mooney 	    "\t\t\tif -e is specified, will be applied after that split\n"
2163d6ee46bSPatrick Mooney 	    "Arguments:\n"
2173d6ee46bSPatrick Mooney 	    "\t<cap_file> is a snoop capture of packets to test.\n"
2183d6ee46bSPatrick Mooney 	    "\tAny TCP or UDP packets (or plain IPv4) are expected to have\n"
2193d6ee46bSPatrick Mooney 	    "\tcorrect checksums.  The emulated results will be compared\n"
2203d6ee46bSPatrick Mooney 	    "\tagainst those sums in the packet (assuming them proper)\n",
2213d6ee46bSPatrick Mooney 	    mac_cksum_cmd);
2223d6ee46bSPatrick Mooney 	exit(EXIT_FAILURE);
2233d6ee46bSPatrick Mooney }
2243d6ee46bSPatrick Mooney 
2253d6ee46bSPatrick Mooney int
main(int argc,char * argv[])2263d6ee46bSPatrick Mooney main(int argc, char *argv[])
2273d6ee46bSPatrick Mooney {
2283d6ee46bSPatrick Mooney 	/* Peel off command name for usage */
2293d6ee46bSPatrick Mooney 	mac_cksum_cmd = argv[0];
2303d6ee46bSPatrick Mooney 	argc--;
2313d6ee46bSPatrick Mooney 	argv++;
2323d6ee46bSPatrick Mooney 	optind = 0;
2333d6ee46bSPatrick Mooney 
2343d6ee46bSPatrick Mooney 	struct payload_opts popts = { 0 };
2353d6ee46bSPatrick Mooney 	int c;
236*1f8b8a01SPatrick Mooney 	while ((c = getopt(argc, argv, "4fpeb:s:")) != -1) {
2373d6ee46bSPatrick Mooney 		switch (c) {
2383d6ee46bSPatrick Mooney 		case 'p':
2393d6ee46bSPatrick Mooney 			popts.po_cksum_partial = B_TRUE;
2403d6ee46bSPatrick Mooney 			break;
2413d6ee46bSPatrick Mooney 		case 'f':
2423d6ee46bSPatrick Mooney 			popts.po_cksum_full = B_TRUE;
2433d6ee46bSPatrick Mooney 			break;
2443d6ee46bSPatrick Mooney 		case '4':
2453d6ee46bSPatrick Mooney 			popts.po_cksum_ipv4 = B_TRUE;
2463d6ee46bSPatrick Mooney 			break;
2473d6ee46bSPatrick Mooney 		case 'b':
2483d6ee46bSPatrick Mooney 			errno = 0;
2493d6ee46bSPatrick Mooney 			popts.po_padding = strtoul(optarg, NULL, 0);
2503d6ee46bSPatrick Mooney 			if (errno != 0) {
2513d6ee46bSPatrick Mooney 				err(EXIT_FAILURE,
2523d6ee46bSPatrick Mooney 				    "invalid padding value %s", optarg);
2533d6ee46bSPatrick Mooney 			}
2543d6ee46bSPatrick Mooney 			break;
255*1f8b8a01SPatrick Mooney 		case 'e':
256*1f8b8a01SPatrick Mooney 			popts.po_split_ether = B_TRUE;
257*1f8b8a01SPatrick Mooney 			break;
258*1f8b8a01SPatrick Mooney 		case 's':
259*1f8b8a01SPatrick Mooney 			errno = 0;
260*1f8b8a01SPatrick Mooney 			popts.po_split_manual = strtoul(optarg, NULL, 0);
261*1f8b8a01SPatrick Mooney 			if (errno != 0) {
262*1f8b8a01SPatrick Mooney 				err(EXIT_FAILURE,
263*1f8b8a01SPatrick Mooney 				    "invalid split value %s", optarg);
264*1f8b8a01SPatrick Mooney 			}
265*1f8b8a01SPatrick Mooney 			break;
266*1f8b8a01SPatrick Mooney 
2673d6ee46bSPatrick Mooney 		case '?':
2683d6ee46bSPatrick Mooney 			warnx("unknown run option: -%c", optopt);
2693d6ee46bSPatrick Mooney 			mac_cksum_usage();
2703d6ee46bSPatrick Mooney 		}
2713d6ee46bSPatrick Mooney 	}
2723d6ee46bSPatrick Mooney 	argc -= optind;
2733d6ee46bSPatrick Mooney 	argv += optind;
2743d6ee46bSPatrick Mooney 
2753d6ee46bSPatrick Mooney 	if (argc != 1) {
2763d6ee46bSPatrick Mooney 		mac_cksum_usage();
2773d6ee46bSPatrick Mooney 	}
2783d6ee46bSPatrick Mooney 
2793d6ee46bSPatrick Mooney 	int fd = open(argv[0], O_RDONLY, 0);
2803d6ee46bSPatrick Mooney 	if (fd < 0) {
2813d6ee46bSPatrick Mooney 		err(EXIT_FAILURE, "could not open cap file %s", argv[0]);
2823d6ee46bSPatrick Mooney 	}
2833d6ee46bSPatrick Mooney 
2843d6ee46bSPatrick Mooney 	pkt_cap_iter_t *iter = pkt_cap_open(fd);
2853d6ee46bSPatrick Mooney 	if (iter == NULL) {
2863d6ee46bSPatrick Mooney 		err(EXIT_FAILURE, "unrecognized cap file %s", argv[0]);
2873d6ee46bSPatrick Mooney 	}
2883d6ee46bSPatrick Mooney 
2893d6ee46bSPatrick Mooney 	if (!ktest_mod_load("mac")) {
2903d6ee46bSPatrick Mooney 		err(EXIT_FAILURE, "could not load mac ktest module");
2913d6ee46bSPatrick Mooney 	}
2923d6ee46bSPatrick Mooney 	if ((kthdl = ktest_init()) == NULL) {
2933d6ee46bSPatrick Mooney 		err(EXIT_FAILURE, "could not initialize libktest");
2943d6ee46bSPatrick Mooney 	}
2953d6ee46bSPatrick Mooney 
2963d6ee46bSPatrick Mooney 	const void *pkt_buf;
2973d6ee46bSPatrick Mooney 	uint_t pkt_sz;
2983d6ee46bSPatrick Mooney 	uint_t count_pass = 0, count_fail = 0, count_skip = 0, idx = 0;
2993d6ee46bSPatrick Mooney 	while (pkt_cap_next(iter, &pkt_buf, &pkt_sz)) {
3003d6ee46bSPatrick Mooney 		ktest_run_req_t req = {
3013d6ee46bSPatrick Mooney 			.krq_module = "mac",
3023d6ee46bSPatrick Mooney 			.krq_suite = "checksum",
3033d6ee46bSPatrick Mooney 			.krq_test = "mac_sw_cksum_test",
3043d6ee46bSPatrick Mooney 		};
3053d6ee46bSPatrick Mooney 		size_t payload_sz;
3063d6ee46bSPatrick Mooney 		char *payload =
3073d6ee46bSPatrick Mooney 		    build_payload(pkt_buf, pkt_sz, &popts, &payload_sz);
3083d6ee46bSPatrick Mooney 		req.krq_input = (uchar_t *)payload;
3093d6ee46bSPatrick Mooney 		req.krq_input_len = (uint_t)payload_sz;
3103d6ee46bSPatrick Mooney 
3113d6ee46bSPatrick Mooney 		ktest_run_result_t result = { 0 };
3123d6ee46bSPatrick Mooney 		if (!ktest_run(kthdl, &req, &result)) {
3133d6ee46bSPatrick Mooney 			err(EXIT_FAILURE, "failure while attempting ktest run");
3143d6ee46bSPatrick Mooney 		}
3153d6ee46bSPatrick Mooney 		free(payload);
3163d6ee46bSPatrick Mooney 
3173d6ee46bSPatrick Mooney 		const char *code_name = ktest_code_name(result.krr_code);
3183d6ee46bSPatrick Mooney 		switch (result.krr_code) {
3193d6ee46bSPatrick Mooney 		case KTEST_CODE_PASS:
3203d6ee46bSPatrick Mooney 			count_pass++;
3213d6ee46bSPatrick Mooney 			break;
3223d6ee46bSPatrick Mooney 		case KTEST_CODE_SKIP:
3233d6ee46bSPatrick Mooney 			count_skip++;
3243d6ee46bSPatrick Mooney 			break;
3253d6ee46bSPatrick Mooney 		default:
3263d6ee46bSPatrick Mooney 			count_fail++;
3273d6ee46bSPatrick Mooney 			break;
3283d6ee46bSPatrick Mooney 		}
3293d6ee46bSPatrick Mooney 		(void) printf("%4u\t%s\t(len: %u)\n", idx, code_name, pkt_sz);
3303d6ee46bSPatrick Mooney 		if (result.krr_msg != NULL) {
3313d6ee46bSPatrick Mooney 			if (result.krr_code != KTEST_CODE_PASS) {
3323d6ee46bSPatrick Mooney 				(void) printf("MSG: %s\n", result.krr_msg);
3333d6ee46bSPatrick Mooney 			}
3343d6ee46bSPatrick Mooney 			free(result.krr_msg);
3353d6ee46bSPatrick Mooney 		}
3363d6ee46bSPatrick Mooney 		idx++;
3373d6ee46bSPatrick Mooney 	}
3383d6ee46bSPatrick Mooney 	if (idx == 0) {
3393d6ee46bSPatrick Mooney 		errx(EXIT_FAILURE, "No valid packets found");
3403d6ee46bSPatrick Mooney 	} else if (idx != 1) {
3413d6ee46bSPatrick Mooney 		/* Summarize for > 1 packet */
3423d6ee46bSPatrick Mooney 		(void) printf("SUMMARY: %u PASS, %u SKIP, %u FAIL\n",
3433d6ee46bSPatrick Mooney 		    count_pass, count_skip, count_fail);
3443d6ee46bSPatrick Mooney 	}
3453d6ee46bSPatrick Mooney 
3463d6ee46bSPatrick Mooney 	pkt_cap_close(iter);
3473d6ee46bSPatrick Mooney 	ktest_fini(kthdl);
3483d6ee46bSPatrick Mooney 
3493d6ee46bSPatrick Mooney 	return (idx == count_pass ? EXIT_SUCCESS : EXIT_FAILURE);
3503d6ee46bSPatrick Mooney }
351