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