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