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