add missing lwkt_msg to manually specified syscall args structure.
[dragonfly.git] / sys / netproto / ipsec / ipsec.c
1 /*      $FreeBSD: src/sys/netipsec/ipsec.c,v 1.2.2.1 2003/01/24 05:11:35 sam Exp $      */
2 /*      $DragonFly: src/sys/netproto/ipsec/ipsec.c,v 1.2 2003/06/17 04:28:53 dillon Exp $       */
3 /*      $KAME: ipsec.c,v 1.103 2001/05/24 07:14:18 sakane Exp $ */
4
5 /*
6  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. Neither the name of the project nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33
34 /*
35  * IPsec controller part.
36  */
37
38 #include "opt_inet.h"
39 #include "opt_inet6.h"
40 #include "opt_ipsec.h"
41
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/malloc.h>
45 #include <sys/mbuf.h>
46 #include <sys/domain.h>
47 #include <sys/protosw.h>
48 #include <sys/socket.h>
49 #include <sys/socketvar.h>
50 #include <sys/errno.h>
51 #include <sys/time.h>
52 #include <sys/kernel.h>
53 #include <sys/syslog.h>
54 #include <sys/sysctl.h>
55 #include <sys/proc.h>
56
57 #include <net/if.h>
58 #include <net/route.h>
59
60 #include <netinet/in.h>
61 #include <netinet/in_systm.h>
62 #include <netinet/ip.h>
63 #include <netinet/ip_var.h>
64 #include <netinet/in_var.h>
65 #include <netinet/udp.h>
66 #include <netinet/udp_var.h>
67 #include <netinet/tcp.h>
68 #include <netinet/udp.h>
69
70 #include <netinet/ip6.h>
71 #ifdef INET6
72 #include <netinet6/ip6_var.h>
73 #endif
74 #include <netinet/in_pcb.h>
75 #ifdef INET6
76 #include <netinet/icmp6.h>
77 #endif
78
79 #include <netipsec/ipsec.h>
80 #ifdef INET6
81 #include <netipsec/ipsec6.h>
82 #endif
83 #include <netipsec/ah_var.h>
84 #include <netipsec/esp_var.h>
85 #include <netipsec/ipcomp.h>            /*XXX*/
86 #include <netipsec/ipcomp_var.h>
87
88 #include <netipsec/key.h>
89 #include <netipsec/keydb.h>
90 #include <netipsec/key_debug.h>
91
92 #include <netipsec/xform.h>
93
94 #include <machine/in_cksum.h>
95
96 #include <net/net_osdep.h>
97
98 #ifdef IPSEC_DEBUG
99 int ipsec_debug = 1;
100 #else
101 int ipsec_debug = 0;
102 #endif
103
104 /* NB: name changed so netstat doesn't use it */
105 struct newipsecstat newipsecstat;
106 int ip4_ah_offsetmask = 0;      /* maybe IP_DF? */
107 int ip4_ipsec_dfbit = 0;        /* DF bit on encap. 0: clear 1: set 2: copy */
108 int ip4_esp_trans_deflev = IPSEC_LEVEL_USE;
109 int ip4_esp_net_deflev = IPSEC_LEVEL_USE;
110 int ip4_ah_trans_deflev = IPSEC_LEVEL_USE;
111 int ip4_ah_net_deflev = IPSEC_LEVEL_USE;
112 struct secpolicy ip4_def_policy;
113 int ip4_ipsec_ecn = 0;          /* ECN ignore(-1)/forbidden(0)/allowed(1) */
114 int ip4_esp_randpad = -1;
115 /*
116  * Crypto support requirements:
117  *
118  *  1   require hardware support
119  * -1   require software support
120  *  0   take anything
121  */
122 int     crypto_support = 0;
123
124 SYSCTL_DECL(_net_inet_ipsec);
125
126 /* net.inet.ipsec */
127 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_POLICY,
128         def_policy, CTLFLAG_RW, &ip4_def_policy.policy, 0, "");
129 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev,
130         CTLFLAG_RW, &ip4_esp_trans_deflev,      0, "");
131 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev,
132         CTLFLAG_RW, &ip4_esp_net_deflev,        0, "");
133 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev,
134         CTLFLAG_RW, &ip4_ah_trans_deflev,       0, "");
135 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev,
136         CTLFLAG_RW, &ip4_ah_net_deflev, 0, "");
137 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_CLEARTOS,
138         ah_cleartos, CTLFLAG_RW,        &ah_cleartos,   0, "");
139 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_OFFSETMASK,
140         ah_offsetmask, CTLFLAG_RW,      &ip4_ah_offsetmask,     0, "");
141 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DFBIT,
142         dfbit, CTLFLAG_RW,      &ip4_ipsec_dfbit,       0, "");
143 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ECN,
144         ecn, CTLFLAG_RW,        &ip4_ipsec_ecn, 0, "");
145 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEBUG,
146         debug, CTLFLAG_RW,      &ipsec_debug,   0, "");
147 SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ESP_RANDPAD,
148         esp_randpad, CTLFLAG_RW,        &ip4_esp_randpad,       0, "");
149 SYSCTL_INT(_net_inet_ipsec, OID_AUTO,
150         crypto_support, CTLFLAG_RW,     &crypto_support,0, "");
151 SYSCTL_STRUCT(_net_inet_ipsec, OID_AUTO,
152         ipsecstats,     CTLFLAG_RD,     &newipsecstat,  newipsecstat, "");
153
154 #ifdef INET6
155 int ip6_esp_trans_deflev = IPSEC_LEVEL_USE;
156 int ip6_esp_net_deflev = IPSEC_LEVEL_USE;
157 int ip6_ah_trans_deflev = IPSEC_LEVEL_USE;
158 int ip6_ah_net_deflev = IPSEC_LEVEL_USE;
159 int ip6_ipsec_ecn = 0;          /* ECN ignore(-1)/forbidden(0)/allowed(1) */
160 int ip6_esp_randpad = -1;
161
162 SYSCTL_DECL(_net_inet6_ipsec6);
163
164 /* net.inet6.ipsec6 */
165 #ifdef COMPAT_KAME
166 SYSCTL_OID(_net_inet6_ipsec6, IPSECCTL_STATS, stats, CTLFLAG_RD,
167         0,0, compat_ipsecstats_sysctl, "S", "");
168 #endif /* COMPAT_KAME */
169 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_POLICY,
170         def_policy, CTLFLAG_RW, &ip4_def_policy.policy, 0, "");
171 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev,
172         CTLFLAG_RW, &ip6_esp_trans_deflev,      0, "");
173 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev,
174         CTLFLAG_RW, &ip6_esp_net_deflev,        0, "");
175 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev,
176         CTLFLAG_RW, &ip6_ah_trans_deflev,       0, "");
177 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev,
178         CTLFLAG_RW, &ip6_ah_net_deflev, 0, "");
179 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ECN,
180         ecn, CTLFLAG_RW,        &ip6_ipsec_ecn, 0, "");
181 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEBUG,
182         debug, CTLFLAG_RW,      &ipsec_debug,   0, "");
183 SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ESP_RANDPAD,
184         esp_randpad, CTLFLAG_RW,        &ip6_esp_randpad,       0, "");
185 #endif /* INET6 */
186
187 static int ipsec4_setspidx_inpcb __P((struct mbuf *, struct inpcb *pcb));
188 #ifdef INET6
189 static int ipsec6_setspidx_in6pcb __P((struct mbuf *, struct in6pcb *pcb));
190 #endif
191 static int ipsec_setspidx __P((struct mbuf *, struct secpolicyindex *, int));
192 static void ipsec4_get_ulp __P((struct mbuf *m, struct secpolicyindex *, int));
193 static int ipsec4_setspidx_ipaddr __P((struct mbuf *, struct secpolicyindex *));
194 #ifdef INET6
195 static void ipsec6_get_ulp __P((struct mbuf *m, struct secpolicyindex *, int));
196 static int ipsec6_setspidx_ipaddr __P((struct mbuf *, struct secpolicyindex *));
197 #endif
198 static void ipsec_delpcbpolicy __P((struct inpcbpolicy *));
199 static struct secpolicy *ipsec_deepcopy_policy __P((struct secpolicy *src));
200 static int ipsec_set_policy __P((struct secpolicy **pcb_sp,
201         int optname, caddr_t request, size_t len, int priv));
202 static int ipsec_get_policy __P((struct secpolicy *pcb_sp, struct mbuf **mp));
203 static void vshiftl __P((unsigned char *, int, int));
204 static size_t ipsec_hdrsiz __P((struct secpolicy *));
205
206 /*
207  * Return a held reference to the default SP.
208  */
209 static struct secpolicy *
210 key_allocsp_default(const char* where, int tag)
211 {
212         struct secpolicy *sp;
213
214         KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
215                 printf("DP key_allocsp_default from %s:%u\n", where, tag));
216
217         sp = &ip4_def_policy;
218         if (sp->policy != IPSEC_POLICY_DISCARD &&
219             sp->policy != IPSEC_POLICY_NONE) {
220                 ipseclog((LOG_INFO, "fixed system default policy: %d->%d\n",
221                     sp->policy, IPSEC_POLICY_NONE));
222                 sp->policy = IPSEC_POLICY_NONE;
223         }
224         sp->refcnt++;
225
226         KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
227                 printf("DP key_allocsp_default returns SP:%p (%u)\n",
228                         sp, sp->refcnt));
229         return sp;
230 }
231 #define KEY_ALLOCSP_DEFAULT() \
232         key_allocsp_default(__FILE__, __LINE__)
233
234 /*
235  * For OUTBOUND packet having a socket. Searching SPD for packet,
236  * and return a pointer to SP.
237  * OUT: NULL:   no apropreate SP found, the following value is set to error.
238  *              0       : bypass
239  *              EACCES  : discard packet.
240  *              ENOENT  : ipsec_acquire() in progress, maybe.
241  *              others  : error occured.
242  *      others: a pointer to SP
243  *
244  * NOTE: IPv6 mapped adddress concern is implemented here.
245  */
246 struct secpolicy *
247 ipsec_getpolicy(struct tdb_ident *tdbi, u_int dir)
248 {
249         struct secpolicy *sp;
250
251         KASSERT(tdbi != NULL, ("ipsec_getpolicy: null tdbi"));
252         KASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
253                 ("ipsec_getpolicy: invalid direction %u", dir));
254
255         sp = KEY_ALLOCSP2(tdbi->spi, &tdbi->dst, tdbi->proto, dir);
256         if (sp == NULL)                 /*XXX????*/
257                 sp = KEY_ALLOCSP_DEFAULT();
258         KASSERT(sp != NULL, ("ipsec_getpolicy: null SP"));
259         return sp;
260 }
261
262 /*
263  * For OUTBOUND packet having a socket. Searching SPD for packet,
264  * and return a pointer to SP.
265  * OUT: NULL:   no apropreate SP found, the following value is set to error.
266  *              0       : bypass
267  *              EACCES  : discard packet.
268  *              ENOENT  : ipsec_acquire() in progress, maybe.
269  *              others  : error occured.
270  *      others: a pointer to SP
271  *
272  * NOTE: IPv6 mapped adddress concern is implemented here.
273  */
274 struct secpolicy *
275 ipsec_getpolicybysock(m, dir, inp, error)
276         struct mbuf *m;
277         u_int dir;
278         struct inpcb *inp;
279         int *error;
280 {
281         struct inpcbpolicy *pcbsp = NULL;
282         struct secpolicy *currsp = NULL;        /* policy on socket */
283         struct secpolicy *sp;
284         int af;
285
286         KASSERT(m != NULL, ("ipsec_getpolicybysock: null mbuf"));
287         KASSERT(inp != NULL, ("ipsec_getpolicybysock: null inpcb"));
288         KASSERT(error != NULL, ("ipsec_getpolicybysock: null error"));
289         KASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
290                 ("ipsec_getpolicybysock: invalid direction %u", dir));
291
292         af = inp->inp_socket->so_proto->pr_domain->dom_family;
293         KASSERT(af == AF_INET || af == AF_INET6,
294                 ("ipsec_getpolicybysock: unexpected protocol family %u", af));
295
296         switch (af) {
297         case AF_INET:
298                 /* set spidx in pcb */
299                 *error = ipsec4_setspidx_inpcb(m, inp);
300                 pcbsp = inp->inp_sp;
301                 break;
302 #ifdef INET6
303         case AF_INET6:
304                 /* set spidx in pcb */
305                 *error = ipsec6_setspidx_in6pcb(m, inp);
306                 pcbsp = inp->in6p_sp;
307                 break;
308 #endif
309         default:
310                 *error = EPFNOSUPPORT;
311                 break;
312         }
313         if (*error)
314                 return NULL;
315
316         KASSERT(pcbsp != NULL, ("ipsec_getpolicybysock: null pcbsp"));
317         switch (dir) {
318         case IPSEC_DIR_INBOUND:
319                 currsp = pcbsp->sp_in;
320                 break;
321         case IPSEC_DIR_OUTBOUND:
322                 currsp = pcbsp->sp_out;
323                 break;
324         }
325         KASSERT(currsp != NULL, ("ipsec_getpolicybysock: null currsp"));
326
327         if (pcbsp->priv) {                      /* when privilieged socket */
328                 switch (currsp->policy) {
329                 case IPSEC_POLICY_BYPASS:
330                 case IPSEC_POLICY_IPSEC:
331                         currsp->refcnt++;
332                         sp = currsp;
333                         break;
334
335                 case IPSEC_POLICY_ENTRUST:
336                         /* look for a policy in SPD */
337                         sp = KEY_ALLOCSP(&currsp->spidx, dir);
338                         if (sp == NULL)         /* no SP found */
339                                 sp = KEY_ALLOCSP_DEFAULT();
340                         break;
341
342                 default:
343                         ipseclog((LOG_ERR, "ipsec_getpolicybysock: "
344                               "Invalid policy for PCB %d\n", currsp->policy));
345                         *error = EINVAL;
346                         return NULL;
347                 }
348         } else {                                /* unpriv, SPD has policy */
349                 sp = KEY_ALLOCSP(&currsp->spidx, dir);
350                 if (sp == NULL) {               /* no SP found */
351                         switch (currsp->policy) {
352                         case IPSEC_POLICY_BYPASS:
353                                 ipseclog((LOG_ERR, "ipsec_getpolicybysock: "
354                                        "Illegal policy for non-priviliged defined %d\n",
355                                         currsp->policy));
356                                 *error = EINVAL;
357                                 return NULL;
358
359                         case IPSEC_POLICY_ENTRUST:
360                                 sp = KEY_ALLOCSP_DEFAULT();
361                                 break;
362
363                         case IPSEC_POLICY_IPSEC:
364                                 currsp->refcnt++;
365                                 sp = currsp;
366                                 break;
367
368                         default:
369                                 ipseclog((LOG_ERR, "ipsec_getpolicybysock: "
370                                    "Invalid policy for PCB %d\n", currsp->policy));
371                                 *error = EINVAL;
372                                 return NULL;
373                         }
374                 }
375         }
376         KASSERT(sp != NULL,
377                 ("ipsec_getpolicybysock: null SP (priv %u policy %u",
378                  pcbsp->priv, currsp->policy));
379         KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
380                 printf("DP ipsec_getpolicybysock (priv %u policy %u) allocates "
381                        "SP:%p (refcnt %u)\n", pcbsp->priv, currsp->policy,
382                        sp, sp->refcnt));
383         return sp;
384 }
385
386 /*
387  * For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet,
388  * and return a pointer to SP.
389  * OUT: positive: a pointer to the entry for security policy leaf matched.
390  *      NULL:   no apropreate SP found, the following value is set to error.
391  *              0       : bypass
392  *              EACCES  : discard packet.
393  *              ENOENT  : ipsec_acquire() in progress, maybe.
394  *              others  : error occured.
395  */
396 struct secpolicy *
397 ipsec_getpolicybyaddr(m, dir, flag, error)
398         struct mbuf *m;
399         u_int dir;
400         int flag;
401         int *error;
402 {
403         struct secpolicyindex spidx;
404         struct secpolicy *sp;
405
406         KASSERT(m != NULL, ("ipsec_getpolicybyaddr: null mbuf"));
407         KASSERT(error != NULL, ("ipsec_getpolicybyaddr: null error"));
408         KASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
409                 ("ipsec4_getpolicybaddr: invalid direction %u", dir));
410
411         sp = NULL;
412         if (key_havesp(dir)) {
413                 /* Make an index to look for a policy. */
414                 *error = ipsec_setspidx(m, &spidx,
415                                         (flag & IP_FORWARDING) ? 0 : 1);
416                 if (*error != 0) {
417                         DPRINTF(("ipsec_getpolicybyaddr: setpidx failed,"
418                                 " dir %u flag %u\n", dir, flag));
419                         bzero(&spidx, sizeof (spidx));
420                         return NULL;
421                 }
422                 spidx.dir = dir;
423
424                 sp = KEY_ALLOCSP(&spidx, dir);
425         }
426         if (sp == NULL)                 /* no SP found, use system default */
427                 sp = KEY_ALLOCSP_DEFAULT();
428         KASSERT(sp != NULL, ("ipsec_getpolicybyaddr: null SP"));
429         return sp;
430 }
431
432 struct secpolicy *
433 ipsec4_checkpolicy(m, dir, flag, error, inp)
434         struct mbuf *m;
435         u_int dir, flag;
436         int *error;
437         struct inpcb *inp;
438 {
439         struct secpolicy *sp;
440
441         *error = 0;
442         if (inp == NULL)
443                 sp = ipsec_getpolicybyaddr(m, dir, flag, error);
444         else
445                 sp = ipsec_getpolicybysock(m, dir, inp, error);
446         if (sp == NULL) {
447                 KASSERT(*error != 0,
448                         ("ipsec4_checkpolicy: getpolicy failed w/o error"));
449                 newipsecstat.ips_out_inval++;
450                 return NULL;
451         }
452         KASSERT(*error == 0,
453                 ("ipsec4_checkpolicy: sp w/ error set to %u", *error));
454         switch (sp->policy) {
455         case IPSEC_POLICY_ENTRUST:
456         default:
457                 printf("ipsec4_checkpolicy: invalid policy %u\n", sp->policy);
458                 /* fall thru... */
459         case IPSEC_POLICY_DISCARD:
460                 newipsecstat.ips_out_polvio++;
461                 *error = -EINVAL;       /* packet is discarded by caller */
462                 break;
463         case IPSEC_POLICY_BYPASS:
464         case IPSEC_POLICY_NONE:
465                 KEY_FREESP(&sp);
466                 sp = NULL;              /* NB: force NULL result */
467                 break;
468         case IPSEC_POLICY_IPSEC:
469                 if (sp->req == NULL)    /* acquire an SA */
470                         *error = key_spdacquire(sp);
471                 break;
472         }
473         if (*error != 0) {
474                 KEY_FREESP(&sp);
475                 sp = NULL;
476         }
477         return sp;
478 }
479
480 static int
481 ipsec4_setspidx_inpcb(m, pcb)
482         struct mbuf *m;
483         struct inpcb *pcb;
484 {
485         int error;
486
487         KASSERT(pcb != NULL, ("ipsec4_setspidx_inpcb: null pcb"));
488         KASSERT(pcb->inp_sp != NULL, ("ipsec4_setspidx_inpcb: null inp_sp"));
489         KASSERT(pcb->inp_sp->sp_out != NULL && pcb->inp_sp->sp_in != NULL,
490                 ("ipsec4_setspidx_inpcb: null sp_in || sp_out"));
491
492         error = ipsec_setspidx(m, &pcb->inp_sp->sp_in->spidx, 1);
493         if (error == 0) {
494                 pcb->inp_sp->sp_in->spidx.dir = IPSEC_DIR_INBOUND;
495                 pcb->inp_sp->sp_out->spidx = pcb->inp_sp->sp_in->spidx;
496                 pcb->inp_sp->sp_out->spidx.dir = IPSEC_DIR_OUTBOUND;
497         } else {
498                 bzero(&pcb->inp_sp->sp_in->spidx,
499                         sizeof (pcb->inp_sp->sp_in->spidx));
500                 bzero(&pcb->inp_sp->sp_out->spidx,
501                         sizeof (pcb->inp_sp->sp_in->spidx));
502         }
503         return error;
504 }
505
506 #ifdef INET6
507 static int
508 ipsec6_setspidx_in6pcb(m, pcb)
509         struct mbuf *m;
510         struct in6pcb *pcb;
511 {
512         struct secpolicyindex *spidx;
513         int error;
514
515         KASSERT(pcb != NULL, ("ipsec6_setspidx_in6pcb: null pcb"));
516         KASSERT(pcb->in6p_sp != NULL, ("ipsec6_setspidx_in6pcb: null inp_sp"));
517         KASSERT(pcb->in6p_sp->sp_out != NULL && pcb->in6p_sp->sp_in != NULL,
518                 ("ipsec6_setspidx_in6pcb: null sp_in || sp_out"));
519
520         bzero(&pcb->in6p_sp->sp_in->spidx, sizeof(*spidx));
521         bzero(&pcb->in6p_sp->sp_out->spidx, sizeof(*spidx));
522
523         spidx = &pcb->in6p_sp->sp_in->spidx;
524         error = ipsec_setspidx(m, spidx, 1);
525         if (error)
526                 goto bad;
527         spidx->dir = IPSEC_DIR_INBOUND;
528
529         spidx = &pcb->in6p_sp->sp_out->spidx;
530         error = ipsec_setspidx(m, spidx, 1);
531         if (error)
532                 goto bad;
533         spidx->dir = IPSEC_DIR_OUTBOUND;
534
535         return 0;
536
537 bad:
538         bzero(&pcb->in6p_sp->sp_in->spidx, sizeof(*spidx));
539         bzero(&pcb->in6p_sp->sp_out->spidx, sizeof(*spidx));
540         return error;
541 }
542 #endif
543
544 /*
545  * configure security policy index (src/dst/proto/sport/dport)
546  * by looking at the content of mbuf.
547  * the caller is responsible for error recovery (like clearing up spidx).
548  */
549 static int
550 ipsec_setspidx(m, spidx, needport)
551         struct mbuf *m;
552         struct secpolicyindex *spidx;
553         int needport;
554 {
555         struct ip *ip = NULL;
556         struct ip ipbuf;
557         u_int v;
558         struct mbuf *n;
559         int len;
560         int error;
561
562         KASSERT(m != NULL, ("ipsec_setspidx: null mbuf"));
563
564         /*
565          * validate m->m_pkthdr.len.  we see incorrect length if we
566          * mistakenly call this function with inconsistent mbuf chain
567          * (like 4.4BSD tcp/udp processing).  XXX should we panic here?
568          */
569         len = 0;
570         for (n = m; n; n = n->m_next)
571                 len += n->m_len;
572         if (m->m_pkthdr.len != len) {
573                 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
574                         printf("ipsec_setspidx: "
575                                "total of m_len(%d) != pkthdr.len(%d), "
576                                "ignored.\n",
577                                 len, m->m_pkthdr.len));
578                 return EINVAL;
579         }
580
581         if (m->m_pkthdr.len < sizeof(struct ip)) {
582                 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
583                         printf("ipsec_setspidx: "
584                             "pkthdr.len(%d) < sizeof(struct ip), ignored.\n",
585                             m->m_pkthdr.len));
586                 return EINVAL;
587         }
588
589         if (m->m_len >= sizeof(*ip))
590                 ip = mtod(m, struct ip *);
591         else {
592                 m_copydata(m, 0, sizeof(ipbuf), (caddr_t)&ipbuf);
593                 ip = &ipbuf;
594         }
595 #ifdef _IP_VHL
596         v = _IP_VHL_V(ip->ip_vhl);
597 #else
598         v = ip->ip_v;
599 #endif
600         switch (v) {
601         case 4:
602                 error = ipsec4_setspidx_ipaddr(m, spidx);
603                 if (error)
604                         return error;
605                 ipsec4_get_ulp(m, spidx, needport);
606                 return 0;
607 #ifdef INET6
608         case 6:
609                 if (m->m_pkthdr.len < sizeof(struct ip6_hdr)) {
610                         KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
611                                 printf("ipsec_setspidx: "
612                                     "pkthdr.len(%d) < sizeof(struct ip6_hdr), "
613                                     "ignored.\n", m->m_pkthdr.len));
614                         return EINVAL;
615                 }
616                 error = ipsec6_setspidx_ipaddr(m, spidx);
617                 if (error)
618                         return error;
619                 ipsec6_get_ulp(m, spidx, needport);
620                 return 0;
621 #endif
622         default:
623                 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
624                         printf("ipsec_setspidx: "
625                             "unknown IP version %u, ignored.\n", v));
626                 return EINVAL;
627         }
628 }
629
630 static void
631 ipsec4_get_ulp(struct mbuf *m, struct secpolicyindex *spidx, int needport)
632 {
633         u_int8_t nxt;
634         int off;
635
636         /* sanity check */
637         KASSERT(m != NULL, ("ipsec4_get_ulp: null mbuf"));
638         KASSERT(m->m_pkthdr.len >= sizeof(struct ip),
639                 ("ipsec4_get_ulp: packet too short"));
640
641         /* NB: ip_input() flips it into host endian XXX need more checking */
642         if (m->m_len < sizeof (struct ip)) {
643                 struct ip *ip = mtod(m, struct ip *);
644                 if (ip->ip_off & (IP_MF | IP_OFFMASK))
645                         goto done;
646 #ifdef _IP_VHL
647                 off = _IP_VHL_HL(ip->ip_vhl) << 2;
648 #else
649                 off = ip->ip_hl << 2;
650 #endif
651                 nxt = ip->ip_p;
652         } else {
653                 struct ip ih;
654
655                 m_copydata(m, 0, sizeof (struct ip), (caddr_t) &ih);
656                 if (ih.ip_off & (IP_MF | IP_OFFMASK))
657                         goto done;
658 #ifdef _IP_VHL
659                 off = _IP_VHL_HL(ih.ip_vhl) << 2;
660 #else
661                 off = ih.ip_hl << 2;
662 #endif
663                 nxt = ih.ip_p;
664         }
665
666         while (off < m->m_pkthdr.len) {
667                 struct ip6_ext ip6e;
668                 struct tcphdr th;
669                 struct udphdr uh;
670
671                 switch (nxt) {
672                 case IPPROTO_TCP:
673                         spidx->ul_proto = nxt;
674                         if (!needport)
675                                 goto done_proto;
676                         if (off + sizeof(struct tcphdr) > m->m_pkthdr.len)
677                                 goto done;
678                         m_copydata(m, off, sizeof (th), (caddr_t) &th);
679                         spidx->src.sin.sin_port = th.th_sport;
680                         spidx->dst.sin.sin_port = th.th_dport;
681                         return;
682                 case IPPROTO_UDP:
683                         spidx->ul_proto = nxt;
684                         if (!needport)
685                                 goto done_proto;
686                         if (off + sizeof(struct udphdr) > m->m_pkthdr.len)
687                                 goto done;
688                         m_copydata(m, off, sizeof (uh), (caddr_t) &uh);
689                         spidx->src.sin.sin_port = uh.uh_sport;
690                         spidx->dst.sin.sin_port = uh.uh_dport;
691                         return;
692                 case IPPROTO_AH:
693                         if (m->m_pkthdr.len > off + sizeof(ip6e))
694                                 goto done;
695                         /* XXX sigh, this works but is totally bogus */
696                         m_copydata(m, off, sizeof(ip6e), (caddr_t) &ip6e);
697                         off += (ip6e.ip6e_len + 2) << 2;
698                         nxt = ip6e.ip6e_nxt;
699                         break;
700                 case IPPROTO_ICMP:
701                 default:
702                         /* XXX intermediate headers??? */
703                         spidx->ul_proto = nxt;
704                         goto done_proto;
705                 }
706         }
707 done:
708         spidx->ul_proto = IPSEC_ULPROTO_ANY;
709 done_proto:
710         spidx->src.sin.sin_port = IPSEC_PORT_ANY;
711         spidx->dst.sin.sin_port = IPSEC_PORT_ANY;
712 }
713
714 /* assumes that m is sane */
715 static int
716 ipsec4_setspidx_ipaddr(struct mbuf *m, struct secpolicyindex *spidx)
717 {
718         static const struct sockaddr_in template = {
719                 sizeof (struct sockaddr_in),
720                 AF_INET,
721                 0, { 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }
722         };
723
724         spidx->src.sin = template;
725         spidx->dst.sin = template;
726
727         if (m->m_len < sizeof (struct ip)) {
728                 m_copydata(m, offsetof(struct ip, ip_src),
729                            sizeof (struct  in_addr),
730                            (caddr_t) &spidx->src.sin.sin_addr);
731                 m_copydata(m, offsetof(struct ip, ip_dst),
732                            sizeof (struct  in_addr),
733                            (caddr_t) &spidx->dst.sin.sin_addr);
734         } else {
735                 struct ip *ip = mtod(m, struct ip *);
736                 spidx->src.sin.sin_addr = ip->ip_src;
737                 spidx->dst.sin.sin_addr = ip->ip_dst;
738         }
739
740         spidx->prefs = sizeof(struct in_addr) << 3;
741         spidx->prefd = sizeof(struct in_addr) << 3;
742
743         return 0;
744 }
745
746 #ifdef INET6
747 static void
748 ipsec6_get_ulp(m, spidx, needport)
749         struct mbuf *m;
750         struct secpolicyindex *spidx;
751         int needport;
752 {
753         int off, nxt;
754         struct tcphdr th;
755         struct udphdr uh;
756
757         /* sanity check */
758         if (m == NULL)
759                 panic("ipsec6_get_ulp: NULL pointer was passed.\n");
760
761         KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
762                 printf("ipsec6_get_ulp:\n"); kdebug_mbuf(m));
763
764         /* set default */
765         spidx->ul_proto = IPSEC_ULPROTO_ANY;
766         ((struct sockaddr_in6 *)&spidx->src)->sin6_port = IPSEC_PORT_ANY;
767         ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = IPSEC_PORT_ANY;
768
769         nxt = -1;
770         off = ip6_lasthdr(m, 0, IPPROTO_IPV6, &nxt);
771         if (off < 0 || m->m_pkthdr.len < off)
772                 return;
773
774         switch (nxt) {
775         case IPPROTO_TCP:
776                 spidx->ul_proto = nxt;
777                 if (!needport)
778                         break;
779                 if (off + sizeof(struct tcphdr) > m->m_pkthdr.len)
780                         break;
781                 m_copydata(m, off, sizeof(th), (caddr_t)&th);
782                 ((struct sockaddr_in6 *)&spidx->src)->sin6_port = th.th_sport;
783                 ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = th.th_dport;
784                 break;
785         case IPPROTO_UDP:
786                 spidx->ul_proto = nxt;
787                 if (!needport)
788                         break;
789                 if (off + sizeof(struct udphdr) > m->m_pkthdr.len)
790                         break;
791                 m_copydata(m, off, sizeof(uh), (caddr_t)&uh);
792                 ((struct sockaddr_in6 *)&spidx->src)->sin6_port = uh.uh_sport;
793                 ((struct sockaddr_in6 *)&spidx->dst)->sin6_port = uh.uh_dport;
794                 break;
795         case IPPROTO_ICMPV6:
796         default:
797                 /* XXX intermediate headers??? */
798                 spidx->ul_proto = nxt;
799                 break;
800         }
801 }
802
803 /* assumes that m is sane */
804 static int
805 ipsec6_setspidx_ipaddr(m, spidx)
806         struct mbuf *m;
807         struct secpolicyindex *spidx;
808 {
809         struct ip6_hdr *ip6 = NULL;
810         struct ip6_hdr ip6buf;
811         struct sockaddr_in6 *sin6;
812
813         if (m->m_len >= sizeof(*ip6))
814                 ip6 = mtod(m, struct ip6_hdr *);
815         else {
816                 m_copydata(m, 0, sizeof(ip6buf), (caddr_t)&ip6buf);
817                 ip6 = &ip6buf;
818         }
819
820         sin6 = (struct sockaddr_in6 *)&spidx->src;
821         bzero(sin6, sizeof(*sin6));
822         sin6->sin6_family = AF_INET6;
823         sin6->sin6_len = sizeof(struct sockaddr_in6);
824         bcopy(&ip6->ip6_src, &sin6->sin6_addr, sizeof(ip6->ip6_src));
825         if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) {
826                 sin6->sin6_addr.s6_addr16[1] = 0;
827                 sin6->sin6_scope_id = ntohs(ip6->ip6_src.s6_addr16[1]);
828         }
829         spidx->prefs = sizeof(struct in6_addr) << 3;
830
831         sin6 = (struct sockaddr_in6 *)&spidx->dst;
832         bzero(sin6, sizeof(*sin6));
833         sin6->sin6_family = AF_INET6;
834         sin6->sin6_len = sizeof(struct sockaddr_in6);
835         bcopy(&ip6->ip6_dst, &sin6->sin6_addr, sizeof(ip6->ip6_dst));
836         if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
837                 sin6->sin6_addr.s6_addr16[1] = 0;
838                 sin6->sin6_scope_id = ntohs(ip6->ip6_dst.s6_addr16[1]);
839         }
840         spidx->prefd = sizeof(struct in6_addr) << 3;
841
842         return 0;
843 }
844 #endif
845
846 static void
847 ipsec_delpcbpolicy(p)
848         struct inpcbpolicy *p;
849 {
850         free(p, M_SECA);
851 }
852
853 /* initialize policy in PCB */
854 int
855 ipsec_init_policy(so, pcb_sp)
856         struct socket *so;
857         struct inpcbpolicy **pcb_sp;
858 {
859         struct inpcbpolicy *new;
860
861         /* sanity check. */
862         if (so == NULL || pcb_sp == NULL)
863                 panic("ipsec_init_policy: NULL pointer was passed.\n");
864
865         new = (struct inpcbpolicy *) malloc(sizeof(struct inpcbpolicy),
866                                             M_SECA, M_NOWAIT|M_ZERO);
867         if (new == NULL) {
868                 ipseclog((LOG_DEBUG, "ipsec_init_policy: No more memory.\n"));
869                 return ENOBUFS;
870         }
871
872         if (so->so_cred != 0 && so->so_cred->cr_uid == 0)
873                 new->priv = 1;
874         else
875                 new->priv = 0;
876
877         if ((new->sp_in = KEY_NEWSP()) == NULL) {
878                 ipsec_delpcbpolicy(new);
879                 return ENOBUFS;
880         }
881         new->sp_in->state = IPSEC_SPSTATE_ALIVE;
882         new->sp_in->policy = IPSEC_POLICY_ENTRUST;
883
884         if ((new->sp_out = KEY_NEWSP()) == NULL) {
885                 KEY_FREESP(&new->sp_in);
886                 ipsec_delpcbpolicy(new);
887                 return ENOBUFS;
888         }
889         new->sp_out->state = IPSEC_SPSTATE_ALIVE;
890         new->sp_out->policy = IPSEC_POLICY_ENTRUST;
891
892         *pcb_sp = new;
893
894         return 0;
895 }
896
897 /* copy old ipsec policy into new */
898 int
899 ipsec_copy_policy(old, new)
900         struct inpcbpolicy *old, *new;
901 {
902         struct secpolicy *sp;
903
904         sp = ipsec_deepcopy_policy(old->sp_in);
905         if (sp) {
906                 KEY_FREESP(&new->sp_in);
907                 new->sp_in = sp;
908         } else
909                 return ENOBUFS;
910
911         sp = ipsec_deepcopy_policy(old->sp_out);
912         if (sp) {
913                 KEY_FREESP(&new->sp_out);
914                 new->sp_out = sp;
915         } else
916                 return ENOBUFS;
917
918         new->priv = old->priv;
919
920         return 0;
921 }
922
923 /* deep-copy a policy in PCB */
924 static struct secpolicy *
925 ipsec_deepcopy_policy(src)
926         struct secpolicy *src;
927 {
928         struct ipsecrequest *newchain = NULL;
929         struct ipsecrequest *p;
930         struct ipsecrequest **q;
931         struct ipsecrequest *r;
932         struct secpolicy *dst;
933
934         if (src == NULL)
935                 return NULL;
936         dst = KEY_NEWSP();
937         if (dst == NULL)
938                 return NULL;
939
940         /*
941          * deep-copy IPsec request chain.  This is required since struct
942          * ipsecrequest is not reference counted.
943          */
944         q = &newchain;
945         for (p = src->req; p; p = p->next) {
946                 *q = (struct ipsecrequest *)malloc(sizeof(struct ipsecrequest),
947                         M_SECA, M_NOWAIT);
948                 if (*q == NULL)
949                         goto fail;
950                 bzero(*q, sizeof(**q));
951                 (*q)->next = NULL;
952
953                 (*q)->saidx.proto = p->saidx.proto;
954                 (*q)->saidx.mode = p->saidx.mode;
955                 (*q)->level = p->level;
956                 (*q)->saidx.reqid = p->saidx.reqid;
957
958                 bcopy(&p->saidx.src, &(*q)->saidx.src, sizeof((*q)->saidx.src));
959                 bcopy(&p->saidx.dst, &(*q)->saidx.dst, sizeof((*q)->saidx.dst));
960
961                 (*q)->sav = NULL;
962                 (*q)->sp = dst;
963
964                 q = &((*q)->next);
965         }
966
967         dst->req = newchain;
968         dst->state = src->state;
969         dst->policy = src->policy;
970         /* do not touch the refcnt fields */
971
972         return dst;
973
974 fail:
975         for (p = newchain; p; p = r) {
976                 r = p->next;
977                 free(p, M_SECA);
978                 p = NULL;
979         }
980         return NULL;
981 }
982
983 /* set policy and ipsec request if present. */
984 static int
985 ipsec_set_policy(pcb_sp, optname, request, len, priv)
986         struct secpolicy **pcb_sp;
987         int optname;
988         caddr_t request;
989         size_t len;
990         int priv;
991 {
992         struct sadb_x_policy *xpl;
993         struct secpolicy *newsp = NULL;
994         int error;
995
996         /* sanity check. */
997         if (pcb_sp == NULL || *pcb_sp == NULL || request == NULL)
998                 return EINVAL;
999         if (len < sizeof(*xpl))
1000                 return EINVAL;
1001         xpl = (struct sadb_x_policy *)request;
1002
1003         KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1004                 printf("ipsec_set_policy: passed policy\n");
1005                 kdebug_sadb_x_policy((struct sadb_ext *)xpl));
1006
1007         /* check policy type */
1008         /* ipsec_set_policy() accepts IPSEC, ENTRUST and BYPASS. */
1009         if (xpl->sadb_x_policy_type == IPSEC_POLICY_DISCARD
1010          || xpl->sadb_x_policy_type == IPSEC_POLICY_NONE)
1011                 return EINVAL;
1012
1013         /* check privileged socket */
1014         if (priv == 0 && xpl->sadb_x_policy_type == IPSEC_POLICY_BYPASS)
1015                 return EACCES;
1016
1017         /* allocation new SP entry */
1018         if ((newsp = key_msg2sp(xpl, len, &error)) == NULL)
1019                 return error;
1020
1021         newsp->state = IPSEC_SPSTATE_ALIVE;
1022
1023         /* clear old SP and set new SP */
1024         KEY_FREESP(pcb_sp);
1025         *pcb_sp = newsp;
1026         KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1027                 printf("ipsec_set_policy: new policy\n");
1028                 kdebug_secpolicy(newsp));
1029
1030         return 0;
1031 }
1032
1033 static int
1034 ipsec_get_policy(pcb_sp, mp)
1035         struct secpolicy *pcb_sp;
1036         struct mbuf **mp;
1037 {
1038
1039         /* sanity check. */
1040         if (pcb_sp == NULL || mp == NULL)
1041                 return EINVAL;
1042
1043         *mp = key_sp2msg(pcb_sp);
1044         if (!*mp) {
1045                 ipseclog((LOG_DEBUG, "ipsec_get_policy: No more memory.\n"));
1046                 return ENOBUFS;
1047         }
1048
1049         (*mp)->m_type = MT_DATA;
1050         KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1051                 printf("ipsec_get_policy:\n");
1052                 kdebug_mbuf(*mp));
1053
1054         return 0;
1055 }
1056
1057 int
1058 ipsec4_set_policy(inp, optname, request, len, priv)
1059         struct inpcb *inp;
1060         int optname;
1061         caddr_t request;
1062         size_t len;
1063         int priv;
1064 {
1065         struct sadb_x_policy *xpl;
1066         struct secpolicy **pcb_sp;
1067
1068         /* sanity check. */
1069         if (inp == NULL || request == NULL)
1070                 return EINVAL;
1071         if (len < sizeof(*xpl))
1072                 return EINVAL;
1073         xpl = (struct sadb_x_policy *)request;
1074
1075         /* select direction */
1076         switch (xpl->sadb_x_policy_dir) {
1077         case IPSEC_DIR_INBOUND:
1078                 pcb_sp = &inp->inp_sp->sp_in;
1079                 break;
1080         case IPSEC_DIR_OUTBOUND:
1081                 pcb_sp = &inp->inp_sp->sp_out;
1082                 break;
1083         default:
1084                 ipseclog((LOG_ERR, "ipsec4_set_policy: invalid direction=%u\n",
1085                         xpl->sadb_x_policy_dir));
1086                 return EINVAL;
1087         }
1088
1089         return ipsec_set_policy(pcb_sp, optname, request, len, priv);
1090 }
1091
1092 int
1093 ipsec4_get_policy(inp, request, len, mp)
1094         struct inpcb *inp;
1095         caddr_t request;
1096         size_t len;
1097         struct mbuf **mp;
1098 {
1099         struct sadb_x_policy *xpl;
1100         struct secpolicy *pcb_sp;
1101
1102         /* sanity check. */
1103         if (inp == NULL || request == NULL || mp == NULL)
1104                 return EINVAL;
1105         KASSERT(inp->inp_sp != NULL, ("ipsec4_get_policy: null inp_sp"));
1106         if (len < sizeof(*xpl))
1107                 return EINVAL;
1108         xpl = (struct sadb_x_policy *)request;
1109
1110         /* select direction */
1111         switch (xpl->sadb_x_policy_dir) {
1112         case IPSEC_DIR_INBOUND:
1113                 pcb_sp = inp->inp_sp->sp_in;
1114                 break;
1115         case IPSEC_DIR_OUTBOUND:
1116                 pcb_sp = inp->inp_sp->sp_out;
1117                 break;
1118         default:
1119                 ipseclog((LOG_ERR, "ipsec4_set_policy: invalid direction=%u\n",
1120                         xpl->sadb_x_policy_dir));
1121                 return EINVAL;
1122         }
1123
1124         return ipsec_get_policy(pcb_sp, mp);
1125 }
1126
1127 /* delete policy in PCB */
1128 int
1129 ipsec4_delete_pcbpolicy(inp)
1130         struct inpcb *inp;
1131 {
1132         KASSERT(inp != NULL, ("ipsec4_delete_pcbpolicy: null inp"));
1133
1134         if (inp->inp_sp == NULL)
1135                 return 0;
1136
1137         if (inp->inp_sp->sp_in != NULL)
1138                 KEY_FREESP(&inp->inp_sp->sp_in);
1139
1140         if (inp->inp_sp->sp_out != NULL)
1141                 KEY_FREESP(&inp->inp_sp->sp_out);
1142
1143         ipsec_delpcbpolicy(inp->inp_sp);
1144         inp->inp_sp = NULL;
1145
1146         return 0;
1147 }
1148
1149 #ifdef INET6
1150 int
1151 ipsec6_set_policy(in6p, optname, request, len, priv)
1152         struct in6pcb *in6p;
1153         int optname;
1154         caddr_t request;
1155         size_t len;
1156         int priv;
1157 {
1158         struct sadb_x_policy *xpl;
1159         struct secpolicy **pcb_sp;
1160
1161         /* sanity check. */
1162         if (in6p == NULL || request == NULL)
1163                 return EINVAL;
1164         if (len < sizeof(*xpl))
1165                 return EINVAL;
1166         xpl = (struct sadb_x_policy *)request;
1167
1168         /* select direction */
1169         switch (xpl->sadb_x_policy_dir) {
1170         case IPSEC_DIR_INBOUND:
1171                 pcb_sp = &in6p->in6p_sp->sp_in;
1172                 break;
1173         case IPSEC_DIR_OUTBOUND:
1174                 pcb_sp = &in6p->in6p_sp->sp_out;
1175                 break;
1176         default:
1177                 ipseclog((LOG_ERR, "ipsec6_set_policy: invalid direction=%u\n",
1178                         xpl->sadb_x_policy_dir));
1179                 return EINVAL;
1180         }
1181
1182         return ipsec_set_policy(pcb_sp, optname, request, len, priv);
1183 }
1184
1185 int
1186 ipsec6_get_policy(in6p, request, len, mp)
1187         struct in6pcb *in6p;
1188         caddr_t request;
1189         size_t len;
1190         struct mbuf **mp;
1191 {
1192         struct sadb_x_policy *xpl;
1193         struct secpolicy *pcb_sp;
1194
1195         /* sanity check. */
1196         if (in6p == NULL || request == NULL || mp == NULL)
1197                 return EINVAL;
1198         KASSERT(in6p->in6p_sp != NULL, ("ipsec6_get_policy: null in6p_sp"));
1199         if (len < sizeof(*xpl))
1200                 return EINVAL;
1201         xpl = (struct sadb_x_policy *)request;
1202
1203         /* select direction */
1204         switch (xpl->sadb_x_policy_dir) {
1205         case IPSEC_DIR_INBOUND:
1206                 pcb_sp = in6p->in6p_sp->sp_in;
1207                 break;
1208         case IPSEC_DIR_OUTBOUND:
1209                 pcb_sp = in6p->in6p_sp->sp_out;
1210                 break;
1211         default:
1212                 ipseclog((LOG_ERR, "ipsec6_set_policy: invalid direction=%u\n",
1213                         xpl->sadb_x_policy_dir));
1214                 return EINVAL;
1215         }
1216
1217         return ipsec_get_policy(pcb_sp, mp);
1218 }
1219
1220 int
1221 ipsec6_delete_pcbpolicy(in6p)
1222         struct in6pcb *in6p;
1223 {
1224         KASSERT(in6p != NULL, ("ipsec6_delete_pcbpolicy: null in6p"));
1225
1226         if (in6p->in6p_sp == NULL)
1227                 return 0;
1228
1229         if (in6p->in6p_sp->sp_in != NULL)
1230                 KEY_FREESP(&in6p->in6p_sp->sp_in);
1231
1232         if (in6p->in6p_sp->sp_out != NULL)
1233                 KEY_FREESP(&in6p->in6p_sp->sp_out);
1234
1235         ipsec_delpcbpolicy(in6p->in6p_sp);
1236         in6p->in6p_sp = NULL;
1237
1238         return 0;
1239 }
1240 #endif
1241
1242 /*
1243  * return current level.
1244  * Either IPSEC_LEVEL_USE or IPSEC_LEVEL_REQUIRE are always returned.
1245  */
1246 u_int
1247 ipsec_get_reqlevel(isr)
1248         struct ipsecrequest *isr;
1249 {
1250         u_int level = 0;
1251         u_int esp_trans_deflev, esp_net_deflev;
1252         u_int ah_trans_deflev, ah_net_deflev;
1253
1254         KASSERT(isr != NULL && isr->sp != NULL,
1255                 ("ipsec_get_reqlevel: null argument"));
1256         KASSERT(isr->sp->spidx.src.sa.sa_family == isr->sp->spidx.dst.sa.sa_family,
1257                 ("ipsec_get_reqlevel: af family mismatch, src %u, dst %u",
1258                  isr->sp->spidx.src.sa.sa_family,
1259                  isr->sp->spidx.dst.sa.sa_family));
1260
1261 /* XXX note that we have ipseclog() expanded here - code sync issue */
1262 #define IPSEC_CHECK_DEFAULT(lev) \
1263         (((lev) != IPSEC_LEVEL_USE && (lev) != IPSEC_LEVEL_REQUIRE            \
1264                         && (lev) != IPSEC_LEVEL_UNIQUE)                       \
1265                 ? (ipsec_debug                                                \
1266                         ? log(LOG_INFO, "fixed system default level " #lev ":%d->%d\n",\
1267                                 (lev), IPSEC_LEVEL_REQUIRE)                   \
1268                         : 0),                                                 \
1269                         (lev) = IPSEC_LEVEL_REQUIRE,                          \
1270                         (lev)                                                 \
1271                 : (lev))
1272
1273         /* set default level */
1274         switch (((struct sockaddr *)&isr->sp->spidx.src)->sa_family) {
1275 #ifdef INET
1276         case AF_INET:
1277                 esp_trans_deflev = IPSEC_CHECK_DEFAULT(ip4_esp_trans_deflev);
1278                 esp_net_deflev = IPSEC_CHECK_DEFAULT(ip4_esp_net_deflev);
1279                 ah_trans_deflev = IPSEC_CHECK_DEFAULT(ip4_ah_trans_deflev);
1280                 ah_net_deflev = IPSEC_CHECK_DEFAULT(ip4_ah_net_deflev);
1281                 break;
1282 #endif
1283 #ifdef INET6
1284         case AF_INET6:
1285                 esp_trans_deflev = IPSEC_CHECK_DEFAULT(ip6_esp_trans_deflev);
1286                 esp_net_deflev = IPSEC_CHECK_DEFAULT(ip6_esp_net_deflev);
1287                 ah_trans_deflev = IPSEC_CHECK_DEFAULT(ip6_ah_trans_deflev);
1288                 ah_net_deflev = IPSEC_CHECK_DEFAULT(ip6_ah_net_deflev);
1289                 break;
1290 #endif /* INET6 */
1291         default:
1292                 panic("key_get_reqlevel: unknown af %u",
1293                         isr->sp->spidx.src.sa.sa_family);
1294         }
1295
1296 #undef IPSEC_CHECK_DEFAULT
1297
1298         /* set level */
1299         switch (isr->level) {
1300         case IPSEC_LEVEL_DEFAULT:
1301                 switch (isr->saidx.proto) {
1302                 case IPPROTO_ESP:
1303                         if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
1304                                 level = esp_net_deflev;
1305                         else
1306                                 level = esp_trans_deflev;
1307                         break;
1308                 case IPPROTO_AH:
1309                         if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
1310                                 level = ah_net_deflev;
1311                         else
1312                                 level = ah_trans_deflev;
1313                 case IPPROTO_IPCOMP:
1314                         /*
1315                          * we don't really care, as IPcomp document says that
1316                          * we shouldn't compress small packets
1317                          */
1318                         level = IPSEC_LEVEL_USE;
1319                         break;
1320                 default:
1321                         panic("ipsec_get_reqlevel: "
1322                                 "Illegal protocol defined %u\n",
1323                                 isr->saidx.proto);
1324                 }
1325                 break;
1326
1327         case IPSEC_LEVEL_USE:
1328         case IPSEC_LEVEL_REQUIRE:
1329                 level = isr->level;
1330                 break;
1331         case IPSEC_LEVEL_UNIQUE:
1332                 level = IPSEC_LEVEL_REQUIRE;
1333                 break;
1334
1335         default:
1336                 panic("ipsec_get_reqlevel: Illegal IPsec level %u\n",
1337                         isr->level);
1338         }
1339
1340         return level;
1341 }
1342
1343 /*
1344  * Check security policy requirements against the actual
1345  * packet contents.  Return one if the packet should be
1346  * reject as "invalid"; otherwiser return zero to have the
1347  * packet treated as "valid".
1348  *
1349  * OUT:
1350  *      0: valid
1351  *      1: invalid
1352  */
1353 int
1354 ipsec_in_reject(struct secpolicy *sp, struct mbuf *m)
1355 {
1356         struct ipsecrequest *isr;
1357         int need_auth;
1358
1359         KEYDEBUG(KEYDEBUG_IPSEC_DATA,
1360                 printf("ipsec_in_reject: using SP\n");
1361                 kdebug_secpolicy(sp));
1362
1363         /* check policy */
1364         switch (sp->policy) {
1365         case IPSEC_POLICY_DISCARD:
1366                 return 1;
1367         case IPSEC_POLICY_BYPASS:
1368         case IPSEC_POLICY_NONE:
1369                 return 0;
1370         }
1371
1372         KASSERT(sp->policy == IPSEC_POLICY_IPSEC,
1373                 ("ipsec_in_reject: invalid policy %u", sp->policy));
1374
1375         /* XXX should compare policy against ipsec header history */
1376
1377         need_auth = 0;
1378         for (isr = sp->req; isr != NULL; isr = isr->next) {
1379                 if (ipsec_get_reqlevel(isr) != IPSEC_LEVEL_REQUIRE)
1380                         continue;
1381                 switch (isr->saidx.proto) {
1382                 case IPPROTO_ESP:
1383                         if ((m->m_flags & M_DECRYPTED) == 0) {
1384                                 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1385                                     printf("ipsec_in_reject: ESP m_flags:%x\n",
1386                                             m->m_flags));
1387                                 return 1;
1388                         }
1389
1390                         if (!need_auth &&
1391                             isr->sav != NULL &&
1392                             isr->sav->tdb_authalgxform != NULL &&
1393                             (m->m_flags & M_AUTHIPDGM) == 0) {
1394                                 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1395                                     printf("ipsec_in_reject: ESP/AH m_flags:%x\n",
1396                                             m->m_flags));
1397                                 return 1;
1398                         }
1399                         break;
1400                 case IPPROTO_AH:
1401                         need_auth = 1;
1402                         if ((m->m_flags & M_AUTHIPHDR) == 0) {
1403                                 KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1404                                     printf("ipsec_in_reject: AH m_flags:%x\n",
1405                                             m->m_flags));
1406                                 return 1;
1407                         }
1408                         break;
1409                 case IPPROTO_IPCOMP:
1410                         /*
1411                          * we don't really care, as IPcomp document
1412                          * says that we shouldn't compress small
1413                          * packets, IPComp policy should always be
1414                          * treated as being in "use" level.
1415                          */
1416                         break;
1417                 }
1418         }
1419         return 0;               /* valid */
1420 }
1421
1422 /*
1423  * Check AH/ESP integrity.
1424  * This function is called from tcp_input(), udp_input(),
1425  * and {ah,esp}4_input for tunnel mode
1426  */
1427 int
1428 ipsec4_in_reject(m, inp)
1429         struct mbuf *m;
1430         struct inpcb *inp;
1431 {
1432         struct secpolicy *sp;
1433         int error;
1434         int result;
1435
1436         KASSERT(m != NULL, ("ipsec4_in_reject_so: null mbuf"));
1437
1438         /* get SP for this packet.
1439          * When we are called from ip_forward(), we call
1440          * ipsec_getpolicybyaddr() with IP_FORWARDING flag.
1441          */
1442         if (inp == NULL)
1443                 sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error);
1444         else
1445                 sp = ipsec_getpolicybysock(m, IPSEC_DIR_INBOUND, inp, &error);
1446
1447         if (sp != NULL) {
1448                 result = ipsec_in_reject(sp, m);
1449                 if (result)
1450                         newipsecstat.ips_in_polvio++;
1451                 KEY_FREESP(&sp);
1452         } else {
1453                 result = 0;     /* XXX should be panic ?
1454                                  * -> No, there may be error. */
1455         }
1456         return result;
1457 }
1458
1459 #ifdef INET6
1460 /*
1461  * Check AH/ESP integrity.
1462  * This function is called from tcp6_input(), udp6_input(),
1463  * and {ah,esp}6_input for tunnel mode
1464  */
1465 int
1466 ipsec6_in_reject(m, inp)
1467         struct mbuf *m;
1468         struct inpcb *inp;
1469 {
1470         struct secpolicy *sp = NULL;
1471         int error;
1472         int result;
1473
1474         /* sanity check */
1475         if (m == NULL)
1476                 return 0;       /* XXX should be panic ? */
1477
1478         /* get SP for this packet.
1479          * When we are called from ip_forward(), we call
1480          * ipsec_getpolicybyaddr() with IP_FORWARDING flag.
1481          */
1482         if (inp == NULL)
1483                 sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error);
1484         else
1485                 sp = ipsec_getpolicybysock(m, IPSEC_DIR_INBOUND, inp, &error);
1486
1487         if (sp != NULL) {
1488                 result = ipsec_in_reject(sp, m);
1489                 if (result)
1490                         newipsecstat.ips_in_polvio++;
1491                 KEY_FREESP(&sp);
1492         } else {
1493                 result = 0;
1494         }
1495         return result;
1496 }
1497 #endif
1498
1499 /*
1500  * compute the byte size to be occupied by IPsec header.
1501  * in case it is tunneled, it includes the size of outer IP header.
1502  * NOTE: SP passed is free in this function.
1503  */
1504 static size_t
1505 ipsec_hdrsiz(struct secpolicy *sp)
1506 {
1507         struct ipsecrequest *isr;
1508         size_t siz;
1509
1510         KEYDEBUG(KEYDEBUG_IPSEC_DATA,
1511                 printf("ipsec_hdrsiz: using SP\n");
1512                 kdebug_secpolicy(sp));
1513
1514         switch (sp->policy) {
1515         case IPSEC_POLICY_DISCARD:
1516         case IPSEC_POLICY_BYPASS:
1517         case IPSEC_POLICY_NONE:
1518                 return 0;
1519         }
1520
1521         KASSERT(sp->policy == IPSEC_POLICY_IPSEC,
1522                 ("ipsec_hdrsiz: invalid policy %u", sp->policy));
1523
1524         siz = 0;
1525         for (isr = sp->req; isr != NULL; isr = isr->next) {
1526                 size_t clen = 0;
1527
1528                 switch (isr->saidx.proto) {
1529                 case IPPROTO_ESP:
1530                         clen = esp_hdrsiz(isr->sav);
1531                         break;
1532                 case IPPROTO_AH:
1533                         clen = ah_hdrsiz(isr->sav);
1534                         break;
1535                 case IPPROTO_IPCOMP:
1536                         clen = sizeof(struct ipcomp);
1537                         break;
1538                 }
1539
1540                 if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
1541                         switch (isr->saidx.dst.sa.sa_family) {
1542                         case AF_INET:
1543                                 clen += sizeof(struct ip);
1544                                 break;
1545 #ifdef INET6
1546                         case AF_INET6:
1547                                 clen += sizeof(struct ip6_hdr);
1548                                 break;
1549 #endif
1550                         default:
1551                                 ipseclog((LOG_ERR, "ipsec_hdrsiz: "
1552                                     "unknown AF %d in IPsec tunnel SA\n",
1553                                     ((struct sockaddr *)&isr->saidx.dst)->sa_family));
1554                                 break;
1555                         }
1556                 }
1557                 siz += clen;
1558         }
1559
1560         return siz;
1561 }
1562
1563 /* This function is called from ip_forward() and ipsec4_hdrsize_tcp(). */
1564 size_t
1565 ipsec4_hdrsiz(m, dir, inp)
1566         struct mbuf *m;
1567         u_int dir;
1568         struct inpcb *inp;
1569 {
1570         struct secpolicy *sp;
1571         int error;
1572         size_t size;
1573
1574         KASSERT(m != NULL, ("ipsec4_hdrsiz: null mbuf"));
1575         KASSERT(inp == NULL || inp->inp_socket != NULL,
1576                 ("ipsec4_hdrsize: socket w/o inpcb"));
1577
1578         /* get SP for this packet.
1579          * When we are called from ip_forward(), we call
1580          * ipsec_getpolicybyaddr() with IP_FORWARDING flag.
1581          */
1582         if (inp == NULL)
1583                 sp = ipsec_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
1584         else
1585                 sp = ipsec_getpolicybysock(m, dir, inp, &error);
1586
1587         if (sp != NULL) {
1588                 size = ipsec_hdrsiz(sp);
1589                 KEYDEBUG(KEYDEBUG_IPSEC_DATA,
1590                         printf("ipsec4_hdrsiz: size:%lu.\n",
1591                                 (unsigned long)size));
1592
1593                 KEY_FREESP(&sp);
1594         } else {
1595                 size = 0;       /* XXX should be panic ? */
1596         }
1597         return size;
1598 }
1599
1600 #ifdef INET6
1601 /* This function is called from ipsec6_hdrsize_tcp(),
1602  * and maybe from ip6_forward.()
1603  */
1604 size_t
1605 ipsec6_hdrsiz(m, dir, in6p)
1606         struct mbuf *m;
1607         u_int dir;
1608         struct in6pcb *in6p;
1609 {
1610         struct secpolicy *sp;
1611         int error;
1612         size_t size;
1613
1614         KASSERT(m != NULL, ("ipsec6_hdrsiz: null mbuf"));
1615         KASSERT(in6p == NULL || in6p->in6p_socket != NULL,
1616                 ("ipsec6_hdrsize: socket w/o inpcb"));
1617
1618         /* get SP for this packet */
1619         /* XXX Is it right to call with IP_FORWARDING. */
1620         if (in6p == NULL)
1621                 sp = ipsec_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
1622         else
1623                 sp = ipsec_getpolicybysock(m, dir, in6p, &error);
1624
1625         if (sp == NULL)
1626                 return 0;
1627         size = ipsec_hdrsiz(sp);
1628         KEYDEBUG(KEYDEBUG_IPSEC_DATA,
1629                 printf("ipsec6_hdrsiz: size:%lu.\n", (unsigned long)size));
1630         KEY_FREESP(&sp);
1631
1632         return size;
1633 }
1634 #endif /*INET6*/
1635
1636 /*
1637  * Check the variable replay window.
1638  * ipsec_chkreplay() performs replay check before ICV verification.
1639  * ipsec_updatereplay() updates replay bitmap.  This must be called after
1640  * ICV verification (it also performs replay check, which is usually done
1641  * beforehand).
1642  * 0 (zero) is returned if packet disallowed, 1 if packet permitted.
1643  *
1644  * based on RFC 2401.
1645  */
1646 int
1647 ipsec_chkreplay(seq, sav)
1648         u_int32_t seq;
1649         struct secasvar *sav;
1650 {
1651         const struct secreplay *replay;
1652         u_int32_t diff;
1653         int fr;
1654         u_int32_t wsizeb;       /* constant: bits of window size */
1655         int frlast;             /* constant: last frame */
1656
1657         SPLASSERT(net, "ipsec_chkreplay");
1658
1659         KASSERT(sav != NULL, ("ipsec_chkreplay: Null SA"));
1660         KASSERT(sav->replay != NULL, ("ipsec_chkreplay: Null replay state"));
1661
1662         replay = sav->replay;
1663
1664         if (replay->wsize == 0)
1665                 return 1;       /* no need to check replay. */
1666
1667         /* constant */
1668         frlast = replay->wsize - 1;
1669         wsizeb = replay->wsize << 3;
1670
1671         /* sequence number of 0 is invalid */
1672         if (seq == 0)
1673                 return 0;
1674
1675         /* first time is always okay */
1676         if (replay->count == 0)
1677                 return 1;
1678
1679         if (seq > replay->lastseq) {
1680                 /* larger sequences are okay */
1681                 return 1;
1682         } else {
1683                 /* seq is equal or less than lastseq. */
1684                 diff = replay->lastseq - seq;
1685
1686                 /* over range to check, i.e. too old or wrapped */
1687                 if (diff >= wsizeb)
1688                         return 0;
1689
1690                 fr = frlast - diff / 8;
1691
1692                 /* this packet already seen ? */
1693                 if ((replay->bitmap)[fr] & (1 << (diff % 8)))
1694                         return 0;
1695
1696                 /* out of order but good */
1697                 return 1;
1698         }
1699 }
1700
1701 /*
1702  * check replay counter whether to update or not.
1703  * OUT: 0:      OK
1704  *      1:      NG
1705  */
1706 int
1707 ipsec_updatereplay(seq, sav)
1708         u_int32_t seq;
1709         struct secasvar *sav;
1710 {
1711         struct secreplay *replay;
1712         u_int32_t diff;
1713         int fr;
1714         u_int32_t wsizeb;       /* constant: bits of window size */
1715         int frlast;             /* constant: last frame */
1716
1717         SPLASSERT(net, "ipsec_updatereplay");
1718
1719         KASSERT(sav != NULL, ("ipsec_updatereplay: Null SA"));
1720         KASSERT(sav->replay != NULL, ("ipsec_updatereplay: Null replay state"));
1721
1722         replay = sav->replay;
1723
1724         if (replay->wsize == 0)
1725                 goto ok;        /* no need to check replay. */
1726
1727         /* constant */
1728         frlast = replay->wsize - 1;
1729         wsizeb = replay->wsize << 3;
1730
1731         /* sequence number of 0 is invalid */
1732         if (seq == 0)
1733                 return 1;
1734
1735         /* first time */
1736         if (replay->count == 0) {
1737                 replay->lastseq = seq;
1738                 bzero(replay->bitmap, replay->wsize);
1739                 (replay->bitmap)[frlast] = 1;
1740                 goto ok;
1741         }
1742
1743         if (seq > replay->lastseq) {
1744                 /* seq is larger than lastseq. */
1745                 diff = seq - replay->lastseq;
1746
1747                 /* new larger sequence number */
1748                 if (diff < wsizeb) {
1749                         /* In window */
1750                         /* set bit for this packet */
1751                         vshiftl(replay->bitmap, diff, replay->wsize);
1752                         (replay->bitmap)[frlast] |= 1;
1753                 } else {
1754                         /* this packet has a "way larger" */
1755                         bzero(replay->bitmap, replay->wsize);
1756                         (replay->bitmap)[frlast] = 1;
1757                 }
1758                 replay->lastseq = seq;
1759
1760                 /* larger is good */
1761         } else {
1762                 /* seq is equal or less than lastseq. */
1763                 diff = replay->lastseq - seq;
1764
1765                 /* over range to check, i.e. too old or wrapped */
1766                 if (diff >= wsizeb)
1767                         return 1;
1768
1769                 fr = frlast - diff / 8;
1770
1771                 /* this packet already seen ? */
1772                 if ((replay->bitmap)[fr] & (1 << (diff % 8)))
1773                         return 1;
1774
1775                 /* mark as seen */
1776                 (replay->bitmap)[fr] |= (1 << (diff % 8));
1777
1778                 /* out of order but good */
1779         }
1780
1781 ok:
1782         if (replay->count == ~0) {
1783
1784                 /* set overflow flag */
1785                 replay->overflow++;
1786
1787                 /* don't increment, no more packets accepted */
1788                 if ((sav->flags & SADB_X_EXT_CYCSEQ) == 0)
1789                         return 1;
1790
1791                 ipseclog((LOG_WARNING, "replay counter made %d cycle. %s\n",
1792                     replay->overflow, ipsec_logsastr(sav)));
1793         }
1794
1795         replay->count++;
1796
1797         return 0;
1798 }
1799
1800 /*
1801  * shift variable length bunffer to left.
1802  * IN:  bitmap: pointer to the buffer
1803  *      nbit:   the number of to shift.
1804  *      wsize:  buffer size (bytes).
1805  */
1806 static void
1807 vshiftl(bitmap, nbit, wsize)
1808         unsigned char *bitmap;
1809         int nbit, wsize;
1810 {
1811         int s, j, i;
1812         unsigned char over;
1813
1814         for (j = 0; j < nbit; j += 8) {
1815                 s = (nbit - j < 8) ? (nbit - j): 8;
1816                 bitmap[0] <<= s;
1817                 for (i = 1; i < wsize; i++) {
1818                         over = (bitmap[i] >> (8 - s));
1819                         bitmap[i] <<= s;
1820                         bitmap[i-1] |= over;
1821                 }
1822         }
1823
1824         return;
1825 }
1826
1827 /* Return a printable string for the IPv4 address. */
1828 static char *
1829 inet_ntoa4(struct in_addr ina)
1830 {
1831         static char buf[4][4 * sizeof "123" + 4];
1832         unsigned char *ucp = (unsigned char *) &ina;
1833         static int i = 3;
1834
1835         i = (i + 1) % 4;
1836         sprintf(buf[i], "%d.%d.%d.%d", ucp[0] & 0xff, ucp[1] & 0xff,
1837             ucp[2] & 0xff, ucp[3] & 0xff);
1838         return (buf[i]);
1839 }
1840
1841 /* Return a printable string for the address. */
1842 char *
1843 ipsec_address(union sockaddr_union* sa)
1844 {
1845         switch (sa->sa.sa_family) {
1846 #if INET
1847         case AF_INET:
1848                 return inet_ntoa4(sa->sin.sin_addr);
1849 #endif /* INET */
1850
1851 #if INET6
1852         case AF_INET6:
1853                 return ip6_sprintf(&sa->sin6.sin6_addr);
1854 #endif /* INET6 */
1855
1856         default:
1857                 return "(unknown address family)";
1858         }
1859 }
1860
1861 const char *
1862 ipsec_logsastr(sav)
1863         struct secasvar *sav;
1864 {
1865         static char buf[256];
1866         char *p;
1867         struct secasindex *saidx = &sav->sah->saidx;
1868
1869         KASSERT(saidx->src.sa.sa_family == saidx->dst.sa.sa_family,
1870                 ("ipsec_logsastr: address family mismatch"));
1871
1872         p = buf;
1873         snprintf(buf, sizeof(buf), "SA(SPI=%u ", (u_int32_t)ntohl(sav->spi));
1874         while (p && *p)
1875                 p++;
1876         /* NB: only use ipsec_address on one address at a time */
1877         snprintf(p, sizeof (buf) - (p - buf), "src=%s ",
1878                 ipsec_address(&saidx->src));
1879         while (p && *p)
1880                 p++;
1881         snprintf(p, sizeof (buf) - (p - buf), "dst=%s)",
1882                 ipsec_address(&saidx->dst));
1883
1884         return buf;
1885 }
1886
1887 void
1888 ipsec_dumpmbuf(m)
1889         struct mbuf *m;
1890 {
1891         int totlen;
1892         int i;
1893         u_char *p;
1894
1895         totlen = 0;
1896         printf("---\n");
1897         while (m) {
1898                 p = mtod(m, u_char *);
1899                 for (i = 0; i < m->m_len; i++) {
1900                         printf("%02x ", p[i]);
1901                         totlen++;
1902                         if (totlen % 16 == 0)
1903                                 printf("\n");
1904                 }
1905                 m = m->m_next;
1906         }
1907         if (totlen % 16 != 0)
1908                 printf("\n");
1909         printf("---\n");
1910 }
1911
1912 /* XXX this stuff doesn't belong here... */
1913
1914 static  struct xformsw* xforms = NULL;
1915
1916 /*
1917  * Register a transform; typically at system startup.
1918  */
1919 void
1920 xform_register(struct xformsw* xsp)
1921 {
1922         xsp->xf_next = xforms;
1923         xforms = xsp;
1924 }
1925
1926 /*
1927  * Initialize transform support in an sav.
1928  */
1929 int
1930 xform_init(struct secasvar *sav, int xftype)
1931 {
1932         struct xformsw *xsp;
1933
1934         for (xsp = xforms; xsp; xsp = xsp->xf_next)
1935                 if (xsp->xf_type == xftype)
1936                         return (*xsp->xf_init)(sav, xsp);
1937         return EINVAL;
1938 }