]> git.saurik.com Git - apple/ipsec.git/blob - ipsec-tools/racoon/pfkey_racoon.c
88ec5f7053852cecc7f891c46e7959a35b1a49a7
[apple/ipsec.git] / ipsec-tools / racoon / pfkey_racoon.c
1 /* $Id: pfkey.c,v 1.31.2.10 2005/10/03 14:52:19 manubsd Exp $ */
2
3 /*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 #include "config.h"
33
34 #include <stdlib.h>
35 #include <string.h>
36 #include <stdio.h>
37 #include <netdb.h>
38 #include <errno.h>
39 #ifdef HAVE_UNISTD_H
40 #include <unistd.h>
41 #endif
42 #include <netdb.h>
43 #include <netinet/in.h>
44 #include <arpa/inet.h>
45
46 #ifdef ENABLE_NATT
47 #include <netinet/udp.h>
48 #endif
49
50 #include <sys/types.h>
51 #include <sys/param.h>
52 #include <sys/socket.h>
53 #include <sys/queue.h>
54 #include <sys/sysctl.h>
55
56 #include <net/route.h>
57 #include <System/net/pfkeyv2.h>
58
59 #include <netinet/in.h>
60 #ifndef HAVE_NETINET6_IPSEC
61 #include <netinet/ipsec.h>
62 #else
63 #include <netinet6/ipsec.h>
64 #endif
65
66 #include "libpfkey.h"
67
68 #include "var.h"
69 #include "misc.h"
70 #include "vmbuf.h"
71 #include "plog.h"
72 #include "sockmisc.h"
73 #include "debug.h"
74
75 #include "schedule.h"
76 #include "localconf.h"
77 #include "remoteconf.h"
78 #include "isakmp_var.h"
79 #include "isakmp.h"
80 #include "isakmp_inf.h"
81 #include "ipsec_doi.h"
82 #include "oakley.h"
83 #include "pfkey.h"
84 #include "handler.h"
85 #include "policy.h"
86 #include "algorithm.h"
87 #include "sainfo.h"
88 #include "proposal.h"
89 #include "admin.h"
90 #include "privsep.h"
91 #include "strnames.h"
92 #include "backupsa.h"
93 #include "gcmalloc.h"
94 #include "nattraversal.h"
95 #include "crypto_openssl.h"
96 #include "grabmyaddr.h"
97 #include "vpn_control.h"
98 #include "vpn_control_var.h"
99 #include "ike_session.h"
100 #include "ipsecSessionTracer.h"
101 #include "ipsecMessageTracer.h"
102 #include "power_mgmt.h"
103
104 #if defined(SADB_X_EALG_RIJNDAELCBC) && !defined(SADB_X_EALG_AESCBC)
105 #define SADB_X_EALG_AESCBC SADB_X_EALG_RIJNDAELCBC
106 #endif
107
108 /* prototype */
109 static u_int ipsecdoi2pfkey_aalg __P((u_int));
110 static u_int ipsecdoi2pfkey_ealg __P((u_int));
111 static u_int ipsecdoi2pfkey_calg __P((u_int));
112 static u_int ipsecdoi2pfkey_alg __P((u_int, u_int));
113 static u_int keylen_aalg __P((u_int));
114 static u_int keylen_ealg __P((u_int, int));
115
116 static int pk_recvgetspi __P((caddr_t *));
117 static int pk_recvupdate __P((caddr_t *));
118 static int pk_recvadd __P((caddr_t *));
119 static int pk_recvdelete __P((caddr_t *));
120 static int pk_recvacquire __P((caddr_t *));
121 static int pk_recvexpire __P((caddr_t *));
122 static int pk_recvflush __P((caddr_t *));
123 static int getsadbpolicy __P((caddr_t *, int *, int, struct ph2handle *));
124 static int pk_recvspdupdate __P((caddr_t *));
125 static int pk_recvspdadd __P((caddr_t *));
126 static int pk_recvspddelete __P((caddr_t *));
127 static int pk_recvspdexpire __P((caddr_t *));
128 static int pk_recvspdget __P((caddr_t *));
129 static int pk_recvspddump __P((caddr_t *));
130 static int pk_recvspdflush __P((caddr_t *));
131 static int pk_recvgetsastat __P((caddr_t *));
132 static struct sadb_msg *pk_recv __P((int, ssize_t *));
133
134 static int (*pkrecvf[]) __P((caddr_t *)) = {
135 NULL,
136 pk_recvgetspi,
137 pk_recvupdate,
138 pk_recvadd,
139 pk_recvdelete,
140 NULL, /* SADB_GET */
141 pk_recvacquire,
142 NULL, /* SABD_REGISTER */
143 pk_recvexpire,
144 pk_recvflush,
145 NULL, /* SADB_DUMP */
146 NULL, /* SADB_X_PROMISC */
147 NULL, /* SADB_X_PCHANGE */
148 pk_recvspdupdate,
149 pk_recvspdadd,
150 pk_recvspddelete,
151 pk_recvspdget,
152 NULL, /* SADB_X_SPDACQUIRE */
153 pk_recvspddump,
154 pk_recvspdflush,
155 NULL, /* SADB_X_SPDSETIDX */
156 pk_recvspdexpire,
157 NULL, /* SADB_X_SPDDELETE2 */
158 pk_recvgetsastat, /* SADB_GETSASTAT */
159 NULL, /* SADB_X_NAT_T_NEW_MAPPING */
160 NULL, /* SADB_X_MIGRATE */
161 #if (SADB_MAX > 25)
162 #error "SADB extra message?"
163 #endif
164 };
165
166 static int addnewsp __P((caddr_t *));
167
168 /* cope with old kame headers - ugly */
169 #ifndef SADB_X_AALG_MD5
170 #define SADB_X_AALG_MD5 SADB_AALG_MD5
171 #endif
172 #ifndef SADB_X_AALG_SHA
173 #define SADB_X_AALG_SHA SADB_AALG_SHA
174 #endif
175 #ifndef SADB_X_AALG_NULL
176 #define SADB_X_AALG_NULL SADB_AALG_NULL
177 #endif
178
179 #ifndef SADB_X_EALG_BLOWFISHCBC
180 #define SADB_X_EALG_BLOWFISHCBC SADB_EALG_BLOWFISHCBC
181 #endif
182 #ifndef SADB_X_EALG_CAST128CBC
183 #define SADB_X_EALG_CAST128CBC SADB_EALG_CAST128CBC
184 #endif
185 #ifndef SADB_X_EALG_RC5CBC
186 #ifdef SADB_EALG_RC5CBC
187 #define SADB_X_EALG_RC5CBC SADB_EALG_RC5CBC
188 #endif
189 #endif
190
191 int
192 pfkey_process(msg)
193 struct sadb_msg *msg;
194 {
195 caddr_t mhp[SADB_EXT_MAX + 1];
196 int error = -1;
197
198 //plog(LLV_DEBUG, LOCATION, NULL, "get pfkey %s message\n",
199 // s_pfkey_type(msg->sadb_msg_type));
200 //plogdump(LLV_DEBUG2, msg, msg->sadb_msg_len << 3);
201
202 /* validity check */
203 if (msg->sadb_msg_errno) {
204 int pri;
205
206 /* when SPD is empty, treat the state as no error. */
207 if (msg->sadb_msg_type == SADB_X_SPDDUMP &&
208 msg->sadb_msg_errno == ENOENT)
209 pri = LLV_DEBUG;
210 else
211 pri = LLV_ERROR;
212
213 plog(pri, LOCATION, NULL,
214 "pfkey %s failed: %s\n",
215 s_pfkey_type(msg->sadb_msg_type),
216 strerror(msg->sadb_msg_errno));
217
218 goto end;
219 }
220
221 /* check pfkey message. */
222 if (pfkey_align(msg, mhp)) {
223 plog(LLV_ERROR, LOCATION, NULL,
224 "libipsec failed pfkey align (%s)\n",
225 ipsec_strerror());
226 goto end;
227 }
228 if (pfkey_check(mhp)) {
229 plog(LLV_ERROR, LOCATION, NULL,
230 "libipsec failed pfkey check (%s)\n",
231 ipsec_strerror());
232 goto end;
233 }
234 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
235
236 /* safety check */
237 if (msg->sadb_msg_type >= ARRAYLEN(pkrecvf)) {
238 plog(LLV_ERROR, LOCATION, NULL,
239 "unknown PF_KEY message type=%u\n",
240 msg->sadb_msg_type);
241 goto end;
242 }
243
244 if (pkrecvf[msg->sadb_msg_type] == NULL) {
245 plog(LLV_INFO, LOCATION, NULL,
246 "unsupported PF_KEY message %s\n",
247 s_pfkey_type(msg->sadb_msg_type));
248 goto end;
249 }
250
251 if ((pkrecvf[msg->sadb_msg_type])(mhp) < 0)
252 goto end;
253
254 error = 0;
255 end:
256 if (msg)
257 racoon_free(msg);
258 return(error);
259 }
260
261 /*
262 * PF_KEY packet handler
263 * 0: success
264 * -1: fail
265 */
266 int
267 pfkey_handler()
268 {
269 struct sadb_msg *msg;
270 ssize_t len;
271
272 if (slept_at || woke_at) {
273 plog(LLV_DEBUG, LOCATION, NULL,
274 "ignoring pfkey port until power-mgmt event is handled.\n");
275 return 0;
276 }
277
278 /* receive pfkey message. */
279 len = 0;
280 msg = (struct sadb_msg *)pk_recv(lcconf->sock_pfkey, &len);
281 if (msg == NULL) {
282 if (len < 0) {
283 plog(LLV_ERROR, LOCATION, NULL,
284 "failed to recv from pfkey (%s)\n",
285 strerror(errno));
286 return -1;
287 } else {
288 /* short message - msg not ready */
289 plog(LLV_ERROR, LOCATION, NULL,
290 "recv short message from pfkey\n");
291 return 0;
292 }
293 }
294 return pfkey_process(msg);
295 }
296
297 void
298 pfkey_post_handler()
299 {
300 struct saved_msg_elem *elem;
301 struct saved_msg_elem *elem_tmp = NULL;
302
303 if (slept_at || woke_at) {
304 plog(LLV_DEBUG, LOCATION, NULL,
305 "ignoring (saved) pfkey messages until power-mgmt event is handled.\n");
306 return;
307 }
308
309 TAILQ_FOREACH_SAFE(elem, &lcconf->saved_msg_queue, chain, elem_tmp) {
310 pfkey_process((struct sadb_msg *)elem->msg);
311 TAILQ_REMOVE(&lcconf->saved_msg_queue, elem, chain);
312 racoon_free(elem);
313
314 }
315 }
316
317 int
318 pfkey_save_msg(msg)
319 struct sadb_msg *msg;
320 {
321 struct saved_msg_elem *elem;
322
323 elem = (struct saved_msg_elem *)racoon_calloc(sizeof(struct saved_msg_elem), 1);
324 if (elem == NULL)
325 return -1;
326 elem->msg = msg;
327 TAILQ_INSERT_TAIL(&lcconf->saved_msg_queue, elem, chain);
328 return 0;
329 }
330
331 /*
332 * dump SADB
333 */
334 vchar_t *
335 pfkey_dump_sadb(satype)
336 int satype;
337 {
338 int s = -1;
339 vchar_t *buf = NULL;
340 pid_t pid = getpid();
341 struct sadb_msg *msg = NULL;
342 size_t bl, ml;
343 ssize_t len;
344
345 if ((s = privsep_pfkey_open()) < 0) {
346 plog(LLV_ERROR, LOCATION, NULL,
347 "libipsec failed pfkey open: %s\n",
348 ipsec_strerror());
349 return NULL;
350 }
351
352 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_dump\n");
353 if (pfkey_send_dump(s, satype) < 0) {
354 plog(LLV_ERROR, LOCATION, NULL,
355 "libipsec failed dump: %s\n", ipsec_strerror());
356 goto fail;
357 }
358
359 while (1) {
360 if (msg)
361 racoon_free(msg);
362 msg = pk_recv(s, &len);
363 if (msg == NULL) {
364 if (len < 0)
365 goto done;
366 else
367 continue;
368 }
369
370 /*
371 * for multi-processor system this had to be added because the messages can
372 * be interleaved - they won't all be dump messages
373 */
374 if (msg->sadb_msg_type != SADB_DUMP) { /* save for later processing */
375 pfkey_save_msg(msg);
376 msg = NULL;
377 continue;
378 }
379
380 // ignore dump messages that aren't racoon's
381 if (msg->sadb_msg_pid != pid)
382 continue;
383
384 ml = msg->sadb_msg_len << 3;
385 bl = buf ? buf->l : 0;
386 buf = vrealloc(buf, bl + ml);
387 if (buf == NULL) {
388 plog(LLV_ERROR, LOCATION, NULL,
389 "failed to reallocate buffer to dump.\n");
390 goto fail;
391 }
392 memcpy(buf->v + bl, msg, ml);
393
394 if (msg->sadb_msg_seq == 0)
395 break;
396 }
397 goto done;
398
399 fail:
400 if (buf)
401 vfree(buf);
402 buf = NULL;
403 done:
404 if (msg)
405 racoon_free(msg);
406 if (s >= 0)
407 privsep_pfkey_close(s);
408 return buf;
409 }
410
411 #ifdef ENABLE_ADMINPORT
412 /*
413 * flush SADB
414 */
415 void
416 pfkey_flush_sadb(proto)
417 u_int proto;
418 {
419 int satype;
420
421 /* convert to SADB_SATYPE */
422 if ((satype = admin2pfkey_proto(proto)) < 0)
423 return;
424
425 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_flush\n");
426 if (pfkey_send_flush(lcconf->sock_pfkey, satype) < 0) {
427 plog(LLV_ERROR, LOCATION, NULL,
428 "libipsec failed send flush (%s)\n", ipsec_strerror());
429 return;
430 }
431
432 return;
433 }
434 #endif
435
436 /*
437 * These are the SATYPEs that we manage. We register to get
438 * PF_KEY messages related to these SATYPEs, and we also use
439 * this list to determine which SATYPEs to delete SAs for when
440 * we receive an INITIAL-CONTACT.
441 */
442 const struct pfkey_satype pfkey_satypes[] = {
443 { SADB_SATYPE_AH, "AH" },
444 { SADB_SATYPE_ESP, "ESP" },
445 { SADB_X_SATYPE_IPCOMP, "IPCOMP" },
446 };
447 const int pfkey_nsatypes =
448 sizeof(pfkey_satypes) / sizeof(pfkey_satypes[0]);
449
450 /*
451 * PF_KEY initialization
452 */
453 int
454 pfkey_init()
455 {
456 int i, reg_fail;
457
458 if ((lcconf->sock_pfkey = privsep_pfkey_open()) < 0) {
459 plog(LLV_ERROR, LOCATION, NULL,
460 "libipsec failed pfkey open (%s)\n", ipsec_strerror());
461 return -1;
462 }
463
464 for (i = 0, reg_fail = 0; i < pfkey_nsatypes; i++) {
465 plog(LLV_DEBUG, LOCATION, NULL,
466 "call pfkey_send_register for %s\n",
467 pfkey_satypes[i].ps_name);
468 if (pfkey_send_register(lcconf->sock_pfkey,
469 pfkey_satypes[i].ps_satype) < 0 ||
470 pfkey_recv_register(lcconf->sock_pfkey) < 0) {
471 plog(LLV_WARNING, LOCATION, NULL,
472 "failed to register %s (%s)\n",
473 pfkey_satypes[i].ps_name,
474 ipsec_strerror());
475 reg_fail++;
476 }
477 }
478
479 if (reg_fail == pfkey_nsatypes) {
480 plog(LLV_ERROR, LOCATION, NULL,
481 "failed to regist any protocol.\n");
482 pfkey_close(lcconf->sock_pfkey);
483 return -1;
484 }
485
486 initsp();
487
488 if (pfkey_send_spddump(lcconf->sock_pfkey) < 0) {
489 plog(LLV_ERROR, LOCATION, NULL,
490 "libipsec sending spddump failed: %s\n",
491 ipsec_strerror());
492 pfkey_close(lcconf->sock_pfkey);
493 return -1;
494 }
495 #if 0
496 if (pfkey_promisc_toggle(1) < 0) {
497 pfkey_close(lcconf->sock_pfkey);
498 return -1;
499 }
500 #endif
501 return 0;
502 }
503
504 /* %%% for conversion */
505 /* IPSECDOI_ATTR_AUTH -> SADB_AALG */
506 static u_int
507 ipsecdoi2pfkey_aalg(hashtype)
508 u_int hashtype;
509 {
510 switch (hashtype) {
511 case IPSECDOI_ATTR_AUTH_HMAC_MD5:
512 return SADB_AALG_MD5HMAC;
513 case IPSECDOI_ATTR_AUTH_HMAC_SHA1:
514 return SADB_AALG_SHA1HMAC;
515 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_256:
516 #if (defined SADB_X_AALG_SHA2_256) && !defined(SADB_X_AALG_SHA2_256HMAC)
517 return SADB_X_AALG_SHA2_256;
518 #else
519 return SADB_X_AALG_SHA2_256HMAC;
520 #endif
521 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_384:
522 #if (defined SADB_X_AALG_SHA2_384) && !defined(SADB_X_AALG_SHA2_384HMAC)
523 return SADB_X_AALG_SHA2_384;
524 #else
525 return SADB_X_AALG_SHA2_384HMAC;
526 #endif
527 case IPSECDOI_ATTR_AUTH_HMAC_SHA2_512:
528 #if (defined SADB_X_AALG_SHA2_512) && !defined(SADB_X_AALG_SHA2_512HMAC)
529 return SADB_X_AALG_SHA2_512;
530 #else
531 return SADB_X_AALG_SHA2_512HMAC;
532 #endif
533 case IPSECDOI_ATTR_AUTH_KPDK: /* need special care */
534 return SADB_AALG_NONE;
535
536 /* not supported */
537 case IPSECDOI_ATTR_AUTH_DES_MAC:
538 plog(LLV_ERROR, LOCATION, NULL,
539 "Not supported hash type: %u\n", hashtype);
540 return ~0;
541
542 case 0: /* reserved */
543 default:
544 return SADB_AALG_NONE;
545
546 plog(LLV_ERROR, LOCATION, NULL,
547 "Invalid hash type: %u\n", hashtype);
548 return ~0;
549 }
550 /*NOTREACHED*/
551 }
552
553 /* IPSECDOI_ESP -> SADB_EALG */
554 static u_int
555 ipsecdoi2pfkey_ealg(t_id)
556 u_int t_id;
557 {
558 switch (t_id) {
559 case IPSECDOI_ESP_DES_IV64: /* sa_flags |= SADB_X_EXT_OLD */
560 return SADB_EALG_DESCBC;
561 case IPSECDOI_ESP_DES:
562 return SADB_EALG_DESCBC;
563 case IPSECDOI_ESP_3DES:
564 return SADB_EALG_3DESCBC;
565 #ifdef SADB_X_EALG_RC5CBC
566 case IPSECDOI_ESP_RC5:
567 return SADB_X_EALG_RC5CBC;
568 #endif
569 case IPSECDOI_ESP_CAST:
570 return SADB_X_EALG_CAST128CBC;
571 case IPSECDOI_ESP_BLOWFISH:
572 return SADB_X_EALG_BLOWFISHCBC;
573 case IPSECDOI_ESP_DES_IV32: /* flags |= (SADB_X_EXT_OLD|
574 SADB_X_EXT_IV4B)*/
575 return SADB_EALG_DESCBC;
576 case IPSECDOI_ESP_NULL:
577 return SADB_EALG_NULL;
578 #ifdef SADB_X_EALG_AESCBC
579 case IPSECDOI_ESP_AES:
580 return SADB_X_EALG_AESCBC;
581 #endif
582 #ifdef SADB_X_EALG_TWOFISHCBC
583 case IPSECDOI_ESP_TWOFISH:
584 return SADB_X_EALG_TWOFISHCBC;
585 #endif
586
587 /* not supported */
588 case IPSECDOI_ESP_3IDEA:
589 case IPSECDOI_ESP_IDEA:
590 case IPSECDOI_ESP_RC4:
591 plog(LLV_ERROR, LOCATION, NULL,
592 "Not supported transform: %u\n", t_id);
593 return ~0;
594
595 case 0: /* reserved */
596 default:
597 plog(LLV_ERROR, LOCATION, NULL,
598 "Invalid transform id: %u\n", t_id);
599 return ~0;
600 }
601 /*NOTREACHED*/
602 }
603
604 /* IPCOMP -> SADB_CALG */
605 static u_int
606 ipsecdoi2pfkey_calg(t_id)
607 u_int t_id;
608 {
609 switch (t_id) {
610 case IPSECDOI_IPCOMP_OUI:
611 return SADB_X_CALG_OUI;
612 case IPSECDOI_IPCOMP_DEFLATE:
613 return SADB_X_CALG_DEFLATE;
614 case IPSECDOI_IPCOMP_LZS:
615 return SADB_X_CALG_LZS;
616
617 case 0: /* reserved */
618 default:
619 plog(LLV_ERROR, LOCATION, NULL,
620 "Invalid transform id: %u\n", t_id);
621 return ~0;
622 }
623 /*NOTREACHED*/
624 }
625
626 /* IPSECDOI_PROTO -> SADB_SATYPE */
627 u_int
628 ipsecdoi2pfkey_proto(proto)
629 u_int proto;
630 {
631 switch (proto) {
632 case IPSECDOI_PROTO_IPSEC_AH:
633 return SADB_SATYPE_AH;
634 case IPSECDOI_PROTO_IPSEC_ESP:
635 return SADB_SATYPE_ESP;
636 case IPSECDOI_PROTO_IPCOMP:
637 return SADB_X_SATYPE_IPCOMP;
638
639 default:
640 plog(LLV_ERROR, LOCATION, NULL,
641 "Invalid ipsec_doi proto: %u\n", proto);
642 return ~0;
643 }
644 /*NOTREACHED*/
645 }
646
647 static u_int
648 ipsecdoi2pfkey_alg(algclass, type)
649 u_int algclass, type;
650 {
651 switch (algclass) {
652 case IPSECDOI_ATTR_AUTH:
653 return ipsecdoi2pfkey_aalg(type);
654 case IPSECDOI_PROTO_IPSEC_ESP:
655 return ipsecdoi2pfkey_ealg(type);
656 case IPSECDOI_PROTO_IPCOMP:
657 return ipsecdoi2pfkey_calg(type);
658 default:
659 plog(LLV_ERROR, LOCATION, NULL,
660 "Invalid ipsec_doi algclass: %u\n", algclass);
661 return ~0;
662 }
663 /*NOTREACHED*/
664 }
665
666 /* SADB_SATYPE -> IPSECDOI_PROTO */
667 u_int
668 pfkey2ipsecdoi_proto(satype)
669 u_int satype;
670 {
671 switch (satype) {
672 case SADB_SATYPE_AH:
673 return IPSECDOI_PROTO_IPSEC_AH;
674 case SADB_SATYPE_ESP:
675 return IPSECDOI_PROTO_IPSEC_ESP;
676 case SADB_X_SATYPE_IPCOMP:
677 return IPSECDOI_PROTO_IPCOMP;
678
679 default:
680 plog(LLV_ERROR, LOCATION, NULL,
681 "Invalid pfkey proto: %u\n", satype);
682 return ~0;
683 }
684 /*NOTREACHED*/
685 }
686
687 /* IPSECDOI_ATTR_ENC_MODE -> IPSEC_MODE */
688 u_int
689 ipsecdoi2pfkey_mode(mode)
690 u_int mode;
691 {
692 switch (mode) {
693 case IPSECDOI_ATTR_ENC_MODE_TUNNEL:
694 #ifdef ENABLE_NATT
695 case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC:
696 case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT:
697 #endif
698 return IPSEC_MODE_TUNNEL;
699 case IPSECDOI_ATTR_ENC_MODE_TRNS:
700 #ifdef ENABLE_NATT
701 case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC:
702 case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT:
703 #endif
704 return IPSEC_MODE_TRANSPORT;
705 default:
706 plog(LLV_ERROR, LOCATION, NULL, "Invalid mode type: %u\n", mode);
707 return ~0;
708 }
709 /*NOTREACHED*/
710 }
711
712 /* IPSECDOI_ATTR_ENC_MODE -> IPSEC_MODE */
713 u_int
714 pfkey2ipsecdoi_mode(mode)
715 u_int mode;
716 {
717 switch (mode) {
718 case IPSEC_MODE_TUNNEL:
719 return IPSECDOI_ATTR_ENC_MODE_TUNNEL;
720 case IPSEC_MODE_TRANSPORT:
721 return IPSECDOI_ATTR_ENC_MODE_TRNS;
722 case IPSEC_MODE_ANY:
723 return IPSECDOI_ATTR_ENC_MODE_ANY;
724 default:
725 plog(LLV_ERROR, LOCATION, NULL, "Invalid mode type: %u\n", mode);
726 return ~0;
727 }
728 /*NOTREACHED*/
729 }
730
731 /* default key length for encryption algorithm */
732 static u_int
733 keylen_aalg(hashtype)
734 u_int hashtype;
735 {
736 int res;
737
738 if (hashtype == 0)
739 return SADB_AALG_NONE;
740
741 res = alg_ipsec_hmacdef_hashlen(hashtype);
742 if (res == -1) {
743 plog(LLV_ERROR, LOCATION, NULL,
744 "invalid hmac algorithm %u.\n", hashtype);
745 return ~0;
746 }
747 return res;
748 }
749
750 /* default key length for encryption algorithm */
751 static u_int
752 keylen_ealg(enctype, encklen)
753 u_int enctype;
754 int encklen;
755 {
756 int res;
757
758 res = alg_ipsec_encdef_keylen(enctype, encklen);
759 if (res == -1) {
760 plog(LLV_ERROR, LOCATION, NULL,
761 "invalid encryption algorithm %u.\n", enctype);
762 return ~0;
763 }
764 return res;
765 }
766
767 int
768 pfkey_convertfromipsecdoi(proto_id, t_id, hashtype,
769 e_type, e_keylen, a_type, a_keylen, flags)
770 u_int proto_id;
771 u_int t_id;
772 u_int hashtype;
773 u_int *e_type;
774 u_int *e_keylen;
775 u_int *a_type;
776 u_int *a_keylen;
777 u_int *flags;
778 {
779 *flags = 0;
780 switch (proto_id) {
781 case IPSECDOI_PROTO_IPSEC_ESP:
782 if ((*e_type = ipsecdoi2pfkey_ealg(t_id)) == ~0)
783 goto bad;
784 if ((*e_keylen = keylen_ealg(t_id, *e_keylen)) == ~0)
785 goto bad;
786 *e_keylen >>= 3;
787
788 if ((*a_type = ipsecdoi2pfkey_aalg(hashtype)) == ~0)
789 goto bad;
790 if ((*a_keylen = keylen_aalg(hashtype)) == ~0)
791 goto bad;
792 *a_keylen >>= 3;
793
794 if (*e_type == SADB_EALG_NONE) {
795 plog(LLV_ERROR, LOCATION, NULL, "no ESP algorithm.\n");
796 goto bad;
797 }
798 break;
799
800 case IPSECDOI_PROTO_IPSEC_AH:
801 if ((*a_type = ipsecdoi2pfkey_aalg(hashtype)) == ~0)
802 goto bad;
803 if ((*a_keylen = keylen_aalg(hashtype)) == ~0)
804 goto bad;
805 *a_keylen >>= 3;
806
807 if (t_id == IPSECDOI_ATTR_AUTH_HMAC_MD5
808 && hashtype == IPSECDOI_ATTR_AUTH_KPDK) {
809 /* AH_MD5 + Auth(KPDK) = RFC1826 keyed-MD5 */
810 *a_type = SADB_X_AALG_MD5;
811 *flags |= SADB_X_EXT_OLD;
812 }
813 *e_type = SADB_EALG_NONE;
814 *e_keylen = 0;
815 if (*a_type == SADB_AALG_NONE) {
816 plog(LLV_ERROR, LOCATION, NULL, "no AH algorithm.\n");
817 goto bad;
818 }
819 break;
820
821 case IPSECDOI_PROTO_IPCOMP:
822 if ((*e_type = ipsecdoi2pfkey_calg(t_id)) == ~0)
823 goto bad;
824 *e_keylen = 0;
825
826 *flags = SADB_X_EXT_RAWCPI;
827
828 *a_type = SADB_AALG_NONE;
829 *a_keylen = 0;
830 if (*e_type == SADB_X_CALG_NONE) {
831 plog(LLV_ERROR, LOCATION, NULL, "no IPCOMP algorithm.\n");
832 goto bad;
833 }
834 break;
835
836 default:
837 plog(LLV_ERROR, LOCATION, NULL, "unknown IPsec protocol.\n");
838 goto bad;
839 }
840
841 return 0;
842
843 bad:
844 errno = EINVAL;
845 return -1;
846 }
847
848 /* called from scheduler */
849 void
850 pfkey_timeover_stub(p)
851 void *p;
852 {
853
854 pfkey_timeover((struct ph2handle *)p);
855 }
856
857 void
858 pfkey_timeover(iph2)
859 struct ph2handle *iph2;
860 {
861 plog(LLV_ERROR, LOCATION, NULL,
862 "%s give up to get IPsec-SA due to time up to wait.\n",
863 saddrwop2str((struct sockaddr *)iph2->dst));
864 SCHED_KILL(iph2->sce);
865
866 /* If initiator side, send error to kernel by SADB_ACQUIRE. */
867 if (iph2->side == INITIATOR)
868 pk_sendeacquire(iph2);
869
870 unbindph12(iph2);
871 remph2(iph2);
872 delph2(iph2);
873
874 return;
875 }
876
877 /*%%%*/
878 /* send getspi message per ipsec protocol per remote address */
879 /*
880 * the local address and remote address in ph1handle are dealed
881 * with destination address and source address respectively.
882 * Because SPI is decided by responder.
883 */
884 int
885 pk_sendgetspi(iph2)
886 struct ph2handle *iph2;
887 {
888 struct sockaddr_storage *src = NULL, *dst = NULL;
889 u_int satype, mode;
890 struct saprop *pp;
891 struct saproto *pr;
892 u_int32_t minspi, maxspi;
893 int proxy = 0;
894
895 if (iph2->side == INITIATOR) {
896 pp = iph2->proposal;
897 proxy = iph2->ph1->rmconf->support_proxy;
898 } else {
899 pp = iph2->approval;
900 if (iph2->sainfo && iph2->sainfo->id_i)
901 proxy = 1;
902 }
903
904 /* for mobile IPv6 */
905 if (proxy && iph2->src_id && iph2->dst_id &&
906 ipsecdoi_transportmode(pp)) {
907 src = iph2->src_id;
908 dst = iph2->dst_id;
909 } else {
910 src = iph2->src;
911 dst = iph2->dst;
912 }
913
914 for (pr = pp->head; pr != NULL; pr = pr->next) {
915
916 /* validity check */
917 satype = ipsecdoi2pfkey_proto(pr->proto_id);
918 if (satype == ~0) {
919 plog(LLV_ERROR, LOCATION, NULL,
920 "invalid proto_id %d\n", pr->proto_id);
921 return -1;
922 }
923 /* this works around a bug in Linux kernel where it allocates 4 byte
924 spi's for IPCOMP */
925 else if (satype == SADB_X_SATYPE_IPCOMP) {
926 minspi = 0x100;
927 maxspi = 0xffff;
928 }
929 else {
930 minspi = 0;
931 maxspi = 0;
932 }
933 mode = ipsecdoi2pfkey_mode(pr->encmode);
934 if (mode == ~0) {
935 plog(LLV_ERROR, LOCATION, NULL,
936 "invalid encmode %d\n", pr->encmode);
937 return -1;
938 }
939
940 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_getspi\n");
941 if (pfkey_send_getspi(
942 lcconf->sock_pfkey,
943 satype,
944 mode,
945 dst, /* src of SA */
946 src, /* dst of SA */
947 minspi, maxspi,
948 pr->reqid_in, iph2->seq) < 0) {
949 plog(LLV_ERROR, LOCATION, NULL,
950 "ipseclib failed send getspi (%s)\n",
951 ipsec_strerror());
952 return -1;
953 }
954 plog(LLV_DEBUG, LOCATION, NULL,
955 "pfkey GETSPI sent: %s\n",
956 sadbsecas2str(dst, src, satype, 0, mode));
957 }
958
959 return 0;
960 }
961
962 /*
963 * receive GETSPI from kernel.
964 */
965 static int
966 pk_recvgetspi(mhp)
967 caddr_t *mhp;
968 {
969 struct sadb_msg *msg;
970 struct sadb_sa *sa;
971 struct ph2handle *iph2;
972 struct sockaddr_storage *dst;
973 int proto_id;
974 int allspiok, notfound;
975 struct saprop *pp;
976 struct saproto *pr;
977
978 /* validity check */
979 if (mhp[SADB_EXT_SA] == NULL
980 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
981 plog(LLV_ERROR, LOCATION, NULL,
982 "inappropriate sadb getspi message passed.\n");
983 return -1;
984 }
985 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
986 sa = ALIGNED_CAST(struct sadb_sa *)mhp[SADB_EXT_SA];
987 dst = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); /* note SA dir */
988
989 /* the message has to be processed or not ? */
990 if (msg->sadb_msg_pid != getpid()) {
991 plog(LLV_DEBUG, LOCATION, NULL,
992 "%s message is not interesting "
993 "because pid %d is not mine.\n",
994 s_pfkey_type(msg->sadb_msg_type),
995 msg->sadb_msg_pid);
996 return -1;
997 }
998
999 iph2 = getph2byseq(msg->sadb_msg_seq);
1000 if (iph2 == NULL) {
1001 plog(LLV_DEBUG, LOCATION, NULL,
1002 "seq %d of %s message not interesting.\n",
1003 msg->sadb_msg_seq,
1004 s_pfkey_type(msg->sadb_msg_type));
1005 return -1;
1006 }
1007
1008 if (iph2->is_dying) {
1009 plog(LLV_ERROR, LOCATION, NULL,
1010 "status mismatch phase2 dying (db:%d msg:%d)\n",
1011 iph2->status, PHASE2ST_GETSPISENT);
1012 return -1;
1013 }
1014
1015 if (iph2->status != PHASE2ST_GETSPISENT) {
1016 plog(LLV_ERROR, LOCATION, NULL,
1017 "status mismatch (db:%d msg:%d)\n",
1018 iph2->status, PHASE2ST_GETSPISENT);
1019 return -1;
1020 }
1021
1022 // check the underlying iph2->ph1
1023 if (!iph2->ph1) {
1024 if (!ike_session_update_ph2_ph1bind(iph2)) {
1025 plog(LLV_ERROR, LOCATION, NULL,
1026 "can't proceed with getspi for %s. no suitable ISAKMP-SA found \n",
1027 saddrwop2str((struct sockaddr *)iph2->dst));
1028 unbindph12(iph2);
1029 remph2(iph2);
1030 delph2(iph2);
1031 return -1;
1032 }
1033 }
1034
1035 /* set SPI, and check to get all spi whether or not */
1036 allspiok = 1;
1037 notfound = 1;
1038 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
1039 pp = iph2->side == INITIATOR ? iph2->proposal : iph2->approval;
1040
1041 for (pr = pp->head; pr != NULL; pr = pr->next) {
1042 if (pr->proto_id == proto_id && pr->spi == 0) {
1043 pr->spi = sa->sadb_sa_spi;
1044 notfound = 0;
1045 plog(LLV_DEBUG, LOCATION, NULL,
1046 "pfkey GETSPI succeeded: %s\n",
1047 sadbsecas2str(iph2->dst, iph2->src,
1048 msg->sadb_msg_satype,
1049 sa->sadb_sa_spi,
1050 ipsecdoi2pfkey_mode(pr->encmode)));
1051 }
1052 if (pr->spi == 0)
1053 allspiok = 0; /* not get all spi */
1054 }
1055
1056 if (notfound) {
1057 plog(LLV_ERROR, LOCATION, NULL,
1058 "get spi for unknown address %s\n",
1059 saddrwop2str((struct sockaddr *)iph2->dst));
1060 unbindph12(iph2);
1061 remph2(iph2);
1062 delph2(iph2);
1063 return -1;
1064 }
1065
1066 if (allspiok) {
1067 /* update status */
1068 iph2->status = PHASE2ST_GETSPIDONE;
1069 if (isakmp_post_getspi(iph2) < 0) {
1070 plog(LLV_ERROR, LOCATION, NULL,
1071 "failed to start post getspi.\n");
1072 unbindph12(iph2);
1073 remph2(iph2);
1074 delph2(iph2);
1075 iph2 = NULL;
1076 return -1;
1077 }
1078 }
1079
1080 return 0;
1081 }
1082
1083 /*
1084 * set inbound SA
1085 */
1086 int
1087 pk_sendupdate(iph2)
1088 struct ph2handle *iph2;
1089 {
1090 struct saproto *pr;
1091 struct sockaddr_storage *src = NULL, *dst = NULL;
1092 u_int e_type, e_keylen, a_type, a_keylen, flags;
1093 u_int satype, mode;
1094 u_int64_t lifebyte = 0;
1095 u_int wsize = 4; /* XXX static size of window */
1096 int proxy = 0;
1097 struct ph2natt natt;
1098
1099 /* sanity check */
1100 if (iph2->approval == NULL) {
1101 plog(LLV_ERROR, LOCATION, NULL,
1102 "no approvaled SAs found.\n");
1103 }
1104
1105 if (iph2->side == INITIATOR)
1106 proxy = iph2->ph1->rmconf->support_proxy;
1107 else if (iph2->sainfo && iph2->sainfo->id_i)
1108 proxy = 1;
1109
1110 /* for mobile IPv6 */
1111 if (proxy && iph2->src_id && iph2->dst_id &&
1112 ipsecdoi_transportmode(iph2->approval)) {
1113 src = iph2->src_id;
1114 dst = iph2->dst_id;
1115 } else {
1116 src = iph2->src;
1117 dst = iph2->dst;
1118 }
1119
1120 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
1121 /* validity check */
1122 satype = ipsecdoi2pfkey_proto(pr->proto_id);
1123 if (satype == ~0) {
1124 plog(LLV_ERROR, LOCATION, NULL,
1125 "invalid proto_id %d\n", pr->proto_id);
1126 return -1;
1127 }
1128 else if (satype == SADB_X_SATYPE_IPCOMP) {
1129 /* IPCOMP has no replay window */
1130 wsize = 0;
1131 }
1132 #ifdef ENABLE_SAMODE_UNSPECIFIED
1133 mode = IPSEC_MODE_ANY;
1134 #else
1135 mode = ipsecdoi2pfkey_mode(pr->encmode);
1136 if (mode == ~0) {
1137 plog(LLV_ERROR, LOCATION, NULL,
1138 "invalid encmode %d\n", pr->encmode);
1139 return -1;
1140 }
1141 #endif
1142
1143 /* set algorithm type and key length */
1144 e_keylen = pr->head->encklen;
1145 if (pfkey_convertfromipsecdoi(
1146 pr->proto_id,
1147 pr->head->trns_id,
1148 pr->head->authtype,
1149 &e_type, &e_keylen,
1150 &a_type, &a_keylen, &flags) < 0)
1151 return -1;
1152
1153 #if 0
1154 lifebyte = iph2->approval->lifebyte * 1024,
1155 #else
1156 lifebyte = 0;
1157 #endif
1158
1159 #ifdef ENABLE_NATT
1160 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_update\n");
1161 if (pr->udp_encap) {
1162 memset (&natt, 0, sizeof (natt));
1163 natt.sport = extract_port (iph2->ph1->remote);
1164 flags |= SADB_X_EXT_NATT;
1165 if (iph2->ph1->natt_flags & NAT_DETECTED_ME) {
1166 if (iph2->ph1->rmconf->natt_keepalive == TRUE)
1167 flags |= SADB_X_EXT_NATT_KEEPALIVE;
1168 } else {
1169 if (iph2->ph1->rmconf->natt_multiple_user == TRUE &&
1170 mode == IPSEC_MODE_TRANSPORT &&
1171 src->ss_family == AF_INET) {
1172 flags |= SADB_X_EXT_NATT_MULTIPLEUSERS;
1173 }
1174 if (iph2->ph1->natt_flags & NAT_DETECTED_PEER) {
1175 // is mutually exclusive with SADB_X_EXT_NATT_KEEPALIVE
1176 flags |= SADB_X_EXT_NATT_DETECTED_PEER;
1177 }
1178 }
1179 } else {
1180 memset (&natt, 0, sizeof (natt));
1181 }
1182
1183 if (pfkey_send_update(
1184 lcconf->sock_pfkey,
1185 satype,
1186 mode,
1187 dst,
1188 src,
1189 pr->spi,
1190 pr->reqid_in,
1191 wsize,
1192 pr->keymat->v,
1193 e_type, e_keylen, a_type, a_keylen, flags,
1194 0, lifebyte, iph2->approval->lifetime, 0,
1195 iph2->seq, natt.sport) < 0) {
1196 plog(LLV_ERROR, LOCATION, NULL,
1197 "libipsec failed send update (%s)\n",
1198 ipsec_strerror());
1199 return -1;
1200 }
1201 #else
1202 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_update\n");
1203 if (pfkey_send_update(
1204 lcconf->sock_pfkey,
1205 satype,
1206 mode,
1207 dst,
1208 src,
1209 pr->spi,
1210 pr->reqid_in,
1211 wsize,
1212 pr->keymat->v,
1213 e_type, e_keylen, a_type, a_keylen, flags,
1214 0, lifebyte, iph2->approval->lifetime, 0,
1215 iph2->seq, 0) < 0) {
1216 plog(LLV_ERROR, LOCATION, NULL,
1217 "libipsec failed send update (%s)\n",
1218 ipsec_strerror());
1219 return -1;
1220 }
1221 #endif /* ENABLE_NATT */
1222
1223 if (!lcconf->pathinfo[LC_PATHTYPE_BACKUPSA])
1224 continue;
1225
1226 /*
1227 * It maybe good idea to call backupsa_to_file() after
1228 * racoon will receive the sadb_update messages.
1229 * But it is impossible because there is not key in the
1230 * information from the kernel.
1231 */
1232 if (backupsa_to_file(satype, mode, (struct sockaddr *)dst, (struct sockaddr *)src,
1233 pr->spi, pr->reqid_in, 4,
1234 pr->keymat->v,
1235 e_type, e_keylen, a_type, a_keylen, flags,
1236 0, iph2->approval->lifebyte * 1024,
1237 iph2->approval->lifetime, 0,
1238 iph2->seq) < 0) {
1239 plog(LLV_ERROR, LOCATION, NULL,
1240 "backuped SA failed: %s\n",
1241 sadbsecas2str(dst, src,
1242 satype, pr->spi, mode));
1243 }
1244 plog(LLV_DEBUG, LOCATION, NULL,
1245 "backuped SA: %s\n",
1246 sadbsecas2str(dst, src,
1247 satype, pr->spi, mode));
1248 }
1249
1250 return 0;
1251 }
1252
1253 static int
1254 pk_recvupdate(mhp)
1255 caddr_t *mhp;
1256 {
1257 struct sadb_msg *msg;
1258 struct sadb_sa *sa;
1259 struct sockaddr_storage *src, *dst;
1260 struct ph2handle *iph2;
1261 u_int proto_id, encmode, sa_mode;
1262 int incomplete = 0;
1263 struct saproto *pr;
1264
1265 /* ignore this message because of local test mode. */
1266 if (f_local)
1267 return 0;
1268
1269 /* sanity check */
1270 if (mhp[0] == NULL
1271 || mhp[SADB_EXT_SA] == NULL
1272 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1273 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
1274 plog(LLV_ERROR, LOCATION, NULL,
1275 "inappropriate sadb update message passed.\n");
1276 return -1;
1277 }
1278 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
1279 src = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1280 dst = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1281 sa = ALIGNED_CAST(struct sadb_sa *)mhp[SADB_EXT_SA];
1282
1283 sa_mode = mhp[SADB_X_EXT_SA2] == NULL
1284 ? IPSEC_MODE_ANY
1285 : (ALIGNED_CAST(struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
1286
1287 /* the message has to be processed or not ? */
1288 if (msg->sadb_msg_pid != getpid()) {
1289 plog(LLV_DEBUG, LOCATION, NULL,
1290 "%s message is not interesting "
1291 "because pid %d is not mine.\n",
1292 s_pfkey_type(msg->sadb_msg_type),
1293 msg->sadb_msg_pid);
1294 return -1;
1295 }
1296
1297 iph2 = getph2byseq(msg->sadb_msg_seq);
1298 if (iph2 == NULL) {
1299 plog(LLV_DEBUG, LOCATION, NULL,
1300 "seq %d of %s message not interesting.\n",
1301 msg->sadb_msg_seq,
1302 s_pfkey_type(msg->sadb_msg_type));
1303 return -1;
1304 }
1305
1306 if (iph2->is_dying) {
1307 plog(LLV_ERROR, LOCATION, NULL,
1308 "status mismatch phase2 dying (db:%d msg:%d)\n",
1309 iph2->status, PHASE2ST_ADDSA);
1310 return -1;
1311 }
1312
1313 if (iph2->status != PHASE2ST_ADDSA) {
1314 plog(LLV_ERROR, LOCATION, NULL,
1315 "status mismatch (db:%d msg:%d)\n",
1316 iph2->status, PHASE2ST_ADDSA);
1317 return -1;
1318 }
1319
1320 /* check to complete all keys ? */
1321 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
1322 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
1323 if (proto_id == ~0) {
1324 plog(LLV_ERROR, LOCATION, NULL,
1325 "invalid proto_id %d\n", msg->sadb_msg_satype);
1326 return -1;
1327 }
1328 encmode = pfkey2ipsecdoi_mode(sa_mode);
1329 if (encmode == ~0) {
1330 plog(LLV_ERROR, LOCATION, NULL,
1331 "invalid encmode %d\n", sa_mode);
1332 return -1;
1333 }
1334
1335 if (pr->proto_id == proto_id
1336 && pr->spi == sa->sadb_sa_spi) {
1337 pr->ok = 1;
1338 plog(LLV_DEBUG, LOCATION, NULL,
1339 "pfkey UPDATE succeeded: %s\n",
1340 sadbsecas2str(iph2->dst, iph2->src,
1341 msg->sadb_msg_satype,
1342 sa->sadb_sa_spi,
1343 sa_mode));
1344
1345 plog(LLV_INFO, LOCATION, NULL,
1346 "IPsec-SA established: %s\n",
1347 sadbsecas2str(iph2->dst, iph2->src,
1348 msg->sadb_msg_satype, sa->sadb_sa_spi,
1349 sa_mode));
1350 }
1351
1352 if (pr->ok == 0)
1353 incomplete = 1;
1354 }
1355
1356 if (incomplete)
1357 return 0;
1358
1359 /* turn off the timer for calling pfkey_timeover() */
1360 SCHED_KILL(iph2->sce);
1361
1362 /* update status */
1363 iph2->status = PHASE2ST_ESTABLISHED;
1364
1365 if (iph2->side == INITIATOR) {
1366 IPSECSESSIONTRACEREVENT(iph2->parent_session,
1367 IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_SUCC,
1368 CONSTSTR("Initiator, Quick-Mode"),
1369 CONSTSTR(NULL));
1370 } else {
1371 IPSECSESSIONTRACEREVENT(iph2->parent_session,
1372 IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_SUCC,
1373 CONSTSTR("Responder, Quick-Mode"),
1374 CONSTSTR(NULL));
1375 }
1376
1377 ike_session_ph2_established(iph2);
1378
1379 IPSECLOGASLMSG("IPSec Phase2 established (Initiated by %s).\n",
1380 (iph2->side == INITIATOR)? "me" : "peer");
1381
1382 #ifdef ENABLE_STATS
1383 gettimeofday(&iph2->end, NULL);
1384 syslog(LOG_NOTICE, "%s(%s): %8.6f",
1385 "phase2", "quick", timedelta(&iph2->start, &iph2->end));
1386 #endif
1387
1388 /* count up */
1389 if (iph2->ph1)
1390 iph2->ph1->ph2cnt++;
1391
1392 /* turn off schedule */
1393 if (iph2->scr)
1394 SCHED_KILL(iph2->scr);
1395
1396 /*
1397 * since we are going to reuse the phase2 handler, we need to
1398 * remain it and refresh all the references between ph1 and ph2 to use.
1399 */
1400 unbindph12(iph2);
1401
1402 iph2->sce = sched_new(iph2->approval->lifetime,
1403 isakmp_ph2expire_stub, iph2);
1404
1405 plog(LLV_DEBUG, LOCATION, NULL, "===\n");
1406 return 0;
1407 }
1408
1409 /*
1410 * set outbound SA
1411 */
1412 int
1413 pk_sendadd(iph2)
1414 struct ph2handle *iph2;
1415 {
1416 struct saproto *pr;
1417 struct sockaddr_storage *src = NULL, *dst = NULL;
1418 u_int e_type, e_keylen, a_type, a_keylen, flags;
1419 u_int satype, mode;
1420 u_int64_t lifebyte = 0;
1421 u_int wsize = 4; /* XXX static size of window */
1422 int proxy = 0;
1423 struct ph2natt natt;
1424
1425 /* sanity check */
1426 if (iph2->approval == NULL) {
1427 plog(LLV_ERROR, LOCATION, NULL,
1428 "no approvaled SAs found.\n");
1429 }
1430
1431 if (iph2->side == INITIATOR)
1432 proxy = iph2->ph1->rmconf->support_proxy;
1433 else if (iph2->sainfo && iph2->sainfo->id_i)
1434 proxy = 1;
1435
1436 /* for mobile IPv6 */
1437 if (proxy && iph2->src_id && iph2->dst_id &&
1438 ipsecdoi_transportmode(iph2->approval)) {
1439 src = iph2->src_id;
1440 dst = iph2->dst_id;
1441 } else {
1442 src = iph2->src;
1443 dst = iph2->dst;
1444 }
1445
1446 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
1447 /* validity check */
1448 satype = ipsecdoi2pfkey_proto(pr->proto_id);
1449 if (satype == ~0) {
1450 plog(LLV_ERROR, LOCATION, NULL,
1451 "invalid proto_id %d\n", pr->proto_id);
1452 return -1;
1453 }
1454 else if (satype == SADB_X_SATYPE_IPCOMP) {
1455 /* no replay window for IPCOMP */
1456 wsize = 0;
1457 }
1458 #ifdef ENABLE_SAMODE_UNSPECIFIED
1459 mode = IPSEC_MODE_ANY;
1460 #else
1461 mode = ipsecdoi2pfkey_mode(pr->encmode);
1462 if (mode == ~0) {
1463 plog(LLV_ERROR, LOCATION, NULL,
1464 "invalid encmode %d\n", pr->encmode);
1465 return -1;
1466 }
1467 #endif
1468
1469 /* set algorithm type and key length */
1470 e_keylen = pr->head->encklen;
1471 if (pfkey_convertfromipsecdoi(
1472 pr->proto_id,
1473 pr->head->trns_id,
1474 pr->head->authtype,
1475 &e_type, &e_keylen,
1476 &a_type, &a_keylen, &flags) < 0)
1477 return -1;
1478
1479 #if 0
1480 lifebyte = iph2->approval->lifebyte * 1024,
1481 #else
1482 lifebyte = 0;
1483 #endif
1484
1485 #ifdef ENABLE_NATT
1486 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_add\n");
1487
1488 if (pr->udp_encap) {
1489 memset (&natt, 0, sizeof (natt));
1490 natt.dport = extract_port (iph2->ph1->remote);
1491 flags |= SADB_X_EXT_NATT;
1492 if (iph2->ph1->natt_flags & NAT_DETECTED_ME) {
1493 if (iph2->ph1->rmconf->natt_keepalive == TRUE)
1494 flags |= SADB_X_EXT_NATT_KEEPALIVE;
1495 } else {
1496 if (iph2->ph1->rmconf->natt_multiple_user == TRUE &&
1497 mode == IPSEC_MODE_TRANSPORT &&
1498 dst->ss_family == AF_INET) {
1499 flags |= SADB_X_EXT_NATT_MULTIPLEUSERS;
1500 }
1501 if (iph2->ph1->natt_flags & NAT_DETECTED_PEER) {
1502 // is mutually exclusive with SADB_X_EXT_NATT_KEEPALIVE
1503 flags |= SADB_X_EXT_NATT_DETECTED_PEER;
1504 }
1505 }
1506 } else {
1507 memset (&natt, 0, sizeof (natt));
1508
1509 /* Remove port information, that SA doesn't use it */
1510 //set_port(src, 0);
1511 //set_port(dst, 0);
1512 }
1513
1514 if (pfkey_send_add(
1515 lcconf->sock_pfkey,
1516 satype,
1517 mode,
1518 src,
1519 dst,
1520 pr->spi_p,
1521 pr->reqid_out,
1522 wsize,
1523 pr->keymat_p->v,
1524 e_type, e_keylen, a_type, a_keylen, flags,
1525 0, lifebyte, iph2->approval->lifetime, 0,
1526 iph2->seq,natt.dport) < 0) {
1527 plog(LLV_ERROR, LOCATION, NULL,
1528 "libipsec failed send add (%s)\n",
1529 ipsec_strerror());
1530 return -1;
1531 }
1532 #else
1533 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_add\n");
1534
1535 /* Remove port information, it is not used without NAT-T */
1536 //set_port(src, 0);
1537 //set_port(dst, 0);
1538
1539 if (pfkey_send_add(
1540 lcconf->sock_pfkey,
1541 satype,
1542 mode,
1543 src,
1544 dst,
1545 pr->spi_p,
1546 pr->reqid_out,
1547 wsize,
1548 pr->keymat_p->v,
1549 e_type, e_keylen, a_type, a_keylen, flags,
1550 0, lifebyte, iph2->approval->lifetime, 0,
1551 iph2->seq, 0) < 0) {
1552 plog(LLV_ERROR, LOCATION, NULL,
1553 "libipsec failed send add (%s)\n",
1554 ipsec_strerror());
1555 return -1;
1556 }
1557 #endif /* ENABLE_NATT */
1558 if (!lcconf->pathinfo[LC_PATHTYPE_BACKUPSA])
1559 continue;
1560
1561 /*
1562 * It maybe good idea to call backupsa_to_file() after
1563 * racoon will receive the sadb_update messages.
1564 * But it is impossible because there is not key in the
1565 * information from the kernel.
1566 */
1567 if (backupsa_to_file(satype, mode, (struct sockaddr *)src, (struct sockaddr *)dst,
1568 pr->spi_p, pr->reqid_out, 4,
1569 pr->keymat_p->v,
1570 e_type, e_keylen, a_type, a_keylen, flags,
1571 0, iph2->approval->lifebyte * 1024,
1572 iph2->approval->lifetime, 0,
1573 iph2->seq) < 0) {
1574 plog(LLV_ERROR, LOCATION, NULL,
1575 "backuped SA failed: %s\n",
1576 sadbsecas2str(src, dst,
1577 satype, pr->spi_p, mode));
1578 }
1579 plog(LLV_DEBUG, LOCATION, NULL,
1580 "backuped SA: %s\n",
1581 sadbsecas2str(src, dst,
1582 satype, pr->spi_p, mode));
1583 }
1584
1585 return 0;
1586 }
1587
1588 static int
1589 pk_recvadd(mhp)
1590 caddr_t *mhp;
1591 {
1592 struct sadb_msg *msg;
1593 struct sadb_sa *sa;
1594 struct sockaddr_storage *src, *dst;
1595 struct ph2handle *iph2;
1596 u_int sa_mode;
1597
1598 /* ignore this message because of local test mode. */
1599 if (f_local)
1600 return 0;
1601
1602 /* sanity check */
1603 if (mhp[0] == NULL
1604 || mhp[SADB_EXT_SA] == NULL
1605 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1606 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
1607 plog(LLV_ERROR, LOCATION, NULL,
1608 "inappropriate sadb add message passed.\n");
1609 return -1;
1610 }
1611 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
1612 src = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1613 dst = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1614 sa = ALIGNED_CAST(struct sadb_sa *)mhp[SADB_EXT_SA];
1615
1616 sa_mode = mhp[SADB_X_EXT_SA2] == NULL
1617 ? IPSEC_MODE_ANY
1618 : (ALIGNED_CAST(struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
1619
1620 /* the message has to be processed or not ? */
1621 if (msg->sadb_msg_pid != getpid()) {
1622 plog(LLV_DEBUG, LOCATION, NULL,
1623 "%s message is not interesting "
1624 "because pid %d is not mine.\n",
1625 s_pfkey_type(msg->sadb_msg_type),
1626 msg->sadb_msg_pid);
1627 return -1;
1628 }
1629
1630 iph2 = getph2byseq(msg->sadb_msg_seq);
1631 if (iph2 == NULL) {
1632 plog(LLV_DEBUG, LOCATION, NULL,
1633 "seq %d of %s message not interesting.\n",
1634 msg->sadb_msg_seq,
1635 s_pfkey_type(msg->sadb_msg_type));
1636 return -1;
1637 }
1638
1639 /*
1640 * NOTE don't update any status of phase2 handle
1641 * because they must be updated by SADB_UPDATE message
1642 */
1643
1644 plog(LLV_INFO, LOCATION, NULL,
1645 "IPsec-SA established: %s\n",
1646 sadbsecas2str(iph2->src, iph2->dst,
1647 msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode));
1648
1649 ike_session_cleanup_other_established_ph2s(iph2->parent_session, iph2);
1650
1651 #ifdef ENABLE_VPNCONTROL_PORT
1652 {
1653 u_int32_t address;
1654
1655 if (iph2->dst->ss_family == AF_INET)
1656 address = ((struct sockaddr_in *)iph2->dst)->sin_addr.s_addr;
1657 else
1658 address = 0;
1659 vpncontrol_notify_phase_change(0, FROM_LOCAL, NULL, iph2);
1660 }
1661 #endif
1662
1663 plog(LLV_DEBUG, LOCATION, NULL, "===\n");
1664 return 0;
1665 }
1666
1667 static int
1668 pk_recvexpire(mhp)
1669 caddr_t *mhp;
1670 {
1671 struct sadb_msg *msg;
1672 struct sadb_sa *sa;
1673 struct sockaddr_storage *src, *dst;
1674 struct ph2handle *iph2;
1675 u_int proto_id, sa_mode;
1676
1677 /* sanity check */
1678 if (mhp[0] == NULL
1679 || mhp[SADB_EXT_SA] == NULL
1680 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1681 || mhp[SADB_EXT_ADDRESS_DST] == NULL
1682 || (mhp[SADB_EXT_LIFETIME_HARD] != NULL
1683 && mhp[SADB_EXT_LIFETIME_SOFT] != NULL)) {
1684 plog(LLV_ERROR, LOCATION, NULL,
1685 "inappropriate sadb expire message passed.\n");
1686 return -1;
1687 }
1688 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
1689 sa = ALIGNED_CAST(struct sadb_sa *)mhp[SADB_EXT_SA];
1690 src = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1691 dst = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1692
1693 sa_mode = mhp[SADB_X_EXT_SA2] == NULL
1694 ? IPSEC_MODE_ANY
1695 : (ALIGNED_CAST(struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
1696
1697 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
1698 if (proto_id == ~0) {
1699 plog(LLV_ERROR, LOCATION, NULL,
1700 "invalid proto_id %d\n", msg->sadb_msg_satype);
1701 return -1;
1702 }
1703
1704 plog(LLV_INFO, LOCATION, NULL,
1705 "IPsec-SA expired: %s\n",
1706 sadbsecas2str(src, dst,
1707 msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode));
1708
1709 iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
1710 if (iph2 == NULL) {
1711 /*
1712 * Ignore it because two expire messages are come up.
1713 * phase2 handler has been deleted already when 2nd message
1714 * is received.
1715 */
1716 plog(LLV_DEBUG, LOCATION, NULL,
1717 "no such a SA found: %s\n",
1718 sadbsecas2str(src, dst,
1719 msg->sadb_msg_satype, sa->sadb_sa_spi,
1720 sa_mode));
1721 return 0;
1722 }
1723 if (iph2->is_dying || iph2->status != PHASE2ST_ESTABLISHED) {
1724 /*
1725 * If the status is not equal to PHASE2ST_ESTABLISHED,
1726 * racoon ignores this expire message. There are two reason.
1727 * One is that the phase 2 probably starts because there is
1728 * a potential that racoon receives the acquire message
1729 * without receiving a expire message. Another is that racoon
1730 * may receive the multiple expire messages from the kernel.
1731 */
1732 plog(LLV_WARNING, LOCATION, NULL,
1733 "the expire message is received "
1734 "but the handler is dying or has not been established.\n");
1735 return 0;
1736 }
1737
1738 /* turn off the timer for calling isakmp_ph2expire() */
1739 SCHED_KILL(iph2->sce);
1740
1741 iph2->status = PHASE2ST_EXPIRED;
1742
1743 /* INITIATOR, begin phase 2 exchange only if there's no other established ph2. */
1744 /* allocate buffer for status management of pfkey message */
1745 if (iph2->side == INITIATOR &&
1746 !ike_session_has_other_established_ph2(iph2->parent_session, iph2) &&
1747 !ike_session_drop_rekey(iph2->parent_session, IKE_SESSION_REKEY_TYPE_PH2)) {
1748
1749 initph2(iph2);
1750
1751 /* update status for re-use */
1752 iph2->status = PHASE2ST_STATUS2;
1753
1754 /* start isakmp initiation by using ident exchange */
1755 if (isakmp_post_acquire(iph2) < 0) {
1756 plog(LLV_ERROR, LOCATION, iph2->dst,
1757 "failed to begin ipsec sa "
1758 "re-negotiation.\n");
1759 unbindph12(iph2);
1760 remph2(iph2);
1761 delph2(iph2);
1762 return -1;
1763 }
1764
1765 return 0;
1766 /*NOTREACHED*/
1767 }
1768
1769 /* If not received SADB_EXPIRE, INITIATOR delete ph2handle. */
1770 /* RESPONDER always delete ph2handle, keep silent. RESPONDER doesn't
1771 * manage IPsec SA, so delete the list */
1772 unbindph12(iph2);
1773 remph2(iph2);
1774 delph2(iph2);
1775
1776 return 0;
1777 }
1778
1779 static int
1780 pk_recvacquire(mhp)
1781 caddr_t *mhp;
1782 {
1783 struct sadb_msg *msg;
1784 struct sadb_x_policy *xpl;
1785 struct secpolicy *sp_out = NULL, *sp_in = NULL;
1786 #define MAXNESTEDSA 5 /* XXX */
1787 struct ph2handle *iph2[MAXNESTEDSA];
1788 struct sockaddr_storage *src, *dst;
1789 int n; /* # of phase 2 handler */
1790
1791 /* ignore this message because of local test mode. */
1792 if (f_local)
1793 return 0;
1794
1795 /* sanity check */
1796 if (mhp[0] == NULL
1797 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1798 || mhp[SADB_EXT_ADDRESS_DST] == NULL
1799 || mhp[SADB_X_EXT_POLICY] == NULL) {
1800 plog(LLV_ERROR, LOCATION, NULL,
1801 "inappropriate sadb acquire message passed.\n");
1802 return -1;
1803 }
1804 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
1805 xpl = ALIGNED_CAST(struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
1806 src = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1807 dst = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1808
1809 /* ignore if type is not IPSEC_POLICY_IPSEC */
1810 if (xpl->sadb_x_policy_type != IPSEC_POLICY_IPSEC) {
1811 plog(LLV_DEBUG, LOCATION, NULL,
1812 "ignore ACQUIRE message. type is not IPsec.\n");
1813 return 0;
1814 }
1815
1816 /* ignore it if src is multicast address */
1817 {
1818 struct sockaddr_storage *sa = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1819
1820 if ((sa->ss_family == AF_INET
1821 && IN_MULTICAST(ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr)))
1822 #ifdef INET6
1823 || (sa->ss_family == AF_INET6
1824 && IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)sa)->sin6_addr))
1825 #endif
1826 ) {
1827 plog(LLV_DEBUG, LOCATION, NULL,
1828 "ignore due to multicast address: %s.\n",
1829 saddrwop2str((struct sockaddr *)sa));
1830 return 0;
1831 }
1832 }
1833
1834 /* ignore, if we do not listen on source address */
1835 {
1836 /* reasons behind:
1837 * - if we'll contact peer from address we do not listen -
1838 * we will be unable to complete negotiation;
1839 * - if we'll negotiate using address we're listening -
1840 * remote peer will send packets to address different
1841 * than one in the policy, so kernel will drop them;
1842 * => therefore this acquire is not for us! --Aidas
1843 */
1844 // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
1845 struct sockaddr_storage *sa = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1846 struct myaddrs *p;
1847 int do_listen = 0;
1848 for (p = lcconf->myaddrs; p; p = p->next) {
1849 if (!cmpsaddrwop(p->addr, sa)) {
1850 do_listen = 1;
1851 break;
1852 }
1853 }
1854
1855 if (!do_listen) {
1856 plog(LLV_DEBUG, LOCATION, NULL,
1857 "ignore because do not listen on source address : %s.\n",
1858 saddrwop2str((struct sockaddr *)sa));
1859 return 0;
1860 }
1861 }
1862
1863 /*
1864 * If there is a phase 2 handler against the policy identifier in
1865 * the acquire message, and if
1866 * 1. its state is less than PHASE2ST_ESTABLISHED, then racoon
1867 * should ignore such a acquire message because the phase 2
1868 * is just negotiating.
1869 * 2. its state is equal to PHASE2ST_ESTABLISHED, then racoon
1870 * has to process such a acquire message because racoon may
1871 * have lost the expire message.
1872 */
1873 iph2[0] = getph2byid(src, dst, xpl->sadb_x_policy_id);
1874 if (iph2[0] != NULL) {
1875 if (iph2[0]->status < PHASE2ST_ESTABLISHED) {
1876 plog(LLV_DEBUG, LOCATION, NULL,
1877 "ignore the acquire because ph2 found\n");
1878 return -1;
1879 }
1880 if (iph2[0]->status == PHASE2ST_EXPIRED)
1881 iph2[0] = NULL;
1882 /*FALLTHROUGH*/
1883 }
1884
1885 /* search for proper policyindex */
1886 sp_out = getspbyspid(xpl->sadb_x_policy_id);
1887 if (sp_out == NULL) {
1888 plog(LLV_ERROR, LOCATION, NULL, "no policy found: id:%d.\n",
1889 xpl->sadb_x_policy_id);
1890 return -1;
1891 }
1892 plog(LLV_DEBUG, LOCATION, NULL,
1893 "suitable outbound SP found: %s.\n", spidx2str(&sp_out->spidx));
1894
1895 /* get inbound policy */
1896 {
1897 struct policyindex spidx;
1898
1899 spidx.dir = IPSEC_DIR_INBOUND;
1900 memcpy(&spidx.src, &sp_out->spidx.dst, sizeof(spidx.src));
1901 memcpy(&spidx.dst, &sp_out->spidx.src, sizeof(spidx.dst));
1902 spidx.prefs = sp_out->spidx.prefd;
1903 spidx.prefd = sp_out->spidx.prefs;
1904 spidx.ul_proto = sp_out->spidx.ul_proto;
1905
1906 sp_in = getsp(&spidx);
1907 if (sp_in) {
1908 plog(LLV_DEBUG, LOCATION, NULL,
1909 "suitable inbound SP found: %s.\n",
1910 spidx2str(&sp_in->spidx));
1911 } else {
1912 plog(LLV_NOTIFY, LOCATION, NULL,
1913 "no in-bound policy found: %s\n",
1914 spidx2str(&spidx));
1915 }
1916 }
1917
1918 memset(iph2, 0, MAXNESTEDSA);
1919
1920 n = 0;
1921
1922 /* allocate a phase 2 */
1923 iph2[n] = newph2();
1924 if (iph2[n] == NULL) {
1925 plog(LLV_ERROR, LOCATION, NULL,
1926 "failed to allocate phase2 entry.\n");
1927 return -1;
1928 }
1929 iph2[n]->side = INITIATOR;
1930 iph2[n]->spid = xpl->sadb_x_policy_id;
1931 iph2[n]->satype = msg->sadb_msg_satype;
1932 iph2[n]->seq = msg->sadb_msg_seq;
1933 iph2[n]->status = PHASE2ST_STATUS2;
1934
1935 /* set end addresses of SA */
1936 // Wcast_align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
1937 iph2[n]->dst = dupsaddr(ALIGNED_CAST(struct sockaddr *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]));
1938 if (iph2[n]->dst == NULL) {
1939 delph2(iph2[n]);
1940 return -1;
1941 }
1942 iph2[n]->src = dupsaddr(ALIGNED_CAST(struct sockaddr *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]));
1943 if (iph2[n]->src == NULL) {
1944 delph2(iph2[n]);
1945 return -1;
1946 }
1947
1948 plog(LLV_DEBUG, LOCATION, NULL,
1949 "new acquire %s\n", spidx2str(&sp_out->spidx));
1950
1951 /* get sainfo */
1952 {
1953 vchar_t *idsrc, *iddst;
1954
1955 idsrc = ipsecdoi_sockaddr2id(&sp_out->spidx.src,
1956 sp_out->spidx.prefs, sp_out->spidx.ul_proto);
1957 if (idsrc == NULL) {
1958 plog(LLV_ERROR, LOCATION, NULL,
1959 "failed to get ID for %s\n",
1960 spidx2str(&sp_out->spidx));
1961 delph2(iph2[n]);
1962 return -1;
1963 }
1964 iddst = ipsecdoi_sockaddr2id(&sp_out->spidx.dst,
1965 sp_out->spidx.prefd, sp_out->spidx.ul_proto);
1966 if (iddst == NULL) {
1967 plog(LLV_ERROR, LOCATION, NULL,
1968 "failed to get ID for %s\n",
1969 spidx2str(&sp_out->spidx));
1970 vfree(idsrc);
1971 delph2(iph2[n]);
1972 return -1;
1973 }
1974 iph2[n]->sainfo = getsainfo(idsrc, iddst, NULL, 0);
1975 vfree(idsrc);
1976 vfree(iddst);
1977 if (iph2[n]->sainfo == NULL) {
1978 plog(LLV_ERROR, LOCATION, NULL,
1979 "failed to get sainfo.\n");
1980 delph2(iph2[n]);
1981 return -1;
1982 /* XXX should use the algorithm list from register message */
1983 }
1984 if (link_sainfo_to_ph2(iph2[n]->sainfo) != 0) {
1985 plog(LLV_ERROR, LOCATION, NULL,
1986 "failed to link sainfo\n");
1987 iph2[n]->sainfo = NULL;
1988 delph2(iph2[n]);
1989 return -1;
1990 }
1991 }
1992
1993 if (set_proposal_from_policy(iph2[n], sp_out, sp_in) < 0) {
1994 plog(LLV_ERROR, LOCATION, NULL,
1995 "failed to create saprop.\n");
1996 delph2(iph2[n]);
1997 return -1;
1998 }
1999 insph2(iph2[n]);
2000
2001 /* start isakmp initiation by using ident exchange */
2002 /* XXX should be looped if there are multiple phase 2 handler. */
2003 if (isakmp_post_acquire(iph2[n]) < 0) {
2004 plog(LLV_ERROR, LOCATION, NULL,
2005 "failed to begin ipsec sa negotiation.\n");
2006 goto err;
2007 }
2008
2009 #if !TARGET_OS_EMBEDDED
2010 if ( lcconf->vt == NULL){
2011 if (!(lcconf->vt = vproc_transaction_begin(NULL)))
2012 plog(LLV_ERROR, LOCATION, NULL,
2013 "vproc_transaction_begin returns NULL.\n");
2014 }
2015 #endif
2016
2017
2018 return 0;
2019
2020 err:
2021 while (n >= 0) {
2022 unbindph12(iph2[n]);
2023 remph2(iph2[n]);
2024 delph2(iph2[n]);
2025 iph2[n] = NULL;
2026 n--;
2027 }
2028 return -1;
2029 }
2030
2031 static int
2032 pk_recvdelete(mhp)
2033 caddr_t *mhp;
2034 {
2035 struct sadb_msg *msg;
2036 struct sadb_sa *sa;
2037 struct sockaddr_storage *src, *dst;
2038 struct ph2handle *iph2 = NULL;
2039 u_int proto_id;
2040
2041 /* ignore this message because of local test mode. */
2042 if (f_local)
2043 return 0;
2044
2045 /* sanity check */
2046 if (mhp[0] == NULL
2047 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2048 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
2049 plog(LLV_ERROR, LOCATION, NULL,
2050 "inappropriate sadb delete message passed.\n");
2051 return -1;
2052 }
2053 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
2054 sa = ALIGNED_CAST(struct sadb_sa *)mhp[SADB_EXT_SA];
2055 src = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
2056 dst = ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
2057
2058 /* the message has to be processed or not ? */
2059 if (msg->sadb_msg_pid == getpid()) {
2060 plog(LLV_DEBUG, LOCATION, NULL,
2061 "%s message is not interesting "
2062 "because the message was originated by me.\n",
2063 s_pfkey_type(msg->sadb_msg_type));
2064 return -1;
2065 }
2066
2067 proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
2068 if (proto_id == ~0) {
2069 plog(LLV_ERROR, LOCATION, NULL,
2070 "invalid proto_id %d\n", msg->sadb_msg_satype);
2071 return -1;
2072 }
2073
2074 plog(LLV_DEBUG2, LOCATION, NULL, "SADB delete message: proto-id %d\n", proto_id);
2075 plog(LLV_DEBUG2, LOCATION, NULL, "src: %s\n", saddr2str((struct sockaddr *)src));
2076 plog(LLV_DEBUG2, LOCATION, NULL, "dst: %s\n", saddr2str((struct sockaddr *)dst));
2077
2078 if (!sa) {
2079 deleteallph2(src, dst, proto_id);
2080 deleteallph1(src, dst);
2081 return 0;
2082 }
2083
2084 iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
2085 if (iph2 == NULL) {
2086 /* ignore */
2087 plog(LLV_ERROR, LOCATION, NULL,
2088 "no iph2 found: %s\n",
2089 sadbsecas2str(src, dst, msg->sadb_msg_satype,
2090 sa->sadb_sa_spi, IPSEC_MODE_ANY));
2091 return 0;
2092 }
2093
2094 plog(LLV_ERROR, LOCATION, NULL,
2095 "pfkey DELETE received: %s\n",
2096 sadbsecas2str(iph2->src, iph2->dst,
2097 msg->sadb_msg_satype, sa->sadb_sa_spi, IPSEC_MODE_ANY));
2098
2099 /* send delete information */
2100 if (iph2->status == PHASE2ST_ESTABLISHED)
2101 isakmp_info_send_d2(iph2);
2102
2103 ike_session_cleanup_ph1s_by_ph2(iph2);
2104 unbindph12(iph2);
2105 remph2(iph2);
2106 delph2(iph2);
2107
2108 return 0;
2109 }
2110
2111 static int
2112 pk_recvflush(mhp)
2113 caddr_t *mhp;
2114 {
2115 /* ignore this message because of local test mode. */
2116 if (f_local)
2117 return 0;
2118
2119 /* sanity check */
2120 if (mhp[0] == NULL) {
2121 plog(LLV_ERROR, LOCATION, NULL,
2122 "inappropriate sadb flush message passed.\n");
2123 return -1;
2124 }
2125
2126 flushph2(false);
2127 flushph1(false);
2128
2129 return 0;
2130 }
2131
2132 static int
2133 getsadbpolicy(policy0, policylen0, type, iph2)
2134 caddr_t *policy0;
2135 int *policylen0, type;
2136 struct ph2handle *iph2;
2137 {
2138 struct policyindex *spidx = iph2->spidx_gen;
2139 struct sadb_x_policy *xpl;
2140 struct sadb_x_ipsecrequest *xisr;
2141 struct saproto *pr;
2142 caddr_t policy, p;
2143 int policylen;
2144 int xisrlen;
2145 u_int satype, mode;
2146
2147 /* get policy buffer size */
2148 policylen = sizeof(struct sadb_x_policy);
2149 if (type != SADB_X_SPDDELETE) {
2150 for (pr = iph2->approval->head; pr; pr = pr->next) {
2151 xisrlen = sizeof(*xisr);
2152 if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) {
2153 xisrlen += (sysdep_sa_len((struct sockaddr *)iph2->src)
2154 + sysdep_sa_len((struct sockaddr *)iph2->dst));
2155 }
2156
2157 policylen += PFKEY_ALIGN8(xisrlen);
2158 }
2159 }
2160
2161 /* make policy structure */
2162 policy = racoon_malloc(policylen);
2163 if (!policy) {
2164 plog(LLV_ERROR, LOCATION, NULL,
2165 "buffer allocation failed.\n");
2166 return -1;
2167 }
2168
2169 xpl = ALIGNED_CAST(struct sadb_x_policy *)policy;
2170 xpl->sadb_x_policy_len = PFKEY_UNIT64(policylen);
2171 xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
2172 xpl->sadb_x_policy_type = IPSEC_POLICY_IPSEC;
2173 xpl->sadb_x_policy_dir = spidx->dir;
2174 xpl->sadb_x_policy_id = 0;
2175 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2176 xpl->sadb_x_policy_priority = PRIORITY_DEFAULT;
2177 #endif
2178
2179 /* no need to append policy information any more if type is SPDDELETE */
2180 if (type == SADB_X_SPDDELETE)
2181 goto end;
2182
2183 xisr = (struct sadb_x_ipsecrequest *)(xpl + 1);
2184
2185 for (pr = iph2->approval->head; pr; pr = pr->next) {
2186
2187 satype = doi2ipproto(pr->proto_id);
2188 if (satype == ~0) {
2189 plog(LLV_ERROR, LOCATION, NULL,
2190 "invalid proto_id %d\n", pr->proto_id);
2191 goto err;
2192 }
2193 mode = ipsecdoi2pfkey_mode(pr->encmode);
2194 if (mode == ~0) {
2195 plog(LLV_ERROR, LOCATION, NULL,
2196 "invalid encmode %d\n", pr->encmode);
2197 goto err;
2198 }
2199
2200 /*
2201 * the policy level cannot be unique because the policy
2202 * is defined later than SA, so req_id cannot be bound to SA.
2203 */
2204 xisr->sadb_x_ipsecrequest_proto = satype;
2205 xisr->sadb_x_ipsecrequest_mode = mode;
2206 xisr->sadb_x_ipsecrequest_level = IPSEC_LEVEL_REQUIRE;
2207 xisr->sadb_x_ipsecrequest_reqid = 0;
2208 p = (caddr_t)(xisr + 1);
2209
2210 xisrlen = sizeof(*xisr);
2211
2212 if (pr->encmode == IPSECDOI_ATTR_ENC_MODE_TUNNEL) {
2213 int src_len, dst_len;
2214
2215 src_len = sysdep_sa_len((struct sockaddr *)iph2->src);
2216 dst_len = sysdep_sa_len((struct sockaddr *)iph2->dst);
2217 xisrlen += src_len + dst_len;
2218
2219 memcpy(p, iph2->src, src_len);
2220 p += src_len;
2221
2222 memcpy(p, iph2->dst, dst_len);
2223 p += dst_len;
2224 }
2225
2226 xisr->sadb_x_ipsecrequest_len = PFKEY_ALIGN8(xisrlen);
2227 }
2228
2229 end:
2230 *policy0 = policy;
2231 *policylen0 = policylen;
2232
2233 return 0;
2234
2235 err:
2236 if (policy)
2237 racoon_free(policy);
2238
2239 return -1;
2240 }
2241
2242 int
2243 pk_sendspdupdate2(iph2)
2244 struct ph2handle *iph2;
2245 {
2246 struct policyindex *spidx = iph2->spidx_gen;
2247 caddr_t policy = NULL;
2248 int policylen = 0;
2249 u_int64_t ltime, vtime;
2250
2251 ltime = iph2->approval->lifetime;
2252 vtime = 0;
2253
2254 if (getsadbpolicy(&policy, &policylen, SADB_X_SPDUPDATE, iph2)) {
2255 plog(LLV_ERROR, LOCATION, NULL,
2256 "getting sadb policy failed.\n");
2257 return -1;
2258 }
2259
2260 if (pfkey_send_spdupdate2(
2261 lcconf->sock_pfkey,
2262 &spidx->src,
2263 spidx->prefs,
2264 &spidx->dst,
2265 spidx->prefd,
2266 spidx->ul_proto,
2267 ltime, vtime,
2268 policy, policylen, 0) < 0) {
2269 plog(LLV_ERROR, LOCATION, NULL,
2270 "libipsec failed send spdupdate2 (%s)\n",
2271 ipsec_strerror());
2272 goto end;
2273 }
2274 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spdupdate2\n");
2275
2276 end:
2277 if (policy)
2278 racoon_free(policy);
2279
2280 return 0;
2281 }
2282
2283 static int
2284 pk_recvspdupdate(mhp)
2285 caddr_t *mhp;
2286 {
2287 struct sadb_address *saddr, *daddr;
2288 struct sadb_x_policy *xpl;
2289 struct policyindex spidx;
2290 struct secpolicy *sp;
2291
2292 /* sanity check */
2293 if (mhp[0] == NULL
2294 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2295 || mhp[SADB_EXT_ADDRESS_DST] == NULL
2296 || mhp[SADB_X_EXT_POLICY] == NULL) {
2297 plog(LLV_ERROR, LOCATION, NULL,
2298 "inappropriate sadb spdupdate message passed.\n");
2299 return -1;
2300 }
2301 saddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
2302 daddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2303 xpl = ALIGNED_CAST(struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2304
2305 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2306 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2307 saddr + 1,
2308 daddr + 1,
2309 saddr->sadb_address_prefixlen,
2310 daddr->sadb_address_prefixlen,
2311 saddr->sadb_address_proto,
2312 xpl->sadb_x_policy_priority,
2313 &spidx);
2314 #else
2315 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2316 saddr + 1,
2317 daddr + 1,
2318 saddr->sadb_address_prefixlen,
2319 daddr->sadb_address_prefixlen,
2320 saddr->sadb_address_proto,
2321 &spidx);
2322 #endif
2323
2324 sp = getsp(&spidx);
2325 if (sp == NULL) {
2326 plog(LLV_ERROR, LOCATION, NULL,
2327 "such policy does not already exist: \"%s\"\n",
2328 spidx2str(&spidx));
2329 } else {
2330 remsp(sp);
2331 delsp(sp);
2332 }
2333
2334 if (addnewsp(mhp) < 0)
2335 return -1;
2336
2337 return 0;
2338 }
2339
2340 /*
2341 * this function has to be used by responder side.
2342 */
2343 int
2344 pk_sendspdadd2(iph2)
2345 struct ph2handle *iph2;
2346 {
2347 struct policyindex *spidx = iph2->spidx_gen;
2348 caddr_t policy = NULL;
2349 int policylen = 0;
2350 u_int64_t ltime, vtime;
2351
2352 ltime = iph2->approval->lifetime;
2353 vtime = 0;
2354
2355 if (getsadbpolicy(&policy, &policylen, SADB_X_SPDADD, iph2)) {
2356 plog(LLV_ERROR, LOCATION, NULL,
2357 "getting sadb policy failed.\n");
2358 return -1;
2359 }
2360
2361 if (pfkey_send_spdadd2(
2362 lcconf->sock_pfkey,
2363 &spidx->src,
2364 spidx->prefs,
2365 &spidx->dst,
2366 spidx->prefd,
2367 spidx->ul_proto,
2368 ltime, vtime,
2369 policy, policylen, 0) < 0) {
2370 plog(LLV_ERROR, LOCATION, NULL,
2371 "libipsec failed send spdadd2 (%s)\n",
2372 ipsec_strerror());
2373 goto end;
2374 }
2375 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spdadd2\n");
2376
2377 end:
2378 if (policy)
2379 racoon_free(policy);
2380
2381 return 0;
2382 }
2383
2384 static int
2385 pk_recvspdadd(mhp)
2386 caddr_t *mhp;
2387 {
2388 struct sadb_address *saddr, *daddr;
2389 struct sadb_x_policy *xpl;
2390 struct policyindex spidx;
2391 struct secpolicy *sp;
2392
2393 /* sanity check */
2394 if (mhp[0] == NULL
2395 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2396 || mhp[SADB_EXT_ADDRESS_DST] == NULL
2397 || mhp[SADB_X_EXT_POLICY] == NULL) {
2398 plog(LLV_ERROR, LOCATION, NULL,
2399 "inappropriate sadb spdadd message passed.\n");
2400 return -1;
2401 }
2402 saddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
2403 daddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2404 xpl = ALIGNED_CAST(struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2405
2406 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2407 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2408 saddr + 1,
2409 daddr + 1,
2410 saddr->sadb_address_prefixlen,
2411 daddr->sadb_address_prefixlen,
2412 saddr->sadb_address_proto,
2413 xpl->sadb_x_policy_priority,
2414 &spidx);
2415 #else
2416 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2417 saddr + 1,
2418 daddr + 1,
2419 saddr->sadb_address_prefixlen,
2420 daddr->sadb_address_prefixlen,
2421 saddr->sadb_address_proto,
2422 &spidx);
2423 #endif
2424
2425 sp = getsp(&spidx);
2426 if (sp != NULL) {
2427 plog(LLV_ERROR, LOCATION, NULL,
2428 "such policy already exists. "
2429 "anyway replace it: %s\n",
2430 spidx2str(&spidx));
2431 remsp(sp);
2432 delsp(sp);
2433 }
2434
2435 if (addnewsp(mhp) < 0)
2436 return -1;
2437
2438 return 0;
2439 }
2440
2441 /*
2442 * this function has to be used by responder side.
2443 */
2444 int
2445 pk_sendspddelete(iph2)
2446 struct ph2handle *iph2;
2447 {
2448 struct policyindex *spidx = iph2->spidx_gen;
2449 caddr_t policy = NULL;
2450 int policylen;
2451
2452 if (getsadbpolicy(&policy, &policylen, SADB_X_SPDDELETE, iph2)) {
2453 plog(LLV_ERROR, LOCATION, NULL,
2454 "getting sadb policy failed.\n");
2455 return -1;
2456 }
2457
2458 if (pfkey_send_spddelete(
2459 lcconf->sock_pfkey,
2460 &spidx->src,
2461 spidx->prefs,
2462 &spidx->dst,
2463 spidx->prefd,
2464 spidx->ul_proto,
2465 policy, policylen, 0) < 0) {
2466 plog(LLV_ERROR, LOCATION, NULL,
2467 "libipsec failed send spddelete (%s)\n",
2468 ipsec_strerror());
2469 goto end;
2470 }
2471 plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spddelete\n");
2472
2473 end:
2474 if (policy)
2475 racoon_free(policy);
2476
2477 return 0;
2478 }
2479
2480 static int
2481 pk_recvspddelete(mhp)
2482 caddr_t *mhp;
2483 {
2484 struct sadb_address *saddr, *daddr;
2485 struct sadb_x_policy *xpl;
2486 struct policyindex spidx;
2487 struct secpolicy *sp;
2488
2489 /* sanity check */
2490 if (mhp[0] == NULL
2491 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2492 || mhp[SADB_EXT_ADDRESS_DST] == NULL
2493 || mhp[SADB_X_EXT_POLICY] == NULL) {
2494 plog(LLV_ERROR, LOCATION, NULL,
2495 "inappropriate sadb spddelete message passed.\n");
2496 return -1;
2497 }
2498 saddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
2499 daddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2500 xpl = ALIGNED_CAST(struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2501
2502 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2503 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2504 saddr + 1,
2505 daddr + 1,
2506 saddr->sadb_address_prefixlen,
2507 daddr->sadb_address_prefixlen,
2508 saddr->sadb_address_proto,
2509 xpl->sadb_x_policy_priority,
2510 &spidx);
2511 #else
2512 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2513 saddr + 1,
2514 daddr + 1,
2515 saddr->sadb_address_prefixlen,
2516 daddr->sadb_address_prefixlen,
2517 saddr->sadb_address_proto,
2518 &spidx);
2519 #endif
2520
2521 sp = getsp(&spidx);
2522 if (sp == NULL) {
2523 plog(LLV_ERROR, LOCATION, NULL,
2524 "no policy found: %s\n",
2525 spidx2str(&spidx));
2526 return -1;
2527 }
2528
2529 purgephXbyspid(xpl->sadb_x_policy_id, true);
2530
2531 remsp(sp);
2532 delsp(sp);
2533
2534 return 0;
2535 }
2536
2537 static int
2538 pk_recvspdexpire(mhp)
2539 caddr_t *mhp;
2540 {
2541 struct sadb_address *saddr, *daddr;
2542 struct sadb_x_policy *xpl;
2543 struct policyindex spidx;
2544 struct secpolicy *sp;
2545
2546 /* sanity check */
2547 if (mhp[0] == NULL
2548 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
2549 || mhp[SADB_EXT_ADDRESS_DST] == NULL
2550 || mhp[SADB_X_EXT_POLICY] == NULL) {
2551 plog(LLV_ERROR, LOCATION, NULL,
2552 "inappropriate sadb spdexpire message passed.\n");
2553 return -1;
2554 }
2555 saddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
2556 daddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2557 xpl = ALIGNED_CAST(struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2558
2559 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2560 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2561 saddr + 1,
2562 daddr + 1,
2563 saddr->sadb_address_prefixlen,
2564 daddr->sadb_address_prefixlen,
2565 saddr->sadb_address_proto,
2566 xpl->sadb_x_policy_priority,
2567 &spidx);
2568 #else
2569 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2570 saddr + 1,
2571 daddr + 1,
2572 saddr->sadb_address_prefixlen,
2573 daddr->sadb_address_prefixlen,
2574 saddr->sadb_address_proto,
2575 &spidx);
2576 #endif
2577
2578 sp = getsp(&spidx);
2579 if (sp == NULL) {
2580 plog(LLV_ERROR, LOCATION, NULL,
2581 "no policy found: %s\n",
2582 spidx2str(&spidx));
2583 return -1;
2584 }
2585
2586 purgephXbyspid(xpl->sadb_x_policy_id, false);
2587
2588 remsp(sp);
2589 delsp(sp);
2590
2591 return 0;
2592 }
2593
2594 static int
2595 pk_recvspdget(mhp)
2596 caddr_t *mhp;
2597 {
2598 /* sanity check */
2599 if (mhp[0] == NULL) {
2600 plog(LLV_ERROR, LOCATION, NULL,
2601 "inappropriate sadb spdget message passed.\n");
2602 return -1;
2603 }
2604
2605 return 0;
2606 }
2607
2608 static int
2609 pk_recvspddump(mhp)
2610 caddr_t *mhp;
2611 {
2612 struct sadb_msg *msg;
2613 struct sadb_address *saddr, *daddr;
2614 struct sadb_x_policy *xpl;
2615 struct policyindex spidx;
2616 struct secpolicy *sp;
2617
2618 /* sanity check */
2619 if (mhp[0] == NULL) {
2620 plog(LLV_ERROR, LOCATION, NULL,
2621 "inappropriate sadb spddump message passed.\n");
2622 return -1;
2623 }
2624 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
2625
2626 saddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
2627 daddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2628 xpl = ALIGNED_CAST(struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2629
2630 if (saddr == NULL || daddr == NULL || xpl == NULL) {
2631 plog(LLV_ERROR, LOCATION, NULL,
2632 "inappropriate sadb spddump message passed.\n");
2633 return -1;
2634 }
2635
2636 #ifdef HAVE_PFKEY_POLICY_PRIORITY
2637 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2638 saddr + 1,
2639 daddr + 1,
2640 saddr->sadb_address_prefixlen,
2641 daddr->sadb_address_prefixlen,
2642 saddr->sadb_address_proto,
2643 xpl->sadb_x_policy_priority,
2644 &spidx);
2645 #else
2646 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
2647 saddr + 1,
2648 daddr + 1,
2649 saddr->sadb_address_prefixlen,
2650 daddr->sadb_address_prefixlen,
2651 saddr->sadb_address_proto,
2652 &spidx);
2653 #endif
2654
2655 sp = getsp(&spidx);
2656 if (sp != NULL) {
2657 plog(LLV_ERROR, LOCATION, NULL,
2658 "such policy already exists. "
2659 "anyway replace it: %s\n",
2660 spidx2str(&spidx));
2661 remsp(sp);
2662 delsp(sp);
2663 }
2664
2665 if (addnewsp(mhp) < 0)
2666 return -1;
2667
2668 return 0;
2669 }
2670
2671 static int
2672 pk_recvspdflush(mhp)
2673 caddr_t *mhp;
2674 {
2675 /* sanity check */
2676 if (mhp[0] == NULL) {
2677 plog(LLV_ERROR, LOCATION, NULL,
2678 "inappropriate sadb spdflush message passed.\n");
2679 return -1;
2680 }
2681
2682 flushph2(false);
2683 flushph1(false);
2684 flushsp();
2685
2686 return 0;
2687 }
2688
2689 /*
2690 * send error against acquire message to kenrel.
2691 */
2692 int
2693 pk_sendeacquire(iph2)
2694 struct ph2handle *iph2;
2695 {
2696 struct sadb_msg *newmsg;
2697 int len;
2698
2699 len = sizeof(struct sadb_msg);
2700 newmsg = racoon_calloc(1, len);
2701 if (newmsg == NULL) {
2702 plog(LLV_ERROR, LOCATION, NULL,
2703 "failed to get buffer to send acquire.\n");
2704 return -1;
2705 }
2706
2707 memset(newmsg, 0, len);
2708 newmsg->sadb_msg_version = PF_KEY_V2;
2709 newmsg->sadb_msg_type = SADB_ACQUIRE;
2710 newmsg->sadb_msg_errno = ENOENT; /* XXX */
2711 newmsg->sadb_msg_satype = iph2->satype;
2712 newmsg->sadb_msg_len = PFKEY_UNIT64(len);
2713 newmsg->sadb_msg_reserved = 0;
2714 newmsg->sadb_msg_seq = iph2->seq;
2715 newmsg->sadb_msg_pid = (u_int32_t)getpid();
2716
2717 /* send message */
2718 len = pfkey_send(lcconf->sock_pfkey, newmsg, len);
2719
2720 racoon_free(newmsg);
2721
2722 return 0;
2723 }
2724
2725 int
2726 pk_sendget_inbound_sastats(ike_session_t *session)
2727 {
2728 u_int32_t max_stats;
2729 u_int32_t seq;
2730
2731 if (!session) {
2732 plog(LLV_DEBUG, LOCATION, NULL, "invalid args in %s \n", __FUNCTION__);
2733 return -1;
2734 }
2735
2736 session->traffic_monitor.num_in_curr_req = 0;
2737 bzero(session->traffic_monitor.in_curr_req, sizeof(session->traffic_monitor.in_curr_req));
2738 max_stats = (sizeof(session->traffic_monitor.in_curr_req) / sizeof(session->traffic_monitor.in_curr_req[0]));
2739
2740 // get list of SAs
2741 if ((session->traffic_monitor.num_in_curr_req = ike_session_get_sas_for_stats(session,
2742 IPSEC_DIR_INBOUND,
2743 &seq,
2744 session->traffic_monitor.in_curr_req,
2745 max_stats))) {
2746 u_int64_t session_ids[] = {(u_int64_t)session, 0};
2747
2748 plog(LLV_DEBUG, LOCATION, NULL, "about to call %s\n", __FUNCTION__);
2749
2750 if (pfkey_send_getsastats(lcconf->sock_pfkey,
2751 seq,
2752 session_ids,
2753 1,
2754 IPSEC_DIR_INBOUND,
2755 session->traffic_monitor.in_curr_req,
2756 session->traffic_monitor.num_in_curr_req) < 0) {
2757 return -1;
2758 }
2759 plog(LLV_DEBUG, LOCATION, NULL, "%s successful\n", __FUNCTION__);
2760
2761 return session->traffic_monitor.num_in_curr_req;
2762 }
2763 return 0;
2764 }
2765
2766 int
2767 pk_sendget_outbound_sastats(ike_session_t *session)
2768 {
2769 u_int32_t max_stats;
2770 u_int32_t seq;
2771
2772 if (!session) {
2773 plog(LLV_DEBUG, LOCATION, NULL, "invalid args in %s \n", __FUNCTION__);
2774 return -1;
2775 }
2776
2777 session->traffic_monitor.num_out_curr_req = 0;
2778 bzero(session->traffic_monitor.out_curr_req, sizeof(session->traffic_monitor.out_curr_req));
2779 max_stats = (sizeof(session->traffic_monitor.out_curr_req) / sizeof(session->traffic_monitor.out_curr_req[0]));
2780
2781 // get list of SAs
2782 if ((session->traffic_monitor.num_out_curr_req = ike_session_get_sas_for_stats(session,
2783 IPSEC_DIR_OUTBOUND,
2784 &seq,
2785 session->traffic_monitor.out_curr_req,
2786 max_stats))) {
2787 u_int64_t session_ids[] = {(u_int64_t)session, 0};
2788
2789 plog(LLV_DEBUG, LOCATION, NULL, "about to call %s\n", __FUNCTION__);
2790
2791 if (pfkey_send_getsastats(lcconf->sock_pfkey,
2792 seq,
2793 session_ids,
2794 1,
2795 IPSEC_DIR_OUTBOUND,
2796 session->traffic_monitor.out_curr_req,
2797 session->traffic_monitor.num_out_curr_req) < 0) {
2798 return -1;
2799 }
2800 plog(LLV_DEBUG, LOCATION, NULL, "%s successful\n", __FUNCTION__);
2801
2802 return session->traffic_monitor.num_out_curr_req;
2803 }
2804 return 0;
2805 }
2806
2807 /*
2808 * receive GETSPDSTAT from kernel.
2809 */
2810 static int
2811 pk_recvgetsastat(mhp)
2812 caddr_t *mhp;
2813 {
2814 struct sadb_msg *msg;
2815 struct sadb_session_id *session_id;
2816 struct sadb_sastat *stat_resp;
2817 ike_session_t *session;
2818
2819 /* validity check */
2820 if (mhp[0] == NULL ||
2821 mhp[SADB_EXT_SESSION_ID] == NULL ||
2822 mhp[SADB_EXT_SASTAT] == NULL) {
2823 plog(LLV_ERROR, LOCATION, NULL,
2824 "inappropriate sadb getsastat response.\n");
2825 return -1;
2826 }
2827 msg = ALIGNED_CAST(struct sadb_msg *)mhp[0]; // Wcast-align fix (void*) - mhp contains pointers to structs in an aligned buffer
2828 session_id = ALIGNED_CAST(struct sadb_session_id *)mhp[SADB_EXT_SESSION_ID];
2829 stat_resp = ALIGNED_CAST(struct sadb_sastat *)mhp[SADB_EXT_SASTAT];
2830
2831 /* the message has to be processed or not ? */
2832 if (msg->sadb_msg_pid != getpid()) {
2833 plog(LLV_DEBUG, LOCATION, NULL,
2834 "%s message is not interesting "
2835 "because pid %d is not mine.\n",
2836 s_pfkey_type(msg->sadb_msg_type),
2837 msg->sadb_msg_pid);
2838 return -1;
2839 }
2840 if (!session_id->sadb_session_id_v[0]) {
2841 plog(LLV_DEBUG, LOCATION, NULL,
2842 "%s message is bad "
2843 "because session-id[0] is invalid.\n",
2844 s_pfkey_type(msg->sadb_msg_type));
2845 return -1;
2846 }
2847 session = ALIGNED_CAST(__typeof__(session))session_id->sadb_session_id_v[0];
2848
2849 if (!stat_resp->sadb_sastat_list_len) {
2850 plog(LLV_DEBUG, LOCATION, NULL,
2851 "%s message is bad "
2852 "because it has no sastats.\n",
2853 s_pfkey_type(msg->sadb_msg_type));
2854 return -1;
2855 }
2856
2857 ike_session_update_traffic_idle_status(session,
2858 stat_resp->sadb_sastat_dir,
2859 (struct sastat *)(stat_resp + 1),
2860 stat_resp->sadb_sastat_list_len);
2861 return 0;
2862 }
2863
2864 /*
2865 * check if the algorithm is supported or not.
2866 * OUT 0: ok
2867 * -1: ng
2868 */
2869 int
2870 pk_checkalg(class, calg, keylen)
2871 int class, calg, keylen;
2872 {
2873 int sup, error;
2874 u_int alg;
2875 struct sadb_alg alg0;
2876
2877 switch (algclass2doi(class)) {
2878 case IPSECDOI_PROTO_IPSEC_ESP:
2879 sup = SADB_EXT_SUPPORTED_ENCRYPT;
2880 break;
2881 case IPSECDOI_ATTR_AUTH:
2882 sup = SADB_EXT_SUPPORTED_AUTH;
2883 break;
2884 case IPSECDOI_PROTO_IPCOMP:
2885 //plog(LLV_DEBUG, LOCATION, NULL,
2886 // "compression algorithm can not be checked "
2887 // "because sadb message doesn't support it.\n");
2888 return 0;
2889 default:
2890 plog(LLV_ERROR, LOCATION, NULL,
2891 "invalid algorithm class.\n");
2892 return -1;
2893 }
2894 alg = ipsecdoi2pfkey_alg(algclass2doi(class), algtype2doi(class, calg));
2895 if (alg == ~0)
2896 return -1;
2897
2898 if (keylen == 0) {
2899 if (ipsec_get_keylen(sup, alg, &alg0)) {
2900 plog(LLV_ERROR, LOCATION, NULL,
2901 "%s.\n", ipsec_strerror());
2902 return -1;
2903 }
2904 keylen = alg0.sadb_alg_minbits;
2905 }
2906
2907 error = ipsec_check_keylen(sup, alg, keylen);
2908 if (error)
2909 plog(LLV_ERROR, LOCATION, NULL,
2910 "%s.\n", ipsec_strerror());
2911
2912 return error;
2913 }
2914
2915 /*
2916 * differences with pfkey_recv() in libipsec/pfkey.c:
2917 * - never performs busy wait loop.
2918 * - returns NULL and set *lenp to negative on fatal failures
2919 * - returns NULL and set *lenp to non-negative on non-fatal failures
2920 * - returns non-NULL on success
2921 */
2922 static struct sadb_msg *
2923 pk_recv(so, lenp)
2924 int so;
2925 ssize_t *lenp;
2926 {
2927 struct sadb_msg *newmsg;
2928 int reallen = 0;
2929 socklen_t optlen = sizeof(reallen);
2930
2931 if (getsockopt(so, SOL_SOCKET, SO_NREAD, &reallen, &optlen) < 0)
2932 return NULL; /*fatal*/
2933
2934 if (reallen == 0)
2935 return NULL;
2936
2937 if ((newmsg = racoon_calloc(1, reallen)) == NULL)
2938 return NULL;
2939
2940 while ((*lenp = recv(so, (caddr_t)newmsg, reallen, 0)) < 0) {
2941 if (errno == EINTR)
2942 continue;
2943 plog(LLV_ERROR, LOCATION, NULL,
2944 "failed to recv pfkey message: %s\n", strerror(errno));
2945 break;
2946 }
2947 if (*lenp < 0) {
2948 racoon_free(newmsg);
2949 return NULL; /*fatal*/
2950 } else if (*lenp != reallen || *lenp < sizeof(struct sadb_msg)) {
2951 racoon_free(newmsg);
2952 return NULL;
2953 }
2954
2955 return newmsg;
2956 }
2957
2958 /* see handler.h */
2959 u_int32_t
2960 pk_getseq()
2961 {
2962 return eay_random();
2963 }
2964
2965 static int
2966 addnewsp(mhp)
2967 caddr_t *mhp;
2968 {
2969 struct secpolicy *new;
2970 struct sadb_address *saddr, *daddr;
2971 struct sadb_x_policy *xpl;
2972
2973 /* sanity check */
2974 if (mhp[SADB_EXT_ADDRESS_SRC] == NULL
2975 || mhp[SADB_EXT_ADDRESS_DST] == NULL
2976 || mhp[SADB_X_EXT_POLICY] == NULL) {
2977 plog(LLV_ERROR, LOCATION, NULL,
2978 "inappropriate sadb spd management message passed.\n");
2979 return -1;
2980 }
2981
2982 saddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC]; // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
2983 daddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
2984 xpl = ALIGNED_CAST(struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
2985
2986 new = newsp();
2987 if (new == NULL) {
2988 plog(LLV_ERROR, LOCATION, NULL,
2989 "failed to allocate buffer\n");
2990 return -1;
2991 }
2992
2993 new->spidx.dir = xpl->sadb_x_policy_dir;
2994 new->id = xpl->sadb_x_policy_id;
2995 new->policy = xpl->sadb_x_policy_type;
2996 new->req = NULL;
2997
2998 /* check policy */
2999 switch (xpl->sadb_x_policy_type) {
3000 case IPSEC_POLICY_DISCARD:
3001 case IPSEC_POLICY_GENERATE:
3002 case IPSEC_POLICY_NONE:
3003 case IPSEC_POLICY_ENTRUST:
3004 case IPSEC_POLICY_BYPASS:
3005 break;
3006
3007 case IPSEC_POLICY_IPSEC:
3008 {
3009 int tlen;
3010 struct sadb_x_ipsecrequest *xisr;
3011 struct ipsecrequest **p_isr = &new->req;
3012
3013 /* validity check */
3014 if (PFKEY_EXTLEN(xpl) < sizeof(*xpl)) {
3015 plog(LLV_ERROR, LOCATION, NULL,
3016 "invalid msg length.\n");
3017 return -1;
3018 }
3019
3020 tlen = PFKEY_EXTLEN(xpl) - sizeof(*xpl);
3021 xisr = (struct sadb_x_ipsecrequest *)(xpl + 1);
3022
3023 while (tlen > 0) {
3024
3025 /* length check */
3026 if (xisr->sadb_x_ipsecrequest_len < sizeof(*xisr)) {
3027 plog(LLV_ERROR, LOCATION, NULL,
3028 "invalid msg length.\n");
3029 return -1;
3030 }
3031
3032 /* allocate request buffer */
3033 *p_isr = newipsecreq();
3034 if (*p_isr == NULL) {
3035 plog(LLV_ERROR, LOCATION, NULL,
3036 "failed to get new ipsecreq.\n");
3037 return -1;
3038 }
3039
3040 /* set values */
3041 (*p_isr)->next = NULL;
3042
3043 switch (xisr->sadb_x_ipsecrequest_proto) {
3044 case IPPROTO_ESP:
3045 case IPPROTO_AH:
3046 case IPPROTO_IPCOMP:
3047 break;
3048 default:
3049 plog(LLV_ERROR, LOCATION, NULL,
3050 "invalid proto type: %u\n",
3051 xisr->sadb_x_ipsecrequest_proto);
3052 return -1;
3053 }
3054 (*p_isr)->saidx.proto = xisr->sadb_x_ipsecrequest_proto;
3055
3056 switch (xisr->sadb_x_ipsecrequest_mode) {
3057 case IPSEC_MODE_TRANSPORT:
3058 case IPSEC_MODE_TUNNEL:
3059 break;
3060 case IPSEC_MODE_ANY:
3061 default:
3062 plog(LLV_ERROR, LOCATION, NULL,
3063 "invalid mode: %u\n",
3064 xisr->sadb_x_ipsecrequest_mode);
3065 return -1;
3066 }
3067 (*p_isr)->saidx.mode = xisr->sadb_x_ipsecrequest_mode;
3068
3069 switch (xisr->sadb_x_ipsecrequest_level) {
3070 case IPSEC_LEVEL_DEFAULT:
3071 case IPSEC_LEVEL_USE:
3072 case IPSEC_LEVEL_REQUIRE:
3073 break;
3074 case IPSEC_LEVEL_UNIQUE:
3075 (*p_isr)->saidx.reqid =
3076 xisr->sadb_x_ipsecrequest_reqid;
3077 break;
3078
3079 default:
3080 plog(LLV_ERROR, LOCATION, NULL,
3081 "invalid level: %u\n",
3082 xisr->sadb_x_ipsecrequest_level);
3083 return -1;
3084 }
3085 (*p_isr)->level = xisr->sadb_x_ipsecrequest_level;
3086
3087 /* set IP addresses if there */
3088 if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) {
3089 struct sockaddr *paddr;
3090
3091 paddr = (struct sockaddr *)(xisr + 1);
3092 bcopy(paddr, &(*p_isr)->saidx.src,
3093 sysdep_sa_len(paddr));
3094
3095 paddr = (struct sockaddr *)((caddr_t)paddr
3096 + sysdep_sa_len(paddr));
3097 bcopy(paddr, &(*p_isr)->saidx.dst,
3098 sysdep_sa_len(paddr));
3099 }
3100
3101 (*p_isr)->sp = new;
3102
3103 /* initialization for the next. */
3104 p_isr = &(*p_isr)->next;
3105 tlen -= xisr->sadb_x_ipsecrequest_len;
3106
3107 /* validity check */
3108 if (tlen < 0) {
3109 plog(LLV_ERROR, LOCATION, NULL,
3110 "becoming tlen < 0\n");
3111 }
3112
3113 xisr = ALIGNED_CAST(struct sadb_x_ipsecrequest *)((caddr_t)xisr
3114 + xisr->sadb_x_ipsecrequest_len);
3115 }
3116 }
3117 break;
3118 default:
3119 plog(LLV_ERROR, LOCATION, NULL,
3120 "invalid policy type.\n");
3121 return -1;
3122 }
3123
3124 #ifdef HAVE_PFKEY_POLICY_PRIORITY
3125 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
3126 saddr + 1,
3127 daddr + 1,
3128 saddr->sadb_address_prefixlen,
3129 daddr->sadb_address_prefixlen,
3130 saddr->sadb_address_proto,
3131 xpl->sadb_x_policy_priority,
3132 &new->spidx);
3133 #else
3134 KEY_SETSECSPIDX(xpl->sadb_x_policy_dir,
3135 saddr + 1,
3136 daddr + 1,
3137 saddr->sadb_address_prefixlen,
3138 daddr->sadb_address_prefixlen,
3139 saddr->sadb_address_proto,
3140 &new->spidx);
3141 #endif
3142
3143 inssp(new);
3144
3145 return 0;
3146 }
3147
3148 /* proto/mode/src->dst spi */
3149 const char *
3150 sadbsecas2str(src, dst, proto, spi, mode)
3151 struct sockaddr_storage *src, *dst;
3152 int proto;
3153 u_int32_t spi;
3154 int mode;
3155 {
3156 static char buf[256];
3157 u_int doi_proto, doi_mode = 0;
3158 char *p;
3159 int blen, i;
3160
3161 doi_proto = pfkey2ipsecdoi_proto(proto);
3162 if (doi_proto == ~0)
3163 return NULL;
3164 if (mode) {
3165 doi_mode = pfkey2ipsecdoi_mode(mode);
3166 if (doi_mode == ~0)
3167 return NULL;
3168 }
3169
3170 blen = sizeof(buf) - 1;
3171 p = buf;
3172
3173 i = snprintf(p, blen, "%s%s%s ",
3174 s_ipsecdoi_proto(doi_proto),
3175 mode ? "/" : "",
3176 mode ? s_ipsecdoi_encmode(doi_mode) : "");
3177 if (i < 0 || i >= blen)
3178 return NULL;
3179 p += i;
3180 blen -= i;
3181
3182 i = snprintf(p, blen, "%s->", saddr2str((struct sockaddr *)src));
3183 if (i < 0 || i >= blen)
3184 return NULL;
3185 p += i;
3186 blen -= i;
3187
3188 i = snprintf(p, blen, "%s ", saddr2str((struct sockaddr *)dst));
3189 if (i < 0 || i >= blen)
3190 return NULL;
3191 p += i;
3192 blen -= i;
3193
3194 if (spi) {
3195 snprintf(p, blen, "spi=%lu(0x%lx)", (unsigned long)ntohl(spi),
3196 (unsigned long)ntohl(spi));
3197 }
3198
3199 return buf;
3200 }