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