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