]> git.saurik.com Git - apple/ipsec.git/blame - ipsec-tools/Common/pfkey.c
ipsec-34.0.2.tar.gz
[apple/ipsec.git] / ipsec-tools / Common / pfkey.c
CommitLineData
52b7d2ce
A
1/* $KAME: pfkey.c,v 1.47 2003/10/02 19:52:12 itojun Exp $ */
2
3/*
4 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 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#ifdef HAVE_CONFIG_H
33#include "config.h"
34#endif
35
36#include <sys/types.h>
37#include <sys/param.h>
38#include <sys/socket.h>
39#ifdef __APPLE__
40#include <System/net/pfkeyv2.h>
41#else
42#include <net/pfkeyv2.h>
43#endif
44#include <netinet/in.h>
45#ifdef HAVE_NETINET6_IPSEC
46# include <netinet6/ipsec.h>
47#else
48# include <netinet/ipsec.h>
49#endif
50
51#include <stdlib.h>
52#include <unistd.h>
53#include <string.h>
54#include <errno.h>
55#include <stdio.h>
56
57#include "ipsec_strerror.h"
58#include "libpfkey.h"
59
60#define CALLOC(size, cast) (cast)calloc(1, (size))
61
62static int findsupportedmap __P((int));
63static int setsupportedmap __P((struct sadb_supported *));
64static struct sadb_alg *findsupportedalg __P((u_int, u_int));
65#ifdef __APPLE__
66static int pfkey_send_x1 __P((int, u_int, u_int, u_int, struct sockaddr *,
67 struct sockaddr *, u_int32_t, u_int32_t, u_int, caddr_t,
68 u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int32_t,
69 u_int32_t, u_int32_t, u_int32_t, u_int16_t));
70#else
71static int pfkey_send_x1 __P((int, u_int, u_int, u_int, struct sockaddr *,
72 struct sockaddr *, u_int32_t, u_int32_t, u_int, caddr_t,
73 u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int32_t,
74 u_int32_t, u_int32_t, u_int32_t,
75 u_int8_t, u_int16_t, u_int16_t, struct sockaddr *, u_int16_t));
76#endif
77static int pfkey_send_x2 __P((int, u_int, u_int, u_int,
78 struct sockaddr *, struct sockaddr *, u_int32_t));
79static int pfkey_send_x3 __P((int, u_int, u_int));
80static int pfkey_send_x4 __P((int, u_int, struct sockaddr *, u_int,
81 struct sockaddr *, u_int, u_int, u_int64_t, u_int64_t,
82 char *, int, u_int32_t));
83static int pfkey_send_x5 __P((int, u_int, u_int32_t));
84
85static caddr_t pfkey_setsadbmsg __P((caddr_t, caddr_t, u_int, u_int,
86 u_int, u_int32_t, pid_t));
87#ifdef __APPLE__
88static caddr_t pfkey_setsadbsa __P((caddr_t, caddr_t, u_int32_t, u_int,
89 u_int, u_int, u_int32_t, u_int16_t));
90#else
91static caddr_t pfkey_setsadbsa __P((caddr_t, caddr_t, u_int32_t, u_int,
92 u_int, u_int, u_int32_t));
93#endif
94static caddr_t pfkey_setsadbaddr __P((caddr_t, caddr_t, u_int,
95 struct sockaddr *, u_int, u_int));
96static caddr_t pfkey_setsadbkey __P((caddr_t, caddr_t, u_int, caddr_t, u_int));
97static caddr_t pfkey_setsadblifetime __P((caddr_t, caddr_t, u_int, u_int32_t,
98 u_int32_t, u_int32_t, u_int32_t));
99static caddr_t pfkey_setsadbxsa2 __P((caddr_t, caddr_t, u_int32_t, u_int32_t));
100
101#ifdef SADB_X_EXT_NAT_T_TYPE
102static caddr_t pfkey_set_natt_type __P((caddr_t, caddr_t, u_int, u_int8_t));
103static caddr_t pfkey_set_natt_port __P((caddr_t, caddr_t, u_int, u_int16_t));
104#endif
105#ifdef SADB_X_EXT_NAT_T_FRAG
106static caddr_t pfkey_set_natt_frag __P((caddr_t, caddr_t, u_int, u_int16_t));
107#endif
108
109/*
110 * make and search supported algorithm structure.
111 */
112static struct sadb_supported *ipsec_supported[] = { NULL, NULL, NULL,
113#ifdef SADB_X_SATYPE_TCPSIGNATURE
114 NULL,
115#endif
116};
117
118static int supported_map[] = {
119 SADB_SATYPE_AH,
120 SADB_SATYPE_ESP,
121 SADB_X_SATYPE_IPCOMP,
122#ifdef SADB_X_SATYPE_TCPSIGNATURE
123 SADB_X_SATYPE_TCPSIGNATURE,
124#endif
125};
126
127static int
128findsupportedmap(satype)
129 int satype;
130{
131 int i;
132
133 for (i = 0; i < sizeof(supported_map)/sizeof(supported_map[0]); i++)
134 if (supported_map[i] == satype)
135 return i;
136 return -1;
137}
138
139static struct sadb_alg *
140findsupportedalg(satype, alg_id)
141 u_int satype, alg_id;
142{
143 int algno;
144 int tlen;
145 caddr_t p;
146
147 /* validity check */
148 algno = findsupportedmap((int)satype);
149 if (algno == -1) {
150 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
151 return NULL;
152 }
153 if (ipsec_supported[algno] == NULL) {
154 __ipsec_errcode = EIPSEC_DO_GET_SUPP_LIST;
155 return NULL;
156 }
157
158 tlen = ipsec_supported[algno]->sadb_supported_len
159 - sizeof(struct sadb_supported);
160 p = (void *)(ipsec_supported[algno] + 1);
161 while (tlen > 0) {
162 if (tlen < sizeof(struct sadb_alg)) {
163 /* invalid format */
164 break;
165 }
166 if (((struct sadb_alg *)(void *)p)->sadb_alg_id == alg_id)
167 return (void *)p;
168
169 tlen -= sizeof(struct sadb_alg);
170 p += sizeof(struct sadb_alg);
171 }
172
173 __ipsec_errcode = EIPSEC_NOT_SUPPORTED;
174 return NULL;
175}
176
177static int
178setsupportedmap(sup)
179 struct sadb_supported *sup;
180{
181 struct sadb_supported **ipsup;
182
183 switch (sup->sadb_supported_exttype) {
184 case SADB_EXT_SUPPORTED_AUTH:
185 ipsup = &ipsec_supported[findsupportedmap(SADB_SATYPE_AH)];
186 break;
187 case SADB_EXT_SUPPORTED_ENCRYPT:
188 ipsup = &ipsec_supported[findsupportedmap(SADB_SATYPE_ESP)];
189 break;
190 default:
191 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
192 return -1;
193 }
194
195 if (*ipsup)
196 free(*ipsup);
197
198 *ipsup = malloc((size_t)sup->sadb_supported_len);
199 if (!*ipsup) {
200 __ipsec_set_strerror(strerror(errno));
201 return -1;
202 }
203 memcpy(*ipsup, sup, (size_t)sup->sadb_supported_len);
204
205 return 0;
206}
207
208/*
209 * check key length against algorithm specified.
210 * This function is called with SADB_EXT_SUPPORTED_{AUTH,ENCRYPT} as the
211 * augument, and only calls to ipsec_check_keylen2();
212 * keylen is the unit of bit.
213 * OUT:
214 * -1: invalid.
215 * 0: valid.
216 */
217int
218ipsec_check_keylen(supported, alg_id, keylen)
219 u_int supported;
220 u_int alg_id;
221 u_int keylen;
222{
223 u_int satype;
224
225 /* validity check */
226 switch (supported) {
227 case SADB_EXT_SUPPORTED_AUTH:
228 satype = SADB_SATYPE_AH;
229 break;
230 case SADB_EXT_SUPPORTED_ENCRYPT:
231 satype = SADB_SATYPE_ESP;
232 break;
233 default:
234 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
235 return -1;
236 }
237
238 return ipsec_check_keylen2(satype, alg_id, keylen);
239}
240
241/*
242 * check key length against algorithm specified.
243 * satype is one of satype defined at pfkeyv2.h.
244 * keylen is the unit of bit.
245 * OUT:
246 * -1: invalid.
247 * 0: valid.
248 */
249int
250ipsec_check_keylen2(satype, alg_id, keylen)
251 u_int satype;
252 u_int alg_id;
253 u_int keylen;
254{
255 struct sadb_alg *alg;
256
257 alg = findsupportedalg(satype, alg_id);
258 if (!alg)
259 return -1;
260
261 if (keylen < alg->sadb_alg_minbits || keylen > alg->sadb_alg_maxbits) {
262 fprintf(stderr, "%d %d %d\n", keylen, alg->sadb_alg_minbits,
263 alg->sadb_alg_maxbits);
264 __ipsec_errcode = EIPSEC_INVAL_KEYLEN;
265 return -1;
266 }
267
268 __ipsec_errcode = EIPSEC_NO_ERROR;
269 return 0;
270}
271
272/*
273 * get max/min key length against algorithm specified.
274 * satype is one of satype defined at pfkeyv2.h.
275 * keylen is the unit of bit.
276 * OUT:
277 * -1: invalid.
278 * 0: valid.
279 */
280int
281ipsec_get_keylen(supported, alg_id, alg0)
282 u_int supported, alg_id;
283 struct sadb_alg *alg0;
284{
285 struct sadb_alg *alg;
286 u_int satype;
287
288 /* validity check */
289 if (!alg0) {
290 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
291 return -1;
292 }
293
294 switch (supported) {
295 case SADB_EXT_SUPPORTED_AUTH:
296 satype = SADB_SATYPE_AH;
297 break;
298 case SADB_EXT_SUPPORTED_ENCRYPT:
299 satype = SADB_SATYPE_ESP;
300 break;
301 default:
302 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
303 return -1;
304 }
305
306 alg = findsupportedalg(satype, alg_id);
307 if (!alg)
308 return -1;
309
310 memcpy(alg0, alg, sizeof(*alg0));
311
312 __ipsec_errcode = EIPSEC_NO_ERROR;
313 return 0;
314}
315
316/*
317 * set the rate for SOFT lifetime against HARD one.
318 * If rate is more than 100 or equal to zero, then set to 100.
319 */
320static u_int soft_lifetime_allocations_rate = PFKEY_SOFT_LIFETIME_RATE;
321static u_int soft_lifetime_bytes_rate = PFKEY_SOFT_LIFETIME_RATE;
322static u_int soft_lifetime_addtime_rate = PFKEY_SOFT_LIFETIME_RATE;
323static u_int soft_lifetime_usetime_rate = PFKEY_SOFT_LIFETIME_RATE;
324
325u_int
326pfkey_set_softrate(type, rate)
327 u_int type, rate;
328{
329 __ipsec_errcode = EIPSEC_NO_ERROR;
330
331 if (rate > 100 || rate == 0)
332 rate = 100;
333
334 switch (type) {
335 case SADB_X_LIFETIME_ALLOCATIONS:
336 soft_lifetime_allocations_rate = rate;
337 return 0;
338 case SADB_X_LIFETIME_BYTES:
339 soft_lifetime_bytes_rate = rate;
340 return 0;
341 case SADB_X_LIFETIME_ADDTIME:
342 soft_lifetime_addtime_rate = rate;
343 return 0;
344 case SADB_X_LIFETIME_USETIME:
345 soft_lifetime_usetime_rate = rate;
346 return 0;
347 }
348
349 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
350 return 1;
351}
352
353/*
354 * get current rate for SOFT lifetime against HARD one.
355 * ATTENTION: ~0 is returned if invalid type was passed.
356 */
357u_int
358pfkey_get_softrate(type)
359 u_int type;
360{
361 switch (type) {
362 case SADB_X_LIFETIME_ALLOCATIONS:
363 return soft_lifetime_allocations_rate;
364 case SADB_X_LIFETIME_BYTES:
365 return soft_lifetime_bytes_rate;
366 case SADB_X_LIFETIME_ADDTIME:
367 return soft_lifetime_addtime_rate;
368 case SADB_X_LIFETIME_USETIME:
369 return soft_lifetime_usetime_rate;
370 }
371
372 return (u_int)~0;
373}
374
375/*
376 * sending SADB_GETSPI message to the kernel.
377 * OUT:
378 * positive: success and return length sent.
379 * -1 : error occured, and set errno.
380 */
381int
382pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq)
383 int so;
384 u_int satype, mode;
385 struct sockaddr *src, *dst;
386 u_int32_t min, max, reqid, seq;
387{
388 struct sadb_msg *newmsg;
389 caddr_t ep;
390 int len;
391 int need_spirange = 0;
392 caddr_t p;
393 int plen;
394
395 /* validity check */
396 if (src == NULL || dst == NULL) {
397 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
398 return -1;
399 }
400 if (src->sa_family != dst->sa_family) {
401 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
402 return -1;
403 }
404 if (min > max || (min > 0 && min <= 255)) {
405 __ipsec_errcode = EIPSEC_INVAL_SPI;
406 return -1;
407 }
408 switch (src->sa_family) {
409 case AF_INET:
410 plen = sizeof(struct in_addr) << 3;
411 break;
412 case AF_INET6:
413 plen = sizeof(struct in6_addr) << 3;
414 break;
415 default:
416 __ipsec_errcode = EIPSEC_INVAL_FAMILY;
417 return -1;
418 }
419
420 /* create new sadb_msg to send. */
421 len = sizeof(struct sadb_msg)
422 + sizeof(struct sadb_x_sa2)
423 + sizeof(struct sadb_address)
424 + PFKEY_ALIGN8(sysdep_sa_len(src))
425 + sizeof(struct sadb_address)
426 + PFKEY_ALIGN8(sysdep_sa_len(dst));
427
428 if (min > 255 && max < (u_int)~0) {
429 need_spirange++;
430 len += sizeof(struct sadb_spirange);
431 }
432
433 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) {
434 __ipsec_set_strerror(strerror(errno));
435 return -1;
436 }
437 ep = ((caddr_t)(void *)newmsg) + len;
438
439 p = pfkey_setsadbmsg((void *)newmsg, ep, SADB_GETSPI,
440 (u_int)len, satype, seq, getpid());
441 if (!p) {
442 free(newmsg);
443 return -1;
444 }
445
446 p = pfkey_setsadbxsa2(p, ep, mode, reqid);
447 if (!p) {
448 free(newmsg);
449 return -1;
450 }
451
452 /* set sadb_address for source */
453 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, (u_int)plen,
454 IPSEC_ULPROTO_ANY);
455 if (!p) {
456 free(newmsg);
457 return -1;
458 }
459
460 /* set sadb_address for destination */
461 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, (u_int)plen,
462 IPSEC_ULPROTO_ANY);
463 if (!p) {
464 free(newmsg);
465 return -1;
466 }
467
468 /* proccessing spi range */
469 if (need_spirange) {
470 struct sadb_spirange spirange;
471
472 if (p + sizeof(spirange) > ep) {
473 free(newmsg);
474 return -1;
475 }
476
477 memset(&spirange, 0, sizeof(spirange));
478 spirange.sadb_spirange_len = PFKEY_UNIT64(sizeof(spirange));
479 spirange.sadb_spirange_exttype = SADB_EXT_SPIRANGE;
480 spirange.sadb_spirange_min = min;
481 spirange.sadb_spirange_max = max;
482
483 memcpy(p, &spirange, sizeof(spirange));
484
485 p += sizeof(spirange);
486 }
487 if (p != ep) {
488 free(newmsg);
489 return -1;
490 }
491
492 /* send message */
493 len = pfkey_send(so, newmsg, len);
494 free(newmsg);
495
496 if (len < 0)
497 return -1;
498
499 __ipsec_errcode = EIPSEC_NO_ERROR;
500 return len;
501}
502
503
504#ifdef __APPLE__
505/*
506 * sending SADB_UPDATE message to the kernel.
507 * The length of key material is a_keylen + e_keylen.
508 * OUT:
509 * positive: success and return length sent.
510 * -1 : error occured, and set errno.
511 */
512int
513pfkey_send_update(so, satype, mode, src, dst, spi, reqid, wsize,
514 keymat, e_type, e_keylen, a_type, a_keylen, flags,
515 l_alloc, l_bytes, l_addtime, l_usetime, seq, port)
516 int so;
517 u_int satype, mode, wsize;
518 struct sockaddr *src, *dst;
519 u_int32_t spi, reqid;
520 caddr_t keymat;
521 u_int e_type, e_keylen, a_type, a_keylen, flags;
522 u_int32_t l_alloc;
523 u_int64_t l_bytes, l_addtime, l_usetime;
524 u_int32_t seq;
525 u_int16_t port;
526{
527 int len;
528 if ((len = pfkey_send_x1(so, SADB_UPDATE, satype, mode, src, dst, spi,
529 reqid, wsize,
530 keymat, e_type, e_keylen, a_type, a_keylen, flags,
531 l_alloc, (u_int)l_bytes, (u_int)l_addtime,
532 (u_int)l_usetime, seq, port)) < 0)
533 return -1;
534
535 return len;
536}
537
538
539/*
540 * sending SADB_ADD message to the kernel.
541 * The length of key material is a_keylen + e_keylen.
542 * OUT:
543 * positive: success and return length sent.
544 * -1 : error occured, and set errno.
545 */
546int
547pfkey_send_add(so, satype, mode, src, dst, spi, reqid, wsize,
548 keymat, e_type, e_keylen, a_type, a_keylen, flags,
549 l_alloc, l_bytes, l_addtime, l_usetime, seq, port)
550 int so;
551 u_int satype, mode, wsize;
552 struct sockaddr *src, *dst;
553 u_int32_t spi, reqid;
554 caddr_t keymat;
555 u_int e_type, e_keylen, a_type, a_keylen, flags;
556 u_int32_t l_alloc;
557 u_int64_t l_bytes, l_addtime, l_usetime;
558 u_int32_t seq;
559 u_int16_t port;
560{
561 int len;
562 if ((len = pfkey_send_x1(so, SADB_ADD, satype, mode, src, dst, spi,
563 reqid, wsize,
564 keymat, e_type, e_keylen, a_type, a_keylen, flags,
565 l_alloc, (u_int)l_bytes, (u_int)l_addtime,
566 (u_int)l_usetime, seq, port)) < 0)
567 return -1;
568
569 return len;
570}
571
572
573#else /* __APPLE__ */
574
575/*
576 * sending SADB_UPDATE message to the kernel.
577 * The length of key material is a_keylen + e_keylen.
578 * OUT:
579 * positive: success and return length sent.
580 * -1 : error occured, and set errno.
581 */
582int
583pfkey_send_update(so, satype, mode, src, dst, spi, reqid, wsize,
584 keymat, e_type, e_keylen, a_type, a_keylen, flags,
585 l_alloc, l_bytes, l_addtime, l_usetime, seq)
586 int so;
587 u_int satype, mode, wsize;
588 struct sockaddr *src, *dst;
589 u_int32_t spi, reqid;
590 caddr_t keymat;
591 u_int e_type, e_keylen, a_type, a_keylen, flags;
592 u_int32_t l_alloc;
593 u_int64_t l_bytes, l_addtime, l_usetime;
594 u_int32_t seq;
595{
596 int len;
597 if ((len = pfkey_send_x1(so, SADB_UPDATE, satype, mode, src, dst, spi,
598 reqid, wsize,
599 keymat, e_type, e_keylen, a_type, a_keylen, flags,
600 l_alloc, (u_int)l_bytes, (u_int)l_addtime,
601 (u_int)l_usetime, seq, 0, 0, 0, NULL, 0)) < 0)
602 return -1;
603
604 return len;
605}
606
607#ifdef SADB_X_EXT_NAT_T_TYPE
608int
609pfkey_send_update_nat(so, satype, mode, src, dst, spi, reqid, wsize,
610 keymat, e_type, e_keylen, a_type, a_keylen, flags,
611 l_alloc, l_bytes, l_addtime, l_usetime, seq,
612 l_natt_type, l_natt_sport, l_natt_dport, l_natt_oa,
613 l_natt_frag)
614 int so;
615 u_int satype, mode, wsize;
616 struct sockaddr *src, *dst;
617 u_int32_t spi, reqid;
618 caddr_t keymat;
619 u_int e_type, e_keylen, a_type, a_keylen, flags;
620 u_int32_t l_alloc;
621 u_int64_t l_bytes, l_addtime, l_usetime;
622 u_int32_t seq;
623 u_int8_t l_natt_type;
624 u_int16_t l_natt_sport, l_natt_dport;
625 struct sockaddr *l_natt_oa;
626 u_int16_t l_natt_frag;
627{
628 int len;
629 if ((len = pfkey_send_x1(so, SADB_UPDATE, satype, mode, src, dst, spi,
630 reqid, wsize,
631 keymat, e_type, e_keylen, a_type, a_keylen, flags,
632 l_alloc, (u_int)l_bytes, (u_int)l_addtime,
633 (u_int)l_usetime, seq, l_natt_type, l_natt_sport,
634 l_natt_dport, l_natt_oa, l_natt_frag)) < 0)
635 return -1;
636
637 return len;
638}
639#endif
640
641/*
642 * sending SADB_ADD message to the kernel.
643 * The length of key material is a_keylen + e_keylen.
644 * OUT:
645 * positive: success and return length sent.
646 * -1 : error occured, and set errno.
647 */
648int
649pfkey_send_add(so, satype, mode, src, dst, spi, reqid, wsize,
650 keymat, e_type, e_keylen, a_type, a_keylen, flags,
651 l_alloc, l_bytes, l_addtime, l_usetime, seq)
652 int so;
653 u_int satype, mode, wsize;
654 struct sockaddr *src, *dst;
655 u_int32_t spi, reqid;
656 caddr_t keymat;
657 u_int e_type, e_keylen, a_type, a_keylen, flags;
658 u_int32_t l_alloc;
659 u_int64_t l_bytes, l_addtime, l_usetime;
660 u_int32_t seq;
661{
662 int len;
663 if ((len = pfkey_send_x1(so, SADB_ADD, satype, mode, src, dst, spi,
664 reqid, wsize,
665 keymat, e_type, e_keylen, a_type, a_keylen, flags,
666 l_alloc, (u_int)l_bytes, (u_int)l_addtime,
667 (u_int)l_usetime, seq, 0, 0, 0, NULL, 0)) < 0)
668 return -1;
669
670 return len;
671}
672
673#ifdef SADB_X_EXT_NAT_T_TYPE
674int
675pfkey_send_add_nat(so, satype, mode, src, dst, spi, reqid, wsize,
676 keymat, e_type, e_keylen, a_type, a_keylen, flags,
677 l_alloc, l_bytes, l_addtime, l_usetime, seq,
678 l_natt_type, l_natt_sport, l_natt_dport, l_natt_oa,
679 l_natt_frag)
680 int so;
681 u_int satype, mode, wsize;
682 struct sockaddr *src, *dst;
683 u_int32_t spi, reqid;
684 caddr_t keymat;
685 u_int e_type, e_keylen, a_type, a_keylen, flags;
686 u_int32_t l_alloc;
687 u_int64_t l_bytes, l_addtime, l_usetime;
688 u_int32_t seq;
689 u_int8_t l_natt_type;
690 u_int16_t l_natt_sport, l_natt_dport;
691 struct sockaddr *l_natt_oa;
692 u_int16_t l_natt_frag;
693{
694 int len;
695 if ((len = pfkey_send_x1(so, SADB_ADD, satype, mode, src, dst, spi,
696 reqid, wsize,
697 keymat, e_type, e_keylen, a_type, a_keylen, flags,
698 l_alloc, (u_int)l_bytes, (u_int)l_addtime,
699 (u_int)l_usetime, seq, l_natt_type, l_natt_sport,
700 l_natt_dport, l_natt_oa, l_natt_frag)) < 0)
701 return -1;
702
703 return len;
704}
705#endif
706#endif /* __APPLE__ */
707
708/*
709 * sending SADB_DELETE message to the kernel.
710 * OUT:
711 * positive: success and return length sent.
712 * -1 : error occured, and set errno.
713 */
714int
715pfkey_send_delete(so, satype, mode, src, dst, spi)
716 int so;
717 u_int satype, mode;
718 struct sockaddr *src, *dst;
719 u_int32_t spi;
720{
721 int len;
722 if ((len = pfkey_send_x2(so, SADB_DELETE, satype, mode, src, dst, spi)) < 0)
723 return -1;
724
725 return len;
726}
727
728/*
729 * sending SADB_DELETE without spi to the kernel. This is
730 * the "delete all" request (an extension also present in
731 * Solaris).
732 *
733 * OUT:
734 * positive: success and return length sent
735 * -1 : error occured, and set errno
736 */
737/*ARGSUSED*/
738int
739pfkey_send_delete_all(so, satype, mode, src, dst)
740 int so;
741 u_int satype, mode;
742 struct sockaddr *src, *dst;
743{
744 struct sadb_msg *newmsg;
745 int len;
746 caddr_t p;
747 int plen;
748 caddr_t ep;
749
750 /* validity check */
751 if (src == NULL || dst == NULL) {
752 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
753 return -1;
754 }
755 if (src->sa_family != dst->sa_family) {
756 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
757 return -1;
758 }
759 switch (src->sa_family) {
760 case AF_INET:
761 plen = sizeof(struct in_addr) << 3;
762 break;
763 case AF_INET6:
764 plen = sizeof(struct in6_addr) << 3;
765 break;
766 default:
767 __ipsec_errcode = EIPSEC_INVAL_FAMILY;
768 return -1;
769 }
770
771 /* create new sadb_msg to reply. */
772 len = sizeof(struct sadb_msg)
773 + sizeof(struct sadb_address)
774 + PFKEY_ALIGN8(sysdep_sa_len(src))
775 + sizeof(struct sadb_address)
776 + PFKEY_ALIGN8(sysdep_sa_len(dst));
777
778 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) {
779 __ipsec_set_strerror(strerror(errno));
780 return -1;
781 }
782 ep = ((caddr_t)(void *)newmsg) + len;
783
784 p = pfkey_setsadbmsg((void *)newmsg, ep, SADB_DELETE, (u_int)len,
785 satype, 0, getpid());
786 if (!p) {
787 free(newmsg);
788 return -1;
789 }
790 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, (u_int)plen,
791 IPSEC_ULPROTO_ANY);
792 if (!p) {
793 free(newmsg);
794 return -1;
795 }
796 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, (u_int)plen,
797 IPSEC_ULPROTO_ANY);
798 if (!p || p != ep) {
799 free(newmsg);
800 return -1;
801 }
802
803 /* send message */
804 len = pfkey_send(so, newmsg, len);
805 free(newmsg);
806
807 if (len < 0)
808 return -1;
809
810 __ipsec_errcode = EIPSEC_NO_ERROR;
811 return len;
812}
813
814/*
815 * sending SADB_GET message to the kernel.
816 * OUT:
817 * positive: success and return length sent.
818 * -1 : error occured, and set errno.
819 */
820int
821pfkey_send_get(so, satype, mode, src, dst, spi)
822 int so;
823 u_int satype, mode;
824 struct sockaddr *src, *dst;
825 u_int32_t spi;
826{
827 int len;
828 if ((len = pfkey_send_x2(so, SADB_GET, satype, mode, src, dst, spi)) < 0)
829 return -1;
830
831 return len;
832}
833
834/*
835 * sending SADB_REGISTER message to the kernel.
836 * OUT:
837 * positive: success and return length sent.
838 * -1 : error occured, and set errno.
839 */
840int
841pfkey_send_register(so, satype)
842 int so;
843 u_int satype;
844{
845 int len, algno;
846
847 if (satype == PF_UNSPEC) {
848 for (algno = 0;
849 algno < sizeof(supported_map)/sizeof(supported_map[0]);
850 algno++) {
851 if (ipsec_supported[algno]) {
852 free(ipsec_supported[algno]);
853 ipsec_supported[algno] = NULL;
854 }
855 }
856 } else {
857 algno = findsupportedmap((int)satype);
858 if (algno == -1) {
859 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
860 return -1;
861 }
862
863 if (ipsec_supported[algno]) {
864 free(ipsec_supported[algno]);
865 ipsec_supported[algno] = NULL;
866 }
867 }
868
869 if ((len = pfkey_send_x3(so, SADB_REGISTER, satype)) < 0)
870 return -1;
871
872 return len;
873}
874
875/*
876 * receiving SADB_REGISTER message from the kernel, and copy buffer for
877 * sadb_supported returned into ipsec_supported.
878 * OUT:
879 * 0: success and return length sent.
880 * -1: error occured, and set errno.
881 */
882int
883pfkey_recv_register(so)
884 int so;
885{
886 pid_t pid = getpid();
887 struct sadb_msg *newmsg;
888 int error = -1;
889
890 /* receive message */
891 for (;;) {
892 if ((newmsg = pfkey_recv(so)) == NULL)
893 return -1;
894 if (newmsg->sadb_msg_type == SADB_REGISTER &&
895 newmsg->sadb_msg_pid == pid)
896 break;
897 free(newmsg);
898 }
899
900 /* check and fix */
901 newmsg->sadb_msg_len = PFKEY_UNUNIT64(newmsg->sadb_msg_len);
902
903 error = pfkey_set_supported(newmsg, newmsg->sadb_msg_len);
904 free(newmsg);
905
906 if (error == 0)
907 __ipsec_errcode = EIPSEC_NO_ERROR;
908
909 return error;
910}
911
912/*
913 * receiving SADB_REGISTER message from the kernel, and copy buffer for
914 * sadb_supported returned into ipsec_supported.
915 * NOTE: sadb_msg_len must be host order.
916 * IN:
917 * tlen: msg length, it's to makeing sure.
918 * OUT:
919 * 0: success and return length sent.
920 * -1: error occured, and set errno.
921 */
922int
923pfkey_set_supported(msg, tlen)
924 struct sadb_msg *msg;
925 int tlen;
926{
927 struct sadb_supported *sup;
928 caddr_t p;
929 caddr_t ep;
930
931 /* validity */
932 if (msg->sadb_msg_len != tlen) {
933 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
934 return -1;
935 }
936
937 p = (void *)msg;
938 ep = p + tlen;
939
940 p += sizeof(struct sadb_msg);
941
942 while (p < ep) {
943 sup = (void *)p;
944 if (ep < p + sizeof(*sup) ||
945 PFKEY_EXTLEN(sup) < sizeof(*sup) ||
946 ep < p + sup->sadb_supported_len) {
947 /* invalid format */
948 break;
949 }
950
951 switch (sup->sadb_supported_exttype) {
952 case SADB_EXT_SUPPORTED_AUTH:
953 case SADB_EXT_SUPPORTED_ENCRYPT:
954 break;
955 default:
956 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
957 return -1;
958 }
959
960 /* fixed length */
961 sup->sadb_supported_len = PFKEY_EXTLEN(sup);
962
963 /* set supported map */
964 if (setsupportedmap(sup) != 0)
965 return -1;
966
967 p += sup->sadb_supported_len;
968 }
969
970 if (p != ep) {
971 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
972 return -1;
973 }
974
975 __ipsec_errcode = EIPSEC_NO_ERROR;
976
977 return 0;
978}
979
980/*
981 * sending SADB_FLUSH message to the kernel.
982 * OUT:
983 * positive: success and return length sent.
984 * -1 : error occured, and set errno.
985 */
986int
987pfkey_send_flush(so, satype)
988 int so;
989 u_int satype;
990{
991 int len;
992
993 if ((len = pfkey_send_x3(so, SADB_FLUSH, satype)) < 0)
994 return -1;
995
996 return len;
997}
998
999/*
1000 * sending SADB_DUMP message to the kernel.
1001 * OUT:
1002 * positive: success and return length sent.
1003 * -1 : error occured, and set errno.
1004 */
1005int
1006pfkey_send_dump(so, satype)
1007 int so;
1008 u_int satype;
1009{
1010 int len;
1011
1012 if ((len = pfkey_send_x3(so, SADB_DUMP, satype)) < 0)
1013 return -1;
1014
1015 return len;
1016}
1017
1018/*
1019 * sending SADB_X_PROMISC message to the kernel.
1020 * NOTE that this function handles promisc mode toggle only.
1021 * IN:
1022 * flag: set promisc off if zero, set promisc on if non-zero.
1023 * OUT:
1024 * positive: success and return length sent.
1025 * -1 : error occured, and set errno.
1026 * 0 : error occured, and set errno.
1027 * others: a pointer to new allocated buffer in which supported
1028 * algorithms is.
1029 */
1030int
1031pfkey_send_promisc_toggle(so, flag)
1032 int so;
1033 int flag;
1034{
1035 int len;
1036
1037 if ((len = pfkey_send_x3(so, SADB_X_PROMISC,
1038 (u_int)(flag ? 1 : 0))) < 0)
1039 return -1;
1040
1041 return len;
1042}
1043
1044/*
1045 * sending SADB_X_SPDADD message to the kernel.
1046 * OUT:
1047 * positive: success and return length sent.
1048 * -1 : error occured, and set errno.
1049 */
1050int
1051pfkey_send_spdadd(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
1052 int so;
1053 struct sockaddr *src, *dst;
1054 u_int prefs, prefd, proto;
1055 caddr_t policy;
1056 int policylen;
1057 u_int32_t seq;
1058{
1059 int len;
1060
1061 if ((len = pfkey_send_x4(so, SADB_X_SPDADD,
1062 src, prefs, dst, prefd, proto,
1063 (u_int64_t)0, (u_int64_t)0,
1064 policy, policylen, seq)) < 0)
1065 return -1;
1066
1067 return len;
1068}
1069
1070/*
1071 * sending SADB_X_SPDADD message to the kernel.
1072 * OUT:
1073 * positive: success and return length sent.
1074 * -1 : error occured, and set errno.
1075 */
1076int
1077pfkey_send_spdadd2(so, src, prefs, dst, prefd, proto, ltime, vtime,
1078 policy, policylen, seq)
1079 int so;
1080 struct sockaddr *src, *dst;
1081 u_int prefs, prefd, proto;
1082 u_int64_t ltime, vtime;
1083 caddr_t policy;
1084 int policylen;
1085 u_int32_t seq;
1086{
1087 int len;
1088
1089 if ((len = pfkey_send_x4(so, SADB_X_SPDADD,
1090 src, prefs, dst, prefd, proto,
1091 ltime, vtime,
1092 policy, policylen, seq)) < 0)
1093 return -1;
1094
1095 return len;
1096}
1097
1098/*
1099 * sending SADB_X_SPDUPDATE message to the kernel.
1100 * OUT:
1101 * positive: success and return length sent.
1102 * -1 : error occured, and set errno.
1103 */
1104int
1105pfkey_send_spdupdate(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
1106 int so;
1107 struct sockaddr *src, *dst;
1108 u_int prefs, prefd, proto;
1109 caddr_t policy;
1110 int policylen;
1111 u_int32_t seq;
1112{
1113 int len;
1114
1115 if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE,
1116 src, prefs, dst, prefd, proto,
1117 (u_int64_t)0, (u_int64_t)0,
1118 policy, policylen, seq)) < 0)
1119 return -1;
1120
1121 return len;
1122}
1123
1124/*
1125 * sending SADB_X_SPDUPDATE message to the kernel.
1126 * OUT:
1127 * positive: success and return length sent.
1128 * -1 : error occured, and set errno.
1129 */
1130int
1131pfkey_send_spdupdate2(so, src, prefs, dst, prefd, proto, ltime, vtime,
1132 policy, policylen, seq)
1133 int so;
1134 struct sockaddr *src, *dst;
1135 u_int prefs, prefd, proto;
1136 u_int64_t ltime, vtime;
1137 caddr_t policy;
1138 int policylen;
1139 u_int32_t seq;
1140{
1141 int len;
1142
1143 if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE,
1144 src, prefs, dst, prefd, proto,
1145 ltime, vtime,
1146 policy, policylen, seq)) < 0)
1147 return -1;
1148
1149 return len;
1150}
1151
1152/*
1153 * sending SADB_X_SPDDELETE message to the kernel.
1154 * OUT:
1155 * positive: success and return length sent.
1156 * -1 : error occured, and set errno.
1157 */
1158int
1159pfkey_send_spddelete(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
1160 int so;
1161 struct sockaddr *src, *dst;
1162 u_int prefs, prefd, proto;
1163 caddr_t policy;
1164 int policylen;
1165 u_int32_t seq;
1166{
1167 int len;
1168
1169 if (policylen != sizeof(struct sadb_x_policy)) {
1170 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1171 return -1;
1172 }
1173
1174 if ((len = pfkey_send_x4(so, SADB_X_SPDDELETE,
1175 src, prefs, dst, prefd, proto,
1176 (u_int64_t)0, (u_int64_t)0,
1177 policy, policylen, seq)) < 0)
1178 return -1;
1179
1180 return len;
1181}
1182
1183/*
1184 * sending SADB_X_SPDDELETE message to the kernel.
1185 * OUT:
1186 * positive: success and return length sent.
1187 * -1 : error occured, and set errno.
1188 */
1189int
1190pfkey_send_spddelete2(so, spid)
1191 int so;
1192 u_int32_t spid;
1193{
1194 int len;
1195
1196 if ((len = pfkey_send_x5(so, SADB_X_SPDDELETE2, spid)) < 0)
1197 return -1;
1198
1199 return len;
1200}
1201
1202/*
1203 * sending SADB_X_SPDGET message to the kernel.
1204 * OUT:
1205 * positive: success and return length sent.
1206 * -1 : error occured, and set errno.
1207 */
1208int
1209pfkey_send_spdget(so, spid)
1210 int so;
1211 u_int32_t spid;
1212{
1213 int len;
1214
1215 if ((len = pfkey_send_x5(so, SADB_X_SPDGET, spid)) < 0)
1216 return -1;
1217
1218 return len;
1219}
1220
1221/*
1222 * sending SADB_X_SPDSETIDX message to the kernel.
1223 * OUT:
1224 * positive: success and return length sent.
1225 * -1 : error occured, and set errno.
1226 */
1227int
1228pfkey_send_spdsetidx(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
1229 int so;
1230 struct sockaddr *src, *dst;
1231 u_int prefs, prefd, proto;
1232 caddr_t policy;
1233 int policylen;
1234 u_int32_t seq;
1235{
1236 int len;
1237
1238 if (policylen != sizeof(struct sadb_x_policy)) {
1239 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1240 return -1;
1241 }
1242
1243 if ((len = pfkey_send_x4(so, SADB_X_SPDSETIDX,
1244 src, prefs, dst, prefd, proto,
1245 (u_int64_t)0, (u_int64_t)0,
1246 policy, policylen, seq)) < 0)
1247 return -1;
1248
1249 return len;
1250}
1251
1252/*
1253 * sending SADB_SPDFLUSH message to the kernel.
1254 * OUT:
1255 * positive: success and return length sent.
1256 * -1 : error occured, and set errno.
1257 */
1258int
1259pfkey_send_spdflush(so)
1260 int so;
1261{
1262 int len;
1263
1264 if ((len = pfkey_send_x3(so, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC)) < 0)
1265 return -1;
1266
1267 return len;
1268}
1269
1270/*
1271 * sending SADB_SPDDUMP message to the kernel.
1272 * OUT:
1273 * positive: success and return length sent.
1274 * -1 : error occured, and set errno.
1275 */
1276int
1277pfkey_send_spddump(so)
1278 int so;
1279{
1280 int len;
1281
1282 if ((len = pfkey_send_x3(so, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC)) < 0)
1283 return -1;
1284
1285 return len;
1286}
1287
1288#ifdef __APPLE__
1289/* sending SADB_ADD or SADB_UPDATE message to the kernel */
1290static int
1291pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize,
1292 keymat, e_type, e_keylen, a_type, a_keylen, flags,
1293 l_alloc, l_bytes, l_addtime, l_usetime, seq, port)
1294 int so;
1295 u_int type, satype, mode;
1296 struct sockaddr *src, *dst;
1297 u_int32_t spi, reqid;
1298 u_int wsize;
1299 caddr_t keymat;
1300 u_int e_type, e_keylen, a_type, a_keylen, flags;
1301 u_int32_t l_alloc, l_bytes, l_addtime, l_usetime, seq;
1302 u_int16_t port;
1303{
1304 struct sadb_msg *newmsg;
1305 int len;
1306 caddr_t p;
1307 int plen;
1308 caddr_t ep;
1309
1310 /* validity check */
1311 if (src == NULL || dst == NULL) {
1312 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1313 return -1;
1314 }
1315 if (src->sa_family != dst->sa_family) {
1316 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
1317 return -1;
1318 }
1319 switch (src->sa_family) {
1320 case AF_INET:
1321 plen = sizeof(struct in_addr) << 3;
1322 break;
1323 case AF_INET6:
1324 plen = sizeof(struct in6_addr) << 3;
1325 break;
1326 default:
1327 __ipsec_errcode = EIPSEC_INVAL_FAMILY;
1328 return -1;
1329 }
1330
1331 switch (satype) {
1332 case SADB_SATYPE_ESP:
1333 if (e_type == SADB_EALG_NONE) {
1334 __ipsec_errcode = EIPSEC_NO_ALGS;
1335 return -1;
1336 }
1337 break;
1338 case SADB_SATYPE_AH:
1339 if (e_type != SADB_EALG_NONE) {
1340 __ipsec_errcode = EIPSEC_INVAL_ALGS;
1341 return -1;
1342 }
1343 if (a_type == SADB_AALG_NONE) {
1344 __ipsec_errcode = EIPSEC_NO_ALGS;
1345 return -1;
1346 }
1347 break;
1348 case SADB_X_SATYPE_IPCOMP:
1349 if (e_type == SADB_X_CALG_NONE) {
1350 __ipsec_errcode = EIPSEC_INVAL_ALGS;
1351 return -1;
1352 }
1353 if (a_type != SADB_AALG_NONE) {
1354 __ipsec_errcode = EIPSEC_NO_ALGS;
1355 return -1;
1356 }
1357 break;
1358#ifdef SADB_X_AALG_TCP_MD5
1359 case SADB_X_SATYPE_TCPSIGNATURE:
1360 if (e_type != SADB_EALG_NONE) {
1361 __ipsec_errcode = EIPSEC_INVAL_ALGS;
1362 return -1;
1363 }
1364 if (a_type != SADB_X_AALG_TCP_MD5) {
1365 __ipsec_errcode = EIPSEC_INVAL_ALGS;
1366 return -1;
1367 }
1368 break;
1369#endif
1370 default:
1371 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
1372 return -1;
1373 }
1374
1375 /* create new sadb_msg to reply. */
1376 len = sizeof(struct sadb_msg)
1377 + sizeof(struct sadb_sa_2)
1378 + sizeof(struct sadb_x_sa2)
1379 + sizeof(struct sadb_address)
1380 + PFKEY_ALIGN8(sysdep_sa_len(src))
1381 + sizeof(struct sadb_address)
1382 + PFKEY_ALIGN8(sysdep_sa_len(dst))
1383 + sizeof(struct sadb_lifetime)
1384 + sizeof(struct sadb_lifetime);
1385
1386 if (e_type != SADB_EALG_NONE && satype != SADB_X_SATYPE_IPCOMP)
1387 len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(e_keylen));
1388 if (a_type != SADB_AALG_NONE)
1389 len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(a_keylen));
1390
1391 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) {
1392 __ipsec_set_strerror(strerror(errno));
1393 return -1;
1394 }
1395 ep = ((caddr_t)(void *)newmsg) + len;
1396
1397 p = pfkey_setsadbmsg((void *)newmsg, ep, type, (u_int)len,
1398 satype, seq, getpid());
1399 if (!p) {
1400 free(newmsg);
1401 return -1;
1402 }
1403 p = pfkey_setsadbsa(p, ep, spi, wsize, a_type, e_type, flags, port);
1404 if (!p) {
1405 free(newmsg);
1406 return -1;
1407 }
1408 p = pfkey_setsadbxsa2(p, ep, mode, reqid);
1409 if (!p) {
1410 free(newmsg);
1411 return -1;
1412 }
1413 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, (u_int)plen,
1414 IPSEC_ULPROTO_ANY);
1415 if (!p) {
1416 free(newmsg);
1417 return -1;
1418 }
1419 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, (u_int)plen,
1420 IPSEC_ULPROTO_ANY);
1421 if (!p) {
1422 free(newmsg);
1423 return -1;
1424 }
1425
1426 if (e_type != SADB_EALG_NONE && satype != SADB_X_SATYPE_IPCOMP) {
1427 p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_ENCRYPT,
1428 keymat, e_keylen);
1429 if (!p) {
1430 free(newmsg);
1431 return -1;
1432 }
1433 }
1434 if (a_type != SADB_AALG_NONE) {
1435 p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_AUTH,
1436 keymat + e_keylen, a_keylen);
1437 if (!p) {
1438 free(newmsg);
1439 return -1;
1440 }
1441 }
1442
1443 /* set sadb_lifetime for destination */
1444 p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD,
1445 l_alloc, l_bytes, l_addtime, l_usetime);
1446 if (!p) {
1447 free(newmsg);
1448 return -1;
1449 }
1450 p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_SOFT,
1451 l_alloc, l_bytes, l_addtime, l_usetime);
1452 if (!p) {
1453 free(newmsg);
1454 return -1;
1455 }
1456
1457 if (p != ep) {
1458 free(newmsg);
1459 return -1;
1460 }
1461
1462 /* send message */
1463 len = pfkey_send(so, newmsg, len);
1464 free(newmsg);
1465
1466 if (len < 0)
1467 return -1;
1468
1469 __ipsec_errcode = EIPSEC_NO_ERROR;
1470 return len;
1471}
1472
1473#else /* __APPLE__ */
1474
1475/* sending SADB_ADD or SADB_UPDATE message to the kernel */
1476static int
1477pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize,
1478 keymat, e_type, e_keylen, a_type, a_keylen, flags,
1479 l_alloc, l_bytes, l_addtime, l_usetime, seq,
1480 l_natt_type, l_natt_sport, l_natt_dport, l_natt_oa,
1481 l_natt_frag)
1482 int so;
1483 u_int type, satype, mode;
1484 struct sockaddr *src, *dst, *l_natt_oa;
1485 u_int32_t spi, reqid;
1486 u_int wsize;
1487 caddr_t keymat;
1488 u_int e_type, e_keylen, a_type, a_keylen, flags;
1489 u_int32_t l_alloc, l_bytes, l_addtime, l_usetime, seq;
1490 u_int16_t l_natt_sport, l_natt_dport;
1491 u_int8_t l_natt_type;
1492 u_int16_t l_natt_frag;
1493{
1494 struct sadb_msg *newmsg;
1495 int len;
1496 caddr_t p;
1497 int plen;
1498 caddr_t ep;
1499
1500 /* validity check */
1501 if (src == NULL || dst == NULL) {
1502 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1503 return -1;
1504 }
1505 if (src->sa_family != dst->sa_family) {
1506 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
1507 return -1;
1508 }
1509 switch (src->sa_family) {
1510 case AF_INET:
1511 plen = sizeof(struct in_addr) << 3;
1512 break;
1513 case AF_INET6:
1514 plen = sizeof(struct in6_addr) << 3;
1515 break;
1516 default:
1517 __ipsec_errcode = EIPSEC_INVAL_FAMILY;
1518 return -1;
1519 }
1520
1521 switch (satype) {
1522 case SADB_SATYPE_ESP:
1523 if (e_type == SADB_EALG_NONE) {
1524 __ipsec_errcode = EIPSEC_NO_ALGS;
1525 return -1;
1526 }
1527 break;
1528 case SADB_SATYPE_AH:
1529 if (e_type != SADB_EALG_NONE) {
1530 __ipsec_errcode = EIPSEC_INVAL_ALGS;
1531 return -1;
1532 }
1533 if (a_type == SADB_AALG_NONE) {
1534 __ipsec_errcode = EIPSEC_NO_ALGS;
1535 return -1;
1536 }
1537 break;
1538 case SADB_X_SATYPE_IPCOMP:
1539 if (e_type == SADB_X_CALG_NONE) {
1540 __ipsec_errcode = EIPSEC_INVAL_ALGS;
1541 return -1;
1542 }
1543 if (a_type != SADB_AALG_NONE) {
1544 __ipsec_errcode = EIPSEC_NO_ALGS;
1545 return -1;
1546 }
1547 break;
1548#ifdef SADB_X_AALG_TCP_MD5
1549 case SADB_X_SATYPE_TCPSIGNATURE:
1550 if (e_type != SADB_EALG_NONE) {
1551 __ipsec_errcode = EIPSEC_INVAL_ALGS;
1552 return -1;
1553 }
1554 if (a_type != SADB_X_AALG_TCP_MD5) {
1555 __ipsec_errcode = EIPSEC_INVAL_ALGS;
1556 return -1;
1557 }
1558 break;
1559#endif
1560 default:
1561 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
1562 return -1;
1563 }
1564
1565 /* create new sadb_msg to reply. */
1566 len = sizeof(struct sadb_msg)
1567 + sizeof(struct sadb_sa)
1568 + sizeof(struct sadb_x_sa2)
1569 + sizeof(struct sadb_address)
1570 + PFKEY_ALIGN8(sysdep_sa_len(src))
1571 + sizeof(struct sadb_address)
1572 + PFKEY_ALIGN8(sysdep_sa_len(dst))
1573 + sizeof(struct sadb_lifetime)
1574 + sizeof(struct sadb_lifetime);
1575
1576 if (e_type != SADB_EALG_NONE && satype != SADB_X_SATYPE_IPCOMP)
1577 len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(e_keylen));
1578 if (a_type != SADB_AALG_NONE)
1579 len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(a_keylen));
1580
1581#ifdef SADB_X_EXT_NAT_T_TYPE
1582 /* add nat-t packets */
1583 if (l_natt_type) {
1584 switch(satype) {
1585 case SADB_SATYPE_ESP:
1586 case SADB_X_SATYPE_IPCOMP:
1587 break;
1588 default:
1589 __ipsec_errcode = EIPSEC_NO_ALGS;
1590 return -1;
1591 }
1592
1593 len += sizeof(struct sadb_x_nat_t_type);
1594 len += sizeof(struct sadb_x_nat_t_port);
1595 len += sizeof(struct sadb_x_nat_t_port);
1596 if (l_natt_oa)
1597 len += sizeof(struct sadb_address) +
1598 PFKEY_ALIGN8(sysdep_sa_len(l_natt_oa));
1599#ifdef SADB_X_EXT_NAT_T_FRAG
1600 if (l_natt_frag)
1601 len += sizeof(struct sadb_x_nat_t_frag);
1602#endif
1603 }
1604#endif
1605
1606 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) {
1607 __ipsec_set_strerror(strerror(errno));
1608 return -1;
1609 }
1610 ep = ((caddr_t)(void *)newmsg) + len;
1611
1612 p = pfkey_setsadbmsg((void *)newmsg, ep, type, (u_int)len,
1613 satype, seq, getpid());
1614 if (!p) {
1615 free(newmsg);
1616 return -1;
1617 }
1618 p = pfkey_setsadbsa(p, ep, spi, wsize, a_type, e_type, flags);
1619 if (!p) {
1620 free(newmsg);
1621 return -1;
1622 }
1623 p = pfkey_setsadbxsa2(p, ep, mode, reqid);
1624 if (!p) {
1625 free(newmsg);
1626 return -1;
1627 }
1628 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, (u_int)plen,
1629 IPSEC_ULPROTO_ANY);
1630 if (!p) {
1631 free(newmsg);
1632 return -1;
1633 }
1634 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, (u_int)plen,
1635 IPSEC_ULPROTO_ANY);
1636 if (!p) {
1637 free(newmsg);
1638 return -1;
1639 }
1640
1641 if (e_type != SADB_EALG_NONE && satype != SADB_X_SATYPE_IPCOMP) {
1642 p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_ENCRYPT,
1643 keymat, e_keylen);
1644 if (!p) {
1645 free(newmsg);
1646 return -1;
1647 }
1648 }
1649 if (a_type != SADB_AALG_NONE) {
1650 p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_AUTH,
1651 keymat + e_keylen, a_keylen);
1652 if (!p) {
1653 free(newmsg);
1654 return -1;
1655 }
1656 }
1657
1658 /* set sadb_lifetime for destination */
1659 p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD,
1660 l_alloc, l_bytes, l_addtime, l_usetime);
1661 if (!p) {
1662 free(newmsg);
1663 return -1;
1664 }
1665 p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_SOFT,
1666 l_alloc, l_bytes, l_addtime, l_usetime);
1667 if (!p) {
1668 free(newmsg);
1669 return -1;
1670 }
1671
1672#ifdef SADB_X_EXT_NAT_T_TYPE
1673 /* Add nat-t messages */
1674 if (l_natt_type) {
1675 p = pfkey_set_natt_type(p, ep, SADB_X_EXT_NAT_T_TYPE, l_natt_type);
1676 if (!p) {
1677 free(newmsg);
1678 return -1;
1679 }
1680
1681 p = pfkey_set_natt_port(p, ep, SADB_X_EXT_NAT_T_SPORT,
1682 l_natt_sport);
1683 if (!p) {
1684 free(newmsg);
1685 return -1;
1686 }
1687
1688 p = pfkey_set_natt_port(p, ep, SADB_X_EXT_NAT_T_DPORT,
1689 l_natt_dport);
1690 if (!p) {
1691 free(newmsg);
1692 return -1;
1693 }
1694
1695 if (l_natt_oa) {
1696 p = pfkey_setsadbaddr(p, ep, SADB_X_EXT_NAT_T_OA,
1697 l_natt_oa,
1698 (u_int)PFKEY_ALIGN8(sysdep_sa_len(l_natt_oa)),
1699 IPSEC_ULPROTO_ANY);
1700 if (!p) {
1701 free(newmsg);
1702 return -1;
1703 }
1704 }
1705
1706 if (l_natt_frag) {
1707#ifdef SADB_X_EXT_NAT_T_FRAG
1708 p = pfkey_set_natt_frag(p, ep, SADB_X_EXT_NAT_T_FRAG,
1709 l_natt_frag);
1710 if (!p) {
1711 free(newmsg);
1712 return -1;
1713 }
1714#endif
1715 }
1716 }
1717#endif
1718
1719 if (p != ep) {
1720 free(newmsg);
1721 return -1;
1722 }
1723
1724 /* send message */
1725 len = pfkey_send(so, newmsg, len);
1726 free(newmsg);
1727
1728 if (len < 0)
1729 return -1;
1730
1731 __ipsec_errcode = EIPSEC_NO_ERROR;
1732 return len;
1733}
1734#endif /* __APPLE__ */
1735
1736/* sending SADB_DELETE or SADB_GET message to the kernel */
1737/*ARGSUSED*/
1738static int
1739pfkey_send_x2(so, type, satype, mode, src, dst, spi)
1740 int so;
1741 u_int type, satype, mode;
1742 struct sockaddr *src, *dst;
1743 u_int32_t spi;
1744{
1745 struct sadb_msg *newmsg;
1746 int len;
1747 caddr_t p;
1748 int plen;
1749 caddr_t ep;
1750
1751 /* validity check */
1752 if (src == NULL || dst == NULL) {
1753 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1754 return -1;
1755 }
1756 if (src->sa_family != dst->sa_family) {
1757 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
1758 return -1;
1759 }
1760 switch (src->sa_family) {
1761 case AF_INET:
1762 plen = sizeof(struct in_addr) << 3;
1763 break;
1764 case AF_INET6:
1765 plen = sizeof(struct in6_addr) << 3;
1766 break;
1767 default:
1768 __ipsec_errcode = EIPSEC_INVAL_FAMILY;
1769 return -1;
1770 }
1771
1772 /* create new sadb_msg to reply. */
1773 len = sizeof(struct sadb_msg)
1774 + sizeof(struct sadb_sa)
1775 + sizeof(struct sadb_address)
1776 + PFKEY_ALIGN8(sysdep_sa_len(src))
1777 + sizeof(struct sadb_address)
1778 + PFKEY_ALIGN8(sysdep_sa_len(dst));
1779
1780 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) {
1781 __ipsec_set_strerror(strerror(errno));
1782 return -1;
1783 }
1784 ep = ((caddr_t)(void *)newmsg) + len;
1785
1786 p = pfkey_setsadbmsg((void *)newmsg, ep, type, (u_int)len, satype, 0,
1787 getpid());
1788 if (!p) {
1789 free(newmsg);
1790 return -1;
1791 }
1792#ifdef __APPLE__
1793 p = pfkey_setsadbsa(p, ep, spi, 0, 0, 0, 0, 0);
1794#else
1795 p = pfkey_setsadbsa(p, ep, spi, 0, 0, 0, 0);
1796#endif
1797 if (!p) {
1798 free(newmsg);
1799 return -1;
1800 }
1801 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, (u_int)plen,
1802 IPSEC_ULPROTO_ANY);
1803 if (!p) {
1804 free(newmsg);
1805 return -1;
1806 }
1807 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, (u_int)plen,
1808 IPSEC_ULPROTO_ANY);
1809 if (!p || p != ep) {
1810 free(newmsg);
1811 return -1;
1812 }
1813
1814 /* send message */
1815 len = pfkey_send(so, newmsg, len);
1816 free(newmsg);
1817
1818 if (len < 0)
1819 return -1;
1820
1821 __ipsec_errcode = EIPSEC_NO_ERROR;
1822 return len;
1823}
1824
1825/*
1826 * sending SADB_REGISTER, SADB_FLUSH, SADB_DUMP or SADB_X_PROMISC message
1827 * to the kernel
1828 */
1829static int
1830pfkey_send_x3(so, type, satype)
1831 int so;
1832 u_int type, satype;
1833{
1834 struct sadb_msg *newmsg;
1835 int len;
1836 caddr_t p;
1837 caddr_t ep;
1838
1839 /* validity check */
1840 switch (type) {
1841 case SADB_X_PROMISC:
1842 if (satype != 0 && satype != 1) {
1843 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
1844 return -1;
1845 }
1846 break;
1847 default:
1848 switch (satype) {
1849 case SADB_SATYPE_UNSPEC:
1850 case SADB_SATYPE_AH:
1851 case SADB_SATYPE_ESP:
1852 case SADB_X_SATYPE_IPCOMP:
1853#ifdef SADB_X_SATYPE_TCPSIGNATURE
1854 case SADB_X_SATYPE_TCPSIGNATURE:
1855#endif
1856 break;
1857 default:
1858 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
1859 return -1;
1860 }
1861 }
1862
1863 /* create new sadb_msg to send. */
1864 len = sizeof(struct sadb_msg);
1865
1866 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) {
1867 __ipsec_set_strerror(strerror(errno));
1868 return -1;
1869 }
1870 ep = ((caddr_t)(void *)newmsg) + len;
1871
1872 p = pfkey_setsadbmsg((void *)newmsg, ep, type, (u_int)len, satype, 0,
1873 getpid());
1874 if (!p || p != ep) {
1875 free(newmsg);
1876 return -1;
1877 }
1878
1879 /* send message */
1880 len = pfkey_send(so, newmsg, len);
1881 free(newmsg);
1882
1883 if (len < 0)
1884 return -1;
1885
1886 __ipsec_errcode = EIPSEC_NO_ERROR;
1887 return len;
1888}
1889
1890/* sending SADB_X_SPDADD message to the kernel */
1891static int
1892pfkey_send_x4(so, type, src, prefs, dst, prefd, proto,
1893 ltime, vtime, policy, policylen, seq)
1894 int so;
1895 struct sockaddr *src, *dst;
1896 u_int type, prefs, prefd, proto;
1897 u_int64_t ltime, vtime;
1898 char *policy;
1899 int policylen;
1900 u_int32_t seq;
1901{
1902 struct sadb_msg *newmsg;
1903 int len;
1904 caddr_t p;
1905 int plen;
1906 caddr_t ep;
1907
1908 /* validity check */
1909 if (src == NULL || dst == NULL) {
1910 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1911 return -1;
1912 }
1913 if (src->sa_family != dst->sa_family) {
1914 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
1915 return -1;
1916 }
1917
1918 switch (src->sa_family) {
1919 case AF_INET:
1920 plen = sizeof(struct in_addr) << 3;
1921 break;
1922 case AF_INET6:
1923 plen = sizeof(struct in6_addr) << 3;
1924 break;
1925 default:
1926 __ipsec_errcode = EIPSEC_INVAL_FAMILY;
1927 return -1;
1928 }
1929 if (prefs > plen || prefd > plen) {
1930 __ipsec_errcode = EIPSEC_INVAL_PREFIXLEN;
1931 return -1;
1932 }
1933
1934 /* create new sadb_msg to reply. */
1935 len = sizeof(struct sadb_msg)
1936 + sizeof(struct sadb_address)
1937 + PFKEY_ALIGN8(sysdep_sa_len(src))
1938 + sizeof(struct sadb_address)
1939 + PFKEY_ALIGN8(sysdep_sa_len(src))
1940 + sizeof(struct sadb_lifetime)
1941 + policylen;
1942
1943 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) {
1944 __ipsec_set_strerror(strerror(errno));
1945 return -1;
1946 }
1947 ep = ((caddr_t)(void *)newmsg) + len;
1948
1949 p = pfkey_setsadbmsg((void *)newmsg, ep, type, (u_int)len,
1950 SADB_SATYPE_UNSPEC, seq, getpid());
1951 if (!p) {
1952 free(newmsg);
1953 return -1;
1954 }
1955 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, prefs, proto);
1956 if (!p) {
1957 free(newmsg);
1958 return -1;
1959 }
1960 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, prefd, proto);
1961 if (!p) {
1962 free(newmsg);
1963 return -1;
1964 }
1965 p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD,
1966 0, 0, (u_int)ltime, (u_int)vtime);
1967 if (!p || p + policylen != ep) {
1968 free(newmsg);
1969 return -1;
1970 }
1971 memcpy(p, policy, (size_t)policylen);
1972
1973 /* send message */
1974 len = pfkey_send(so, newmsg, len);
1975 free(newmsg);
1976
1977 if (len < 0)
1978 return -1;
1979
1980 __ipsec_errcode = EIPSEC_NO_ERROR;
1981 return len;
1982}
1983
1984/* sending SADB_X_SPDGET or SADB_X_SPDDELETE message to the kernel */
1985static int
1986pfkey_send_x5(so, type, spid)
1987 int so;
1988 u_int type;
1989 u_int32_t spid;
1990{
1991 struct sadb_msg *newmsg;
1992 struct sadb_x_policy xpl;
1993 int len;
1994 caddr_t p;
1995 caddr_t ep;
1996
1997 /* create new sadb_msg to reply. */
1998 len = sizeof(struct sadb_msg)
1999 + sizeof(xpl);
2000
2001 if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) {
2002 __ipsec_set_strerror(strerror(errno));
2003 return -1;
2004 }
2005 ep = ((caddr_t)(void *)newmsg) + len;
2006
2007 p = pfkey_setsadbmsg((void *)newmsg, ep, type, (u_int)len,
2008 SADB_SATYPE_UNSPEC, 0, getpid());
2009 if (!p) {
2010 free(newmsg);
2011 return -1;
2012 }
2013
2014 if (p + sizeof(xpl) != ep) {
2015 free(newmsg);
2016 return -1;
2017 }
2018 memset(&xpl, 0, sizeof(xpl));
2019 xpl.sadb_x_policy_len = PFKEY_UNIT64(sizeof(xpl));
2020 xpl.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
2021 xpl.sadb_x_policy_id = spid;
2022 memcpy(p, &xpl, sizeof(xpl));
2023
2024 /* send message */
2025 len = pfkey_send(so, newmsg, len);
2026 free(newmsg);
2027
2028 if (len < 0)
2029 return -1;
2030
2031 __ipsec_errcode = EIPSEC_NO_ERROR;
2032 return len;
2033}
2034
2035/*
2036 * open a socket.
2037 * OUT:
2038 * -1: fail.
2039 * others : success and return value of socket.
2040 */
2041int
2042pfkey_open()
2043{
2044 int so;
2045 int bufsiz = 0; /* Max allowed by default */
2046 const unsigned long newbufk = 1536;
2047 unsigned long oldmax;
2048 size_t oldmaxsize = sizeof(oldmax);
2049 unsigned long newmax = newbufk * (1024 + 128);
2050
2051 if ((so = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) {
2052 __ipsec_set_strerror(strerror(errno));
2053 return -1;
2054 }
2055
2056 /*
2057 * This is a temporary workaround for KAME PR 154.
2058 * Don't really care even if it fails.
2059 */
2060 if (sysctlbyname("kern.ipc.maxsockbuf", &oldmax, &oldmaxsize, &newmax, sizeof(newmax)) != 0)
2061 bufsiz = 233016; /* Max allowed by default */
2062 else
2063 bufsiz = newbufk * 1024;
2064
2065 setsockopt(so, SOL_SOCKET, SO_SNDBUF, &bufsiz, sizeof(bufsiz));
2066 setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz));
2067
2068 if (bufsiz == newbufk * 1024)
2069 sysctlbyname("kern.ipc.maxsockbuf", NULL, NULL, &oldmax, oldmaxsize);
2070
2071 __ipsec_errcode = EIPSEC_NO_ERROR;
2072 return so;
2073}
2074
2075/*
2076 * close a socket.
2077 * OUT:
2078 * 0: success.
2079 * -1: fail.
2080 */
2081void
2082pfkey_close(so)
2083 int so;
2084{
2085 (void)close(so);
2086
2087 __ipsec_errcode = EIPSEC_NO_ERROR;
2088 return;
2089}
2090
2091/*
2092 * receive sadb_msg data, and return pointer to new buffer allocated.
2093 * Must free this buffer later.
2094 * OUT:
2095 * NULL : error occured.
2096 * others : a pointer to sadb_msg structure.
2097 *
2098 * XXX should be rewritten to pass length explicitly
2099 */
2100struct sadb_msg *
2101pfkey_recv(so)
2102 int so;
2103{
2104 struct sadb_msg buf, *newmsg;
2105 int len, reallen;
2106
2107 while ((len = recv(so, (void *)&buf, sizeof(buf), MSG_PEEK)) < 0) {
2108 if (errno == EINTR)
2109 continue;
2110 __ipsec_set_strerror(strerror(errno));
2111 return NULL;
2112 }
2113
2114 if (len < sizeof(buf)) {
2115 recv(so, (void *)&buf, sizeof(buf), 0);
2116 __ipsec_errcode = EIPSEC_MAX;
2117 return NULL;
2118 }
2119
2120 /* read real message */
2121 reallen = PFKEY_UNUNIT64(buf.sadb_msg_len);
2122 if ((newmsg = CALLOC((size_t)reallen, struct sadb_msg *)) == 0) {
2123 __ipsec_set_strerror(strerror(errno));
2124 return NULL;
2125 }
2126
2127 while ((len = recv(so, (void *)newmsg, (socklen_t)reallen, 0)) < 0) {
2128 if (errno == EINTR)
2129 continue;
2130 __ipsec_set_strerror(strerror(errno));
2131 free(newmsg);
2132 return NULL;
2133 }
2134
2135 if (len != reallen) {
2136 __ipsec_errcode = EIPSEC_SYSTEM_ERROR;
2137 free(newmsg);
2138 return NULL;
2139 }
2140
2141 /* don't trust what the kernel says, validate! */
2142 if (PFKEY_UNUNIT64(newmsg->sadb_msg_len) != len) {
2143 __ipsec_errcode = EIPSEC_SYSTEM_ERROR;
2144 free(newmsg);
2145 return NULL;
2146 }
2147
2148 __ipsec_errcode = EIPSEC_NO_ERROR;
2149 return newmsg;
2150}
2151
2152/*
2153 * send message to a socket.
2154 * OUT:
2155 * others: success and return length sent.
2156 * -1 : fail.
2157 */
2158int
2159pfkey_send(so, msg, len)
2160 int so;
2161 struct sadb_msg *msg;
2162 int len;
2163{
2164 if ((len = send(so, (void *)msg, (socklen_t)len, 0)) < 0) {
2165 __ipsec_set_strerror(strerror(errno));
2166 return -1;
2167 }
2168
2169 __ipsec_errcode = EIPSEC_NO_ERROR;
2170 return len;
2171}
2172
2173/*
2174 * %%% Utilities
2175 * NOTE: These functions are derived from netkey/key.c in KAME.
2176 */
2177/*
2178 * set the pointer to each header in this message buffer.
2179 * IN: msg: pointer to message buffer.
2180 * mhp: pointer to the buffer initialized like below:
2181 * caddr_t mhp[SADB_EXT_MAX + 1];
2182 * OUT: -1: invalid.
2183 * 0: valid.
2184 *
2185 * XXX should be rewritten to obtain length explicitly
2186 */
2187int
2188pfkey_align(msg, mhp)
2189 struct sadb_msg *msg;
2190 caddr_t *mhp;
2191{
2192 struct sadb_ext *ext;
2193 int i;
2194 caddr_t p;
2195 caddr_t ep; /* XXX should be passed from upper layer */
2196
2197 /* validity check */
2198 if (msg == NULL || mhp == NULL) {
2199 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
2200 return -1;
2201 }
2202
2203 /* initialize */
2204 for (i = 0; i < SADB_EXT_MAX + 1; i++)
2205 mhp[i] = NULL;
2206
2207 mhp[0] = (void *)msg;
2208
2209 /* initialize */
2210 p = (void *) msg;
2211 ep = p + PFKEY_UNUNIT64(msg->sadb_msg_len);
2212
2213 /* skip base header */
2214 p += sizeof(struct sadb_msg);
2215
2216 while (p < ep) {
2217 ext = (void *)p;
2218 if (ep < p + sizeof(*ext) || PFKEY_EXTLEN(ext) < sizeof(*ext) ||
2219 ep < p + PFKEY_EXTLEN(ext)) {
2220 /* invalid format */
2221 break;
2222 }
2223
2224 /* duplicate check */
2225 /* XXX Are there duplication either KEY_AUTH or KEY_ENCRYPT ?*/
2226 if (mhp[ext->sadb_ext_type] != NULL) {
2227 __ipsec_errcode = EIPSEC_INVAL_EXTTYPE;
2228 return -1;
2229 }
2230
2231 /* set pointer */
2232 switch (ext->sadb_ext_type) {
2233 case SADB_EXT_SA:
2234 case SADB_EXT_LIFETIME_CURRENT:
2235 case SADB_EXT_LIFETIME_HARD:
2236 case SADB_EXT_LIFETIME_SOFT:
2237 case SADB_EXT_ADDRESS_SRC:
2238 case SADB_EXT_ADDRESS_DST:
2239 case SADB_EXT_ADDRESS_PROXY:
2240 case SADB_EXT_KEY_AUTH:
2241 /* XXX should to be check weak keys. */
2242 case SADB_EXT_KEY_ENCRYPT:
2243 /* XXX should to be check weak keys. */
2244 case SADB_EXT_IDENTITY_SRC:
2245 case SADB_EXT_IDENTITY_DST:
2246 case SADB_EXT_SENSITIVITY:
2247 case SADB_EXT_PROPOSAL:
2248 case SADB_EXT_SUPPORTED_AUTH:
2249 case SADB_EXT_SUPPORTED_ENCRYPT:
2250 case SADB_EXT_SPIRANGE:
2251 case SADB_X_EXT_POLICY:
2252 case SADB_X_EXT_SA2:
2253#ifdef SADB_X_EXT_NAT_T_TYPE
2254 case SADB_X_EXT_NAT_T_TYPE:
2255 case SADB_X_EXT_NAT_T_SPORT:
2256 case SADB_X_EXT_NAT_T_DPORT:
2257 case SADB_X_EXT_NAT_T_OA:
2258#endif
2259#ifdef SADB_X_EXT_TAG
2260 case SADB_X_EXT_TAG:
2261#endif
2262#ifdef SADB_X_EXT_PACKET
2263 case SADB_X_EXT_PACKET:
2264#endif
2265
2266 mhp[ext->sadb_ext_type] = (void *)ext;
2267 break;
2268 default:
2269 __ipsec_errcode = EIPSEC_INVAL_EXTTYPE;
2270 return -1;
2271 }
2272
2273 p += PFKEY_EXTLEN(ext);
2274 }
2275
2276 if (p != ep) {
2277 __ipsec_errcode = EIPSEC_INVAL_SADBMSG;
2278 return -1;
2279 }
2280
2281 __ipsec_errcode = EIPSEC_NO_ERROR;
2282 return 0;
2283}
2284
2285/*
2286 * check basic usage for sadb_msg,
2287 * NOTE: This routine is derived from netkey/key.c in KAME.
2288 * IN: msg: pointer to message buffer.
2289 * mhp: pointer to the buffer initialized like below:
2290 *
2291 * caddr_t mhp[SADB_EXT_MAX + 1];
2292 *
2293 * OUT: -1: invalid.
2294 * 0: valid.
2295 */
2296int
2297pfkey_check(mhp)
2298 caddr_t *mhp;
2299{
2300 struct sadb_msg *msg;
2301
2302 /* validity check */
2303 if (mhp == NULL || mhp[0] == NULL) {
2304 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
2305 return -1;
2306 }
2307
2308 msg = (void *)mhp[0];
2309
2310 /* check version */
2311 if (msg->sadb_msg_version != PF_KEY_V2) {
2312 __ipsec_errcode = EIPSEC_INVAL_VERSION;
2313 return -1;
2314 }
2315
2316 /* check type */
2317 if (msg->sadb_msg_type > SADB_MAX) {
2318 __ipsec_errcode = EIPSEC_INVAL_MSGTYPE;
2319 return -1;
2320 }
2321
2322 /* check SA type */
2323 switch (msg->sadb_msg_satype) {
2324 case SADB_SATYPE_UNSPEC:
2325 switch (msg->sadb_msg_type) {
2326 case SADB_GETSPI:
2327 case SADB_UPDATE:
2328 case SADB_ADD:
2329 case SADB_DELETE:
2330 case SADB_GET:
2331 case SADB_ACQUIRE:
2332 case SADB_EXPIRE:
2333#ifdef SADB_X_NAT_T_NEW_MAPPING
2334 case SADB_X_NAT_T_NEW_MAPPING:
2335#endif
2336 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
2337 return -1;
2338 }
2339 break;
2340 case SADB_SATYPE_ESP:
2341 case SADB_SATYPE_AH:
2342 case SADB_X_SATYPE_IPCOMP:
2343#ifdef SADB_X_SATYPE_TCPSIGNATURE
2344 case SADB_X_SATYPE_TCPSIGNATURE:
2345#endif
2346 switch (msg->sadb_msg_type) {
2347 case SADB_X_SPDADD:
2348 case SADB_X_SPDDELETE:
2349 case SADB_X_SPDGET:
2350 case SADB_X_SPDDUMP:
2351 case SADB_X_SPDFLUSH:
2352 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
2353 return -1;
2354 }
2355#ifdef SADB_X_NAT_T_NEW_MAPPING
2356 if (msg->sadb_msg_type == SADB_X_NAT_T_NEW_MAPPING &&
2357 msg->sadb_msg_satype != SADB_SATYPE_ESP) {
2358 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
2359 return -1;
2360 }
2361#endif
2362 break;
2363 case SADB_SATYPE_RSVP:
2364 case SADB_SATYPE_OSPFV2:
2365 case SADB_SATYPE_RIPV2:
2366 case SADB_SATYPE_MIP:
2367 __ipsec_errcode = EIPSEC_NOT_SUPPORTED;
2368 return -1;
2369 case 1: /* XXX: What does it do ? */
2370 if (msg->sadb_msg_type == SADB_X_PROMISC)
2371 break;
2372 /*FALLTHROUGH*/
2373 default:
2374 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
2375 return -1;
2376 }
2377
2378 /* check field of upper layer protocol and address family */
2379 if (mhp[SADB_EXT_ADDRESS_SRC] != NULL
2380 && mhp[SADB_EXT_ADDRESS_DST] != NULL) {
2381 struct sadb_address *src0, *dst0;
2382
2383 src0 = (void *)(mhp[SADB_EXT_ADDRESS_SRC]);
2384 dst0 = (void *)(mhp[SADB_EXT_ADDRESS_DST]);
2385
2386 if (src0->sadb_address_proto != dst0->sadb_address_proto) {
2387 __ipsec_errcode = EIPSEC_PROTO_MISMATCH;
2388 return -1;
2389 }
2390
2391 if (PFKEY_ADDR_SADDR(src0)->sa_family
2392 != PFKEY_ADDR_SADDR(dst0)->sa_family) {
2393 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
2394 return -1;
2395 }
2396
2397 switch (PFKEY_ADDR_SADDR(src0)->sa_family) {
2398 case AF_INET:
2399 case AF_INET6:
2400 break;
2401 default:
2402 __ipsec_errcode = EIPSEC_INVAL_FAMILY;
2403 return -1;
2404 }
2405
2406 /*
2407 * prefixlen == 0 is valid because there must be the case
2408 * all addresses are matched.
2409 */
2410 }
2411
2412 __ipsec_errcode = EIPSEC_NO_ERROR;
2413 return 0;
2414}
2415
2416/*
2417 * set data into sadb_msg.
2418 * `buf' must has been allocated sufficiently.
2419 */
2420static caddr_t
2421pfkey_setsadbmsg(buf, lim, type, tlen, satype, seq, pid)
2422 caddr_t buf;
2423 caddr_t lim;
2424 u_int type, satype;
2425 u_int tlen;
2426 u_int32_t seq;
2427 pid_t pid;
2428{
2429 struct sadb_msg *p;
2430 u_int len;
2431
2432 p = (void *)buf;
2433 len = sizeof(struct sadb_msg);
2434
2435 if (buf + len > lim)
2436 return NULL;
2437
2438 memset(p, 0, len);
2439 p->sadb_msg_version = PF_KEY_V2;
2440 p->sadb_msg_type = type;
2441 p->sadb_msg_errno = 0;
2442 p->sadb_msg_satype = satype;
2443 p->sadb_msg_len = PFKEY_UNIT64(tlen);
2444 p->sadb_msg_reserved = 0;
2445 p->sadb_msg_seq = seq;
2446 p->sadb_msg_pid = (u_int32_t)pid;
2447
2448 return(buf + len);
2449}
2450
2451#ifdef __APPLE__
2452/*
2453 * copy secasvar data into sadb_address.
2454 * `buf' must has been allocated sufficiently.
2455 */
2456static caddr_t
2457pfkey_setsadbsa(buf, lim, spi, wsize, auth, enc, flags, port)
2458 caddr_t buf;
2459 caddr_t lim;
2460 u_int32_t spi, flags;
2461 u_int wsize, auth, enc;
2462 u_int16_t port;
2463{
2464 struct sadb_sa_2 *p;
2465 u_int len;
2466
2467 p = (void *)buf;
2468 len = sizeof(struct sadb_sa_2);
2469
2470 if (buf + len > lim)
2471 return NULL;
2472
2473 memset(p, 0, len);
2474 p->sa.sadb_sa_len = PFKEY_UNIT64(len);
2475 p->sa.sadb_sa_exttype = SADB_EXT_SA;
2476 p->sa.sadb_sa_spi = spi;
2477 p->sa.sadb_sa_replay = wsize;
2478 p->sa.sadb_sa_state = SADB_SASTATE_LARVAL;
2479 p->sa.sadb_sa_auth = auth;
2480 p->sa.sadb_sa_encrypt = enc;
2481 p->sa.sadb_sa_flags = flags;
2482 p->sadb_sa_natt_port = port;
2483
2484 return(buf + len);
2485}
2486#else
2487
2488/*
2489 * copy secasvar data into sadb_address.
2490 * `buf' must has been allocated sufficiently.
2491 */
2492static caddr_t
2493pfkey_setsadbsa(buf, lim, spi, wsize, auth, enc, flags)
2494 caddr_t buf;
2495 caddr_t lim;
2496 u_int32_t spi, flags;
2497 u_int wsize, auth, enc;
2498{
2499 struct sadb_sa *p;
2500 u_int len;
2501
2502 p = (void *)buf;
2503 len = sizeof(struct sadb_sa);
2504
2505 if (buf + len > lim)
2506 return NULL;
2507
2508 memset(p, 0, len);
2509 p->sadb_sa_len = PFKEY_UNIT64(len);
2510 p->sadb_sa_exttype = SADB_EXT_SA;
2511 p->sadb_sa_spi = spi;
2512 p->sadb_sa_replay = wsize;
2513 p->sadb_sa_state = SADB_SASTATE_LARVAL;
2514 p->sadb_sa_auth = auth;
2515 p->sadb_sa_encrypt = enc;
2516 p->sadb_sa_flags = flags;
2517 p->sadb_sa_natt_port = port;
2518
2519 return(buf + len);
2520}
2521#endif
2522
2523/*
2524 * set data into sadb_address.
2525 * `buf' must has been allocated sufficiently.
2526 * prefixlen is in bits.
2527 */
2528static caddr_t
2529pfkey_setsadbaddr(buf, lim, exttype, saddr, prefixlen, ul_proto)
2530 caddr_t buf;
2531 caddr_t lim;
2532 u_int exttype;
2533 struct sockaddr *saddr;
2534 u_int prefixlen;
2535 u_int ul_proto;
2536{
2537 struct sadb_address *p;
2538 u_int len;
2539
2540 p = (void *)buf;
2541 len = sizeof(struct sadb_address) + PFKEY_ALIGN8(sysdep_sa_len(saddr));
2542
2543 if (buf + len > lim)
2544 return NULL;
2545
2546 memset(p, 0, len);
2547 p->sadb_address_len = PFKEY_UNIT64(len);
2548 p->sadb_address_exttype = exttype & 0xffff;
2549 p->sadb_address_proto = ul_proto & 0xff;
2550 p->sadb_address_prefixlen = prefixlen;
2551 p->sadb_address_reserved = 0;
2552
2553 memcpy(p + 1, saddr, (size_t)sysdep_sa_len(saddr));
2554
2555 return(buf + len);
2556}
2557
2558/*
2559 * set sadb_key structure after clearing buffer with zero.
2560 * OUT: the pointer of buf + len.
2561 */
2562static caddr_t
2563pfkey_setsadbkey(buf, lim, type, key, keylen)
2564 caddr_t buf;
2565 caddr_t lim;
2566 caddr_t key;
2567 u_int type, keylen;
2568{
2569 struct sadb_key *p;
2570 u_int len;
2571
2572 p = (void *)buf;
2573 len = sizeof(struct sadb_key) + PFKEY_ALIGN8(keylen);
2574
2575 if (buf + len > lim)
2576 return NULL;
2577
2578 memset(p, 0, len);
2579 p->sadb_key_len = PFKEY_UNIT64(len);
2580 p->sadb_key_exttype = type;
2581 p->sadb_key_bits = keylen << 3;
2582 p->sadb_key_reserved = 0;
2583
2584 memcpy(p + 1, key, keylen);
2585
2586 return buf + len;
2587}
2588
2589/*
2590 * set sadb_lifetime structure after clearing buffer with zero.
2591 * OUT: the pointer of buf + len.
2592 */
2593static caddr_t
2594pfkey_setsadblifetime(buf, lim, type, l_alloc, l_bytes, l_addtime, l_usetime)
2595 caddr_t buf;
2596 caddr_t lim;
2597 u_int type;
2598 u_int32_t l_alloc, l_bytes, l_addtime, l_usetime;
2599{
2600 struct sadb_lifetime *p;
2601 u_int len;
2602
2603 p = (void *)buf;
2604 len = sizeof(struct sadb_lifetime);
2605
2606 if (buf + len > lim)
2607 return NULL;
2608
2609 memset(p, 0, len);
2610 p->sadb_lifetime_len = PFKEY_UNIT64(len);
2611 p->sadb_lifetime_exttype = type;
2612
2613 switch (type) {
2614 case SADB_EXT_LIFETIME_SOFT:
2615 p->sadb_lifetime_allocations
2616 = (l_alloc * soft_lifetime_allocations_rate) /100;
2617 p->sadb_lifetime_bytes
2618 = (l_bytes * soft_lifetime_bytes_rate) /100;
2619 p->sadb_lifetime_addtime
2620 = (l_addtime * soft_lifetime_addtime_rate) /100;
2621 p->sadb_lifetime_usetime
2622 = (l_usetime * soft_lifetime_usetime_rate) /100;
2623 break;
2624 case SADB_EXT_LIFETIME_HARD:
2625 p->sadb_lifetime_allocations = l_alloc;
2626 p->sadb_lifetime_bytes = l_bytes;
2627 p->sadb_lifetime_addtime = l_addtime;
2628 p->sadb_lifetime_usetime = l_usetime;
2629 break;
2630 }
2631
2632 return buf + len;
2633}
2634
2635/*
2636 * copy secasvar data into sadb_address.
2637 * `buf' must has been allocated sufficiently.
2638 */
2639static caddr_t
2640pfkey_setsadbxsa2(buf, lim, mode0, reqid)
2641 caddr_t buf;
2642 caddr_t lim;
2643 u_int32_t mode0;
2644 u_int32_t reqid;
2645{
2646 struct sadb_x_sa2 *p;
2647 u_int8_t mode = mode0 & 0xff;
2648 u_int len;
2649
2650 p = (void *)buf;
2651 len = sizeof(struct sadb_x_sa2);
2652
2653 if (buf + len > lim)
2654 return NULL;
2655
2656 memset(p, 0, len);
2657 p->sadb_x_sa2_len = PFKEY_UNIT64(len);
2658 p->sadb_x_sa2_exttype = SADB_X_EXT_SA2;
2659 p->sadb_x_sa2_mode = mode;
2660 p->sadb_x_sa2_reqid = reqid;
2661
2662 return(buf + len);
2663}
2664
2665#ifdef SADB_X_EXT_NAT_T_TYPE
2666static caddr_t
2667pfkey_set_natt_type(buf, lim, type, l_natt_type)
2668 caddr_t buf;
2669 caddr_t lim;
2670 u_int type;
2671 u_int8_t l_natt_type;
2672{
2673 struct sadb_x_nat_t_type *p;
2674 u_int len;
2675
2676 p = (void *)buf;
2677 len = sizeof(struct sadb_x_nat_t_type);
2678
2679 if (buf + len > lim)
2680 return NULL;
2681
2682 memset(p, 0, len);
2683 p->sadb_x_nat_t_type_len = PFKEY_UNIT64(len);
2684 p->sadb_x_nat_t_type_exttype = type;
2685 p->sadb_x_nat_t_type_type = l_natt_type;
2686
2687 return(buf + len);
2688}
2689
2690static caddr_t
2691pfkey_set_natt_port(buf, lim, type, l_natt_port)
2692 caddr_t buf;
2693 caddr_t lim;
2694 u_int type;
2695 u_int16_t l_natt_port;
2696{
2697 struct sadb_x_nat_t_port *p;
2698 u_int len;
2699
2700 p = (void *)buf;
2701 len = sizeof(struct sadb_x_nat_t_port);
2702
2703 if (buf + len > lim)
2704 return NULL;
2705
2706 memset(p, 0, len);
2707 p->sadb_x_nat_t_port_len = PFKEY_UNIT64(len);
2708 p->sadb_x_nat_t_port_exttype = type;
2709 p->sadb_x_nat_t_port_port = htons(l_natt_port);
2710
2711 return(buf + len);
2712}
2713#endif
2714
2715#ifdef SADB_X_EXT_NAT_T_FRAG
2716static caddr_t
2717pfkey_set_natt_frag(buf, lim, type, l_natt_frag)
2718 caddr_t buf;
2719 caddr_t lim;
2720 u_int type;
2721 u_int16_t l_natt_frag;
2722{
2723 struct sadb_x_nat_t_frag *p;
2724 u_int len;
2725
2726 p = (void *)buf;
2727 len = sizeof(struct sadb_x_nat_t_frag);
2728
2729 if (buf + len > lim)
2730 return NULL;
2731
2732 memset(p, 0, len);
2733 p->sadb_x_nat_t_frag_len = PFKEY_UNIT64(len);
2734 p->sadb_x_nat_t_frag_exttype = type;
2735 p->sadb_x_nat_t_frag_fraglen = l_natt_frag;
2736
2737 return(buf + len);
2738}
2739#endif