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