xref: /openbsd/sbin/ipsecctl/ipsecctl.c (revision 8529ddd3)
1 /*	$OpenBSD: ipsecctl.c,v 1.79 2015/01/16 06:39:58 deraadt Exp $	*/
2 /*
3  * Copyright (c) 2004, 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <sys/socket.h>
19 #include <sys/sysctl.h>
20 #include <sys/queue.h>
21 #include <sys/stat.h>
22 #include <net/pfkeyv2.h>
23 #include <net/route.h>
24 #include <netinet/in.h>
25 #include <netinet/ip_ipsp.h>
26 #include <arpa/inet.h>
27 
28 #include <err.h>
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <netdb.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <unistd.h>
36 
37 #include "ipsecctl.h"
38 #include "pfkey.h"
39 
40 int		 ipsecctl_rules(char *, int);
41 FILE		*ipsecctl_fopen(const char *, const char *);
42 int		 ipsecctl_commit(int, struct ipsecctl *);
43 int		 ipsecctl_add_rule(struct ipsecctl *, struct ipsec_rule *);
44 void		 ipsecctl_free_rule(struct ipsec_rule *);
45 void		 ipsecctl_print_addr(struct ipsec_addr_wrap *);
46 void		 ipsecctl_print_proto(u_int8_t);
47 void		 ipsecctl_print_port(u_int16_t, const char *);
48 void		 ipsecctl_print_key(struct ipsec_key *);
49 void		 ipsecctl_print_flow(struct ipsec_rule *, int);
50 void		 ipsecctl_print_sa(struct ipsec_rule *, int);
51 void		 ipsecctl_print_sagroup(struct ipsec_rule *, int);
52 int		 ipsecctl_flush(int);
53 void		 ipsecctl_get_rules(struct ipsecctl *);
54 void		 ipsecctl_print_title(char *);
55 void		 ipsecctl_show_flows(int);
56 void		 ipsecctl_show_sas(int);
57 int		 ipsecctl_monitor(int);
58 void		 usage(void);
59 const char	*ipsecctl_lookup_option(char *, const char **);
60 static int	 unmask(struct ipsec_addr *, sa_family_t);
61 int		 sacompare(const void *, const void *);
62 
63 const char	*showopt;
64 char		*isakmpd_fifo = "/var/run/isakmpd.fifo";
65 
66 int		 first_title = 1;
67 
68 static const char *showopt_list[] = {
69 	"flow", "sa", "all", NULL
70 };
71 
72 static const char *direction[] = {"?", "in", "out"};
73 static const char *flowtype[] = {"?", "use", "acquire", "require", "deny",
74     "bypass", "dontacq"};
75 static const char *satype[] = {"?", "esp", "ah", "ipcomp", "tcpmd5", "ipip"};
76 static const char *tmode[] = {"?", "transport", "tunnel"};
77 static const char *auth[] = {"?", "psk", "rsa"};
78 
79 struct sad {
80 	struct sadb_msg	*sad_msg;
81 	u_int32_t	 sad_spi;
82 };
83 
84 int
85 sacompare(const void *va, const void *vb)
86 {
87 	const struct sad *a = va, *b = vb;
88 
89 	if (a->sad_spi < b->sad_spi)
90 		return (-1);
91 	if (a->sad_spi > b->sad_spi)
92 		return (1);
93 	return (0);
94 }
95 
96 int
97 ipsecctl_rules(char *filename, int opts)
98 {
99 	struct ipsecctl		 ipsec;
100 	struct ipsec_rule	*rp;
101 	int			 action, error = 0;
102 
103 	bzero(&ipsec, sizeof(ipsec));
104 	ipsec.opts = opts;
105 	TAILQ_INIT(&ipsec.rule_queue);
106 	TAILQ_INIT(&ipsec.group_queue);
107 
108 	if (parse_rules(filename, &ipsec) < 0) {
109 		warnx("Syntax error in config file: ipsec rules not loaded");
110 		error = 1;
111 	} else {
112 		if (opts & IPSECCTL_OPT_DELETE)
113 			action = ACTION_DELETE;
114 		else
115 			action = ACTION_ADD;
116 
117 		if ((opts & IPSECCTL_OPT_NOACTION) == 0)
118 			error = ipsecctl_commit(action, &ipsec);
119 
120 	}
121 
122 	/* This also frees the rules in ipsec.group_queue. */
123 	while ((rp = TAILQ_FIRST(&ipsec.rule_queue))) {
124 		TAILQ_REMOVE(&ipsec.rule_queue, rp, rule_entry);
125 		ipsecctl_free_rule(rp);
126 	}
127 
128 	return (error);
129 }
130 
131 FILE *
132 ipsecctl_fopen(const char *name, const char *mode)
133 {
134 	struct stat	 st;
135 	FILE		*fp;
136 
137 	fp = fopen(name, mode);
138 	if (fp == NULL)
139 		return (NULL);
140 
141 	if (fstat(fileno(fp), &st)) {
142 		fclose(fp);
143 		return (NULL);
144 	}
145 	if (S_ISDIR(st.st_mode)) {
146 		fclose(fp);
147 		errno = EISDIR;
148 		return (NULL);
149 	}
150 	return (fp);
151 }
152 
153 int
154 ipsecctl_commit(int action, struct ipsecctl *ipsec)
155 {
156 	struct ipsec_rule	*rp;
157 	int			 ret = 0;
158 
159 	if (pfkey_init() == -1)
160 		errx(1, "ipsecctl_commit: failed to open PF_KEY socket");
161 
162 	TAILQ_FOREACH(rp, &ipsec->rule_queue, rule_entry) {
163 		if (rp->type & RULE_IKE) {
164 			if (ike_ipsec_establish(action, rp, isakmpd_fifo) ==
165 			    -1) {
166 				warnx("failed to %s ike rule %d",
167 				    action == ACTION_DELETE ? "delete" : "add",
168 				    rp->nr);
169 				ret = 2;
170 			}
171 		} else {
172 			if (pfkey_ipsec_establish(action, rp) == -1) {
173 				warnx("failed to %s rule %d",
174 				    action == ACTION_DELETE ? "delete" : "add",
175 				    rp->nr);
176 				ret = 2;
177 			}
178 		}
179 	}
180 
181 	return (ret);
182 }
183 
184 int
185 ipsecctl_add_rule(struct ipsecctl *ipsec, struct ipsec_rule *r)
186 {
187 	TAILQ_INSERT_TAIL(&ipsec->rule_queue, r, rule_entry);
188 
189 	if ((ipsec->opts & IPSECCTL_OPT_VERBOSE) && !(ipsec->opts &
190 	    IPSECCTL_OPT_SHOW))
191 		ipsecctl_print_rule(r, ipsec->opts);
192 
193 	return (0);
194 }
195 
196 void
197 ipsecctl_free_rule(struct ipsec_rule *rp)
198 {
199 	if (rp->src) {
200 		free(rp->src->name);
201 		free(rp->src);
202 	}
203 	if (rp->dst) {
204 		free(rp->dst->name);
205 		free(rp->dst);
206 	}
207 	if (rp->dst2) {
208 		free(rp->dst2->name);
209 		free(rp->dst2);
210 	}
211 	if (rp->local) {
212 		free(rp->local->name);
213 		free(rp->local);
214 	}
215 	if (rp->peer) {
216 		free(rp->peer->name);
217 		free(rp->peer);
218 	}
219 	if (rp->auth) {
220 		if (rp->auth->srcid)
221 			free(rp->auth->srcid);
222 		if (rp->auth->dstid)
223 			free(rp->auth->dstid);
224 		free(rp->auth);
225 	}
226 	if (rp->ikeauth) {
227 		if (rp->ikeauth->string)
228 			free(rp->ikeauth->string);
229 		free(rp->ikeauth);
230 	}
231 	if (rp->xfs)
232 		free(rp->xfs);
233 	if (rp->p1xfs)
234 		free(rp->p1xfs);
235 	if (rp->p2xfs)
236 		free(rp->p2xfs);
237 	if (rp->p1life)
238 		free(rp->p1life);
239 	if (rp->p2life)
240 		free(rp->p2life);
241 	if (rp->authkey) {
242 		free(rp->authkey->data);
243 		free(rp->authkey);
244 	}
245 	if (rp->enckey) {
246 		free(rp->enckey->data);
247 		free(rp->enckey);
248 	}
249 	if (rp->p1name)
250 		free(rp->p1name);
251 	if (rp->p2name)
252 		free(rp->p2name);
253 	if (rp->p2lid)
254 		free(rp->p2lid);
255 	if (rp->p2nid)
256 		free(rp->p2nid);
257 	if (rp->p2rid)
258 		free(rp->p2rid);
259 	free(rp);
260 }
261 
262 void
263 ipsecctl_print_addr(struct ipsec_addr_wrap *ipa)
264 {
265 	int		bits;
266 	char		buf[NI_MAXHOST];
267 
268 	if (ipa == NULL) {
269 		printf("?");
270 		return;
271 	}
272 	if (inet_ntop(ipa->af, &ipa->address, buf, sizeof(buf)) == NULL)
273 		printf("?");
274 	else
275 		printf("%s", buf);
276 
277 	bits = unmask(&ipa->mask, ipa->af);
278 	if (bits != (ipa->af == AF_INET ? 32 : 128))
279 		printf("/%d", bits);
280 }
281 
282 void
283 ipsecctl_print_proto(u_int8_t proto)
284 {
285 	struct protoent *p;
286 
287 	if ((p = getprotobynumber(proto)) != NULL)
288 		printf("%s", p->p_name);
289 	else
290 		printf("%u", proto);
291 }
292 
293 void
294 ipsecctl_print_port(u_int16_t port, const char *proto)
295 {
296 	struct servent *s;
297 
298 	if ((s = getservbyport(port, proto)) != NULL)
299 		printf("%s", s->s_name);
300 	else
301 		printf("%u", ntohs(port));
302 }
303 
304 void
305 ipsecctl_print_key(struct ipsec_key *key)
306 {
307 	int	i;
308 
309 	for (i = 0; i < (int)key->len; i++)
310 		printf("%02x", key->data[i]);
311 }
312 
313 void
314 ipsecctl_print_flow(struct ipsec_rule *r, int opts)
315 {
316 	printf("flow %s %s", satype[r->satype], direction[r->direction]);
317 
318 	if (r->proto) {
319 		printf(" proto ");
320 		ipsecctl_print_proto(r->proto);
321 	}
322 	printf(" from ");
323 	ipsecctl_print_addr(r->src);
324 	if (r->sport) {
325 		printf(" port ");
326 		ipsecctl_print_port(r->sport,
327 		    r->proto == IPPROTO_TCP ? "tcp" : "udp");
328 	}
329 	printf(" to ");
330 	ipsecctl_print_addr(r->dst);
331 	if (r->dport) {
332 		printf(" port ");
333 		ipsecctl_print_port(r->dport,
334 		    r->proto == IPPROTO_TCP ? "tcp" : "udp");
335 	}
336 	if (r->local) {
337 		printf(" local ");
338 		ipsecctl_print_addr(r->local);
339 	}
340 	if (r->peer) {
341 		printf(" peer ");
342 		ipsecctl_print_addr(r->peer);
343 	}
344 	if (r->auth) {
345 		if (r->auth->srcid)
346 			printf(" srcid %s", r->auth->srcid);
347 		if (r->auth->dstid)
348 			printf(" dstid %s", r->auth->dstid);
349 		if (r->auth->type > 0)
350 			printf(" %s", auth[r->auth->type]);
351 	}
352 	printf(" type %s", flowtype[r->flowtype]);
353 	printf("\n");
354 }
355 
356 /* ARGSUSED1 */
357 void
358 ipsecctl_print_sa(struct ipsec_rule *r, int opts)
359 {
360 	printf("%s ", satype[r->satype]);
361 	/* tunnel/transport is only meaningful for esp/ah/ipcomp */
362 	if (r->satype != IPSEC_TCPMD5 && r->satype != IPSEC_IPIP)
363 		printf("%s ", tmode[r->tmode]);
364 	printf("from ");
365 	ipsecctl_print_addr(r->src);
366 	printf(" to ");
367 	ipsecctl_print_addr(r->dst);
368 	printf(" spi 0x%08x", r->spi);
369 
370 	if (r->satype != IPSEC_TCPMD5) {
371 		if (r->xfs && r->xfs->authxf)
372 			printf(" auth %s", r->xfs->authxf->name);
373 		if (r->xfs && r->xfs->encxf)
374 			printf(" enc %s", r->xfs->encxf->name);
375 		if (r->xfs && r->xfs->compxf)
376 			printf(" comp %s", r->xfs->compxf->name);
377 	}
378 	if (r->authkey && (opts & IPSECCTL_OPT_SHOWKEY)) {
379 		if (r->satype == IPSEC_TCPMD5)
380 			printf(" ");
381 		else
382 			printf(" \\\n\t");
383 		printf("authkey 0x");
384 		ipsecctl_print_key(r->authkey);
385 	}
386 	if (r->enckey && (opts & IPSECCTL_OPT_SHOWKEY)) {
387 		if (r->satype == IPSEC_TCPMD5)
388 			printf(" ");
389 		else
390 			printf(" \\\n\t");
391 		printf("enckey 0x");
392 		ipsecctl_print_key(r->enckey);
393 	}
394 	printf("\n");
395 }
396 
397 void
398 ipsecctl_print_sagroup(struct ipsec_rule *r, int opts)
399 {
400 	if (!(opts & IPSECCTL_OPT_VERBOSE2))
401 		return;
402 
403 	printf("[group %s to ", satype[r->proto]);
404 	ipsecctl_print_addr(r->dst);
405 	printf(" spi 0x%08x with %s to ", r->spi, satype[r->proto2]);
406 	ipsecctl_print_addr(r->dst2);
407 	printf(" spi 0x%08x", r->spi2);
408 
409 	printf("]\n");
410 }
411 
412 void
413 ipsecctl_print_rule(struct ipsec_rule *r, int opts)
414 {
415 	if (opts & IPSECCTL_OPT_VERBOSE2)
416 		printf("@%d ", r->nr);
417 
418 	if (r->type & RULE_FLOW)
419 		ipsecctl_print_flow(r, opts);
420 	if (r->type & RULE_SA)
421 		ipsecctl_print_sa(r, opts);
422 	if (r->type & RULE_IKE)
423 		ike_print_config(r, opts);
424 	if (r->type & RULE_GROUP)
425 		ipsecctl_print_sagroup(r, opts);
426 }
427 
428 int
429 ipsecctl_flush(int opts)
430 {
431 	if (opts & IPSECCTL_OPT_NOACTION)
432 		return (0);
433 
434 	if (pfkey_init() == -1)
435 		errx(1, "ipsecctl_flush: failed to open PF_KEY socket");
436 
437 	if (pfkey_ipsec_flush() == -1)
438 		errx(1, "ipsecctl_flush: failed to flush");
439 
440 	return (0);
441 }
442 
443 void
444 ipsecctl_get_rules(struct ipsecctl *ipsec)
445 {
446 	struct sadb_msg *msg;
447 	struct ipsec_rule *rule;
448 	int		 mib[4];
449 	size_t		 need;
450 	char		*buf, *lim, *next;
451 
452 	mib[0] = CTL_NET;
453 	mib[1] = PF_KEY;
454 	mib[2] = PF_KEY_V2;
455 	mib[3] = NET_KEY_SPD_DUMP;
456 
457 	if (sysctl(mib, 4, NULL, &need, NULL, 0) == -1)
458 		err(1, "ipsecctl_get_rules: sysctl");
459 	if (need == 0)
460 		return;
461 	if ((buf = malloc(need)) == NULL)
462 		err(1, "ipsecctl_get_rules: malloc");
463 	if (sysctl(mib, 4, buf, &need, NULL, 0) == -1)
464 		err(1, "ipsecctl_get_rules: sysctl");
465 	lim = buf + need;
466 
467 	for (next = buf; next < lim; next += msg->sadb_msg_len *
468 	    PFKEYV2_CHUNK) {
469 		msg = (struct sadb_msg *)next;
470 		if (msg->sadb_msg_len == 0)
471 			break;
472 
473 		rule = calloc(1, sizeof(struct ipsec_rule));
474 		if (rule == NULL)
475 			err(1, "ipsecctl_get_rules: calloc");
476 		rule->nr = ipsec->rule_nr++;
477 		rule->type |= RULE_FLOW;
478 
479 		if (pfkey_parse(msg, rule))
480 			errx(1, "ipsecctl_get_rules: "
481 			    "failed to parse PF_KEY message");
482 
483 		ipsecctl_add_rule(ipsec, rule);
484 	}
485 
486 	free(buf);
487 }
488 
489 void
490 ipsecctl_print_title(char *title)
491 {
492 	if (!first_title)
493 		printf("\n");
494 	first_title = 0;
495 	printf("%s\n", title);
496 }
497 
498 void
499 ipsecctl_show_flows(int opts)
500 {
501 	struct ipsecctl ipsec;
502 	struct ipsec_rule *rp;
503 
504 	bzero(&ipsec, sizeof(ipsec));
505 	ipsec.opts = opts;
506 	TAILQ_INIT(&ipsec.rule_queue);
507 
508 	ipsecctl_get_rules(&ipsec);
509 
510 	if (opts & IPSECCTL_OPT_SHOWALL)
511 		ipsecctl_print_title("FLOWS:");
512 
513 	if (TAILQ_FIRST(&ipsec.rule_queue) == 0) {
514 		if (opts & IPSECCTL_OPT_SHOWALL)
515 			printf("No flows\n");
516 		return;
517 	}
518 
519 	while ((rp = TAILQ_FIRST(&ipsec.rule_queue))) {
520 		TAILQ_REMOVE(&ipsec.rule_queue, rp, rule_entry);
521 
522 		ipsecctl_print_rule(rp, ipsec.opts);
523 
524 		free(rp->src->name);
525 		free(rp->src);
526 		free(rp->dst->name);
527 		free(rp->dst);
528 		if (rp->local) {
529 			free(rp->local->name);
530 			free(rp->local);
531 		}
532 		if (rp->peer) {
533 			free(rp->peer->name);
534 			free(rp->peer);
535 		}
536 		if (rp->auth) {
537 			if (rp->auth->srcid)
538 				free(rp->auth->srcid);
539 			if (rp->auth->dstid)
540 				free(rp->auth->dstid);
541 			free(rp->auth);
542 		}
543 		free(rp);
544 	}
545 }
546 
547 void
548 ipsecctl_show_sas(int opts)
549 {
550 	struct sadb_msg *msg;
551 	struct sad	*sad;
552 	int		 mib[5], sacount, i;
553 	size_t		 need = 0;
554 	char		*buf, *lim, *next;
555 
556 	mib[0] = CTL_NET;
557 	mib[1] = PF_KEY;
558 	mib[2] = PF_KEY_V2;
559 	mib[3] = NET_KEY_SADB_DUMP;
560 	mib[4] = SADB_SATYPE_UNSPEC;
561 
562 	if (opts & IPSECCTL_OPT_SHOWALL)
563 		ipsecctl_print_title("SAD:");
564 
565 	/* When the SAD is empty we get ENOENT, no need to err(). */
566 	if (sysctl(mib, 5, NULL, &need, NULL, 0) == -1 && errno != ENOENT)
567 		err(1, "ipsecctl_show_sas: sysctl");
568 	if (need == 0) {
569 		if (opts & IPSECCTL_OPT_SHOWALL)
570 			printf("No entries\n");
571 		return;
572 	}
573 	if ((buf = malloc(need)) == NULL)
574 		err(1, "ipsecctl_show_sas: malloc");
575 	if (sysctl(mib, 5, buf, &need, NULL, 0) == -1)
576 		err(1, "ipsecctl_show_sas: sysctl");
577 	sacount = 0;
578 	lim = buf + need;
579 	for (next = buf; next < lim;
580 	    next += msg->sadb_msg_len * PFKEYV2_CHUNK) {
581 		msg = (struct sadb_msg *)next;
582 		if (msg->sadb_msg_len == 0)
583 			break;
584 		sacount++;
585 	}
586 	if ((sad = calloc(sacount, sizeof(*sad))) == NULL)
587 		err(1, "ipsecctl_show_sas: calloc");
588 	i = 0;
589 	for (next = buf; next < lim;
590 	    next += msg->sadb_msg_len * PFKEYV2_CHUNK) {
591 		msg = (struct sadb_msg *)next;
592 		if (msg->sadb_msg_len == 0)
593 			break;
594 		sad[i].sad_spi = pfkey_get_spi(msg);
595 		sad[i].sad_msg = msg;
596 		i++;
597 	}
598 	qsort(sad, sacount, sizeof(*sad), sacompare);
599 	for (i = 0; i < sacount; i++)
600 		pfkey_print_sa(sad[i].sad_msg, opts);
601 	free(sad);
602 	free(buf);
603 }
604 
605 int
606 ipsecctl_monitor(int opts)
607 {
608 	return (pfkey_monitor(opts));
609 }
610 
611 __dead void
612 usage(void)
613 {
614 	extern char	*__progname;
615 
616 	fprintf(stderr, "usage: %s [-dFkmnv] [-D macro=value] [-f file]"
617 	    " [-i fifo] [-s modifier]\n", __progname);
618 	exit(1);
619 }
620 
621 const char *
622 ipsecctl_lookup_option(char *cmd, const char **list)
623 {
624 	if (cmd != NULL && *cmd)
625 		for (; *list; list++)
626 			if (!strncmp(cmd, *list, strlen(cmd)))
627 				return (*list);
628 	return (NULL);
629 }
630 
631 int
632 main(int argc, char *argv[])
633 {
634 	int		 error = 0;
635 	int		 ch;
636 	int		 opts = 0;
637 	char		*rulesopt = NULL;
638 
639 	if (argc < 2)
640 		usage();
641 
642 	while ((ch = getopt(argc, argv, "D:df:Fi:kmnvs:")) != -1) {
643 		switch (ch) {
644 		case 'D':
645 			if (cmdline_symset(optarg) < 0)
646 				warnx("could not parse macro definition %s",
647 				    optarg);
648 			break;
649 
650 		case 'd':
651 			opts |= IPSECCTL_OPT_DELETE;
652 			break;
653 
654 		case 'f':
655 			rulesopt = optarg;
656 			break;
657 
658 		case 'F':
659 			opts |= IPSECCTL_OPT_FLUSH;
660 			break;
661 
662 		case 'i':
663 			isakmpd_fifo = optarg;
664 			break;
665 
666 		case 'k':
667 			opts |= IPSECCTL_OPT_SHOWKEY;
668 			break;
669 
670 		case 'm':
671 			opts |= IPSECCTL_OPT_MONITOR;
672 			break;
673 
674 		case 'n':
675 			opts |= IPSECCTL_OPT_NOACTION;
676 			break;
677 
678 		case 'v':
679 			if (opts & IPSECCTL_OPT_VERBOSE)
680 				opts |= IPSECCTL_OPT_VERBOSE2;
681 			opts |= IPSECCTL_OPT_VERBOSE;
682 			break;
683 
684 		case 's':
685 			showopt = ipsecctl_lookup_option(optarg, showopt_list);
686 			if (showopt == NULL) {
687 				warnx("Unknown show modifier '%s'", optarg);
688 				usage();
689 				/* NOTREACHED */
690 			}
691 			opts |= IPSECCTL_OPT_SHOW;
692 			break;
693 
694 		default:
695 			usage();
696 			/* NOTREACHED */
697 		}
698 	}
699 
700 	if (argc != optind) {
701 		warnx("unknown command line argument: %s ...", argv[optind]);
702 		usage();
703 		/* NOTREACHED */
704 	}
705 	if (opts & IPSECCTL_OPT_FLUSH)
706 		if (ipsecctl_flush(opts))
707 			error = 1;
708 
709 	if (rulesopt != NULL)
710 		if (ipsecctl_rules(rulesopt, opts))
711 			error = 1;
712 
713 	if (showopt != NULL) {
714 		switch (*showopt) {
715 		case 'f':
716 			ipsecctl_show_flows(opts);
717 			break;
718 		case 's':
719 			ipsecctl_show_sas(opts);
720 			break;
721 		case 'a':
722 			opts |= IPSECCTL_OPT_SHOWALL;
723 			ipsecctl_show_flows(opts);
724 			ipsecctl_show_sas(opts);
725 		}
726 	}
727 
728 	if (opts & IPSECCTL_OPT_MONITOR)
729 		if (ipsecctl_monitor(opts))
730 			error = 1;
731 
732 	exit(error);
733 }
734 
735 /* ARGSUSED1 */
736 static int
737 unmask(struct ipsec_addr *ipa, sa_family_t af)
738 {
739 	int		i = 31, j = 0, b = 0;
740 	u_int32_t	tmp;
741 
742 	while (j < 4 && ipa->addr32[j] == 0xffffffff) {
743 		b += 32;
744 		j++;
745 	}
746 	if (j < 4) {
747 		tmp = ntohl(ipa->addr32[j]);
748 		for (i = 31; tmp & (1 << i); --i)
749 			b++;
750 	}
751 	return (b);
752 }
753