pfs.c revision 1.2 1 1.2 christos /* $NetBSD: pfs.c,v 1.2 2015/06/16 23:04:14 christos Exp $ */
2 1.1 degroote
3 1.1 degroote /*-
4 1.1 degroote * Copyright (c) 2010 The NetBSD Foundation, Inc.
5 1.1 degroote * All rights reserved.
6 1.1 degroote *
7 1.1 degroote * Redistribution and use in source and binary forms, with or without
8 1.1 degroote * modification, are permitted provided that the following conditions
9 1.1 degroote * are met:
10 1.1 degroote * 1. Redistributions of source code must retain the above copyright
11 1.1 degroote * notice, this list of conditions and the following disclaimer.
12 1.1 degroote * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 degroote * notice, this list of conditions and the following disclaimer in the
14 1.1 degroote * documentation and/or other materials provided with the distribution.
15 1.1 degroote *
16 1.1 degroote * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 1.1 degroote * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 1.1 degroote * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 1.1 degroote * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 1.1 degroote * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 1.1 degroote * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 1.1 degroote * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 1.1 degroote * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 1.1 degroote * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 1.1 degroote * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 1.1 degroote * POSSIBILITY OF SUCH DAMAGE.
27 1.1 degroote */
28 1.1 degroote
29 1.1 degroote #include <sys/cdefs.h>
30 1.1 degroote
31 1.1 degroote #ifndef lint
32 1.2 christos __RCSID("$NetBSD: pfs.c,v 1.2 2015/06/16 23:04:14 christos Exp $");
33 1.1 degroote #endif
34 1.1 degroote
35 1.1 degroote #include <sys/types.h>
36 1.1 degroote #include <sys/ioctl.h>
37 1.1 degroote #include <sys/socket.h>
38 1.1 degroote #include <sys/stat.h>
39 1.1 degroote
40 1.1 degroote #include <net/if.h>
41 1.1 degroote #include <netinet/in.h>
42 1.1 degroote #define TCPSTATES
43 1.1 degroote #include <netinet/tcp_fsm.h>
44 1.1 degroote #include <net/pfvar.h>
45 1.1 degroote #include <arpa/inet.h>
46 1.1 degroote
47 1.1 degroote #include <err.h>
48 1.1 degroote #include <errno.h>
49 1.1 degroote #include <fcntl.h>
50 1.1 degroote #include <limits.h>
51 1.1 degroote #include <netdb.h>
52 1.1 degroote #include <stdio.h>
53 1.1 degroote #include <stdlib.h>
54 1.1 degroote #include <string.h>
55 1.1 degroote #include <stdbool.h>
56 1.1 degroote #include <unistd.h>
57 1.1 degroote
58 1.1 degroote #include "parser.h"
59 1.1 degroote
60 1.1 degroote __dead static void usage(void);
61 1.1 degroote static int setlock(int, int, int);
62 1.1 degroote static int get_states(int, int, struct pfioc_states*);
63 1.1 degroote static int dump_states_binary(int, int, const char*);
64 1.1 degroote static int restore_states_binary(int, int, const char*);
65 1.1 degroote static int dump_states_ascii(int, int, const char*);
66 1.1 degroote static int restore_states_ascii(int, int, const char*);
67 1.1 degroote static char* print_host(const struct pfsync_state_host *h, sa_family_t, char*, size_t);
68 1.1 degroote static void print_peer(const struct pfsync_state_peer *peer, uint8_t, FILE*);
69 1.1 degroote static int print_states(int, int, FILE*);
70 1.1 degroote static void display_states(const struct pfioc_states*, int, FILE*);
71 1.1 degroote static int test_ascii_dump(int, const char*, const char*);
72 1.1 degroote
73 1.1 degroote static char pf_device[] = "/dev/pf";
74 1.1 degroote
75 1.1 degroote __dead static void
76 1.1 degroote usage(void)
77 1.1 degroote {
78 1.1 degroote fprintf(stderr,
79 1.1 degroote "usage : %s [-v] [-u | -l | -w <filename> | -r <filename> |\n"
80 1.1 degroote " [ -W <filename> | -R <filename> ]\n",
81 1.1 degroote getprogname());
82 1.1 degroote exit(EXIT_FAILURE);
83 1.1 degroote }
84 1.1 degroote
85 1.1 degroote /*
86 1.1 degroote * The state table must be locked before calling this function
87 1.1 degroote * Return the number of state in case of success, -1 in case of failure
88 1.1 degroote * ps::ps_buf must be freed by user after use (in case of success)
89 1.1 degroote */
90 1.1 degroote static int
91 1.1 degroote get_states(int fd, int verbose __unused, struct pfioc_states* ps)
92 1.1 degroote {
93 1.1 degroote memset(ps, 0, sizeof(*ps));
94 1.1 degroote ps->ps_len = 0;
95 1.1 degroote char* inbuf;
96 1.1 degroote
97 1.1 degroote // ask the kernel how much memory we need to allocate
98 1.1 degroote if (ioctl(fd, DIOCGETSTATES, ps) == -1) {
99 1.1 degroote err(EXIT_FAILURE, "DIOCGETSTATES");
100 1.1 degroote }
101 1.1 degroote
102 1.1 degroote /* no state */
103 1.1 degroote if (ps->ps_len == 0)
104 1.1 degroote return 0;
105 1.1 degroote
106 1.1 degroote inbuf = malloc(ps->ps_len);
107 1.1 degroote if (inbuf == NULL)
108 1.1 degroote err(EXIT_FAILURE, NULL);
109 1.1 degroote
110 1.1 degroote ps->ps_buf = inbuf;
111 1.1 degroote
112 1.1 degroote // really retrieve the different states
113 1.1 degroote if (ioctl(fd, DIOCGETSTATES, ps) == -1) {
114 1.1 degroote free(ps->ps_buf);
115 1.1 degroote err(EXIT_FAILURE, "DIOCGETSTATES");
116 1.1 degroote }
117 1.1 degroote
118 1.1 degroote return (ps->ps_len / sizeof(struct pfsync_state));
119 1.1 degroote }
120 1.1 degroote
121 1.1 degroote static int
122 1.1 degroote dump_states_binary(int fd, int verbose, const char* filename)
123 1.1 degroote {
124 1.1 degroote int wfd;
125 1.1 degroote struct pfioc_states ps;
126 1.1 degroote struct pfsync_state *p = NULL;
127 1.1 degroote int nb_states;
128 1.1 degroote int i;
129 1.1 degroote int error = 0;
130 1.1 degroote int errno_saved = 0;
131 1.1 degroote
132 1.1 degroote wfd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0600);
133 1.1 degroote if (wfd == -1)
134 1.1 degroote err(EXIT_FAILURE, "Cannot open %s", filename);
135 1.1 degroote
136 1.1 degroote nb_states = get_states(fd, verbose, &ps);
137 1.1 degroote if (nb_states <= 0) {
138 1.1 degroote close(wfd);
139 1.1 degroote return nb_states;
140 1.1 degroote }
141 1.1 degroote
142 1.1 degroote /*
143 1.1 degroote * In the file, write the number of states, then store the different states
144 1.1 degroote * When we will switch to text format, we probably don't care any more about the len
145 1.1 degroote */
146 1.1 degroote if (write(wfd, &nb_states, sizeof(nb_states)) != sizeof(nb_states)) {
147 1.1 degroote error = EXIT_FAILURE;
148 1.1 degroote errno_saved = errno;
149 1.1 degroote goto done;
150 1.1 degroote }
151 1.1 degroote
152 1.1 degroote p = ps.ps_states;
153 1.1 degroote for (i = 0; i < nb_states; i++) {
154 1.1 degroote if (write(wfd, &p[i], sizeof(*p)) != sizeof(*p)) {
155 1.1 degroote error = EXIT_FAILURE;
156 1.1 degroote errno_saved = errno;
157 1.1 degroote goto done;
158 1.1 degroote }
159 1.1 degroote }
160 1.1 degroote
161 1.1 degroote done:
162 1.1 degroote free(p);
163 1.1 degroote close(wfd);
164 1.1 degroote // close can't modify errno
165 1.1 degroote if (error) {
166 1.1 degroote errno = errno_saved;
167 1.1 degroote err(error, NULL);
168 1.1 degroote }
169 1.1 degroote
170 1.1 degroote return 0;
171 1.1 degroote }
172 1.1 degroote
173 1.1 degroote static int
174 1.1 degroote restore_states_binary(int fd, int verbose __unused, const char* filename)
175 1.1 degroote {
176 1.1 degroote int rfd;
177 1.1 degroote struct pfioc_states ps;
178 1.1 degroote struct pfsync_state *p;
179 1.1 degroote int nb_states;
180 1.1 degroote int errno_saved = 0;
181 1.1 degroote int i;
182 1.1 degroote
183 1.1 degroote rfd = open(filename, O_RDONLY, 0600);
184 1.1 degroote if (rfd == -1)
185 1.1 degroote err(EXIT_FAILURE, "Cannot open %s", filename);
186 1.1 degroote
187 1.1 degroote if (read(rfd, &nb_states, sizeof(nb_states)) != sizeof(nb_states)) {
188 1.1 degroote errno_saved = errno;
189 1.1 degroote close(rfd);
190 1.1 degroote errno = errno_saved;
191 1.1 degroote err(EXIT_FAILURE, NULL);
192 1.1 degroote }
193 1.1 degroote
194 1.1 degroote ps.ps_len = nb_states * sizeof(struct pfsync_state);
195 1.1 degroote ps.ps_states = malloc(ps.ps_len);
196 1.1 degroote if (ps.ps_states == NULL) {
197 1.1 degroote errno_saved = errno;
198 1.1 degroote close(rfd);
199 1.1 degroote errno = errno_saved;
200 1.1 degroote err(EXIT_FAILURE, NULL);
201 1.1 degroote }
202 1.1 degroote
203 1.1 degroote p = ps.ps_states;
204 1.1 degroote
205 1.1 degroote for (i = 0; i < nb_states; i++) {
206 1.1 degroote if (read(rfd, &p[i], sizeof(*p)) != sizeof(*p)) {
207 1.1 degroote errno_saved = errno;
208 1.1 degroote close(rfd);
209 1.1 degroote free(ps.ps_states);
210 1.1 degroote errno = errno_saved;
211 1.1 degroote err(EXIT_FAILURE, NULL);
212 1.1 degroote }
213 1.1 degroote }
214 1.1 degroote
215 1.1 degroote if (ioctl(fd, DIOCADDSTATES, &ps) == -1) {
216 1.1 degroote errno_saved = errno;
217 1.1 degroote close(rfd);
218 1.1 degroote free(ps.ps_states);
219 1.1 degroote errno = errno_saved;
220 1.1 degroote err(EXIT_FAILURE, "DIOCADDSTATES");
221 1.1 degroote }
222 1.1 degroote
223 1.1 degroote free(ps.ps_states);
224 1.1 degroote close(rfd);
225 1.1 degroote return 0;
226 1.1 degroote }
227 1.1 degroote
228 1.1 degroote static char*
229 1.1 degroote print_host(const struct pfsync_state_host *h, sa_family_t af, char* buf,
230 1.1 degroote size_t size_buf)
231 1.1 degroote {
232 1.1 degroote uint16_t port;
233 1.1 degroote char buf_addr[48];
234 1.1 degroote
235 1.1 degroote port = ntohs(h->port);
236 1.1 degroote if (inet_ntop(af, &(h->addr) , buf_addr, sizeof(buf_addr)) == NULL) {
237 1.1 degroote strcpy(buf_addr, "?");
238 1.1 degroote }
239 1.1 degroote
240 1.1 degroote snprintf(buf, size_buf, "%s:[%d]", buf_addr, port);
241 1.1 degroote return buf;
242 1.1 degroote }
243 1.1 degroote
244 1.1 degroote static void
245 1.1 degroote print_peer(const struct pfsync_state_peer* peer, uint8_t proto, FILE* f)
246 1.1 degroote {
247 1.1 degroote if (proto == IPPROTO_TCP) {
248 1.1 degroote if (peer->state < TCP_NSTATES)
249 1.1 degroote fprintf(f, "state %s", tcpstates[peer->state]);
250 1.1 degroote
251 1.1 degroote if (peer->seqdiff != 0)
252 1.1 degroote fprintf(f, " seq [%" PRIu32 ":%" PRIu32 ",%" PRIu32"]",
253 1.1 degroote peer->seqlo, peer->seqhi, peer->seqdiff);
254 1.1 degroote else
255 1.1 degroote fprintf(f, " seq [%" PRIu32 ":%" PRIu32 "]",
256 1.1 degroote peer->seqlo, peer->seqhi);
257 1.1 degroote
258 1.1 degroote if (peer->mss != 0)
259 1.1 degroote fprintf(f, " max_win %" PRIu16 " mss %" PRIu16 " wscale %" PRIu8,
260 1.1 degroote peer->max_win, peer->mss, peer->wscale);
261 1.1 degroote else
262 1.1 degroote fprintf(f, " max_win %" PRIu16 " wscale %" PRIu8, peer->max_win,
263 1.1 degroote peer->wscale);
264 1.1 degroote
265 1.1 degroote } else {
266 1.1 degroote if (proto == IPPROTO_UDP) {
267 1.1 degroote const char *mystates[] = PFUDPS_NAMES;
268 1.1 degroote if (peer->state < PFUDPS_NSTATES)
269 1.1 degroote fprintf(f, "state %s", mystates[peer->state]);
270 1.1 degroote } else if (proto == IPPROTO_ICMP || proto == IPPROTO_ICMPV6) {
271 1.1 degroote fprintf(f, " state %" PRIu8, peer->state);
272 1.1 degroote } else {
273 1.1 degroote const char *mystates[] = PFOTHERS_NAMES;
274 1.1 degroote if (peer->state < PFOTHERS_NSTATES)
275 1.1 degroote fprintf(f, " state %s", mystates[peer->state]);
276 1.1 degroote }
277 1.1 degroote }
278 1.1 degroote
279 1.1 degroote if (peer->scrub.scrub_flag == PFSYNC_SCRUB_FLAG_VALID) {
280 1.1 degroote fprintf(f, " scrub flags %" PRIu16 "ttl %" PRIu8 "mod %"PRIu32,
281 1.1 degroote peer->scrub.pfss_flags, peer->scrub.pfss_ttl, peer->scrub.pfss_ts_mod);
282 1.1 degroote } else {
283 1.1 degroote fprintf(f, " no-scrub");
284 1.1 degroote }
285 1.1 degroote }
286 1.1 degroote
287 1.1 degroote static void
288 1.1 degroote display_states(const struct pfioc_states *ps, int verbose __unused, FILE* f)
289 1.1 degroote {
290 1.1 degroote struct pfsync_state *p = NULL;
291 1.1 degroote struct pfsync_state_peer *src, *dst;
292 1.1 degroote struct protoent *proto;
293 1.1 degroote int nb_states;
294 1.1 degroote int i;
295 1.1 degroote uint64_t id;
296 1.1 degroote
297 1.1 degroote p = ps->ps_states;
298 1.1 degroote nb_states = ps->ps_len / sizeof(struct pfsync_state);
299 1.1 degroote
300 1.1 degroote for (i = 0; i < nb_states; i++, p++) {
301 1.1 degroote fprintf(f, "state %s ", p->direction == PF_OUT ? "out" : "in");
302 1.1 degroote fprintf(f, "on %s ", p->ifname);
303 1.1 degroote
304 1.1 degroote if ((proto = getprotobynumber(p->proto)) != NULL)
305 1.1 degroote fprintf(f, "proto %s ", proto->p_name);
306 1.1 degroote else
307 1.1 degroote fprintf(f, "proto %u ", p->proto);
308 1.1 degroote
309 1.1 degroote
310 1.1 degroote if (PF_ANEQ(&p->lan.addr, &p->gwy.addr, p->af) ||
311 1.1 degroote (p->lan.port != p->gwy.port)) {
312 1.1 degroote
313 1.1 degroote char buf1[64], buf2[64], buf3[64];
314 1.1 degroote fprintf(f, "from %s to %s using %s",
315 1.1 degroote print_host(&p->lan, p->af, buf1, sizeof(buf1)),
316 1.1 degroote print_host(&p->ext, p->af, buf2, sizeof(buf2)),
317 1.1 degroote print_host(&p->gwy, p->af, buf3, sizeof(buf3)));
318 1.1 degroote } else {
319 1.1 degroote char buf1[64], buf2[64];
320 1.1 degroote fprintf(f, "from %s to %s",
321 1.1 degroote print_host(&p->lan, p->af, buf1, sizeof(buf1)),
322 1.1 degroote print_host(&p->ext, p->af, buf2, sizeof(buf2)));
323 1.1 degroote }
324 1.1 degroote
325 1.1 degroote memcpy(&id, p->id, sizeof(p->id));
326 1.1 degroote fprintf(f, " id %" PRIu64 " cid %" PRIu32 " expire %" PRIu32 " timeout %" PRIu8,
327 1.1 degroote id , p->creatorid, p->expire, p->timeout);
328 1.1 degroote
329 1.1 degroote if (p->direction == PF_OUT) {
330 1.1 degroote src = &p->src;
331 1.1 degroote dst = &p->dst;
332 1.1 degroote } else {
333 1.1 degroote src = &p->dst;
334 1.1 degroote dst = &p->src;
335 1.1 degroote }
336 1.1 degroote
337 1.1 degroote fprintf(f, " src ");
338 1.1 degroote print_peer(src, p->proto, f);
339 1.1 degroote fprintf(f, " dst ");
340 1.1 degroote print_peer(dst, p->proto, f);
341 1.1 degroote
342 1.1 degroote fprintf(f, "\n");
343 1.1 degroote }
344 1.1 degroote }
345 1.1 degroote
346 1.1 degroote static int
347 1.1 degroote print_states(int fd, int verbose, FILE* f)
348 1.1 degroote {
349 1.1 degroote struct pfioc_states ps;
350 1.1 degroote int nb_states;
351 1.1 degroote
352 1.1 degroote nb_states = get_states(fd, verbose, &ps);
353 1.1 degroote if (nb_states <= 0) {
354 1.1 degroote return nb_states;
355 1.1 degroote }
356 1.1 degroote
357 1.1 degroote display_states(&ps, verbose, f);
358 1.1 degroote
359 1.1 degroote free(ps.ps_states);
360 1.1 degroote return 0;
361 1.1 degroote }
362 1.1 degroote
363 1.1 degroote static int
364 1.1 degroote dump_states_ascii(int fd, int verbose, const char* filename)
365 1.1 degroote {
366 1.1 degroote FILE *f;
367 1.1 degroote
368 1.1 degroote if (strcmp(filename, "-") == 0) {
369 1.1 degroote f = stdout;
370 1.1 degroote } else {
371 1.1 degroote f = fopen(filename, "w");
372 1.1 degroote if (f == NULL)
373 1.2 christos err(EXIT_FAILURE, "Can't open %s", filename);
374 1.1 degroote }
375 1.1 degroote
376 1.1 degroote print_states(fd, verbose, f);
377 1.1 degroote
378 1.1 degroote if (f != stdout)
379 1.1 degroote fclose(f);
380 1.1 degroote
381 1.1 degroote return 0;
382 1.1 degroote }
383 1.1 degroote
384 1.1 degroote static int
385 1.1 degroote restore_states_ascii(int fd, int verbose __unused, const char* filename)
386 1.1 degroote {
387 1.1 degroote FILE *f;
388 1.1 degroote struct pfioc_states ps;
389 1.1 degroote int errno_saved;
390 1.1 degroote
391 1.1 degroote f = fopen(filename, "r");
392 1.1 degroote if (f == NULL)
393 1.2 christos err(EXIT_FAILURE, "Can't open %s", filename);
394 1.1 degroote
395 1.1 degroote parse(f, &ps);
396 1.1 degroote
397 1.1 degroote if (ioctl(fd, DIOCADDSTATES, &ps) == -1) {
398 1.1 degroote errno_saved = errno;
399 1.1 degroote fclose(f);
400 1.1 degroote free(ps.ps_states);
401 1.1 degroote errno = errno_saved;
402 1.1 degroote err(EXIT_FAILURE, "DIOCADDSTATES");
403 1.1 degroote }
404 1.1 degroote
405 1.1 degroote free(ps.ps_states);
406 1.1 degroote fclose(f);
407 1.1 degroote return 0;
408 1.1 degroote }
409 1.1 degroote
410 1.1 degroote static int
411 1.1 degroote setlock(int fd, int verbose, int lock)
412 1.1 degroote {
413 1.1 degroote if (verbose)
414 1.1 degroote printf("Turning lock %s\n", lock ? "on" : "off");
415 1.1 degroote
416 1.1 degroote if (ioctl(fd, DIOCSETLCK, &lock) == -1)
417 1.1 degroote err(EXIT_FAILURE, "DIOCSETLCK");
418 1.1 degroote
419 1.1 degroote return 0;
420 1.1 degroote }
421 1.1 degroote
422 1.1 degroote static int
423 1.1 degroote test_ascii_dump(int verbose, const char* file1, const char *file2)
424 1.1 degroote {
425 1.1 degroote FILE *f1, *f2;
426 1.1 degroote struct pfioc_states ps;
427 1.1 degroote int errno_saved;
428 1.1 degroote
429 1.1 degroote f1 = fopen(file1, "r");
430 1.1 degroote if (f1 == NULL)
431 1.2 christos err(EXIT_FAILURE, "Can't open %s", file1);
432 1.1 degroote
433 1.1 degroote
434 1.1 degroote f2 = fopen(file2, "w");
435 1.1 degroote if (f2 == NULL) {
436 1.1 degroote errno_saved = errno;
437 1.1 degroote fclose(f2);
438 1.1 degroote errno = errno_saved;
439 1.2 christos err(EXIT_FAILURE, "Can't open %s", file2);
440 1.1 degroote }
441 1.1 degroote
442 1.1 degroote parse(f1, &ps);
443 1.1 degroote display_states(&ps, verbose, f2);
444 1.1 degroote
445 1.1 degroote free(ps.ps_states);
446 1.1 degroote fclose(f1);
447 1.1 degroote fclose(f2);
448 1.1 degroote
449 1.1 degroote return 0;
450 1.1 degroote }
451 1.1 degroote
452 1.1 degroote int main(int argc, char *argv[])
453 1.1 degroote {
454 1.1 degroote setprogname(argv[0]);
455 1.1 degroote
456 1.1 degroote int lock = 0;
457 1.1 degroote int set = 0;
458 1.1 degroote int dump = 0;
459 1.1 degroote int restore = 0;
460 1.1 degroote int verbose = 0;
461 1.1 degroote int test = 0;
462 1.1 degroote bool binary = false;
463 1.1 degroote char* filename = NULL;
464 1.1 degroote char* filename2 = NULL;
465 1.1 degroote int error = 0;
466 1.1 degroote int fd;
467 1.1 degroote int c;
468 1.1 degroote
469 1.1 degroote while ((c = getopt(argc, argv, "ulvw:r:R:W:bt:o:")) != -1)
470 1.1 degroote switch (c) {
471 1.1 degroote case 'u' :
472 1.1 degroote lock = 0;
473 1.1 degroote set = 1;
474 1.1 degroote break;
475 1.1 degroote
476 1.1 degroote case 'l' :
477 1.1 degroote lock = 1;
478 1.1 degroote set = 1;
479 1.1 degroote break;
480 1.1 degroote
481 1.1 degroote case 'b':
482 1.1 degroote binary = true;
483 1.1 degroote break;
484 1.1 degroote
485 1.1 degroote case 'r':
486 1.1 degroote restore = 1;
487 1.1 degroote filename = optarg;
488 1.1 degroote break;
489 1.1 degroote
490 1.1 degroote case 'v':
491 1.1 degroote verbose=1;
492 1.1 degroote break;
493 1.1 degroote
494 1.1 degroote case 'w':
495 1.1 degroote dump=1;
496 1.1 degroote filename=optarg;
497 1.1 degroote break;
498 1.1 degroote
499 1.1 degroote case 'R':
500 1.1 degroote restore = 1;
501 1.1 degroote set = 1;
502 1.1 degroote filename = optarg;
503 1.1 degroote break;
504 1.1 degroote
505 1.1 degroote case 'W':
506 1.1 degroote dump = 1;
507 1.1 degroote set = 1;
508 1.1 degroote filename = optarg;
509 1.1 degroote break;
510 1.1 degroote
511 1.1 degroote case 't':
512 1.1 degroote test=1;
513 1.1 degroote filename = optarg;
514 1.1 degroote break;
515 1.1 degroote
516 1.1 degroote case 'o':
517 1.1 degroote filename2 = optarg;
518 1.1 degroote break;
519 1.1 degroote
520 1.1 degroote case '?' :
521 1.1 degroote default:
522 1.1 degroote usage();
523 1.1 degroote }
524 1.1 degroote
525 1.1 degroote if (set == 0 && dump == 0 && restore == 0 && test == 0)
526 1.1 degroote usage();
527 1.1 degroote
528 1.1 degroote if (dump == 1 && restore == 1)
529 1.1 degroote usage();
530 1.1 degroote
531 1.1 degroote if (test == 1) {
532 1.1 degroote if (filename2 == NULL) {
533 1.1 degroote fprintf(stderr, "-o <file> is required when using -t\n");
534 1.1 degroote err(EXIT_FAILURE, NULL);
535 1.1 degroote }
536 1.1 degroote error = test_ascii_dump(verbose, filename, filename2);
537 1.1 degroote } else {
538 1.1 degroote fd = open(pf_device, O_RDWR);
539 1.1 degroote if (fd == -1)
540 1.1 degroote err(EXIT_FAILURE, "Cannot open %s", pf_device);
541 1.1 degroote
542 1.1 degroote if (set != 0 && dump == 0 && restore == 0)
543 1.1 degroote error = setlock(fd, verbose, lock);
544 1.1 degroote
545 1.1 degroote if (dump) {
546 1.1 degroote if (set)
547 1.1 degroote error = setlock(fd, verbose, 1);
548 1.1 degroote
549 1.1 degroote if (binary)
550 1.1 degroote error = dump_states_binary(fd, verbose, filename);
551 1.1 degroote else
552 1.1 degroote error = dump_states_ascii(fd, verbose, filename);
553 1.1 degroote
554 1.1 degroote if (set)
555 1.1 degroote error = setlock(fd, verbose, 0);
556 1.1 degroote }
557 1.1 degroote
558 1.1 degroote if (restore) {
559 1.1 degroote if (set)
560 1.1 degroote error = setlock(fd, verbose, 1);
561 1.1 degroote
562 1.1 degroote if (binary)
563 1.1 degroote error = restore_states_binary(fd, verbose, filename);
564 1.1 degroote else
565 1.1 degroote error = restore_states_ascii(fd, verbose, filename);
566 1.1 degroote
567 1.1 degroote if (set)
568 1.1 degroote error = setlock(fd, verbose, 0);
569 1.1 degroote }
570 1.1 degroote
571 1.1 degroote close(fd);
572 1.1 degroote }
573 1.1 degroote
574 1.1 degroote return error;
575 1.1 degroote }
576