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