Home | History | Annotate | Line # | Download | only in npftest
npftest.c revision 1.2
      1  1.2  rmind /*	$NetBSD: npftest.c,v 1.2 2012/05/30 21:38:04 rmind Exp $	*/
      2  1.1  rmind 
      3  1.1  rmind /*
      4  1.1  rmind  * NPF testing framework.
      5  1.1  rmind  *
      6  1.1  rmind  * Public Domain.
      7  1.1  rmind  */
      8  1.1  rmind 
      9  1.1  rmind #include <stdio.h>
     10  1.1  rmind #include <stdlib.h>
     11  1.1  rmind #include <stdbool.h>
     12  1.2  rmind #include <string.h>
     13  1.1  rmind #include <unistd.h>
     14  1.1  rmind #include <assert.h>
     15  1.2  rmind #include <fcntl.h>
     16  1.2  rmind #include <err.h>
     17  1.2  rmind 
     18  1.2  rmind #include <sys/ioctl.h>
     19  1.2  rmind #include <net/if.h>
     20  1.2  rmind #include <arpa/inet.h>
     21  1.1  rmind 
     22  1.1  rmind #include <rump/rump.h>
     23  1.2  rmind #include <rump/rump_syscalls.h>
     24  1.1  rmind 
     25  1.1  rmind #include "npftest.h"
     26  1.1  rmind 
     27  1.2  rmind static bool verbose, quiet;
     28  1.1  rmind 
     29  1.1  rmind static void
     30  1.1  rmind usage(void)
     31  1.1  rmind {
     32  1.2  rmind 	printf("usage: %s: [ -q | -v ] [ -c <config> ] "
     33  1.2  rmind 	    "[ -i 'interfaces' ] < -b | -t | -s file >\n"
     34  1.2  rmind 	    "\t-b: benchmark\n"
     35  1.2  rmind 	    "\t-t: regression test\n"
     36  1.2  rmind 	    "\t-c <config>: NPF configuration file\n"
     37  1.2  rmind 	    "\t-i 'interfaces': interfaces to create\n"
     38  1.2  rmind 	    "\t-q: quiet mode\n"
     39  1.2  rmind 	    "\t-s <file>: pcap stream\n"
     40  1.2  rmind 	    "\t-v: verbose mode\n",
     41  1.2  rmind 	    getprogname());
     42  1.2  rmind 	exit(EXIT_FAILURE);
     43  1.1  rmind }
     44  1.1  rmind 
     45  1.1  rmind static void
     46  1.2  rmind result(const char *testcase, bool ok)
     47  1.1  rmind {
     48  1.1  rmind 	if (!quiet) {
     49  1.2  rmind 		printf("NPF %-10s\t%s\n", testcase, ok ? "OK" : "fail");
     50  1.1  rmind 	}
     51  1.1  rmind 	if (verbose) {
     52  1.1  rmind 		puts("-----");
     53  1.1  rmind 	}
     54  1.1  rmind 	if (!ok) {
     55  1.1  rmind 		exit(EXIT_FAILURE);
     56  1.1  rmind 	}
     57  1.1  rmind }
     58  1.1  rmind 
     59  1.2  rmind #if 0
     60  1.2  rmind static void
     61  1.2  rmind construct_interfaces(char *ifs)
     62  1.2  rmind {
     63  1.2  rmind 	char *ifname, *addr, *mask, *sptr;
     64  1.2  rmind 
     65  1.2  rmind 	/*
     66  1.2  rmind 	 * Format: ifname0[,ip0,mask1];ifname1,...
     67  1.2  rmind 	 */
     68  1.2  rmind 	ifname = strtok_r(ifs, ";", &sptr);
     69  1.2  rmind 	while (ifname) {
     70  1.2  rmind 		/* Address and netmask. */
     71  1.2  rmind 		addr = strchr(ifname, ',');
     72  1.2  rmind 		if (addr) {
     73  1.2  rmind 			*addr++ = '\0';
     74  1.2  rmind 		}
     75  1.2  rmind 		mask = strchr(addr, ',');
     76  1.2  rmind 		if (mask) {
     77  1.2  rmind 			*mask++ = '\0';
     78  1.2  rmind 		}
     79  1.2  rmind 
     80  1.2  rmind 		/* Construct; next.. */
     81  1.2  rmind 		setup_rump_if(ifname, addr, mask);
     82  1.2  rmind 		ifname = strtok_r(NULL, ";", &sptr);
     83  1.2  rmind 	}
     84  1.2  rmind }
     85  1.2  rmind #endif
     86  1.2  rmind 
     87  1.2  rmind static void
     88  1.2  rmind load_npf_config(const char *config)
     89  1.2  rmind {
     90  1.2  rmind 	prop_dictionary_t npf_dict;
     91  1.2  rmind 	void *xml;
     92  1.2  rmind 	int error;
     93  1.2  rmind 
     94  1.2  rmind 	npf_dict = prop_dictionary_internalize_from_file(config);
     95  1.2  rmind 	if (!npf_dict) {
     96  1.2  rmind 		err(EXIT_FAILURE, "prop_dictionary_internalize_from_file");
     97  1.2  rmind 	}
     98  1.2  rmind 	xml = prop_dictionary_externalize(npf_dict);
     99  1.2  rmind 	prop_object_release(npf_dict);
    100  1.2  rmind 
    101  1.2  rmind 	error = rumpns_npf_test_load(xml);
    102  1.2  rmind 	if (error) {
    103  1.2  rmind 		errx(EXIT_FAILURE, "npf_test_load: %s\n", strerror(error));
    104  1.2  rmind 	}
    105  1.2  rmind 	free(xml);
    106  1.2  rmind 
    107  1.2  rmind 	if (verbose) {
    108  1.2  rmind 		printf("Loaded NPF config at '%s'\n", config);
    109  1.2  rmind 	}
    110  1.2  rmind }
    111  1.2  rmind 
    112  1.1  rmind int
    113  1.1  rmind main(int argc, char **argv)
    114  1.1  rmind {
    115  1.2  rmind 	bool benchmark, test, ok;
    116  1.2  rmind 	char *config, *interfaces, *stream;
    117  1.1  rmind 	int ch;
    118  1.1  rmind 
    119  1.1  rmind 	benchmark = false;
    120  1.2  rmind 	test = false;
    121  1.2  rmind 
    122  1.2  rmind 	config = NULL;
    123  1.2  rmind 	interfaces = NULL;
    124  1.2  rmind 	stream = NULL;
    125  1.2  rmind 
    126  1.1  rmind 	verbose = false;
    127  1.1  rmind 	quiet = false;
    128  1.1  rmind 
    129  1.2  rmind 	while ((ch = getopt(argc, argv, "bqvc:i:s:t")) != -1) {
    130  1.1  rmind 		switch (ch) {
    131  1.1  rmind 		case 'b':
    132  1.1  rmind 			benchmark = true;
    133  1.1  rmind 			break;
    134  1.1  rmind 		case 'q':
    135  1.1  rmind 			quiet = true;
    136  1.1  rmind 			break;
    137  1.1  rmind 		case 'v':
    138  1.1  rmind 			verbose = true;
    139  1.1  rmind 			break;
    140  1.2  rmind 		case 'c':
    141  1.2  rmind 			config = optarg;
    142  1.2  rmind 			break;
    143  1.2  rmind 		case 'i':
    144  1.2  rmind 			interfaces = optarg;
    145  1.2  rmind 			break;
    146  1.2  rmind 		case 's':
    147  1.2  rmind 			stream = optarg;
    148  1.2  rmind 			break;
    149  1.2  rmind 		case 't':
    150  1.2  rmind 			test = true;
    151  1.2  rmind 			break;
    152  1.1  rmind 		default:
    153  1.1  rmind 			usage();
    154  1.1  rmind 		}
    155  1.1  rmind 	}
    156  1.1  rmind 
    157  1.2  rmind 	/* Either benchmark or test. */
    158  1.2  rmind 	if (benchmark == test && (!stream || !interfaces)) {
    159  1.2  rmind 		usage();
    160  1.2  rmind 	}
    161  1.2  rmind 
    162  1.1  rmind 	/* XXX rn_init */
    163  1.1  rmind 	extern int rumpns_max_keylen;
    164  1.1  rmind 	rumpns_max_keylen = 1;
    165  1.1  rmind 
    166  1.1  rmind 	rump_init();
    167  1.1  rmind 	rump_schedule();
    168  1.1  rmind 
    169  1.2  rmind 	if (config) {
    170  1.2  rmind 		load_npf_config(config);
    171  1.2  rmind 	}
    172  1.2  rmind 
    173  1.2  rmind 	if (test) {
    174  1.2  rmind 		ok = rumpns_npf_nbuf_test(verbose);
    175  1.2  rmind 		result("nbuf", ok);
    176  1.1  rmind 
    177  1.2  rmind 		ok = rumpns_npf_processor_test(verbose);
    178  1.2  rmind 		result("processor", ok);
    179  1.1  rmind 
    180  1.2  rmind 		ok = rumpns_npf_table_test(verbose);
    181  1.2  rmind 		result("table", ok);
    182  1.2  rmind 	}
    183  1.2  rmind 
    184  1.2  rmind 	if (stream) {
    185  1.2  rmind 		unsigned idx = if_nametoindex(interfaces);
    186  1.2  rmind 		if (idx == 0) {
    187  1.2  rmind 			err(EXIT_FAILURE, "if_nametoindex");
    188  1.2  rmind 		} else if (verbose) {
    189  1.2  rmind 			printf("Interface %s index %u\n", interfaces, idx);
    190  1.2  rmind 		}
    191  1.2  rmind 		process_stream(stream, NULL, idx);
    192  1.2  rmind 	}
    193  1.1  rmind 
    194  1.1  rmind 	rump_unschedule();
    195  1.1  rmind 
    196  1.1  rmind 	return EXIT_SUCCESS;
    197  1.1  rmind }
    198