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