Initial import from FreeBSD RELENG_4:
[dragonfly.git] / lib / libipsec / pfkey.c
CommitLineData
984263bc
MD
1/* $FreeBSD: src/lib/libipsec/pfkey.c,v 1.1.2.2 2001/07/03 11:01:14 ume Exp $ */
2/* $KAME: pfkey.c,v 1.39 2001/03/05 18:22:17 thorpej Exp $ */
3
4/*
5 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33#include <sys/types.h>
34#include <sys/param.h>
35#include <sys/socket.h>
36#include <net/pfkeyv2.h>
37#include <netkey/key_var.h>
38#include <netinet/in.h>
39#include <netinet6/ipsec.h>
40
41#include <stdlib.h>
42#include <unistd.h>
43#include <string.h>
44#include <errno.h>
45#include <stdio.h>
46
47#include "ipsec_strerror.h"
48#include "libpfkey.h"
49
50#define CALLOC(size, cast) (cast)calloc(1, (size))
51
52static int findsupportedmap __P((int));
53static int setsupportedmap __P((struct sadb_supported *));
54static struct sadb_alg *findsupportedalg __P((u_int, u_int));
55static int pfkey_send_x1 __P((int, u_int, u_int, u_int, struct sockaddr *,
56 struct sockaddr *, u_int32_t, u_int32_t, u_int, caddr_t,
57 u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int32_t,
58 u_int32_t, u_int32_t, u_int32_t));
59static int pfkey_send_x2 __P((int, u_int, u_int, u_int,
60 struct sockaddr *, struct sockaddr *, u_int32_t));
61static int pfkey_send_x3 __P((int, u_int, u_int));
62static int pfkey_send_x4 __P((int, u_int, struct sockaddr *, u_int,
63 struct sockaddr *, u_int, u_int, u_int64_t, u_int64_t,
64 char *, int, u_int32_t));
65static int pfkey_send_x5 __P((int, u_int, u_int32_t));
66
67static caddr_t pfkey_setsadbmsg __P((caddr_t, caddr_t, u_int, u_int,
68 u_int, u_int32_t, pid_t));
69static caddr_t pfkey_setsadbsa __P((caddr_t, caddr_t, u_int32_t, u_int,
70 u_int, u_int, u_int32_t));
71static caddr_t pfkey_setsadbaddr __P((caddr_t, caddr_t, u_int,
72 struct sockaddr *, u_int, u_int));
73static caddr_t pfkey_setsadbkey __P((caddr_t, caddr_t, u_int, caddr_t, u_int));
74static caddr_t pfkey_setsadblifetime __P((caddr_t, caddr_t, u_int, u_int32_t,
75 u_int32_t, u_int32_t, u_int32_t));
76static caddr_t pfkey_setsadbxsa2 __P((caddr_t, caddr_t, u_int32_t, u_int32_t));
77
78/*
79 * make and search supported algorithm structure.
80 */
81static struct sadb_supported *ipsec_supported[] = { NULL, NULL, NULL, };
82
83static int supported_map[] = {
84 SADB_SATYPE_AH,
85 SADB_SATYPE_ESP,
86 SADB_X_SATYPE_IPCOMP,
87};
88
89static int
90findsupportedmap(satype)
91 int satype;
92{
93 int i;
94
95 for (i = 0; i < sizeof(supported_map)/sizeof(supported_map[0]); i++)
96 if (supported_map[i] == satype)
97 return i;
98 return -1;
99}
100
101static struct sadb_alg *
102findsupportedalg(satype, alg_id)
103 u_int satype, alg_id;
104{
105 int algno;
106 int tlen;
107 caddr_t p;
108
109 /* validity check */
110 algno = findsupportedmap(satype);
111 if (algno == -1) {
112 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
113 return NULL;
114 }
115 if (ipsec_supported[algno] == NULL) {
116 __ipsec_errcode = EIPSEC_DO_GET_SUPP_LIST;
117 return NULL;
118 }
119
120 tlen = ipsec_supported[algno]->sadb_supported_len
121 - sizeof(struct sadb_supported);
122 p = (caddr_t)(ipsec_supported[algno] + 1);
123 while (tlen > 0) {
124 if (tlen < sizeof(struct sadb_alg)) {
125 /* invalid format */
126 break;
127 }
128 if (((struct sadb_alg *)p)->sadb_alg_id == alg_id)
129 return (struct sadb_alg *)p;
130
131 tlen -= sizeof(struct sadb_alg);
132 p += sizeof(struct sadb_alg);
133 }
134
135 __ipsec_errcode = EIPSEC_NOT_SUPPORTED;
136 return NULL;
137}
138
139static int
140setsupportedmap(sup)
141 struct sadb_supported *sup;
142{
143 struct sadb_supported **ipsup;
144
145 switch (sup->sadb_supported_exttype) {
146 case SADB_EXT_SUPPORTED_AUTH:
147 ipsup = &ipsec_supported[findsupportedmap(SADB_SATYPE_AH)];
148 break;
149 case SADB_EXT_SUPPORTED_ENCRYPT:
150 ipsup = &ipsec_supported[findsupportedmap(SADB_SATYPE_ESP)];
151 break;
152 default:
153 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
154 return -1;
155 }
156
157 if (*ipsup)
158 free(*ipsup);
159
160 *ipsup = malloc(sup->sadb_supported_len);
161 if (!*ipsup) {
162 __ipsec_set_strerror(strerror(errno));
163 return -1;
164 }
165 memcpy(*ipsup, sup, sup->sadb_supported_len);
166
167 return 0;
168}
169
170/*
171 * check key length against algorithm specified.
172 * This function is called with SADB_EXT_SUPPORTED_{AUTH,ENCRYPT} as the
173 * augument, and only calls to ipsec_check_keylen2();
174 * keylen is the unit of bit.
175 * OUT:
176 * -1: invalid.
177 * 0: valid.
178 */
179int
180ipsec_check_keylen(supported, alg_id, keylen)
181 u_int supported;
182 u_int alg_id;
183 u_int keylen;
184{
185 int satype;
186
187 /* validity check */
188 switch (supported) {
189 case SADB_EXT_SUPPORTED_AUTH:
190 satype = SADB_SATYPE_AH;
191 break;
192 case SADB_EXT_SUPPORTED_ENCRYPT:
193 satype = SADB_SATYPE_ESP;
194 break;
195 default:
196 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
197 return -1;
198 }
199
200 return ipsec_check_keylen2(satype, alg_id, keylen);
201}
202
203/*
204 * check key length against algorithm specified.
205 * satype is one of satype defined at pfkeyv2.h.
206 * keylen is the unit of bit.
207 * OUT:
208 * -1: invalid.
209 * 0: valid.
210 */
211int
212ipsec_check_keylen2(satype, alg_id, keylen)
213 u_int satype;
214 u_int alg_id;
215 u_int keylen;
216{
217 struct sadb_alg *alg;
218
219 alg = findsupportedalg(satype, alg_id);
220 if (!alg)
221 return -1;
222
223 if (keylen < alg->sadb_alg_minbits || keylen > alg->sadb_alg_maxbits) {
224 __ipsec_errcode = EIPSEC_INVAL_KEYLEN;
225 return -1;
226 }
227
228 __ipsec_errcode = EIPSEC_NO_ERROR;
229 return 0;
230}
231
232/*
233 * get max/min key length against algorithm specified.
234 * satype is one of satype defined at pfkeyv2.h.
235 * keylen is the unit of bit.
236 * OUT:
237 * -1: invalid.
238 * 0: valid.
239 */
240int
241ipsec_get_keylen(supported, alg_id, alg0)
242 u_int supported, alg_id;
243 struct sadb_alg *alg0;
244{
245 struct sadb_alg *alg;
246 u_int satype;
247
248 /* validity check */
249 if (!alg0) {
250 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
251 return -1;
252 }
253
254 switch (supported) {
255 case SADB_EXT_SUPPORTED_AUTH:
256 satype = SADB_SATYPE_AH;
257 break;
258 case SADB_EXT_SUPPORTED_ENCRYPT:
259 satype = SADB_SATYPE_ESP;
260 break;
261 default:
262 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
263 return -1;
264 }
265
266 alg = findsupportedalg(satype, alg_id);
267 if (!alg)
268 return -1;
269
270 memcpy(alg0, alg, sizeof(*alg0));
271
272 __ipsec_errcode = EIPSEC_NO_ERROR;
273 return 0;
274}
275
276/*
277 * set the rate for SOFT lifetime against HARD one.
278 * If rate is more than 100 or equal to zero, then set to 100.
279 */
280static u_int soft_lifetime_allocations_rate = PFKEY_SOFT_LIFETIME_RATE;
281static u_int soft_lifetime_bytes_rate = PFKEY_SOFT_LIFETIME_RATE;
282static u_int soft_lifetime_addtime_rate = PFKEY_SOFT_LIFETIME_RATE;
283static u_int soft_lifetime_usetime_rate = PFKEY_SOFT_LIFETIME_RATE;
284
285u_int
286pfkey_set_softrate(type, rate)
287 u_int type, rate;
288{
289 __ipsec_errcode = EIPSEC_NO_ERROR;
290
291 if (rate > 100 || rate == 0)
292 rate = 100;
293
294 switch (type) {
295 case SADB_X_LIFETIME_ALLOCATIONS:
296 soft_lifetime_allocations_rate = rate;
297 return 0;
298 case SADB_X_LIFETIME_BYTES:
299 soft_lifetime_bytes_rate = rate;
300 return 0;
301 case SADB_X_LIFETIME_ADDTIME:
302 soft_lifetime_addtime_rate = rate;
303 return 0;
304 case SADB_X_LIFETIME_USETIME:
305 soft_lifetime_usetime_rate = rate;
306 return 0;
307 }
308
309 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
310 return 1;
311}
312
313/*
314 * get current rate for SOFT lifetime against HARD one.
315 * ATTENTION: ~0 is returned if invalid type was passed.
316 */
317u_int
318pfkey_get_softrate(type)
319 u_int type;
320{
321 switch (type) {
322 case SADB_X_LIFETIME_ALLOCATIONS:
323 return soft_lifetime_allocations_rate;
324 case SADB_X_LIFETIME_BYTES:
325 return soft_lifetime_bytes_rate;
326 case SADB_X_LIFETIME_ADDTIME:
327 return soft_lifetime_addtime_rate;
328 case SADB_X_LIFETIME_USETIME:
329 return soft_lifetime_usetime_rate;
330 }
331
332 return ~0;
333}
334
335/*
336 * sending SADB_GETSPI message to the kernel.
337 * OUT:
338 * positive: success and return length sent.
339 * -1 : error occured, and set errno.
340 */
341int
342pfkey_send_getspi(so, satype, mode, src, dst, min, max, reqid, seq)
343 int so;
344 u_int satype, mode;
345 struct sockaddr *src, *dst;
346 u_int32_t min, max, reqid, seq;
347{
348 struct sadb_msg *newmsg;
349 caddr_t ep;
350 int len;
351 int need_spirange = 0;
352 caddr_t p;
353 int plen;
354
355 /* validity check */
356 if (src == NULL || dst == NULL) {
357 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
358 return -1;
359 }
360 if (src->sa_family != dst->sa_family) {
361 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
362 return -1;
363 }
364 if (min > max || (min > 0 && min <= 255)) {
365 __ipsec_errcode = EIPSEC_INVAL_SPI;
366 return -1;
367 }
368 switch (src->sa_family) {
369 case AF_INET:
370 plen = sizeof(struct in_addr) << 3;
371 break;
372 case AF_INET6:
373 plen = sizeof(struct in6_addr) << 3;
374 break;
375 default:
376 __ipsec_errcode = EIPSEC_INVAL_FAMILY;
377 return -1;
378 }
379
380 /* create new sadb_msg to send. */
381 len = sizeof(struct sadb_msg)
382 + sizeof(struct sadb_x_sa2)
383 + sizeof(struct sadb_address)
384 + PFKEY_ALIGN8(src->sa_len)
385 + sizeof(struct sadb_address)
386 + PFKEY_ALIGN8(dst->sa_len);
387
388 if (min > 255 && max < ~0) {
389 need_spirange++;
390 len += sizeof(struct sadb_spirange);
391 }
392
393 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
394 __ipsec_set_strerror(strerror(errno));
395 return -1;
396 }
397 ep = ((caddr_t)newmsg) + len;
398
399 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, SADB_GETSPI,
400 len, satype, seq, getpid());
401 if (!p) {
402 free(newmsg);
403 return -1;
404 }
405
406 p = pfkey_setsadbxsa2(p, ep, mode, reqid);
407 if (!p) {
408 free(newmsg);
409 return -1;
410 }
411
412 /* set sadb_address for source */
413 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen,
414 IPSEC_ULPROTO_ANY);
415 if (!p) {
416 free(newmsg);
417 return -1;
418 }
419
420 /* set sadb_address for destination */
421 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen,
422 IPSEC_ULPROTO_ANY);
423 if (!p) {
424 free(newmsg);
425 return -1;
426 }
427
428 /* proccessing spi range */
429 if (need_spirange) {
430 struct sadb_spirange spirange;
431
432 if (p + sizeof(spirange) > ep) {
433 free(newmsg);
434 return -1;
435 }
436
437 memset(&spirange, 0, sizeof(spirange));
438 spirange.sadb_spirange_len = PFKEY_UNIT64(sizeof(spirange));
439 spirange.sadb_spirange_exttype = SADB_EXT_SPIRANGE;
440 spirange.sadb_spirange_min = min;
441 spirange.sadb_spirange_max = max;
442
443 memcpy(p, &spirange, sizeof(spirange));
444
445 p += sizeof(spirange);
446 }
447 if (p != ep) {
448 free(newmsg);
449 return -1;
450 }
451
452 /* send message */
453 len = pfkey_send(so, newmsg, len);
454 free(newmsg);
455
456 if (len < 0)
457 return -1;
458
459 __ipsec_errcode = EIPSEC_NO_ERROR;
460 return len;
461}
462
463/*
464 * sending SADB_UPDATE message to the kernel.
465 * The length of key material is a_keylen + e_keylen.
466 * OUT:
467 * positive: success and return length sent.
468 * -1 : error occured, and set errno.
469 */
470int
471pfkey_send_update(so, satype, mode, src, dst, spi, reqid, wsize,
472 keymat, e_type, e_keylen, a_type, a_keylen, flags,
473 l_alloc, l_bytes, l_addtime, l_usetime, seq)
474 int so;
475 u_int satype, mode, wsize;
476 struct sockaddr *src, *dst;
477 u_int32_t spi, reqid;
478 caddr_t keymat;
479 u_int e_type, e_keylen, a_type, a_keylen, flags;
480 u_int32_t l_alloc;
481 u_int64_t l_bytes, l_addtime, l_usetime;
482 u_int32_t seq;
483{
484 int len;
485 if ((len = pfkey_send_x1(so, SADB_UPDATE, satype, mode, src, dst, spi,
486 reqid, wsize,
487 keymat, e_type, e_keylen, a_type, a_keylen, flags,
488 l_alloc, l_bytes, l_addtime, l_usetime, seq)) < 0)
489 return -1;
490
491 return len;
492}
493
494/*
495 * sending SADB_ADD message to the kernel.
496 * The length of key material is a_keylen + e_keylen.
497 * OUT:
498 * positive: success and return length sent.
499 * -1 : error occured, and set errno.
500 */
501int
502pfkey_send_add(so, satype, mode, src, dst, spi, reqid, wsize,
503 keymat, e_type, e_keylen, a_type, a_keylen, flags,
504 l_alloc, l_bytes, l_addtime, l_usetime, seq)
505 int so;
506 u_int satype, mode, wsize;
507 struct sockaddr *src, *dst;
508 u_int32_t spi, reqid;
509 caddr_t keymat;
510 u_int e_type, e_keylen, a_type, a_keylen, flags;
511 u_int32_t l_alloc;
512 u_int64_t l_bytes, l_addtime, l_usetime;
513 u_int32_t seq;
514{
515 int len;
516 if ((len = pfkey_send_x1(so, SADB_ADD, satype, mode, src, dst, spi,
517 reqid, wsize,
518 keymat, e_type, e_keylen, a_type, a_keylen, flags,
519 l_alloc, l_bytes, l_addtime, l_usetime, seq)) < 0)
520 return -1;
521
522 return len;
523}
524
525/*
526 * sending SADB_DELETE message to the kernel.
527 * OUT:
528 * positive: success and return length sent.
529 * -1 : error occured, and set errno.
530 */
531int
532pfkey_send_delete(so, satype, mode, src, dst, spi)
533 int so;
534 u_int satype, mode;
535 struct sockaddr *src, *dst;
536 u_int32_t spi;
537{
538 int len;
539 if ((len = pfkey_send_x2(so, SADB_DELETE, satype, mode, src, dst, spi)) < 0)
540 return -1;
541
542 return len;
543}
544
545/*
546 * sending SADB_DELETE without spi to the kernel. This is
547 * the "delete all" request (an extension also present in
548 * Solaris).
549 *
550 * OUT:
551 * positive: success and return length sent
552 * -1 : error occured, and set errno
553 */
554int
555pfkey_send_delete_all(so, satype, mode, src, dst)
556 int so;
557 u_int satype, mode;
558 struct sockaddr *src, *dst;
559{
560 struct sadb_msg *newmsg;
561 int len;
562 caddr_t p;
563 int plen;
564 caddr_t ep;
565
566 /* validity check */
567 if (src == NULL || dst == NULL) {
568 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
569 return -1;
570 }
571 if (src->sa_family != dst->sa_family) {
572 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
573 return -1;
574 }
575 switch (src->sa_family) {
576 case AF_INET:
577 plen = sizeof(struct in_addr) << 3;
578 break;
579 case AF_INET6:
580 plen = sizeof(struct in6_addr) << 3;
581 break;
582 default:
583 __ipsec_errcode = EIPSEC_INVAL_FAMILY;
584 return -1;
585 }
586
587 /* create new sadb_msg to reply. */
588 len = sizeof(struct sadb_msg)
589 + sizeof(struct sadb_address)
590 + PFKEY_ALIGN8(src->sa_len)
591 + sizeof(struct sadb_address)
592 + PFKEY_ALIGN8(dst->sa_len);
593
594 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
595 __ipsec_set_strerror(strerror(errno));
596 return -1;
597 }
598 ep = ((caddr_t)newmsg) + len;
599
600 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, SADB_DELETE, len, satype, 0,
601 getpid());
602 if (!p) {
603 free(newmsg);
604 return -1;
605 }
606 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen,
607 IPSEC_ULPROTO_ANY);
608 if (!p) {
609 free(newmsg);
610 return -1;
611 }
612 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen,
613 IPSEC_ULPROTO_ANY);
614 if (!p || p != ep) {
615 free(newmsg);
616 return -1;
617 }
618
619 /* send message */
620 len = pfkey_send(so, newmsg, len);
621 free(newmsg);
622
623 if (len < 0)
624 return -1;
625
626 __ipsec_errcode = EIPSEC_NO_ERROR;
627 return len;
628}
629
630/*
631 * sending SADB_GET message to the kernel.
632 * OUT:
633 * positive: success and return length sent.
634 * -1 : error occured, and set errno.
635 */
636int
637pfkey_send_get(so, satype, mode, src, dst, spi)
638 int so;
639 u_int satype, mode;
640 struct sockaddr *src, *dst;
641 u_int32_t spi;
642{
643 int len;
644 if ((len = pfkey_send_x2(so, SADB_GET, satype, mode, src, dst, spi)) < 0)
645 return -1;
646
647 return len;
648}
649
650/*
651 * sending SADB_REGISTER message to the kernel.
652 * OUT:
653 * positive: success and return length sent.
654 * -1 : error occured, and set errno.
655 */
656int
657pfkey_send_register(so, satype)
658 int so;
659 u_int satype;
660{
661 int len, algno;
662
663 if (satype == PF_UNSPEC) {
664 for (algno = 0;
665 algno < sizeof(supported_map)/sizeof(supported_map[0]);
666 algno++) {
667 if (ipsec_supported[algno]) {
668 free(ipsec_supported[algno]);
669 ipsec_supported[algno] = NULL;
670 }
671 }
672 } else {
673 algno = findsupportedmap(satype);
674 if (algno == -1) {
675 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
676 return -1;
677 }
678
679 if (ipsec_supported[algno]) {
680 free(ipsec_supported[algno]);
681 ipsec_supported[algno] = NULL;
682 }
683 }
684
685 if ((len = pfkey_send_x3(so, SADB_REGISTER, satype)) < 0)
686 return -1;
687
688 return len;
689}
690
691/*
692 * receiving SADB_REGISTER message from the kernel, and copy buffer for
693 * sadb_supported returned into ipsec_supported.
694 * OUT:
695 * 0: success and return length sent.
696 * -1: error occured, and set errno.
697 */
698int
699pfkey_recv_register(so)
700 int so;
701{
702 pid_t pid = getpid();
703 struct sadb_msg *newmsg;
704 int error = -1;
705
706 /* receive message */
707 do {
708 if ((newmsg = pfkey_recv(so)) == NULL)
709 return -1;
710 } while (newmsg->sadb_msg_type != SADB_REGISTER
711 || newmsg->sadb_msg_pid != pid);
712
713 /* check and fix */
714 newmsg->sadb_msg_len = PFKEY_UNUNIT64(newmsg->sadb_msg_len);
715
716 error = pfkey_set_supported(newmsg, newmsg->sadb_msg_len);
717 free(newmsg);
718
719 if (error == 0)
720 __ipsec_errcode = EIPSEC_NO_ERROR;
721
722 return error;
723}
724
725/*
726 * receiving SADB_REGISTER message from the kernel, and copy buffer for
727 * sadb_supported returned into ipsec_supported.
728 * NOTE: sadb_msg_len must be host order.
729 * IN:
730 * tlen: msg length, it's to makeing sure.
731 * OUT:
732 * 0: success and return length sent.
733 * -1: error occured, and set errno.
734 */
735int
736pfkey_set_supported(msg, tlen)
737 struct sadb_msg *msg;
738 int tlen;
739{
740 struct sadb_supported *sup;
741 caddr_t p;
742 caddr_t ep;
743
744 /* validity */
745 if (msg->sadb_msg_len != tlen) {
746 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
747 return -1;
748 }
749
750 p = (caddr_t)msg;
751 ep = p + tlen;
752
753 p += sizeof(struct sadb_msg);
754
755 while (p < ep) {
756 sup = (struct sadb_supported *)p;
757 if (ep < p + sizeof(*sup) ||
758 PFKEY_EXTLEN(sup) < sizeof(*sup) ||
759 ep < p + sup->sadb_supported_len) {
760 /* invalid format */
761 break;
762 }
763
764 switch (sup->sadb_supported_exttype) {
765 case SADB_EXT_SUPPORTED_AUTH:
766 case SADB_EXT_SUPPORTED_ENCRYPT:
767 break;
768 default:
769 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
770 return -1;
771 }
772
773 /* fixed length */
774 sup->sadb_supported_len = PFKEY_EXTLEN(sup);
775
776 /* set supported map */
777 if (setsupportedmap(sup) != 0)
778 return -1;
779
780 p += sup->sadb_supported_len;
781 }
782
783 if (p != ep) {
784 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
785 return -1;
786 }
787
788 __ipsec_errcode = EIPSEC_NO_ERROR;
789
790 return 0;
791}
792
793/*
794 * sending SADB_FLUSH message to the kernel.
795 * OUT:
796 * positive: success and return length sent.
797 * -1 : error occured, and set errno.
798 */
799int
800pfkey_send_flush(so, satype)
801 int so;
802 u_int satype;
803{
804 int len;
805
806 if ((len = pfkey_send_x3(so, SADB_FLUSH, satype)) < 0)
807 return -1;
808
809 return len;
810}
811
812/*
813 * sending SADB_DUMP message to the kernel.
814 * OUT:
815 * positive: success and return length sent.
816 * -1 : error occured, and set errno.
817 */
818int
819pfkey_send_dump(so, satype)
820 int so;
821 u_int satype;
822{
823 int len;
824
825 if ((len = pfkey_send_x3(so, SADB_DUMP, satype)) < 0)
826 return -1;
827
828 return len;
829}
830
831/*
832 * sending SADB_X_PROMISC message to the kernel.
833 * NOTE that this function handles promisc mode toggle only.
834 * IN:
835 * flag: set promisc off if zero, set promisc on if non-zero.
836 * OUT:
837 * positive: success and return length sent.
838 * -1 : error occured, and set errno.
839 * 0 : error occured, and set errno.
840 * others: a pointer to new allocated buffer in which supported
841 * algorithms is.
842 */
843int
844pfkey_send_promisc_toggle(so, flag)
845 int so;
846 int flag;
847{
848 int len;
849
850 if ((len = pfkey_send_x3(so, SADB_X_PROMISC, (flag ? 1 : 0))) < 0)
851 return -1;
852
853 return len;
854}
855
856/*
857 * sending SADB_X_SPDADD message to the kernel.
858 * OUT:
859 * positive: success and return length sent.
860 * -1 : error occured, and set errno.
861 */
862int
863pfkey_send_spdadd(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
864 int so;
865 struct sockaddr *src, *dst;
866 u_int prefs, prefd, proto;
867 caddr_t policy;
868 int policylen;
869 u_int32_t seq;
870{
871 int len;
872
873 if ((len = pfkey_send_x4(so, SADB_X_SPDADD,
874 src, prefs, dst, prefd, proto,
875 0, 0,
876 policy, policylen, seq)) < 0)
877 return -1;
878
879 return len;
880}
881
882/*
883 * sending SADB_X_SPDADD message to the kernel.
884 * OUT:
885 * positive: success and return length sent.
886 * -1 : error occured, and set errno.
887 */
888int
889pfkey_send_spdadd2(so, src, prefs, dst, prefd, proto, ltime, vtime,
890 policy, policylen, seq)
891 int so;
892 struct sockaddr *src, *dst;
893 u_int prefs, prefd, proto;
894 u_int64_t ltime, vtime;
895 caddr_t policy;
896 int policylen;
897 u_int32_t seq;
898{
899 int len;
900
901 if ((len = pfkey_send_x4(so, SADB_X_SPDADD,
902 src, prefs, dst, prefd, proto,
903 ltime, vtime,
904 policy, policylen, seq)) < 0)
905 return -1;
906
907 return len;
908}
909
910/*
911 * sending SADB_X_SPDUPDATE message to the kernel.
912 * OUT:
913 * positive: success and return length sent.
914 * -1 : error occured, and set errno.
915 */
916int
917pfkey_send_spdupdate(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
918 int so;
919 struct sockaddr *src, *dst;
920 u_int prefs, prefd, proto;
921 caddr_t policy;
922 int policylen;
923 u_int32_t seq;
924{
925 int len;
926
927 if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE,
928 src, prefs, dst, prefd, proto,
929 0, 0,
930 policy, policylen, seq)) < 0)
931 return -1;
932
933 return len;
934}
935
936/*
937 * sending SADB_X_SPDUPDATE message to the kernel.
938 * OUT:
939 * positive: success and return length sent.
940 * -1 : error occured, and set errno.
941 */
942int
943pfkey_send_spdupdate2(so, src, prefs, dst, prefd, proto, ltime, vtime,
944 policy, policylen, seq)
945 int so;
946 struct sockaddr *src, *dst;
947 u_int prefs, prefd, proto;
948 u_int64_t ltime, vtime;
949 caddr_t policy;
950 int policylen;
951 u_int32_t seq;
952{
953 int len;
954
955 if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE,
956 src, prefs, dst, prefd, proto,
957 ltime, vtime,
958 policy, policylen, seq)) < 0)
959 return -1;
960
961 return len;
962}
963
964/*
965 * sending SADB_X_SPDDELETE message to the kernel.
966 * OUT:
967 * positive: success and return length sent.
968 * -1 : error occured, and set errno.
969 */
970int
971pfkey_send_spddelete(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
972 int so;
973 struct sockaddr *src, *dst;
974 u_int prefs, prefd, proto;
975 caddr_t policy;
976 int policylen;
977 u_int32_t seq;
978{
979 int len;
980
981 if (policylen != sizeof(struct sadb_x_policy)) {
982 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
983 return -1;
984 }
985
986 if ((len = pfkey_send_x4(so, SADB_X_SPDDELETE,
987 src, prefs, dst, prefd, proto,
988 0, 0,
989 policy, policylen, seq)) < 0)
990 return -1;
991
992 return len;
993}
994
995/*
996 * sending SADB_X_SPDDELETE message to the kernel.
997 * OUT:
998 * positive: success and return length sent.
999 * -1 : error occured, and set errno.
1000 */
1001int
1002pfkey_send_spddelete2(so, spid)
1003 int so;
1004 u_int32_t spid;
1005{
1006 int len;
1007
1008 if ((len = pfkey_send_x5(so, SADB_X_SPDDELETE2, spid)) < 0)
1009 return -1;
1010
1011 return len;
1012}
1013
1014/*
1015 * sending SADB_X_SPDGET message to the kernel.
1016 * OUT:
1017 * positive: success and return length sent.
1018 * -1 : error occured, and set errno.
1019 */
1020int
1021pfkey_send_spdget(so, spid)
1022 int so;
1023 u_int32_t spid;
1024{
1025 int len;
1026
1027 if ((len = pfkey_send_x5(so, SADB_X_SPDGET, spid)) < 0)
1028 return -1;
1029
1030 return len;
1031}
1032
1033/*
1034 * sending SADB_X_SPDSETIDX message to the kernel.
1035 * OUT:
1036 * positive: success and return length sent.
1037 * -1 : error occured, and set errno.
1038 */
1039int
1040pfkey_send_spdsetidx(so, src, prefs, dst, prefd, proto, policy, policylen, seq)
1041 int so;
1042 struct sockaddr *src, *dst;
1043 u_int prefs, prefd, proto;
1044 caddr_t policy;
1045 int policylen;
1046 u_int32_t seq;
1047{
1048 int len;
1049
1050 if (policylen != sizeof(struct sadb_x_policy)) {
1051 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1052 return -1;
1053 }
1054
1055 if ((len = pfkey_send_x4(so, SADB_X_SPDSETIDX,
1056 src, prefs, dst, prefd, proto,
1057 0, 0,
1058 policy, policylen, seq)) < 0)
1059 return -1;
1060
1061 return len;
1062}
1063
1064/*
1065 * sending SADB_SPDFLUSH message to the kernel.
1066 * OUT:
1067 * positive: success and return length sent.
1068 * -1 : error occured, and set errno.
1069 */
1070int
1071pfkey_send_spdflush(so)
1072 int so;
1073{
1074 int len;
1075
1076 if ((len = pfkey_send_x3(so, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC)) < 0)
1077 return -1;
1078
1079 return len;
1080}
1081
1082/*
1083 * sending SADB_SPDDUMP message to the kernel.
1084 * OUT:
1085 * positive: success and return length sent.
1086 * -1 : error occured, and set errno.
1087 */
1088int
1089pfkey_send_spddump(so)
1090 int so;
1091{
1092 int len;
1093
1094 if ((len = pfkey_send_x3(so, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC)) < 0)
1095 return -1;
1096
1097 return len;
1098}
1099
1100/* sending SADB_ADD or SADB_UPDATE message to the kernel */
1101static int
1102pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize,
1103 keymat, e_type, e_keylen, a_type, a_keylen, flags,
1104 l_alloc, l_bytes, l_addtime, l_usetime, seq)
1105 int so;
1106 u_int type, satype, mode;
1107 struct sockaddr *src, *dst;
1108 u_int32_t spi, reqid;
1109 u_int wsize;
1110 caddr_t keymat;
1111 u_int e_type, e_keylen, a_type, a_keylen, flags;
1112 u_int32_t l_alloc, l_bytes, l_addtime, l_usetime, seq;
1113{
1114 struct sadb_msg *newmsg;
1115 int len;
1116 caddr_t p;
1117 int plen;
1118 caddr_t ep;
1119
1120 /* validity check */
1121 if (src == NULL || dst == NULL) {
1122 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1123 return -1;
1124 }
1125 if (src->sa_family != dst->sa_family) {
1126 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
1127 return -1;
1128 }
1129 switch (src->sa_family) {
1130 case AF_INET:
1131 plen = sizeof(struct in_addr) << 3;
1132 break;
1133 case AF_INET6:
1134 plen = sizeof(struct in6_addr) << 3;
1135 break;
1136 default:
1137 __ipsec_errcode = EIPSEC_INVAL_FAMILY;
1138 return -1;
1139 }
1140
1141 switch (satype) {
1142 case SADB_SATYPE_ESP:
1143 if (e_type == SADB_EALG_NONE) {
1144 __ipsec_errcode = EIPSEC_NO_ALGS;
1145 return -1;
1146 }
1147 break;
1148 case SADB_SATYPE_AH:
1149 if (e_type != SADB_EALG_NONE) {
1150 __ipsec_errcode = EIPSEC_INVAL_ALGS;
1151 return -1;
1152 }
1153 if (a_type == SADB_AALG_NONE) {
1154 __ipsec_errcode = EIPSEC_NO_ALGS;
1155 return -1;
1156 }
1157 break;
1158 case SADB_X_SATYPE_IPCOMP:
1159 if (e_type == SADB_X_CALG_NONE) {
1160 __ipsec_errcode = EIPSEC_INVAL_ALGS;
1161 return -1;
1162 }
1163 if (a_type != SADB_AALG_NONE) {
1164 __ipsec_errcode = EIPSEC_NO_ALGS;
1165 return -1;
1166 }
1167 break;
1168 default:
1169 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
1170 return -1;
1171 }
1172
1173 /* create new sadb_msg to reply. */
1174 len = sizeof(struct sadb_msg)
1175 + sizeof(struct sadb_sa)
1176 + sizeof(struct sadb_x_sa2)
1177 + sizeof(struct sadb_address)
1178 + PFKEY_ALIGN8(src->sa_len)
1179 + sizeof(struct sadb_address)
1180 + PFKEY_ALIGN8(dst->sa_len)
1181 + sizeof(struct sadb_lifetime)
1182 + sizeof(struct sadb_lifetime);
1183
1184 if (e_type != SADB_EALG_NONE)
1185 len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(e_keylen));
1186 if (a_type != SADB_AALG_NONE)
1187 len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(a_keylen));
1188
1189 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
1190 __ipsec_set_strerror(strerror(errno));
1191 return -1;
1192 }
1193 ep = ((caddr_t)newmsg) + len;
1194
1195 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len,
1196 satype, seq, getpid());
1197 if (!p) {
1198 free(newmsg);
1199 return -1;
1200 }
1201 p = pfkey_setsadbsa(p, ep, spi, wsize, a_type, e_type, flags);
1202 if (!p) {
1203 free(newmsg);
1204 return -1;
1205 }
1206 p = pfkey_setsadbxsa2(p, ep, mode, reqid);
1207 if (!p) {
1208 free(newmsg);
1209 return -1;
1210 }
1211 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen,
1212 IPSEC_ULPROTO_ANY);
1213 if (!p) {
1214 free(newmsg);
1215 return -1;
1216 }
1217 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen,
1218 IPSEC_ULPROTO_ANY);
1219 if (!p) {
1220 free(newmsg);
1221 return -1;
1222 }
1223
1224 if (e_type != SADB_EALG_NONE) {
1225 p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_ENCRYPT,
1226 keymat, e_keylen);
1227 if (!p) {
1228 free(newmsg);
1229 return -1;
1230 }
1231 }
1232 if (a_type != SADB_AALG_NONE) {
1233 p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_AUTH,
1234 keymat + e_keylen, a_keylen);
1235 if (!p) {
1236 free(newmsg);
1237 return -1;
1238 }
1239 }
1240
1241 /* set sadb_lifetime for destination */
1242 p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD,
1243 l_alloc, l_bytes, l_addtime, l_usetime);
1244 if (!p) {
1245 free(newmsg);
1246 return -1;
1247 }
1248 p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_SOFT,
1249 l_alloc, l_bytes, l_addtime, l_usetime);
1250 if (!p || p != ep) {
1251 free(newmsg);
1252 return -1;
1253 }
1254
1255 /* send message */
1256 len = pfkey_send(so, newmsg, len);
1257 free(newmsg);
1258
1259 if (len < 0)
1260 return -1;
1261
1262 __ipsec_errcode = EIPSEC_NO_ERROR;
1263 return len;
1264}
1265
1266/* sending SADB_DELETE or SADB_GET message to the kernel */
1267static int
1268pfkey_send_x2(so, type, satype, mode, src, dst, spi)
1269 int so;
1270 u_int type, satype, mode;
1271 struct sockaddr *src, *dst;
1272 u_int32_t spi;
1273{
1274 struct sadb_msg *newmsg;
1275 int len;
1276 caddr_t p;
1277 int plen;
1278 caddr_t ep;
1279
1280 /* validity check */
1281 if (src == NULL || dst == NULL) {
1282 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1283 return -1;
1284 }
1285 if (src->sa_family != dst->sa_family) {
1286 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
1287 return -1;
1288 }
1289 switch (src->sa_family) {
1290 case AF_INET:
1291 plen = sizeof(struct in_addr) << 3;
1292 break;
1293 case AF_INET6:
1294 plen = sizeof(struct in6_addr) << 3;
1295 break;
1296 default:
1297 __ipsec_errcode = EIPSEC_INVAL_FAMILY;
1298 return -1;
1299 }
1300
1301 /* create new sadb_msg to reply. */
1302 len = sizeof(struct sadb_msg)
1303 + sizeof(struct sadb_sa)
1304 + sizeof(struct sadb_address)
1305 + PFKEY_ALIGN8(src->sa_len)
1306 + sizeof(struct sadb_address)
1307 + PFKEY_ALIGN8(dst->sa_len);
1308
1309 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
1310 __ipsec_set_strerror(strerror(errno));
1311 return -1;
1312 }
1313 ep = ((caddr_t)newmsg) + len;
1314
1315 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len, satype, 0,
1316 getpid());
1317 if (!p) {
1318 free(newmsg);
1319 return -1;
1320 }
1321 p = pfkey_setsadbsa(p, ep, spi, 0, 0, 0, 0);
1322 if (!p) {
1323 free(newmsg);
1324 return -1;
1325 }
1326 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen,
1327 IPSEC_ULPROTO_ANY);
1328 if (!p) {
1329 free(newmsg);
1330 return -1;
1331 }
1332 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen,
1333 IPSEC_ULPROTO_ANY);
1334 if (!p || p != ep) {
1335 free(newmsg);
1336 return -1;
1337 }
1338
1339 /* send message */
1340 len = pfkey_send(so, newmsg, len);
1341 free(newmsg);
1342
1343 if (len < 0)
1344 return -1;
1345
1346 __ipsec_errcode = EIPSEC_NO_ERROR;
1347 return len;
1348}
1349
1350/*
1351 * sending SADB_REGISTER, SADB_FLUSH, SADB_DUMP or SADB_X_PROMISC message
1352 * to the kernel
1353 */
1354static int
1355pfkey_send_x3(so, type, satype)
1356 int so;
1357 u_int type, satype;
1358{
1359 struct sadb_msg *newmsg;
1360 int len;
1361 caddr_t p;
1362 caddr_t ep;
1363
1364 /* validity check */
1365 switch (type) {
1366 case SADB_X_PROMISC:
1367 if (satype != 0 && satype != 1) {
1368 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
1369 return -1;
1370 }
1371 break;
1372 default:
1373 switch (satype) {
1374 case SADB_SATYPE_UNSPEC:
1375 case SADB_SATYPE_AH:
1376 case SADB_SATYPE_ESP:
1377 case SADB_X_SATYPE_IPCOMP:
1378 break;
1379 default:
1380 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
1381 return -1;
1382 }
1383 }
1384
1385 /* create new sadb_msg to send. */
1386 len = sizeof(struct sadb_msg);
1387
1388 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
1389 __ipsec_set_strerror(strerror(errno));
1390 return -1;
1391 }
1392 ep = ((caddr_t)newmsg) + len;
1393
1394 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len, satype, 0,
1395 getpid());
1396 if (!p || p != ep) {
1397 free(newmsg);
1398 return -1;
1399 }
1400
1401 /* send message */
1402 len = pfkey_send(so, newmsg, len);
1403 free(newmsg);
1404
1405 if (len < 0)
1406 return -1;
1407
1408 __ipsec_errcode = EIPSEC_NO_ERROR;
1409 return len;
1410}
1411
1412/* sending SADB_X_SPDADD message to the kernel */
1413static int
1414pfkey_send_x4(so, type, src, prefs, dst, prefd, proto,
1415 ltime, vtime, policy, policylen, seq)
1416 int so;
1417 struct sockaddr *src, *dst;
1418 u_int type, prefs, prefd, proto;
1419 u_int64_t ltime, vtime;
1420 char *policy;
1421 int policylen;
1422 u_int32_t seq;
1423{
1424 struct sadb_msg *newmsg;
1425 int len;
1426 caddr_t p;
1427 int plen;
1428 caddr_t ep;
1429
1430 /* validity check */
1431 if (src == NULL || dst == NULL) {
1432 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1433 return -1;
1434 }
1435 if (src->sa_family != dst->sa_family) {
1436 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
1437 return -1;
1438 }
1439
1440 switch (src->sa_family) {
1441 case AF_INET:
1442 plen = sizeof(struct in_addr) << 3;
1443 break;
1444 case AF_INET6:
1445 plen = sizeof(struct in6_addr) << 3;
1446 break;
1447 default:
1448 __ipsec_errcode = EIPSEC_INVAL_FAMILY;
1449 return -1;
1450 }
1451 if (prefs > plen || prefd > plen) {
1452 __ipsec_errcode = EIPSEC_INVAL_PREFIXLEN;
1453 return -1;
1454 }
1455
1456 /* create new sadb_msg to reply. */
1457 len = sizeof(struct sadb_msg)
1458 + sizeof(struct sadb_address)
1459 + PFKEY_ALIGN8(src->sa_len)
1460 + sizeof(struct sadb_address)
1461 + PFKEY_ALIGN8(src->sa_len)
1462 + sizeof(struct sadb_lifetime)
1463 + policylen;
1464
1465 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
1466 __ipsec_set_strerror(strerror(errno));
1467 return -1;
1468 }
1469 ep = ((caddr_t)newmsg) + len;
1470
1471 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len,
1472 SADB_SATYPE_UNSPEC, seq, getpid());
1473 if (!p) {
1474 free(newmsg);
1475 return -1;
1476 }
1477 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, prefs, proto);
1478 if (!p) {
1479 free(newmsg);
1480 return -1;
1481 }
1482 p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, prefd, proto);
1483 if (!p) {
1484 free(newmsg);
1485 return -1;
1486 }
1487 p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD,
1488 0, 0, ltime, vtime);
1489 if (!p || p + policylen != ep) {
1490 free(newmsg);
1491 return -1;
1492 }
1493 memcpy(p, policy, policylen);
1494
1495 /* send message */
1496 len = pfkey_send(so, newmsg, len);
1497 free(newmsg);
1498
1499 if (len < 0)
1500 return -1;
1501
1502 __ipsec_errcode = EIPSEC_NO_ERROR;
1503 return len;
1504}
1505
1506/* sending SADB_X_SPDGET or SADB_X_SPDDELETE message to the kernel */
1507static int
1508pfkey_send_x5(so, type, spid)
1509 int so;
1510 u_int type;
1511 u_int32_t spid;
1512{
1513 struct sadb_msg *newmsg;
1514 struct sadb_x_policy xpl;
1515 int len;
1516 caddr_t p;
1517 caddr_t ep;
1518
1519 /* create new sadb_msg to reply. */
1520 len = sizeof(struct sadb_msg)
1521 + sizeof(xpl);
1522
1523 if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
1524 __ipsec_set_strerror(strerror(errno));
1525 return -1;
1526 }
1527 ep = ((caddr_t)newmsg) + len;
1528
1529 p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len,
1530 SADB_SATYPE_UNSPEC, 0, getpid());
1531 if (!p) {
1532 free(newmsg);
1533 return -1;
1534 }
1535
1536 if (p + sizeof(xpl) != ep) {
1537 free(newmsg);
1538 return -1;
1539 }
1540 memset(&xpl, 0, sizeof(xpl));
1541 xpl.sadb_x_policy_len = PFKEY_UNUNIT64(sizeof(xpl));
1542 xpl.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
1543 xpl.sadb_x_policy_id = spid;
1544 memcpy(p, &xpl, sizeof(xpl));
1545
1546 /* send message */
1547 len = pfkey_send(so, newmsg, len);
1548 free(newmsg);
1549
1550 if (len < 0)
1551 return -1;
1552
1553 __ipsec_errcode = EIPSEC_NO_ERROR;
1554 return len;
1555}
1556
1557/*
1558 * open a socket.
1559 * OUT:
1560 * -1: fail.
1561 * others : success and return value of socket.
1562 */
1563int
1564pfkey_open()
1565{
1566 int so;
1567 const int bufsiz = 128 * 1024; /*is 128K enough?*/
1568
1569 if ((so = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) {
1570 __ipsec_set_strerror(strerror(errno));
1571 return -1;
1572 }
1573
1574 /*
1575 * This is a temporary workaround for KAME PR 154.
1576 * Don't really care even if it fails.
1577 */
1578 (void)setsockopt(so, SOL_SOCKET, SO_SNDBUF, &bufsiz, sizeof(bufsiz));
1579 (void)setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz));
1580
1581 __ipsec_errcode = EIPSEC_NO_ERROR;
1582 return so;
1583}
1584
1585/*
1586 * close a socket.
1587 * OUT:
1588 * 0: success.
1589 * -1: fail.
1590 */
1591void
1592pfkey_close(so)
1593 int so;
1594{
1595 (void)close(so);
1596
1597 __ipsec_errcode = EIPSEC_NO_ERROR;
1598 return;
1599}
1600
1601/*
1602 * receive sadb_msg data, and return pointer to new buffer allocated.
1603 * Must free this buffer later.
1604 * OUT:
1605 * NULL : error occured.
1606 * others : a pointer to sadb_msg structure.
1607 *
1608 * XXX should be rewritten to pass length explicitly
1609 */
1610struct sadb_msg *
1611pfkey_recv(so)
1612 int so;
1613{
1614 struct sadb_msg buf, *newmsg;
1615 int len, reallen;
1616
1617 while ((len = recv(so, (caddr_t)&buf, sizeof(buf), MSG_PEEK)) < 0) {
1618 if (errno == EINTR)
1619 continue;
1620 __ipsec_set_strerror(strerror(errno));
1621 return NULL;
1622 }
1623
1624 if (len < sizeof(buf)) {
1625 recv(so, (caddr_t)&buf, sizeof(buf), 0);
1626 __ipsec_errcode = EIPSEC_MAX;
1627 return NULL;
1628 }
1629
1630 /* read real message */
1631 reallen = PFKEY_UNUNIT64(buf.sadb_msg_len);
1632 if ((newmsg = CALLOC(reallen, struct sadb_msg *)) == 0) {
1633 __ipsec_set_strerror(strerror(errno));
1634 return NULL;
1635 }
1636
1637 while ((len = recv(so, (caddr_t)newmsg, reallen, 0)) < 0) {
1638 if (errno == EINTR)
1639 continue;
1640 __ipsec_set_strerror(strerror(errno));
1641 free(newmsg);
1642 return NULL;
1643 }
1644
1645 if (len != reallen) {
1646 __ipsec_errcode = EIPSEC_SYSTEM_ERROR;
1647 free(newmsg);
1648 return NULL;
1649 }
1650
1651 /* don't trust what the kernel says, validate! */
1652 if (PFKEY_UNUNIT64(newmsg->sadb_msg_len) != len) {
1653 __ipsec_errcode = EIPSEC_SYSTEM_ERROR;
1654 free(newmsg);
1655 return NULL;
1656 }
1657
1658 __ipsec_errcode = EIPSEC_NO_ERROR;
1659 return newmsg;
1660}
1661
1662/*
1663 * send message to a socket.
1664 * OUT:
1665 * others: success and return length sent.
1666 * -1 : fail.
1667 */
1668int
1669pfkey_send(so, msg, len)
1670 int so;
1671 struct sadb_msg *msg;
1672 int len;
1673{
1674 if ((len = send(so, (caddr_t)msg, len, 0)) < 0) {
1675 __ipsec_set_strerror(strerror(errno));
1676 return -1;
1677 }
1678
1679 __ipsec_errcode = EIPSEC_NO_ERROR;
1680 return len;
1681}
1682
1683/*
1684 * %%% Utilities
1685 * NOTE: These functions are derived from netkey/key.c in KAME.
1686 */
1687/*
1688 * set the pointer to each header in this message buffer.
1689 * IN: msg: pointer to message buffer.
1690 * mhp: pointer to the buffer initialized like below:
1691 * caddr_t mhp[SADB_EXT_MAX + 1];
1692 * OUT: -1: invalid.
1693 * 0: valid.
1694 *
1695 * XXX should be rewritten to obtain length explicitly
1696 */
1697int
1698pfkey_align(msg, mhp)
1699 struct sadb_msg *msg;
1700 caddr_t *mhp;
1701{
1702 struct sadb_ext *ext;
1703 int i;
1704 caddr_t p;
1705 caddr_t ep; /* XXX should be passed from upper layer */
1706
1707 /* validity check */
1708 if (msg == NULL || mhp == NULL) {
1709 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1710 return -1;
1711 }
1712
1713 /* initialize */
1714 for (i = 0; i < SADB_EXT_MAX + 1; i++)
1715 mhp[i] = NULL;
1716
1717 mhp[0] = (caddr_t)msg;
1718
1719 /* initialize */
1720 p = (caddr_t) msg;
1721 ep = p + PFKEY_UNUNIT64(msg->sadb_msg_len);
1722
1723 /* skip base header */
1724 p += sizeof(struct sadb_msg);
1725
1726 while (p < ep) {
1727 ext = (struct sadb_ext *)p;
1728 if (ep < p + sizeof(*ext) || PFKEY_EXTLEN(ext) < sizeof(*ext) ||
1729 ep < p + PFKEY_EXTLEN(ext)) {
1730 /* invalid format */
1731 break;
1732 }
1733
1734 /* duplicate check */
1735 /* XXX Are there duplication either KEY_AUTH or KEY_ENCRYPT ?*/
1736 if (mhp[ext->sadb_ext_type] != NULL) {
1737 __ipsec_errcode = EIPSEC_INVAL_EXTTYPE;
1738 return -1;
1739 }
1740
1741 /* set pointer */
1742 switch (ext->sadb_ext_type) {
1743 case SADB_EXT_SA:
1744 case SADB_EXT_LIFETIME_CURRENT:
1745 case SADB_EXT_LIFETIME_HARD:
1746 case SADB_EXT_LIFETIME_SOFT:
1747 case SADB_EXT_ADDRESS_SRC:
1748 case SADB_EXT_ADDRESS_DST:
1749 case SADB_EXT_ADDRESS_PROXY:
1750 case SADB_EXT_KEY_AUTH:
1751 /* XXX should to be check weak keys. */
1752 case SADB_EXT_KEY_ENCRYPT:
1753 /* XXX should to be check weak keys. */
1754 case SADB_EXT_IDENTITY_SRC:
1755 case SADB_EXT_IDENTITY_DST:
1756 case SADB_EXT_SENSITIVITY:
1757 case SADB_EXT_PROPOSAL:
1758 case SADB_EXT_SUPPORTED_AUTH:
1759 case SADB_EXT_SUPPORTED_ENCRYPT:
1760 case SADB_EXT_SPIRANGE:
1761 case SADB_X_EXT_POLICY:
1762 case SADB_X_EXT_SA2:
1763 mhp[ext->sadb_ext_type] = (caddr_t)ext;
1764 break;
1765 default:
1766 __ipsec_errcode = EIPSEC_INVAL_EXTTYPE;
1767 return -1;
1768 }
1769
1770 p += PFKEY_EXTLEN(ext);
1771 }
1772
1773 if (p != ep) {
1774 __ipsec_errcode = EIPSEC_INVAL_SADBMSG;
1775 return -1;
1776 }
1777
1778 __ipsec_errcode = EIPSEC_NO_ERROR;
1779 return 0;
1780}
1781
1782/*
1783 * check basic usage for sadb_msg,
1784 * NOTE: This routine is derived from netkey/key.c in KAME.
1785 * IN: msg: pointer to message buffer.
1786 * mhp: pointer to the buffer initialized like below:
1787 *
1788 * caddr_t mhp[SADB_EXT_MAX + 1];
1789 *
1790 * OUT: -1: invalid.
1791 * 0: valid.
1792 */
1793int
1794pfkey_check(mhp)
1795 caddr_t *mhp;
1796{
1797 struct sadb_msg *msg;
1798
1799 /* validity check */
1800 if (mhp == NULL || mhp[0] == NULL) {
1801 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1802 return -1;
1803 }
1804
1805 msg = (struct sadb_msg *)mhp[0];
1806
1807 /* check version */
1808 if (msg->sadb_msg_version != PF_KEY_V2) {
1809 __ipsec_errcode = EIPSEC_INVAL_VERSION;
1810 return -1;
1811 }
1812
1813 /* check type */
1814 if (msg->sadb_msg_type > SADB_MAX) {
1815 __ipsec_errcode = EIPSEC_INVAL_MSGTYPE;
1816 return -1;
1817 }
1818
1819 /* check SA type */
1820 switch (msg->sadb_msg_satype) {
1821 case SADB_SATYPE_UNSPEC:
1822 switch (msg->sadb_msg_type) {
1823 case SADB_GETSPI:
1824 case SADB_UPDATE:
1825 case SADB_ADD:
1826 case SADB_DELETE:
1827 case SADB_GET:
1828 case SADB_ACQUIRE:
1829 case SADB_EXPIRE:
1830 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
1831 return -1;
1832 }
1833 break;
1834 case SADB_SATYPE_ESP:
1835 case SADB_SATYPE_AH:
1836 case SADB_X_SATYPE_IPCOMP:
1837 switch (msg->sadb_msg_type) {
1838 case SADB_X_SPDADD:
1839 case SADB_X_SPDDELETE:
1840 case SADB_X_SPDGET:
1841 case SADB_X_SPDDUMP:
1842 case SADB_X_SPDFLUSH:
1843 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
1844 return -1;
1845 }
1846 break;
1847 case SADB_SATYPE_RSVP:
1848 case SADB_SATYPE_OSPFV2:
1849 case SADB_SATYPE_RIPV2:
1850 case SADB_SATYPE_MIP:
1851 __ipsec_errcode = EIPSEC_NOT_SUPPORTED;
1852 return -1;
1853 case 1: /* XXX: What does it do ? */
1854 if (msg->sadb_msg_type == SADB_X_PROMISC)
1855 break;
1856 /*FALLTHROUGH*/
1857 default:
1858 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
1859 return -1;
1860 }
1861
1862 /* check field of upper layer protocol and address family */
1863 if (mhp[SADB_EXT_ADDRESS_SRC] != NULL
1864 && mhp[SADB_EXT_ADDRESS_DST] != NULL) {
1865 struct sadb_address *src0, *dst0;
1866
1867 src0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_SRC]);
1868 dst0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_DST]);
1869
1870 if (src0->sadb_address_proto != dst0->sadb_address_proto) {
1871 __ipsec_errcode = EIPSEC_PROTO_MISMATCH;
1872 return -1;
1873 }
1874
1875 if (PFKEY_ADDR_SADDR(src0)->sa_family
1876 != PFKEY_ADDR_SADDR(dst0)->sa_family) {
1877 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
1878 return -1;
1879 }
1880
1881 switch (PFKEY_ADDR_SADDR(src0)->sa_family) {
1882 case AF_INET:
1883 case AF_INET6:
1884 break;
1885 default:
1886 __ipsec_errcode = EIPSEC_INVAL_FAMILY;
1887 return -1;
1888 }
1889
1890 /*
1891 * prefixlen == 0 is valid because there must be the case
1892 * all addresses are matched.
1893 */
1894 }
1895
1896 __ipsec_errcode = EIPSEC_NO_ERROR;
1897 return 0;
1898}
1899
1900/*
1901 * set data into sadb_msg.
1902 * `buf' must has been allocated sufficiently.
1903 */
1904static caddr_t
1905pfkey_setsadbmsg(buf, lim, type, tlen, satype, seq, pid)
1906 caddr_t buf;
1907 caddr_t lim;
1908 u_int type, satype;
1909 u_int tlen;
1910 u_int32_t seq;
1911 pid_t pid;
1912{
1913 struct sadb_msg *p;
1914 u_int len;
1915
1916 p = (struct sadb_msg *)buf;
1917 len = sizeof(struct sadb_msg);
1918
1919 if (buf + len > lim)
1920 return NULL;
1921
1922 memset(p, 0, len);
1923 p->sadb_msg_version = PF_KEY_V2;
1924 p->sadb_msg_type = type;
1925 p->sadb_msg_errno = 0;
1926 p->sadb_msg_satype = satype;
1927 p->sadb_msg_len = PFKEY_UNIT64(tlen);
1928 p->sadb_msg_reserved = 0;
1929 p->sadb_msg_seq = seq;
1930 p->sadb_msg_pid = (u_int32_t)pid;
1931
1932 return(buf + len);
1933}
1934
1935/*
1936 * copy secasvar data into sadb_address.
1937 * `buf' must has been allocated sufficiently.
1938 */
1939static caddr_t
1940pfkey_setsadbsa(buf, lim, spi, wsize, auth, enc, flags)
1941 caddr_t buf;
1942 caddr_t lim;
1943 u_int32_t spi, flags;
1944 u_int wsize, auth, enc;
1945{
1946 struct sadb_sa *p;
1947 u_int len;
1948
1949 p = (struct sadb_sa *)buf;
1950 len = sizeof(struct sadb_sa);
1951
1952 if (buf + len > lim)
1953 return NULL;
1954
1955 memset(p, 0, len);
1956 p->sadb_sa_len = PFKEY_UNIT64(len);
1957 p->sadb_sa_exttype = SADB_EXT_SA;
1958 p->sadb_sa_spi = spi;
1959 p->sadb_sa_replay = wsize;
1960 p->sadb_sa_state = SADB_SASTATE_LARVAL;
1961 p->sadb_sa_auth = auth;
1962 p->sadb_sa_encrypt = enc;
1963 p->sadb_sa_flags = flags;
1964
1965 return(buf + len);
1966}
1967
1968/*
1969 * set data into sadb_address.
1970 * `buf' must has been allocated sufficiently.
1971 * prefixlen is in bits.
1972 */
1973static caddr_t
1974pfkey_setsadbaddr(buf, lim, exttype, saddr, prefixlen, ul_proto)
1975 caddr_t buf;
1976 caddr_t lim;
1977 u_int exttype;
1978 struct sockaddr *saddr;
1979 u_int prefixlen;
1980 u_int ul_proto;
1981{
1982 struct sadb_address *p;
1983 u_int len;
1984
1985 p = (struct sadb_address *)buf;
1986 len = sizeof(struct sadb_address) + PFKEY_ALIGN8(saddr->sa_len);
1987
1988 if (buf + len > lim)
1989 return NULL;
1990
1991 memset(p, 0, len);
1992 p->sadb_address_len = PFKEY_UNIT64(len);
1993 p->sadb_address_exttype = exttype & 0xffff;
1994 p->sadb_address_proto = ul_proto & 0xff;
1995 p->sadb_address_prefixlen = prefixlen;
1996 p->sadb_address_reserved = 0;
1997
1998 memcpy(p + 1, saddr, saddr->sa_len);
1999
2000 return(buf + len);
2001}
2002
2003/*
2004 * set sadb_key structure after clearing buffer with zero.
2005 * OUT: the pointer of buf + len.
2006 */
2007static caddr_t
2008pfkey_setsadbkey(buf, lim, type, key, keylen)
2009 caddr_t buf;
2010 caddr_t lim;
2011 caddr_t key;
2012 u_int type, keylen;
2013{
2014 struct sadb_key *p;
2015 u_int len;
2016
2017 p = (struct sadb_key *)buf;
2018 len = sizeof(struct sadb_key) + PFKEY_ALIGN8(keylen);
2019
2020 if (buf + len > lim)
2021 return NULL;
2022
2023 memset(p, 0, len);
2024 p->sadb_key_len = PFKEY_UNIT64(len);
2025 p->sadb_key_exttype = type;
2026 p->sadb_key_bits = keylen << 3;
2027 p->sadb_key_reserved = 0;
2028
2029 memcpy(p + 1, key, keylen);
2030
2031 return buf + len;
2032}
2033
2034/*
2035 * set sadb_lifetime structure after clearing buffer with zero.
2036 * OUT: the pointer of buf + len.
2037 */
2038static caddr_t
2039pfkey_setsadblifetime(buf, lim, type, l_alloc, l_bytes, l_addtime, l_usetime)
2040 caddr_t buf;
2041 caddr_t lim;
2042 u_int type;
2043 u_int32_t l_alloc, l_bytes, l_addtime, l_usetime;
2044{
2045 struct sadb_lifetime *p;
2046 u_int len;
2047
2048 p = (struct sadb_lifetime *)buf;
2049 len = sizeof(struct sadb_lifetime);
2050
2051 if (buf + len > lim)
2052 return NULL;
2053
2054 memset(p, 0, len);
2055 p->sadb_lifetime_len = PFKEY_UNIT64(len);
2056 p->sadb_lifetime_exttype = type;
2057
2058 switch (type) {
2059 case SADB_EXT_LIFETIME_SOFT:
2060 p->sadb_lifetime_allocations
2061 = (l_alloc * soft_lifetime_allocations_rate) /100;
2062 p->sadb_lifetime_bytes
2063 = (l_bytes * soft_lifetime_bytes_rate) /100;
2064 p->sadb_lifetime_addtime
2065 = (l_addtime * soft_lifetime_addtime_rate) /100;
2066 p->sadb_lifetime_usetime
2067 = (l_usetime * soft_lifetime_usetime_rate) /100;
2068 break;
2069 case SADB_EXT_LIFETIME_HARD:
2070 p->sadb_lifetime_allocations = l_alloc;
2071 p->sadb_lifetime_bytes = l_bytes;
2072 p->sadb_lifetime_addtime = l_addtime;
2073 p->sadb_lifetime_usetime = l_usetime;
2074 break;
2075 }
2076
2077 return buf + len;
2078}
2079
2080/*
2081 * copy secasvar data into sadb_address.
2082 * `buf' must has been allocated sufficiently.
2083 */
2084static caddr_t
2085pfkey_setsadbxsa2(buf, lim, mode0, reqid)
2086 caddr_t buf;
2087 caddr_t lim;
2088 u_int32_t mode0;
2089 u_int32_t reqid;
2090{
2091 struct sadb_x_sa2 *p;
2092 u_int8_t mode = mode0 & 0xff;
2093 u_int len;
2094
2095 p = (struct sadb_x_sa2 *)buf;
2096 len = sizeof(struct sadb_x_sa2);
2097
2098 if (buf + len > lim)
2099 return NULL;
2100
2101 memset(p, 0, len);
2102 p->sadb_x_sa2_len = PFKEY_UNIT64(len);
2103 p->sadb_x_sa2_exttype = SADB_X_EXT_SA2;
2104 p->sadb_x_sa2_mode = mode;
2105 p->sadb_x_sa2_reqid = reqid;
2106
2107 return(buf + len);
2108}