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