Ansify some function definitions that were previously overlooked.
[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 < sizeof(supported_map)/sizeof(supported_map[0]); 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;
627                      algno < sizeof(supported_map)/sizeof(supported_map[0]);
628                      algno++) {
629                         if (ipsec_supported[algno]) {
630                                 free(ipsec_supported[algno]);
631                                 ipsec_supported[algno] = NULL;
632                         }
633                 }
634         } else {
635                 algno = findsupportedmap(satype);
636                 if (algno == -1) {
637                         __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
638                         return -1;
639                 }
640
641                 if (ipsec_supported[algno]) {
642                         free(ipsec_supported[algno]);
643                         ipsec_supported[algno] = NULL;
644                 }
645         }
646
647         if ((len = pfkey_send_x3(so, SADB_REGISTER, satype)) < 0)
648                 return -1;
649
650         return len;
651 }
652
653 /*
654  * receiving SADB_REGISTER message from the kernel, and copy buffer for
655  * sadb_supported returned into ipsec_supported.
656  * OUT:
657  *       0: success and return length sent.
658  *      -1: error occured, and set errno.
659  */
660 int
661 pfkey_recv_register(int so)
662 {
663         pid_t pid = getpid();
664         struct sadb_msg *newmsg;
665         int error = -1;
666
667         /* receive message */
668         do {
669                 if ((newmsg = pfkey_recv(so)) == NULL)
670                         return -1;
671         } while (newmsg->sadb_msg_type != SADB_REGISTER
672             || newmsg->sadb_msg_pid != pid);
673
674         /* check and fix */
675         newmsg->sadb_msg_len = PFKEY_UNUNIT64(newmsg->sadb_msg_len);
676
677         error = pfkey_set_supported(newmsg, newmsg->sadb_msg_len);
678         free(newmsg);
679
680         if (error == 0)
681                 __ipsec_errcode = EIPSEC_NO_ERROR;
682
683         return error;
684 }
685
686 /*
687  * receiving SADB_REGISTER message from the kernel, and copy buffer for
688  * sadb_supported returned into ipsec_supported.
689  * NOTE: sadb_msg_len must be host order.
690  * IN:
691  *      tlen: msg length, it's to makeing sure.
692  * OUT:
693  *       0: success and return length sent.
694  *      -1: error occured, and set errno.
695  */
696 int
697 pfkey_set_supported(struct sadb_msg *msg, int tlen)
698 {
699         struct sadb_supported *sup;
700         caddr_t p;
701         caddr_t ep;
702
703         /* validity */
704         if (msg->sadb_msg_len != tlen) {
705                 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
706                 return -1;
707         }
708
709         p = (caddr_t)msg;
710         ep = p + tlen;
711
712         p += sizeof(struct sadb_msg);
713
714         while (p < ep) {
715                 sup = (struct sadb_supported *)p;
716                 if (ep < p + sizeof(*sup) ||
717                     PFKEY_EXTLEN(sup) < sizeof(*sup) ||
718                     ep < p + sup->sadb_supported_len) {
719                         /* invalid format */
720                         break;
721                 }
722
723                 switch (sup->sadb_supported_exttype) {
724                 case SADB_EXT_SUPPORTED_AUTH:
725                 case SADB_EXT_SUPPORTED_ENCRYPT:
726                         break;
727                 default:
728                         __ipsec_errcode = EIPSEC_INVAL_SATYPE;
729                         return -1;
730                 }
731
732                 /* fixed length */
733                 sup->sadb_supported_len = PFKEY_EXTLEN(sup);
734
735                 /* set supported map */
736                 if (setsupportedmap(sup) != 0)
737                         return -1;
738
739                 p += sup->sadb_supported_len;
740         }
741
742         if (p != ep) {
743                 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
744                 return -1;
745         }
746
747         __ipsec_errcode = EIPSEC_NO_ERROR;
748
749         return 0;
750 }
751
752 /*
753  * sending SADB_FLUSH message to the kernel.
754  * OUT:
755  *      positive: success and return length sent.
756  *      -1      : error occured, and set errno.
757  */
758 int
759 pfkey_send_flush(int so, u_int satype)
760 {
761         int len;
762
763         if ((len = pfkey_send_x3(so, SADB_FLUSH, satype)) < 0)
764                 return -1;
765
766         return len;
767 }
768
769 /*
770  * sending SADB_DUMP message to the kernel.
771  * OUT:
772  *      positive: success and return length sent.
773  *      -1      : error occured, and set errno.
774  */
775 int
776 pfkey_send_dump(int so, u_int satype)
777 {
778         int len;
779
780         if ((len = pfkey_send_x3(so, SADB_DUMP, satype)) < 0)
781                 return -1;
782
783         return len;
784 }
785
786 /*
787  * sending SADB_X_PROMISC message to the kernel.
788  * NOTE that this function handles promisc mode toggle only.
789  * IN:
790  *      flag:   set promisc off if zero, set promisc on if non-zero.
791  * OUT:
792  *      positive: success and return length sent.
793  *      -1      : error occured, and set errno.
794  *      0     : error occured, and set errno.
795  *      others: a pointer to new allocated buffer in which supported
796  *              algorithms is.
797  */
798 int
799 pfkey_send_promisc_toggle(int so, int flag)
800 {
801         int len;
802
803         if ((len = pfkey_send_x3(so, SADB_X_PROMISC, (flag ? 1 : 0))) < 0)
804                 return -1;
805
806         return len;
807 }
808
809 /*
810  * sending SADB_X_SPDADD message to the kernel.
811  * OUT:
812  *      positive: success and return length sent.
813  *      -1      : error occured, and set errno.
814  */
815 int
816 pfkey_send_spdadd(int so, struct sockaddr *src, u_int prefs,
817     struct sockaddr *dst, u_int prefd, u_int proto, caddr_t policy,
818     int policylen, u_int32_t seq)
819 {
820         int len;
821
822         if ((len = pfkey_send_x4(so, SADB_X_SPDADD,
823                                 src, prefs, dst, prefd, proto,
824                                 0, 0,
825                                 policy, policylen, seq)) < 0)
826                 return -1;
827
828         return len;
829 }
830
831 /*
832  * sending SADB_X_SPDADD message to the kernel.
833  * OUT:
834  *      positive: success and return length sent.
835  *      -1      : error occured, and set errno.
836  */
837 int
838 pfkey_send_spdadd2(int so, struct sockaddr *src, u_int prefs,
839     struct sockaddr *dst, u_int prefd, u_int proto, u_int64_t ltime,
840     u_int64_t vtime, caddr_t policy, int policylen, u_int32_t seq)
841 {
842         int len;
843
844         if ((len = pfkey_send_x4(so, SADB_X_SPDADD,
845                                 src, prefs, dst, prefd, proto,
846                                 ltime, vtime,
847                                 policy, policylen, seq)) < 0)
848                 return -1;
849
850         return len;
851 }
852
853 /*
854  * sending SADB_X_SPDUPDATE message to the kernel.
855  * OUT:
856  *      positive: success and return length sent.
857  *      -1      : error occured, and set errno.
858  */
859 int
860 pfkey_send_spdupdate(int so, struct sockaddr *src, u_int prefs,
861     struct sockaddr *dst, u_int prefd, u_int proto, caddr_t policy,
862     int policylen, u_int32_t seq)
863 {
864         int len;
865
866         if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE,
867                                 src, prefs, dst, prefd, proto,
868                                 0, 0,
869                                 policy, policylen, seq)) < 0)
870                 return -1;
871
872         return len;
873 }
874
875 /*
876  * sending SADB_X_SPDUPDATE message to the kernel.
877  * OUT:
878  *      positive: success and return length sent.
879  *      -1      : error occured, and set errno.
880  */
881 int
882 pfkey_send_spdupdate2(int so, struct sockaddr *src, u_int prefs,
883     struct sockaddr *dst, u_int prefd, u_int proto, u_int64_t ltime,
884     u_int64_t vtime, caddr_t policy, int policylen, u_int32_t seq)
885 {
886         int len;
887
888         if ((len = pfkey_send_x4(so, SADB_X_SPDUPDATE,
889                                 src, prefs, dst, prefd, proto,
890                                 ltime, vtime,
891                                 policy, policylen, seq)) < 0)
892                 return -1;
893
894         return len;
895 }
896
897 /*
898  * sending SADB_X_SPDDELETE message to the kernel.
899  * OUT:
900  *      positive: success and return length sent.
901  *      -1      : error occured, and set errno.
902  */
903 int
904 pfkey_send_spddelete(int so, struct sockaddr *src, u_int prefs,
905     struct sockaddr *dst, u_int prefd, u_int proto, caddr_t policy,
906     int policylen, u_int32_t seq)
907 {
908         int len;
909
910         if (policylen != sizeof(struct sadb_x_policy)) {
911                 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
912                 return -1;
913         }
914
915         if ((len = pfkey_send_x4(so, SADB_X_SPDDELETE,
916                                 src, prefs, dst, prefd, proto,
917                                 0, 0,
918                                 policy, policylen, seq)) < 0)
919                 return -1;
920
921         return len;
922 }
923
924 /*
925  * sending SADB_X_SPDDELETE message to the kernel.
926  * OUT:
927  *      positive: success and return length sent.
928  *      -1      : error occured, and set errno.
929  */
930 int
931 pfkey_send_spddelete2(int so, u_int32_t spid)
932 {
933         int len;
934
935         if ((len = pfkey_send_x5(so, SADB_X_SPDDELETE2, spid)) < 0)
936                 return -1;
937
938         return len;
939 }
940
941 /*
942  * sending SADB_X_SPDGET message to the kernel.
943  * OUT:
944  *      positive: success and return length sent.
945  *      -1      : error occured, and set errno.
946  */
947 int
948 pfkey_send_spdget(int so, u_int32_t spid)
949 {
950         int len;
951
952         if ((len = pfkey_send_x5(so, SADB_X_SPDGET, spid)) < 0)
953                 return -1;
954
955         return len;
956 }
957
958 /*
959  * sending SADB_X_SPDSETIDX message to the kernel.
960  * OUT:
961  *      positive: success and return length sent.
962  *      -1      : error occured, and set errno.
963  */
964 int
965 pfkey_send_spdsetidx(int so, struct sockaddr *src, u_int prefs,
966     struct sockaddr *dst, u_int prefd, u_int proto, caddr_t policy,
967     int policylen, u_int32_t seq)
968 {
969         int len;
970
971         if (policylen != sizeof(struct sadb_x_policy)) {
972                 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
973                 return -1;
974         }
975
976         if ((len = pfkey_send_x4(so, SADB_X_SPDSETIDX,
977                                 src, prefs, dst, prefd, proto,
978                                 0, 0,
979                                 policy, policylen, seq)) < 0)
980                 return -1;
981
982         return len;
983 }
984
985 /*
986  * sending SADB_SPDFLUSH message to the kernel.
987  * OUT:
988  *      positive: success and return length sent.
989  *      -1      : error occured, and set errno.
990  */
991 int
992 pfkey_send_spdflush(int so)
993 {
994         int len;
995
996         if ((len = pfkey_send_x3(so, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC)) < 0)
997                 return -1;
998
999         return len;
1000 }
1001
1002 /*
1003  * sending SADB_SPDDUMP message to the kernel.
1004  * OUT:
1005  *      positive: success and return length sent.
1006  *      -1      : error occured, and set errno.
1007  */
1008 int
1009 pfkey_send_spddump(int so)
1010 {
1011         int len;
1012
1013         if ((len = pfkey_send_x3(so, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC)) < 0)
1014                 return -1;
1015
1016         return len;
1017 }
1018
1019 /* sending SADB_ADD or SADB_UPDATE message to the kernel */
1020 static int
1021 pfkey_send_x1(int so, u_int type, u_int satype, u_int mode,
1022     struct sockaddr *src, struct sockaddr *dst, u_int32_t spi, u_int32_t reqid,
1023     u_int wsize, caddr_t keymat, u_int e_type, u_int e_keylen, u_int a_type,
1024     u_int a_keylen, u_int flags,u_int32_t l_alloc, u_int32_t l_bytes,
1025     u_int32_t l_addtime, u_int32_t l_usetime, u_int32_t seq)
1026 {
1027         struct sadb_msg *newmsg;
1028         int len;
1029         caddr_t p;
1030         int plen;
1031         caddr_t ep;
1032
1033         /* validity check */
1034         if (src == NULL || dst == NULL) {
1035                 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1036                 return -1;
1037         }
1038         if (src->sa_family != dst->sa_family) {
1039                 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
1040                 return -1;
1041         }
1042         switch (src->sa_family) {
1043         case AF_INET:
1044                 plen = sizeof(struct in_addr) << 3;
1045                 break;
1046         case AF_INET6:
1047                 plen = sizeof(struct in6_addr) << 3;
1048                 break;
1049         default:
1050                 __ipsec_errcode = EIPSEC_INVAL_FAMILY;
1051                 return -1;
1052         }
1053
1054         switch (satype) {
1055         case SADB_SATYPE_ESP:
1056                 if (e_type == SADB_EALG_NONE) {
1057                         __ipsec_errcode = EIPSEC_NO_ALGS;
1058                         return -1;
1059                 }
1060                 break;
1061         case SADB_SATYPE_AH:
1062                 if (e_type != SADB_EALG_NONE) {
1063                         __ipsec_errcode = EIPSEC_INVAL_ALGS;
1064                         return -1;
1065                 }
1066                 if (a_type == SADB_AALG_NONE) {
1067                         __ipsec_errcode = EIPSEC_NO_ALGS;
1068                         return -1;
1069                 }
1070                 break;
1071         case SADB_X_SATYPE_IPCOMP:
1072                 if (e_type == SADB_X_CALG_NONE) {
1073                         __ipsec_errcode = EIPSEC_INVAL_ALGS;
1074                         return -1;
1075                 }
1076                 if (a_type != SADB_AALG_NONE) {
1077                         __ipsec_errcode = EIPSEC_NO_ALGS;
1078                         return -1;
1079                 }
1080                 break;
1081         case SADB_X_SATYPE_TCPSIGNATURE:
1082                 if (e_type != SADB_EALG_NONE) {
1083                         __ipsec_errcode = EIPSEC_INVAL_ALGS;
1084                         return -1;
1085                 }
1086                 if (a_type != SADB_X_AALG_TCP_MD5) {
1087                         __ipsec_errcode = EIPSEC_INVAL_ALGS;
1088                         return -1;
1089                 }
1090                 break;
1091         default:
1092                 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
1093                 return -1;
1094         }
1095
1096         /* create new sadb_msg to reply. */
1097         len = sizeof(struct sadb_msg)
1098                 + sizeof(struct sadb_sa)
1099                 + sizeof(struct sadb_x_sa2)
1100                 + sizeof(struct sadb_address)
1101                 + PFKEY_ALIGN8(src->sa_len)
1102                 + sizeof(struct sadb_address)
1103                 + PFKEY_ALIGN8(dst->sa_len)
1104                 + sizeof(struct sadb_lifetime)
1105                 + sizeof(struct sadb_lifetime);
1106
1107         if (e_type != SADB_EALG_NONE)
1108                 len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(e_keylen));
1109         if (a_type != SADB_AALG_NONE)
1110                 len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(a_keylen));
1111
1112         if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
1113                 __ipsec_set_strerror(strerror(errno));
1114                 return -1;
1115         }
1116         ep = ((caddr_t)newmsg) + len;
1117
1118         p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len,
1119                              satype, seq, getpid());
1120         if (!p) {
1121                 free(newmsg);
1122                 return -1;
1123         }
1124         p = pfkey_setsadbsa(p, ep, spi, wsize, a_type, e_type, flags);
1125         if (!p) {
1126                 free(newmsg);
1127                 return -1;
1128         }
1129         p = pfkey_setsadbxsa2(p, ep, mode, reqid);
1130         if (!p) {
1131                 free(newmsg);
1132                 return -1;
1133         }
1134         p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen,
1135             IPSEC_ULPROTO_ANY);
1136         if (!p) {
1137                 free(newmsg);
1138                 return -1;
1139         }
1140         p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen,
1141             IPSEC_ULPROTO_ANY);
1142         if (!p) {
1143                 free(newmsg);
1144                 return -1;
1145         }
1146
1147         if (e_type != SADB_EALG_NONE) {
1148                 p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_ENCRYPT,
1149                                    keymat, e_keylen);
1150                 if (!p) {
1151                         free(newmsg);
1152                         return -1;
1153                 }
1154         }
1155         if (a_type != SADB_AALG_NONE) {
1156                 p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_AUTH,
1157                                    keymat + e_keylen, a_keylen);
1158                 if (!p) {
1159                         free(newmsg);
1160                         return -1;
1161                 }
1162         }
1163
1164         /* set sadb_lifetime for destination */
1165         p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD,
1166                         l_alloc, l_bytes, l_addtime, l_usetime);
1167         if (!p) {
1168                 free(newmsg);
1169                 return -1;
1170         }
1171         p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_SOFT,
1172                         l_alloc, l_bytes, l_addtime, l_usetime);
1173         if (!p || p != ep) {
1174                 free(newmsg);
1175                 return -1;
1176         }
1177
1178         /* send message */
1179         len = pfkey_send(so, newmsg, len);
1180         free(newmsg);
1181
1182         if (len < 0)
1183                 return -1;
1184
1185         __ipsec_errcode = EIPSEC_NO_ERROR;
1186         return len;
1187 }
1188
1189 /* sending SADB_DELETE or SADB_GET message to the kernel */
1190 static int
1191 pfkey_send_x2(int so, u_int type, u_int satype, u_int mode,
1192     struct sockaddr *src, struct sockaddr *dst, u_int32_t spi)
1193 {
1194         struct sadb_msg *newmsg;
1195         int len;
1196         caddr_t p;
1197         int plen;
1198         caddr_t ep;
1199
1200         /* validity check */
1201         if (src == NULL || dst == NULL) {
1202                 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1203                 return -1;
1204         }
1205         if (src->sa_family != dst->sa_family) {
1206                 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
1207                 return -1;
1208         }
1209         switch (src->sa_family) {
1210         case AF_INET:
1211                 plen = sizeof(struct in_addr) << 3;
1212                 break;
1213         case AF_INET6:
1214                 plen = sizeof(struct in6_addr) << 3;
1215                 break;
1216         default:
1217                 __ipsec_errcode = EIPSEC_INVAL_FAMILY;
1218                 return -1;
1219         }
1220
1221         /* create new sadb_msg to reply. */
1222         len = sizeof(struct sadb_msg)
1223                 + sizeof(struct sadb_sa)
1224                 + sizeof(struct sadb_address)
1225                 + PFKEY_ALIGN8(src->sa_len)
1226                 + sizeof(struct sadb_address)
1227                 + PFKEY_ALIGN8(dst->sa_len);
1228
1229         if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
1230                 __ipsec_set_strerror(strerror(errno));
1231                 return -1;
1232         }
1233         ep = ((caddr_t)newmsg) + len;
1234
1235         p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len, satype, 0,
1236             getpid());
1237         if (!p) {
1238                 free(newmsg);
1239                 return -1;
1240         }
1241         p = pfkey_setsadbsa(p, ep, spi, 0, 0, 0, 0);
1242         if (!p) {
1243                 free(newmsg);
1244                 return -1;
1245         }
1246         p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen,
1247             IPSEC_ULPROTO_ANY);
1248         if (!p) {
1249                 free(newmsg);
1250                 return -1;
1251         }
1252         p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, plen,
1253             IPSEC_ULPROTO_ANY);
1254         if (!p || p != ep) {
1255                 free(newmsg);
1256                 return -1;
1257         }
1258
1259         /* send message */
1260         len = pfkey_send(so, newmsg, len);
1261         free(newmsg);
1262
1263         if (len < 0)
1264                 return -1;
1265
1266         __ipsec_errcode = EIPSEC_NO_ERROR;
1267         return len;
1268 }
1269
1270 /*
1271  * sending SADB_REGISTER, SADB_FLUSH, SADB_DUMP or SADB_X_PROMISC message
1272  * to the kernel
1273  */
1274 static int
1275 pfkey_send_x3(int so, u_int type, u_int satype)
1276 {
1277         struct sadb_msg *newmsg;
1278         int len;
1279         caddr_t p;
1280         caddr_t ep;
1281
1282         /* validity check */
1283         switch (type) {
1284         case SADB_X_PROMISC:
1285                 if (satype != 0 && satype != 1) {
1286                         __ipsec_errcode = EIPSEC_INVAL_SATYPE;
1287                         return -1;
1288                 }
1289                 break;
1290         default:
1291                 switch (satype) {
1292                 case SADB_SATYPE_UNSPEC:
1293                 case SADB_SATYPE_AH:
1294                 case SADB_SATYPE_ESP:
1295                 case SADB_X_SATYPE_IPCOMP:
1296                 case SADB_X_SATYPE_TCPSIGNATURE:
1297                         break;
1298                 default:
1299                         __ipsec_errcode = EIPSEC_INVAL_SATYPE;
1300                         return -1;
1301                 }
1302         }
1303
1304         /* create new sadb_msg to send. */
1305         len = sizeof(struct sadb_msg);
1306
1307         if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
1308                 __ipsec_set_strerror(strerror(errno));
1309                 return -1;
1310         }
1311         ep = ((caddr_t)newmsg) + len;
1312
1313         p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len, satype, 0,
1314             getpid());
1315         if (!p || p != ep) {
1316                 free(newmsg);
1317                 return -1;
1318         }
1319
1320         /* send message */
1321         len = pfkey_send(so, newmsg, len);
1322         free(newmsg);
1323
1324         if (len < 0)
1325                 return -1;
1326
1327         __ipsec_errcode = EIPSEC_NO_ERROR;
1328         return len;
1329 }
1330
1331 /* sending SADB_X_SPDADD message to the kernel */
1332 static int
1333 pfkey_send_x4(int so, u_int type, struct sockaddr *src, u_int prefs,
1334     struct sockaddr *dst, u_int prefd, u_int proto, u_int64_t ltime,
1335     u_int64_t vtime, char *policy, int policylen, u_int32_t seq)
1336 {
1337         struct sadb_msg *newmsg;
1338         int len;
1339         caddr_t p;
1340         int plen;
1341         caddr_t ep;
1342
1343         /* validity check */
1344         if (src == NULL || dst == NULL) {
1345                 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1346                 return -1;
1347         }
1348         if (src->sa_family != dst->sa_family) {
1349                 __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
1350                 return -1;
1351         }
1352
1353         switch (src->sa_family) {
1354         case AF_INET:
1355                 plen = sizeof(struct in_addr) << 3;
1356                 break;
1357         case AF_INET6:
1358                 plen = sizeof(struct in6_addr) << 3;
1359                 break;
1360         default:
1361                 __ipsec_errcode = EIPSEC_INVAL_FAMILY;
1362                 return -1;
1363         }
1364         if (prefs > plen || prefd > plen) {
1365                 __ipsec_errcode = EIPSEC_INVAL_PREFIXLEN;
1366                 return -1;
1367         }
1368
1369         /* create new sadb_msg to reply. */
1370         len = sizeof(struct sadb_msg)
1371                 + sizeof(struct sadb_address)
1372                 + PFKEY_ALIGN8(src->sa_len)
1373                 + sizeof(struct sadb_address)
1374                 + PFKEY_ALIGN8(src->sa_len)
1375                 + sizeof(struct sadb_lifetime)
1376                 + policylen;
1377
1378         if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
1379                 __ipsec_set_strerror(strerror(errno));
1380                 return -1;
1381         }
1382         ep = ((caddr_t)newmsg) + len;
1383
1384         p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len,
1385             SADB_SATYPE_UNSPEC, seq, getpid());
1386         if (!p) {
1387                 free(newmsg);
1388                 return -1;
1389         }
1390         p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, prefs, proto);
1391         if (!p) {
1392                 free(newmsg);
1393                 return -1;
1394         }
1395         p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, prefd, proto);
1396         if (!p) {
1397                 free(newmsg);
1398                 return -1;
1399         }
1400         p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD,
1401                         0, 0, ltime, vtime);
1402         if (!p || p + policylen != ep) {
1403                 free(newmsg);
1404                 return -1;
1405         }
1406         memcpy(p, policy, policylen);
1407
1408         /* send message */
1409         len = pfkey_send(so, newmsg, len);
1410         free(newmsg);
1411
1412         if (len < 0)
1413                 return -1;
1414
1415         __ipsec_errcode = EIPSEC_NO_ERROR;
1416         return len;
1417 }
1418
1419 /* sending SADB_X_SPDGET or SADB_X_SPDDELETE message to the kernel */
1420 static int
1421 pfkey_send_x5(int so, u_int type, u_int32_t spid)
1422 {
1423         struct sadb_msg *newmsg;
1424         struct sadb_x_policy xpl;
1425         int len;
1426         caddr_t p;
1427         caddr_t ep;
1428
1429         /* create new sadb_msg to reply. */
1430         len = sizeof(struct sadb_msg)
1431                 + sizeof(xpl);
1432
1433         if ((newmsg = CALLOC(len, struct sadb_msg *)) == NULL) {
1434                 __ipsec_set_strerror(strerror(errno));
1435                 return -1;
1436         }
1437         ep = ((caddr_t)newmsg) + len;
1438
1439         p = pfkey_setsadbmsg((caddr_t)newmsg, ep, type, len,
1440             SADB_SATYPE_UNSPEC, 0, getpid());
1441         if (!p) {
1442                 free(newmsg);
1443                 return -1;
1444         }
1445
1446         if (p + sizeof(xpl) != ep) {
1447                 free(newmsg);
1448                 return -1;
1449         }
1450         memset(&xpl, 0, sizeof(xpl));
1451         xpl.sadb_x_policy_len = PFKEY_UNUNIT64(sizeof(xpl));
1452         xpl.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
1453         xpl.sadb_x_policy_id = spid;
1454         memcpy(p, &xpl, sizeof(xpl));
1455
1456         /* send message */
1457         len = pfkey_send(so, newmsg, len);
1458         free(newmsg);
1459
1460         if (len < 0)
1461                 return -1;
1462
1463         __ipsec_errcode = EIPSEC_NO_ERROR;
1464         return len;
1465 }
1466
1467 /*
1468  * open a socket.
1469  * OUT:
1470  *      -1: fail.
1471  *      others : success and return value of socket.
1472  */
1473 int
1474 pfkey_open(void)
1475 {
1476         int so;
1477         const int bufsiz = 128 * 1024;  /*is 128K enough?*/
1478
1479         if ((so = socket(PF_KEY, SOCK_RAW, PF_KEY_V2)) < 0) {
1480                 __ipsec_set_strerror(strerror(errno));
1481                 return -1;
1482         }
1483
1484         /*
1485          * This is a temporary workaround for KAME PR 154.
1486          * Don't really care even if it fails.
1487          */
1488         (void)setsockopt(so, SOL_SOCKET, SO_SNDBUF, &bufsiz, sizeof(bufsiz));
1489         (void)setsockopt(so, SOL_SOCKET, SO_RCVBUF, &bufsiz, sizeof(bufsiz));
1490
1491         __ipsec_errcode = EIPSEC_NO_ERROR;
1492         return so;
1493 }
1494
1495 /*
1496  * close a socket.
1497  * OUT:
1498  *       0: success.
1499  *      -1: fail.
1500  */
1501 void
1502 pfkey_close(int so)
1503 {
1504         (void)close(so);
1505
1506         __ipsec_errcode = EIPSEC_NO_ERROR;
1507         return;
1508 }
1509
1510 /*
1511  * receive sadb_msg data, and return pointer to new buffer allocated.
1512  * Must free this buffer later.
1513  * OUT:
1514  *      NULL    : error occured.
1515  *      others  : a pointer to sadb_msg structure.
1516  *
1517  * XXX should be rewritten to pass length explicitly
1518  */
1519 struct sadb_msg *
1520 pfkey_recv(int so)
1521 {
1522         struct sadb_msg buf, *newmsg;
1523         int len, reallen;
1524
1525         while ((len = recv(so, (caddr_t)&buf, sizeof(buf), MSG_PEEK)) < 0) {
1526                 if (errno == EINTR)
1527                         continue;
1528                 __ipsec_set_strerror(strerror(errno));
1529                 return NULL;
1530         }
1531
1532         if (len < sizeof(buf)) {
1533                 recv(so, (caddr_t)&buf, sizeof(buf), 0);
1534                 __ipsec_errcode = EIPSEC_MAX;
1535                 return NULL;
1536         }
1537
1538         /* read real message */
1539         reallen = PFKEY_UNUNIT64(buf.sadb_msg_len);
1540         if ((newmsg = CALLOC(reallen, struct sadb_msg *)) == NULL) {
1541                 __ipsec_set_strerror(strerror(errno));
1542                 return NULL;
1543         }
1544
1545         while ((len = recv(so, (caddr_t)newmsg, reallen, 0)) < 0) {
1546                 if (errno == EINTR)
1547                         continue;
1548                 __ipsec_set_strerror(strerror(errno));
1549                 free(newmsg);
1550                 return NULL;
1551         }
1552
1553         if (len != reallen) {
1554                 __ipsec_errcode = EIPSEC_SYSTEM_ERROR;
1555                 free(newmsg);
1556                 return NULL;
1557         }
1558
1559         /* don't trust what the kernel says, validate! */
1560         if (PFKEY_UNUNIT64(newmsg->sadb_msg_len) != len) {
1561                 __ipsec_errcode = EIPSEC_SYSTEM_ERROR;
1562                 free(newmsg);
1563                 return NULL;
1564         }
1565
1566         __ipsec_errcode = EIPSEC_NO_ERROR;
1567         return newmsg;
1568 }
1569
1570 /*
1571  * send message to a socket.
1572  * OUT:
1573  *       others: success and return length sent.
1574  *      -1     : fail.
1575  */
1576 int
1577 pfkey_send(int so, struct sadb_msg *msg, int len)
1578 {
1579         if ((len = send(so, (caddr_t)msg, len, 0)) < 0) {
1580                 __ipsec_set_strerror(strerror(errno));
1581                 return -1;
1582         }
1583
1584         __ipsec_errcode = EIPSEC_NO_ERROR;
1585         return len;
1586 }
1587
1588 /*
1589  * %%% Utilities
1590  * NOTE: These functions are derived from netkey/key.c in KAME.
1591  */
1592 /*
1593  * set the pointer to each header in this message buffer.
1594  * IN:  msg: pointer to message buffer.
1595  *      mhp: pointer to the buffer initialized like below:
1596  *              caddr_t mhp[SADB_EXT_MAX + 1];
1597  * OUT: -1: invalid.
1598  *       0: valid.
1599  *
1600  * XXX should be rewritten to obtain length explicitly
1601  */
1602 int
1603 pfkey_align(struct sadb_msg *msg, caddr_t *mhp)
1604 {
1605         struct sadb_ext *ext;
1606         int i;
1607         caddr_t p;
1608         caddr_t ep;     /* XXX should be passed from upper layer */
1609
1610         /* validity check */
1611         if (msg == NULL || mhp == NULL) {
1612                 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1613                 return -1;
1614         }
1615
1616         /* initialize */
1617         for (i = 0; i < SADB_EXT_MAX + 1; i++)
1618                 mhp[i] = NULL;
1619
1620         mhp[0] = (caddr_t)msg;
1621
1622         /* initialize */
1623         p = (caddr_t) msg;
1624         ep = p + PFKEY_UNUNIT64(msg->sadb_msg_len);
1625
1626         /* skip base header */
1627         p += sizeof(struct sadb_msg);
1628
1629         while (p < ep) {
1630                 ext = (struct sadb_ext *)p;
1631                 if (ep < p + sizeof(*ext) || PFKEY_EXTLEN(ext) < sizeof(*ext) ||
1632                     ep < p + PFKEY_EXTLEN(ext)) {
1633                         /* invalid format */
1634                         break;
1635                 }
1636
1637                 /* duplicate check */
1638                 /* XXX Are there duplication either KEY_AUTH or KEY_ENCRYPT ?*/
1639                 if (mhp[ext->sadb_ext_type] != NULL) {
1640                         __ipsec_errcode = EIPSEC_INVAL_EXTTYPE;
1641                         return -1;
1642                 }
1643
1644                 /* set pointer */
1645                 switch (ext->sadb_ext_type) {
1646                 case SADB_EXT_SA:
1647                 case SADB_EXT_LIFETIME_CURRENT:
1648                 case SADB_EXT_LIFETIME_HARD:
1649                 case SADB_EXT_LIFETIME_SOFT:
1650                 case SADB_EXT_ADDRESS_SRC:
1651                 case SADB_EXT_ADDRESS_DST:
1652                 case SADB_EXT_ADDRESS_PROXY:
1653                 case SADB_EXT_KEY_AUTH:
1654                         /* XXX should to be check weak keys. */
1655                 case SADB_EXT_KEY_ENCRYPT:
1656                         /* XXX should to be check weak keys. */
1657                 case SADB_EXT_IDENTITY_SRC:
1658                 case SADB_EXT_IDENTITY_DST:
1659                 case SADB_EXT_SENSITIVITY:
1660                 case SADB_EXT_PROPOSAL:
1661                 case SADB_EXT_SUPPORTED_AUTH:
1662                 case SADB_EXT_SUPPORTED_ENCRYPT:
1663                 case SADB_EXT_SPIRANGE:
1664                 case SADB_X_EXT_POLICY:
1665                 case SADB_X_EXT_SA2:
1666                         mhp[ext->sadb_ext_type] = (caddr_t)ext;
1667                         break;
1668                 default:
1669                         __ipsec_errcode = EIPSEC_INVAL_EXTTYPE;
1670                         return -1;
1671                 }
1672
1673                 p += PFKEY_EXTLEN(ext);
1674         }
1675
1676         if (p != ep) {
1677                 __ipsec_errcode = EIPSEC_INVAL_SADBMSG;
1678                 return -1;
1679         }
1680
1681         __ipsec_errcode = EIPSEC_NO_ERROR;
1682         return 0;
1683 }
1684
1685 /*
1686  * check basic usage for sadb_msg,
1687  * NOTE: This routine is derived from netkey/key.c in KAME.
1688  * IN:  msg: pointer to message buffer.
1689  *      mhp: pointer to the buffer initialized like below:
1690  *
1691  *              caddr_t mhp[SADB_EXT_MAX + 1];
1692  *
1693  * OUT: -1: invalid.
1694  *       0: valid.
1695  */
1696 int
1697 pfkey_check(caddr_t *mhp)
1698 {
1699         struct sadb_msg *msg;
1700
1701         /* validity check */
1702         if (mhp == NULL || mhp[0] == NULL) {
1703                 __ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
1704                 return -1;
1705         }
1706
1707         msg = (struct sadb_msg *)mhp[0];
1708
1709         /* check version */
1710         if (msg->sadb_msg_version != PF_KEY_V2) {
1711                 __ipsec_errcode = EIPSEC_INVAL_VERSION;
1712                 return -1;
1713         }
1714
1715         /* check type */
1716         if (msg->sadb_msg_type > SADB_MAX) {
1717                 __ipsec_errcode = EIPSEC_INVAL_MSGTYPE;
1718                 return -1;
1719         }
1720
1721         /* check SA type */
1722         switch (msg->sadb_msg_satype) {
1723         case SADB_SATYPE_UNSPEC:
1724                 switch (msg->sadb_msg_type) {
1725                 case SADB_GETSPI:
1726                 case SADB_UPDATE:
1727                 case SADB_ADD:
1728                 case SADB_DELETE:
1729                 case SADB_GET:
1730                 case SADB_ACQUIRE:
1731                 case SADB_EXPIRE:
1732                         __ipsec_errcode = EIPSEC_INVAL_SATYPE;
1733                         return -1;
1734                 }
1735                 break;
1736         case SADB_SATYPE_ESP:
1737         case SADB_SATYPE_AH:
1738         case SADB_X_SATYPE_IPCOMP:
1739         case SADB_X_SATYPE_TCPSIGNATURE:
1740                 switch (msg->sadb_msg_type) {
1741                 case SADB_X_SPDADD:
1742                 case SADB_X_SPDDELETE:
1743                 case SADB_X_SPDGET:
1744                 case SADB_X_SPDDUMP:
1745                 case SADB_X_SPDFLUSH:
1746                         __ipsec_errcode = EIPSEC_INVAL_SATYPE;
1747                         return -1;
1748                 }
1749                 break;
1750         case SADB_SATYPE_RSVP:
1751         case SADB_SATYPE_OSPFV2:
1752         case SADB_SATYPE_RIPV2:
1753         case SADB_SATYPE_MIP:
1754                 __ipsec_errcode = EIPSEC_NOT_SUPPORTED;
1755                 return -1;
1756         case 1: /* XXX: What does it do ? */
1757                 if (msg->sadb_msg_type == SADB_X_PROMISC)
1758                         break;
1759                 /*FALLTHROUGH*/
1760         default:
1761                 __ipsec_errcode = EIPSEC_INVAL_SATYPE;
1762                 return -1;
1763         }
1764
1765         /* check field of upper layer protocol and address family */
1766         if (mhp[SADB_EXT_ADDRESS_SRC] != NULL
1767          && mhp[SADB_EXT_ADDRESS_DST] != NULL) {
1768                 struct sadb_address *src0, *dst0;
1769
1770                 src0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_SRC]);
1771                 dst0 = (struct sadb_address *)(mhp[SADB_EXT_ADDRESS_DST]);
1772
1773                 if (src0->sadb_address_proto != dst0->sadb_address_proto) {
1774                         __ipsec_errcode = EIPSEC_PROTO_MISMATCH;
1775                         return -1;
1776                 }
1777
1778                 if (PFKEY_ADDR_SADDR(src0)->sa_family
1779                  != PFKEY_ADDR_SADDR(dst0)->sa_family) {
1780                         __ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
1781                         return -1;
1782                 }
1783
1784                 switch (PFKEY_ADDR_SADDR(src0)->sa_family) {
1785                 case AF_INET:
1786                 case AF_INET6:
1787                         break;
1788                 default:
1789                         __ipsec_errcode = EIPSEC_INVAL_FAMILY;
1790                         return -1;
1791                 }
1792
1793                 /*
1794                  * prefixlen == 0 is valid because there must be the case
1795                  * all addresses are matched.
1796                  */
1797         }
1798
1799         __ipsec_errcode = EIPSEC_NO_ERROR;
1800         return 0;
1801 }
1802
1803 /*
1804  * set data into sadb_msg.
1805  * `buf' must has been allocated sufficiently.
1806  */
1807 static caddr_t
1808 pfkey_setsadbmsg(caddr_t buf, caddr_t lim, u_int type, u_int tlen,
1809     u_int satype, u_int32_t seq, pid_t pid)
1810 {
1811         struct sadb_msg *p;
1812         u_int len;
1813
1814         p = (struct sadb_msg *)buf;
1815         len = sizeof(struct sadb_msg);
1816
1817         if (buf + len > lim)
1818                 return NULL;
1819
1820         memset(p, 0, len);
1821         p->sadb_msg_version = PF_KEY_V2;
1822         p->sadb_msg_type = type;
1823         p->sadb_msg_errno = 0;
1824         p->sadb_msg_satype = satype;
1825         p->sadb_msg_len = PFKEY_UNIT64(tlen);
1826         p->sadb_msg_reserved = 0;
1827         p->sadb_msg_seq = seq;
1828         p->sadb_msg_pid = (u_int32_t)pid;
1829
1830         return(buf + len);
1831 }
1832
1833 /*
1834  * copy secasvar data into sadb_address.
1835  * `buf' must has been allocated sufficiently.
1836  */
1837 static caddr_t
1838 pfkey_setsadbsa(caddr_t buf, caddr_t lim, u_int32_t spi, u_int wsize,
1839     u_int auth, u_int enc, u_int32_t flags)
1840 {
1841         struct sadb_sa *p;
1842         u_int len;
1843
1844         p = (struct sadb_sa *)buf;
1845         len = sizeof(struct sadb_sa);
1846
1847         if (buf + len > lim)
1848                 return NULL;
1849
1850         memset(p, 0, len);
1851         p->sadb_sa_len = PFKEY_UNIT64(len);
1852         p->sadb_sa_exttype = SADB_EXT_SA;
1853         p->sadb_sa_spi = spi;
1854         p->sadb_sa_replay = wsize;
1855         p->sadb_sa_state = SADB_SASTATE_LARVAL;
1856         p->sadb_sa_auth = auth;
1857         p->sadb_sa_encrypt = enc;
1858         p->sadb_sa_flags = flags;
1859
1860         return(buf + len);
1861 }
1862
1863 /*
1864  * set data into sadb_address.
1865  * `buf' must has been allocated sufficiently.
1866  * prefixlen is in bits.
1867  */
1868 static caddr_t
1869 pfkey_setsadbaddr(caddr_t buf, caddr_t lim, u_int exttype,
1870     struct sockaddr *saddr, u_int prefixlen, u_int ul_proto)
1871 {
1872         struct sadb_address *p;
1873         u_int len;
1874
1875         p = (struct sadb_address *)buf;
1876         len = sizeof(struct sadb_address) + PFKEY_ALIGN8(saddr->sa_len);
1877
1878         if (buf + len > lim)
1879                 return NULL;
1880
1881         memset(p, 0, len);
1882         p->sadb_address_len = PFKEY_UNIT64(len);
1883         p->sadb_address_exttype = exttype & 0xffff;
1884         p->sadb_address_proto = ul_proto & 0xff;
1885         p->sadb_address_prefixlen = prefixlen;
1886         p->sadb_address_reserved = 0;
1887
1888         memcpy(p + 1, saddr, saddr->sa_len);
1889
1890         return(buf + len);
1891 }
1892
1893 /*
1894  * set sadb_key structure after clearing buffer with zero.
1895  * OUT: the pointer of buf + len.
1896  */
1897 static caddr_t
1898 pfkey_setsadbkey(caddr_t buf, caddr_t lim, u_int type, caddr_t key,
1899     u_int keylen)
1900 {
1901         struct sadb_key *p;
1902         u_int len;
1903
1904         p = (struct sadb_key *)buf;
1905         len = sizeof(struct sadb_key) + PFKEY_ALIGN8(keylen);
1906
1907         if (buf + len > lim)
1908                 return NULL;
1909
1910         memset(p, 0, len);
1911         p->sadb_key_len = PFKEY_UNIT64(len);
1912         p->sadb_key_exttype = type;
1913         p->sadb_key_bits = keylen << 3;
1914         p->sadb_key_reserved = 0;
1915
1916         memcpy(p + 1, key, keylen);
1917
1918         return buf + len;
1919 }
1920
1921 /*
1922  * set sadb_lifetime structure after clearing buffer with zero.
1923  * OUT: the pointer of buf + len.
1924  */
1925 static caddr_t
1926 pfkey_setsadblifetime(caddr_t buf, caddr_t lim, u_int type, u_int32_t l_alloc,
1927     u_int32_t l_bytes, u_int32_t l_addtime, u_int32_t l_usetime)
1928 {
1929         struct sadb_lifetime *p;
1930         u_int len;
1931
1932         p = (struct sadb_lifetime *)buf;
1933         len = sizeof(struct sadb_lifetime);
1934
1935         if (buf + len > lim)
1936                 return NULL;
1937
1938         memset(p, 0, len);
1939         p->sadb_lifetime_len = PFKEY_UNIT64(len);
1940         p->sadb_lifetime_exttype = type;
1941
1942         switch (type) {
1943         case SADB_EXT_LIFETIME_SOFT:
1944                 p->sadb_lifetime_allocations
1945                         = (l_alloc * soft_lifetime_allocations_rate) /100;
1946                 p->sadb_lifetime_bytes
1947                         = (l_bytes * soft_lifetime_bytes_rate) /100;
1948                 p->sadb_lifetime_addtime
1949                         = (l_addtime * soft_lifetime_addtime_rate) /100;
1950                 p->sadb_lifetime_usetime
1951                         = (l_usetime * soft_lifetime_usetime_rate) /100;
1952                 break;
1953         case SADB_EXT_LIFETIME_HARD:
1954                 p->sadb_lifetime_allocations = l_alloc;
1955                 p->sadb_lifetime_bytes = l_bytes;
1956                 p->sadb_lifetime_addtime = l_addtime;
1957                 p->sadb_lifetime_usetime = l_usetime;
1958                 break;
1959         }
1960
1961         return buf + len;
1962 }
1963
1964 /*
1965  * copy secasvar data into sadb_address.
1966  * `buf' must has been allocated sufficiently.
1967  */
1968 static caddr_t
1969 pfkey_setsadbxsa2(caddr_t buf, caddr_t lim, u_int32_t mode0, u_int32_t reqid)
1970 {
1971         struct sadb_x_sa2 *p;
1972         u_int8_t mode = mode0 & 0xff;
1973         u_int len;
1974
1975         p = (struct sadb_x_sa2 *)buf;
1976         len = sizeof(struct sadb_x_sa2);
1977
1978         if (buf + len > lim)
1979                 return NULL;
1980
1981         memset(p, 0, len);
1982         p->sadb_x_sa2_len = PFKEY_UNIT64(len);
1983         p->sadb_x_sa2_exttype = SADB_X_EXT_SA2;
1984         p->sadb_x_sa2_mode = mode;
1985         p->sadb_x_sa2_reqid = reqid;
1986
1987         return(buf + len);
1988 }