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