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