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