xref: /openbsd-src/sbin/ipsecctl/ike.c (revision a28daedfc357b214be5c701aa8ba8adb29a7f1c2)
1 /*	$OpenBSD: ike.c,v 1.65 2009/01/20 14:36:19 mpf Exp $	*/
2 /*
3  * Copyright (c) 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/types.h>
19 #include <sys/socket.h>
20 #include <sys/stat.h>
21 #include <sys/queue.h>
22 #include <netinet/in.h>
23 #include <netdb.h>
24 #include <arpa/inet.h>
25 
26 #include <err.h>
27 #include <fcntl.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <unistd.h>
32 
33 #include "ipsecctl.h"
34 
35 static void	ike_section_general(struct ipsec_rule *, FILE *);
36 static void	ike_section_peer(struct ipsec_rule *, FILE *);
37 static void	ike_section_ids(struct ipsec_rule *, FILE *);
38 static void	ike_section_ipsec(struct ipsec_rule *, FILE *);
39 static int	ike_section_p1(struct ipsec_rule *, FILE *);
40 static int	ike_section_p2(struct ipsec_rule *, FILE *);
41 static void	ike_section_p2ids(struct ipsec_rule *, FILE *);
42 static int	ike_connect(struct ipsec_rule *, FILE *);
43 static int	ike_gen_config(struct ipsec_rule *, FILE *);
44 static int	ike_delete_config(struct ipsec_rule *, FILE *);
45 static void	ike_setup_ids(struct ipsec_rule *);
46 
47 int		ike_print_config(struct ipsec_rule *, int);
48 int		ike_ipsec_establish(int, struct ipsec_rule *);
49 
50 #define	SET	"C set "
51 #define	ADD	"C add "
52 #define	DELETE	"C rms "
53 #define	RMV	"C rmv "
54 
55 #define ISAKMPD_FIFO	"/var/run/isakmpd.fifo"
56 
57 #define CONF_DFLT_DYNAMIC_DPD_CHECK_INTERVAL	5
58 #define CONF_DFLT_DYNAMIC_CHECK_INTERVAL	30
59 
60 char *ike_id_types[] = { "", "", "FQDN", "USER_FQDN" };
61 
62 static void
63 ike_section_general(struct ipsec_rule *r, FILE *fd)
64 {
65 	if (r->ikemode == IKE_DYNAMIC) {
66 		fprintf(fd, SET "[General]:Check-interval=%d force\n",
67 		    CONF_DFLT_DYNAMIC_CHECK_INTERVAL);
68 		fprintf(fd, SET "[General]:DPD-check-interval=%d force\n",
69 		    CONF_DFLT_DYNAMIC_DPD_CHECK_INTERVAL);
70 	}
71 	if (r->p1life && r->p1life->lifetime != -1)
72 		fprintf(fd, SET "[General]:Default-phase-1-lifetime=%d force\n",
73 		    r->p1life->lifetime);
74 	if (r->p2life && r->p2life->lifetime != -1)
75 		fprintf(fd, SET "[General]:Default-phase-2-lifetime=%d force\n",
76 		    r->p2life->lifetime);
77 }
78 
79 static void
80 ike_section_peer(struct ipsec_rule *r, FILE *fd)
81 {
82 	if (r->peer)
83 		fprintf(fd, SET "[Phase 1]:%s=%s force\n", r->peer->name,
84 		    r->p1name);
85 	else
86 		fprintf(fd, SET "[Phase 1]:Default=%s force\n", r->p1name);
87 	fprintf(fd, SET "[%s]:Phase=1 force\n", r->p1name);
88 	if (r->peer)
89 		fprintf(fd, SET "[%s]:Address=%s force\n", r->p1name,
90 		    r->peer->name);
91 	if (r->local)
92 		fprintf(fd, SET "[%s]:Local-address=%s force\n", r->p1name,
93 		    r->local->name);
94 	if (r->ikeauth->type == IKE_AUTH_PSK)
95 		fprintf(fd, SET "[%s]:Authentication=%s force\n", r->p1name,
96 		    r->ikeauth->string);
97 }
98 
99 static void
100 ike_section_ids(struct ipsec_rule *r, FILE *fd)
101 {
102 	char myname[MAXHOSTNAMELEN];
103 
104 	if (r->auth == NULL)
105 		return;
106 
107 	if (r->ikemode == IKE_DYNAMIC && r->auth->srcid == NULL) {
108 		if (gethostname(myname, sizeof(myname)) == -1)
109 			err(1, "ike_section_ids: gethostname");
110 		if ((r->auth->srcid = strdup(myname)) == NULL)
111 			err(1, "ike_section_ids: strdup");
112 	}
113 	if (r->auth->srcid) {
114 		fprintf(fd, SET "[%s]:ID=id-%s force\n", r->p1name,
115 		    r->auth->srcid);
116 		fprintf(fd, SET "[id-%s]:ID-type=%s force\n", r->auth->srcid,
117 		    ike_id_types[r->auth->srcid_type]);
118 		fprintf(fd, SET "[id-%s]:Name=%s force\n", r->auth->srcid,
119 		    r->auth->srcid);
120 	}
121 	if (r->auth->dstid) {
122 		fprintf(fd, SET "[%s]:Remote-ID=id-%s force\n", r->p1name,
123 		    r->auth->dstid);
124 		fprintf(fd, SET "[id-%s]:ID-type=%s force\n", r->auth->dstid,
125 		    ike_id_types[r->auth->dstid_type]);
126 		fprintf(fd, SET "[id-%s]:Name=%s force\n", r->auth->dstid,
127 		    r->auth->dstid);
128 	}
129 }
130 
131 static void
132 ike_section_ipsec(struct ipsec_rule *r, FILE *fd)
133 {
134 	fprintf(fd, SET "[%s]:Phase=2 force\n", r->p2name);
135 	fprintf(fd, SET "[%s]:ISAKMP-peer=%s force\n", r->p2name, r->p1name);
136 	fprintf(fd, SET "[%s]:Configuration=phase2-%s force\n", r->p2name,
137 	    r->p2name);
138 	fprintf(fd, SET "[%s]:Local-ID=%s force\n", r->p2name, r->p2lid);
139 	if (r->p2nid)
140 		fprintf(fd, SET "[%s]:NAT-ID=%s force\n", r->p2name, r->p2nid);
141 	fprintf(fd, SET "[%s]:Remote-ID=%s force\n", r->p2name, r->p2rid);
142 
143 	if (r->tag)
144 		fprintf(fd, SET "[%s]:PF-Tag=%s force\n", r->p2name, r->tag);
145 }
146 
147 static int
148 ike_section_p2(struct ipsec_rule *r, FILE *fd)
149 {
150 	char	*exchange_type, *sprefix;
151 
152 	switch (r->p2ie) {
153 	case IKE_QM:
154 		exchange_type = "QUICK_MODE";
155 		sprefix = "QM";
156 		break;
157 	default:
158 		warnx("illegal phase 2 ike mode %d", r->p2ie);
159 		return (-1);
160 	}
161 
162 	fprintf(fd, SET "[phase2-%s]:EXCHANGE_TYPE=%s force\n", r->p2name,
163 	    exchange_type);
164 	fprintf(fd, SET "[phase2-%s]:Suites=%s-", r->p2name, sprefix);
165 
166 	switch (r->satype) {
167 	case IPSEC_ESP:
168 		fprintf(fd, "ESP");
169 		break;
170 	case IPSEC_AH:
171 		fprintf(fd, "AH");
172 		break;
173 	default:
174 		warnx("illegal satype %d", r->satype);
175 		return (-1);
176 	}
177 	fprintf(fd, "-");
178 
179 	switch (r->tmode) {
180 	case IPSEC_TUNNEL:
181 		break;
182 	case IPSEC_TRANSPORT:
183 		fprintf(fd, "TRP-");
184 		break;
185 	default:
186 		warnx("illegal encapsulation mode %d", r->tmode);
187 		return (-1);
188 	}
189 
190 	if (r->p2xfs && r->p2xfs->encxf) {
191 		if (r->satype == IPSEC_ESP) {
192 			switch (r->p2xfs->encxf->id) {
193 			case ENCXF_3DES_CBC:
194 				fprintf(fd, "3DES");
195 				break;
196 			case ENCXF_DES_CBC:
197 				fprintf(fd, "DES");
198 				break;
199 			case ENCXF_AES:
200 				fprintf(fd, "AES");
201 				break;
202 			case ENCXF_AES_128:
203 				fprintf(fd, "AES-128");
204 				break;
205 			case ENCXF_AES_192:
206 				fprintf(fd, "AES-192");
207 				break;
208 			case ENCXF_AES_256:
209 				fprintf(fd, "AES-256");
210 				break;
211 			case ENCXF_AESCTR:
212 				fprintf(fd, "AESCTR");
213 				break;
214 			case ENCXF_BLOWFISH:
215 				fprintf(fd, "BLF");
216 				break;
217 			case ENCXF_CAST128:
218 				fprintf(fd, "CAST");
219 				break;
220 			case ENCXF_NULL:
221 				fprintf(fd, "NULL");
222 				break;
223 			default:
224 				warnx("illegal transform %s",
225 				    r->p2xfs->encxf->name);
226 				return (-1);
227 			}
228 			fprintf(fd, "-");
229 		} else {
230 			warnx("illegal transform %s", r->p2xfs->encxf->name);
231 			return (-1);
232 		}
233 	} else if (r->satype == IPSEC_ESP)
234 		fprintf(fd, "AES-");
235 
236 	if (r->p2xfs && r->p2xfs->authxf) {
237 		switch (r->p2xfs->authxf->id) {
238 		case AUTHXF_HMAC_MD5:
239 			fprintf(fd, "MD5");
240 			break;
241 		case AUTHXF_HMAC_SHA1:
242 			fprintf(fd, "SHA");
243 			break;
244 		case AUTHXF_HMAC_RIPEMD160:
245 			fprintf(fd, "RIPEMD");
246 			break;
247 		case AUTHXF_HMAC_SHA2_256:
248 			fprintf(fd, "SHA2-256");
249 			break;
250 		case AUTHXF_HMAC_SHA2_384:
251 			fprintf(fd, "SHA2-384");
252 			break;
253 		case AUTHXF_HMAC_SHA2_512:
254 			fprintf(fd, "SHA2-512");
255 			break;
256 		default:
257 			warnx("illegal transform %s", r->p2xfs->authxf->name);
258 			return (-1);
259 		}
260 	} else
261 		fprintf(fd, "SHA2-256");
262 
263 	if (r->p2xfs && r->p2xfs->groupxf) {
264 		switch (r->p2xfs->groupxf->id) {
265 		case GROUPXF_NONE:
266 			break;
267 		case GROUPXF_768:
268 			fprintf(fd, "-PFS-GRP1");
269 			break;
270 		case GROUPXF_1024:
271 			fprintf(fd, "-PFS-GRP2");
272 			break;
273 		case GROUPXF_1536:
274 			fprintf(fd, "-PFS-GRP5");
275 			break;
276 		case GROUPXF_2048:
277 			fprintf(fd, "-PFS-GRP14");
278 			break;
279 		case GROUPXF_3072:
280 			fprintf(fd, "-PFS-GRP15");
281 			break;
282 		case GROUPXF_4096:
283 			fprintf(fd, "-PFS-GRP16");
284 			break;
285 		case GROUPXF_6144:
286 			fprintf(fd, "-PFS-GRP17");
287 			break;
288 		case GROUPXF_8192:
289 			fprintf(fd, "-PFS-GRP18");
290 			break;
291 		default:
292 			warnx("illegal group %s", r->p2xfs->groupxf->name);
293 			return (-1);
294 		};
295 	} else
296 		fprintf(fd, "-PFS");
297 	fprintf(fd, "-SUITE force\n");
298 
299 	return (0);
300 }
301 
302 static int
303 ike_section_p1(struct ipsec_rule *r, FILE *fd)
304 {
305 	char *exchange_type;
306 
307 	switch (r->p1ie) {
308 	case IKE_MM:
309 		exchange_type = "ID_PROT";
310 		break;
311 	case IKE_AM:
312 		exchange_type = "AGGRESSIVE";
313 		break;
314 	default:
315 		warnx("illegal phase 2 ike mode %d", r->p1ie);
316 		return (-1);
317 	}
318 
319 	fprintf(fd, SET "[%s]:Configuration=phase1-%s force\n", r->p1name,
320 	    r->p1name);
321 	fprintf(fd, SET "[phase1-%s]:EXCHANGE_TYPE=%s force\n", r->p1name,
322 	    exchange_type);
323 	fprintf(fd, ADD "[phase1-%s]:Transforms=", r->p1name);
324 
325 	if (r->p1xfs && r->p1xfs->encxf) {
326 		switch (r->p1xfs->encxf->id) {
327 		case ENCXF_3DES_CBC:
328 			fprintf(fd, "3DES");
329 			break;
330 		case ENCXF_DES_CBC:
331 			fprintf(fd, "DES");
332 			break;
333 		case ENCXF_AES:
334 			fprintf(fd, "AES");
335 			break;
336 		case ENCXF_AES_128:
337 			fprintf(fd, "AES-128");
338 			break;
339 		case ENCXF_AES_192:
340 			fprintf(fd, "AES-192");
341 			break;
342 		case ENCXF_AES_256:
343 			fprintf(fd, "AES-256");
344 			break;
345 		case ENCXF_BLOWFISH:
346 			fprintf(fd, "BLF");
347 			break;
348 		case ENCXF_CAST128:
349 			fprintf(fd, "CAST");
350 			break;
351 		default:
352 			warnx("illegal transform %s", r->p1xfs->encxf->name);
353 			return (-1);
354 		}
355 	} else
356 		fprintf(fd, "AES");
357 	fprintf(fd, "-");
358 
359 	if (r->p1xfs && r->p1xfs->authxf) {
360 		switch (r->p1xfs->authxf->id) {
361 		case AUTHXF_HMAC_MD5:
362 			fprintf(fd, "MD5");
363 			break;
364 		case AUTHXF_HMAC_SHA1:
365 			fprintf(fd, "SHA");
366 			break;
367 		case AUTHXF_HMAC_SHA2_256:
368 			fprintf(fd, "SHA2-256");
369 			break;
370 		case AUTHXF_HMAC_SHA2_384:
371 			fprintf(fd, "SHA2-384");
372 			break;
373 		case AUTHXF_HMAC_SHA2_512:
374 			fprintf(fd, "SHA2-512");
375 			break;
376 		default:
377 			warnx("illegal transform %s", r->p1xfs->authxf->name);
378 			return (-1);
379 		}
380 	} else
381 		fprintf(fd, "SHA");
382 
383 	if (r->p1xfs && r->p1xfs->groupxf) {
384 		switch (r->p1xfs->groupxf->id) {
385 		case GROUPXF_768:
386 			fprintf(fd, "-GRP1");
387 			break;
388 		case GROUPXF_1024:
389 			fprintf(fd, "-GRP2");
390 			break;
391 		case GROUPXF_1536:
392 			fprintf(fd, "-GRP5");
393 			break;
394 		case GROUPXF_2048:
395 			fprintf(fd, "-GRP14");
396 			break;
397 		case GROUPXF_3072:
398 			fprintf(fd, "-GRP15");
399 			break;
400 		case GROUPXF_4096:
401 			fprintf(fd, "-GRP16");
402 			break;
403 		case GROUPXF_6144:
404 			fprintf(fd, "-GRP17");
405 			break;
406 		case GROUPXF_8192:
407 			fprintf(fd, "-GRP18");
408 			break;
409 		default:
410 			warnx("illegal group %s", r->p1xfs->groupxf->name);
411 			return (-1);
412 		};
413 	}
414 
415 	if (r->ikeauth->type == IKE_AUTH_RSA)
416 		fprintf(fd, "-RSA_SIG");
417 	fprintf(fd, " force\n");
418 
419 	return (0);
420 }
421 
422 static void
423 ike_section_p2ids_net(struct ipsec_addr *iamask, sa_family_t af, char *name,
424     char *p2xid, FILE *fd)
425 {
426 	char mask[NI_MAXHOST], *network, *p;
427 	struct sockaddr_storage sas;
428 	struct sockaddr *sa = (struct sockaddr *)&sas;
429 
430 	bzero(&sas, sizeof(struct sockaddr_storage));
431 	bzero(mask, sizeof(mask));
432 	sa->sa_family = af;
433 	switch (af) {
434 	case AF_INET:
435 		sa->sa_len = sizeof(struct sockaddr_in);
436 		bcopy(&iamask->ipa,
437 		    &((struct sockaddr_in *)(sa))->sin_addr,
438 		    sizeof(struct in6_addr));
439 		break;
440 	case AF_INET6:
441 		sa->sa_len = sizeof(struct sockaddr_in6);
442 		bcopy(&iamask->ipa,
443 		    &((struct sockaddr_in6 *)(sa))->sin6_addr,
444 		    sizeof(struct in6_addr));
445 		break;
446 	}
447 	if (getnameinfo(sa, sa->sa_len, mask, sizeof(mask), NULL, 0,
448 	    NI_NUMERICHOST))
449 		errx(1, "could not get a numeric mask");
450 
451 	if ((network = strdup(name)) == NULL)
452 		err(1, "ike_section_p2ids: strdup");
453 	if ((p = strrchr(network, '/')) != NULL)
454 		*p = '\0';
455 
456 	fprintf(fd, SET "[%s]:ID-type=IPV%d_ADDR_SUBNET force\n",
457 	    p2xid, ((af == AF_INET) ? 4 : 6));
458 	fprintf(fd, SET "[%s]:Network=%s force\n", p2xid, network);
459 	fprintf(fd, SET "[%s]:Netmask=%s force\n", p2xid, mask);
460 
461 	free(network);
462 }
463 
464 static void
465 ike_section_p2ids(struct ipsec_rule *r, FILE *fd)
466 {
467 	char *p;
468 	struct ipsec_addr_wrap *src = r->src;
469 	struct ipsec_addr_wrap *dst = r->dst;
470 
471 	if (src->netaddress) {
472 		ike_section_p2ids_net(&src->mask, src->af, src->name,
473 		    r->p2lid, fd);
474 	} else {
475 		fprintf(fd, SET "[%s]:ID-type=IPV%d_ADDR force\n",
476 		    r->p2lid, ((src->af == AF_INET) ? 4 : 6));
477 		if ((p = strrchr(src->name, '/')) != NULL)
478 			*p = '\0';
479 		fprintf(fd, SET "[%s]:Address=%s force\n", r->p2lid,
480 		    src->name);
481 	}
482 
483 	if (src->srcnat && src->srcnat->netaddress) {
484 		ike_section_p2ids_net(&src->srcnat->mask, src->af, src->srcnat->name,
485 		    r->p2nid, fd);
486 	} else if (src->srcnat) {
487 		fprintf(fd, SET "[%s]:ID-type=IPV%d_ADDR force\n",
488 		    r->p2nid, ((src->af == AF_INET) ? 4 : 6));
489 		if ((p = strrchr(src->srcnat->name, '/')) != NULL)
490 			*p = '\0';
491 		fprintf(fd, SET "[%s]:Address=%s force\n", r->p2nid,
492 		    src->srcnat->name);
493 	}
494 
495 	if (dst->netaddress) {
496 		ike_section_p2ids_net(&dst->mask, dst->af, dst->name,
497 		    r->p2rid, fd);
498 	} else {
499 		fprintf(fd, SET "[%s]:ID-type=IPV%d_ADDR force\n",
500 		    r->p2rid, ((dst->af == AF_INET) ? 4 : 6));
501 		if ((p = strrchr(dst->name, '/')) != NULL)
502 			*p = '\0';
503 		fprintf(fd, SET "[%s]:Address=%s force\n", r->p2rid,
504 		    dst->name);
505 	}
506 	if (r->proto) {
507 		fprintf(fd, SET "[%s]:Protocol=%d force\n",
508 		    r->p2lid, r->proto);
509 		fprintf(fd, SET "[%s]:Protocol=%d force\n",
510 		    r->p2rid, r->proto);
511 	}
512 	if (r->sport)
513 		fprintf(fd, SET "[%s]:Port=%d force\n", r->p2lid,
514 		    ntohs(r->sport));
515 	if (r->dport)
516 		fprintf(fd, SET "[%s]:Port=%d force\n", r->p2rid,
517 		    ntohs(r->dport));
518 }
519 
520 static int
521 ike_connect(struct ipsec_rule *r, FILE *fd)
522 {
523 	switch (r->ikemode) {
524 	case IKE_ACTIVE:
525 	case IKE_DYNAMIC:
526 		fprintf(fd, ADD "[Phase 2]:Connections=%s\n", r->p2name);
527 		break;
528 	case IKE_PASSIVE:
529 		fprintf(fd, ADD "[Phase 2]:Passive-Connections=%s\n",
530 		    r->p2name);
531 		break;
532 	default:
533 		return (-1);
534 	}
535 	return (0);
536 }
537 
538 static int
539 ike_gen_config(struct ipsec_rule *r, FILE *fd)
540 {
541 	ike_setup_ids(r);
542 	ike_section_general(r, fd);
543 	ike_section_peer(r, fd);
544 	if (ike_section_p1(r, fd) == -1) {
545 		return (-1);
546 	}
547 	ike_section_ids(r, fd);
548 	ike_section_ipsec(r, fd);
549 	if (ike_section_p2(r, fd) == -1) {
550 		return (-1);
551 	}
552 	ike_section_p2ids(r, fd);
553 
554 	if (ike_connect(r, fd) == -1)
555 		return (-1);
556 	return (0);
557 }
558 
559 static int
560 ike_delete_config(struct ipsec_rule *r, FILE *fd)
561 {
562 	ike_setup_ids(r);
563 #if 0
564 	switch (r->ikemode) {
565 	case IKE_ACTIVE:
566 	case IKE_DYNAMIC:
567 		fprintf(fd, "t %s\n", r->p2name);
568 		break;
569 	case IKE_PASSIVE:
570 		fprintf(fd, DELETE "[Phase 2]\n");
571 		fprintf(fd, "t %s\n", r->p2name);
572 		break;
573 	default:
574 		return (-1);
575 	}
576 
577 	if (r->peer) {
578 		fprintf(fd, DELETE "[%s]\n", r->p1name);
579 		fprintf(fd, DELETE "[phase1-%s]\n", r->p1name);
580 	}
581 	if (r->auth) {
582 		if (r->auth->srcid)
583 			fprintf(fd, DELETE "[%s-ID]\n", r->auth->srcid);
584 		if (r->auth->dstid)
585 			fprintf(fd, DELETE "[%s-ID]\n", r->auth->dstid);
586 	}
587 	fprintf(fd, DELETE "[%s]\n", r->p2name);
588 	fprintf(fd, DELETE "[phase2-%s]\n", r->p2name);
589 	fprintf(fd, DELETE "[%s]\n", r->p2lid);
590 	fprintf(fd, DELETE "[%s]\n", r->p2rid);
591 #else
592 	fprintf(fd, "t %s\n", r->p2name);
593 	switch (r->ikemode) {
594 	case IKE_ACTIVE:
595 	case IKE_DYNAMIC:
596 		fprintf(fd, RMV "[Phase 2]:Connections=%s\n", r->p2name);
597 		break;
598 	case IKE_PASSIVE:
599 		fprintf(fd, RMV "[Phase 2]:Passive-Connections=%s\n",
600 		    r->p2name);
601 		break;
602 	default:
603 		return (-1);
604 	}
605 	fprintf(fd, DELETE "[%s]\n", r->p2name);
606 	fprintf(fd, DELETE "[phase2-%s]\n", r->p2name);
607 #endif
608 
609 	return (0);
610 }
611 
612 static void
613 ike_setup_ids(struct ipsec_rule *r)
614 {
615 	char sproto[10], ssport[10], sdport[10];
616 
617 	/* phase 1 name is peer and local address */
618 	if (r->peer) {
619 		if (r->local) {
620 			/* peer-dstaddr-local-srcaddr */
621 			if (asprintf(&r->p1name, "peer-%s-local-%s",
622 			    r->peer->name, r->local->name) == -1)
623 				err(1, "ike_setup_ids");
624 		} else
625 			/* peer-dstaddr */
626 			if (asprintf(&r->p1name, "peer-%s",
627 			    r->peer->name) == -1)
628 				err(1, "ike_setup_ids");
629 	} else
630 		if ((r->p1name = strdup("peer-default")) == NULL)
631 			err(1, "ike_setup_ids");
632 
633 	/* Phase 2 name is from and to network, protocol, port*/
634 	sproto[0] = ssport[0] = sdport[0] = 0;
635 	if (r->proto)
636 		snprintf(sproto, sizeof sproto, "=%u", r->proto);
637 	if (r->sport)
638 		snprintf(ssport, sizeof ssport, ":%u", ntohs(r->sport));
639 	if (r->dport)
640 		snprintf(sdport, sizeof sdport, ":%u", ntohs(r->dport));
641 	/* from-network/masklen=proto:port */
642 	if (asprintf(&r->p2lid, "from-%s%s%s", r->src->name, sproto, ssport)
643 	    == -1)
644 		err(1, "ike_setup_ids");
645 	/* to-network/masklen=proto:port */
646 	if (asprintf(&r->p2rid, "to-%s%s%s", r->dst->name, sproto, sdport)
647 	    == -1)
648 		err(1, "ike_setup_ids");
649 	/* from-network/masklen=proto:port-to-network/masklen=proto:port */
650 	if (asprintf(&r->p2name, "%s-%s", r->p2lid , r->p2rid) == -1)
651 		err(1, "ike_setup_ids");
652 	/* nat-network/masklen=proto:port */
653 	if (r->src->srcnat && r->src->srcnat->name) {
654 		if (asprintf(&r->p2nid, "nat-%s%s%s", r->src->srcnat->name, sproto,
655 		    ssport) == -1)
656 			err(1, "ike_setup_ids");
657 	}
658 }
659 
660 int
661 ike_print_config(struct ipsec_rule *r, int opts)
662 {
663 	if (opts & IPSECCTL_OPT_DELETE)
664 		return (ike_delete_config(r, stdout));
665 	else
666 		return (ike_gen_config(r, stdout));
667 }
668 
669 int
670 ike_ipsec_establish(int action, struct ipsec_rule *r)
671 {
672 	struct stat	 sb;
673 	FILE		*fdp;
674 	int		 fd, ret = 0;
675 
676 	if ((fd = open(ISAKMPD_FIFO, O_WRONLY)) == -1)
677 		err(1, "ike_ipsec_establish: open(%s)", ISAKMPD_FIFO);
678 	if (fstat(fd, &sb) == -1)
679 		err(1, "ike_ipsec_establish: fstat(%s)", ISAKMPD_FIFO);
680 	if (!S_ISFIFO(sb.st_mode))
681 		errx(1, "ike_ipsec_establish: %s not a fifo", ISAKMPD_FIFO);
682 	if ((fdp = fdopen(fd, "w")) == NULL)
683 		err(1, "ike_ipsec_establish: fdopen(%s)", ISAKMPD_FIFO);
684 
685 	switch (action) {
686 	case ACTION_ADD:
687 		ret = ike_gen_config(r, fdp);
688 		break;
689 	case ACTION_DELETE:
690 		ret = ike_delete_config(r, fdp);
691 		break;
692 	default:
693 		ret = -1;
694 	}
695 
696 	fclose(fdp);
697 	return (ret);
698 }
699