]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/netkey/key.c
This commit was generated by cvs2svn to compensate for changes in r26180,
[FreeBSD/FreeBSD.git] / sys / netkey / key.c
1 /*----------------------------------------------------------------------
2   key.c :         Key Management Engine for BSD
3
4   Copyright 1995 by Bao Phan,  Randall Atkinson, & Dan McDonald,
5   All Rights Reserved.  All Rights have been assigned to the US
6   Naval Research Laboratory (NRL).  The NRL Copyright Notice and
7   License governs distribution and use of this software.
8
9   Patents are pending on this technology.  NRL grants a license
10   to use this technology at no cost under the terms below with
11   the additional requirement that software, hardware, and 
12   documentation relating to use of this technology must include
13   the note that:
14         This product includes technology developed at and
15         licensed from the Information Technology Division, 
16         US Naval Research Laboratory.
17
18 ----------------------------------------------------------------------*/
19 /*----------------------------------------------------------------------
20 #       @(#)COPYRIGHT   1.1a (NRL) 17 August 1995
21
22 COPYRIGHT NOTICE
23
24 All of the documentation and software included in this software
25 distribution from the US Naval Research Laboratory (NRL) are
26 copyrighted by their respective developers.
27
28 This software and documentation were developed at NRL by various
29 people.  Those developers have each copyrighted the portions that they
30 developed at NRL and have assigned All Rights for those portions to
31 NRL.  Outside the USA, NRL also has copyright on the software
32 developed at NRL. The affected files all contain specific copyright
33 notices and those notices must be retained in any derived work.
34
35 NRL LICENSE
36
37 NRL grants permission for redistribution and use in source and binary
38 forms, with or without modification, of the software and documentation
39 created at NRL provided that the following conditions are met:
40
41 1. Redistributions of source code must retain the above copyright
42    notice, this list of conditions and the following disclaimer.
43 2. Redistributions in binary form must reproduce the above copyright
44    notice, this list of conditions and the following disclaimer in the
45    documentation and/or other materials provided with the distribution.
46 3. All advertising materials mentioning features or use of this software
47    must display the following acknowledgement:
48
49         This product includes software developed at the Information
50         Technology Division, US Naval Research Laboratory.
51
52 4. Neither the name of the NRL nor the names of its contributors
53    may be used to endorse or promote products derived from this software
54    without specific prior written permission.
55
56 THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS
57 IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
58 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
59 PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL NRL OR
60 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
61 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
62 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
63 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
64 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
65 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
66 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
67
68 The views and conclusions contained in the software and documentation
69 are those of the authors and should not be interpreted as representing
70 official policies, either expressed or implied, of the US Naval
71 Research Laboratory (NRL).
72
73 ----------------------------------------------------------------------*/
74
75 #include <sys/param.h>
76 #include <sys/systm.h>
77 #include <sys/kernel.h>
78 #include <sys/domain.h>
79 #include <sys/mbuf.h>
80 #include <sys/proc.h>
81 #include <sys/protosw.h>
82 #include <sys/socket.h>
83 #include <sys/socketvar.h>
84 #include <sys/time.h>
85
86 #include <net/raw_cb.h>
87 #include <net/if.h>
88 #include <net/if_types.h>
89 #include <net/if_dl.h>
90 #include <net/route.h>
91
92 #include <netinet/in.h>
93 #include <netinet/in_var.h>
94 #include <netinet/if_ether.h>
95
96 #ifdef INET6
97 #include <netinet6/in6.h>
98 #include <netinet6/in6_var.h>
99 #endif /* INET6 */
100
101 #include <netkey/key.h>
102 #include <netkey/key_debug.h>
103
104 #define SOCKADDR struct sockaddr
105
106 #define KMALLOC(p, t, n) (p = (t) malloc((unsigned long)(n), M_SECA, M_DONTWAIT))
107 #define KFREE(p) free((caddr_t)p, M_SECA);
108
109 #define CRITICAL_DCL int critical_s;
110 #define CRITICAL_START critical_s = splnet()
111 #define CRITICAL_END splx(critical_s)
112
113 #define TIME_SECONDS time.tv_sec
114 #define CURRENT_PID curproc->p_pid
115
116 #define DEFARGS(arglist, args) arglist args;
117 #define AND ;
118
119 #ifdef INET6
120 #define MAXHASHKEYLEN (2 * sizeof(int) + 2 * sizeof(struct sockaddr_in6))
121 #else
122 #define MAXHASHKEYLEN (2 * sizeof(int) + 2 * sizeof(struct sockaddr_in))
123 #endif
124
125
126 /*
127  *  Not clear whether these values should be 
128  *  tweakable at kernel config time.
129  */
130 #define KEYTBLSIZE 61
131 #define KEYALLOCTBLSIZE 61
132 #define SO2SPITBLSIZE 61
133
134 /*
135  *  These values should be tweakable...
136  *  perhaps by using sysctl
137  */
138
139 #define MAXLARVALTIME 240;   /* Lifetime of a larval key table entry */ 
140 #define MAXKEYACQUIRE 1;     /* Max number of key acquire messages sent */
141                              /*   per destination address               */
142 #define MAXACQUIRETIME 15;   /* Lifetime of acquire message */
143
144 /*
145  *  Key engine tables and global variables
146  */
147
148 struct key_tblnode keytable[KEYTBLSIZE];
149 struct key_allocnode keyalloctbl[KEYALLOCTBLSIZE];
150 struct key_so2spinode so2spitbl[SO2SPITBLSIZE];
151
152 struct keyso_cb keyso_cb;
153 struct key_tblnode nullkeynode;
154 struct key_registry *keyregtable;
155 struct key_acquirelist *key_acquirelist;
156 u_long maxlarvallifetime = MAXLARVALTIME;
157 int maxkeyacquire = MAXKEYACQUIRE;
158 u_long maxacquiretime = MAXACQUIRETIME;
159
160 extern SOCKADDR key_addr;
161
162 #define ROUNDUP(a) \
163   ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
164 #define ADVANCE(x, n) \
165     { x += ROUNDUP(n); }
166
167 static int my_addr __P((SOCKADDR *));
168 static int key_sendup __P((struct socket *, struct key_msghdr *));
169
170 /*----------------------------------------------------------------------
171  * key_secassoc2msghdr(): 
172  *      Copy info from a security association into a key message buffer.
173  *      Assume message buffer is sufficiently large to hold all security
174  *      association information including src, dst, from, key and iv.
175  ----------------------------------------------------------------------*/
176 int
177 key_secassoc2msghdr(struct key_secassoc *secassoc,
178                     struct key_msghdr *km,
179                     struct key_msgdata *keyinfo)
180 {
181   char *cp;
182   DPRINTF(IDL_FINISHED, ("Entering key_secassoc2msghdr\n"));
183
184   if ((km == 0) || (keyinfo == 0) || (secassoc == 0))
185     return(-1);
186
187   km->type = secassoc->type;
188   km->state = secassoc->state;
189   km->label = secassoc->label;
190   km->spi = secassoc->spi;
191   km->keylen = secassoc->keylen;
192   km->ivlen = secassoc->ivlen;
193   km->algorithm = secassoc->algorithm;
194   km->lifetype = secassoc->lifetype;
195   km->lifetime1 = secassoc->lifetime1;
196   km->lifetime2 = secassoc->lifetime2;
197
198   /*
199    *  Stuff src/dst/from/key/iv in buffer after
200    *  the message header.
201    */
202   cp = (char *)(km + 1);
203
204   DPRINTF(IDL_FINISHED, ("sa2msghdr: 1\n"));
205   keyinfo->src = (SOCKADDR *)cp;
206   if (secassoc->src->sa_len) {
207     bcopy(secassoc->src, cp, secassoc->src->sa_len);
208     ADVANCE(cp, secassoc->src->sa_len);
209   } else {
210     bzero(cp, MAX_SOCKADDR_SZ);
211     ADVANCE(cp, MAX_SOCKADDR_SZ);
212   }
213
214   DPRINTF(IDL_FINISHED, ("sa2msghdr: 2\n"));
215   keyinfo->dst = (SOCKADDR *)cp;
216   if (secassoc->dst->sa_len) {
217     bcopy(secassoc->dst, cp, secassoc->dst->sa_len);
218     ADVANCE(cp, secassoc->dst->sa_len);
219   } else {
220     bzero(cp, MAX_SOCKADDR_SZ);
221     ADVANCE(cp, MAX_SOCKADDR_SZ);
222   }
223
224   DPRINTF(IDL_FINISHED, ("sa2msghdr: 3\n"));
225   keyinfo->from = (SOCKADDR *)cp;
226   if (secassoc->from->sa_len) {
227     bcopy(secassoc->from, cp, secassoc->from->sa_len);
228     ADVANCE(cp, secassoc->from->sa_len);
229   } else {
230     bzero(cp, MAX_SOCKADDR_SZ);
231     ADVANCE(cp, MAX_SOCKADDR_SZ);
232   }
233
234   DPRINTF(IDL_FINISHED, ("sa2msghdr: 4\n"));
235
236   keyinfo->key = cp;
237   keyinfo->keylen = secassoc->keylen;
238   if (secassoc->keylen) {
239     bcopy((char *)(secassoc->key), cp, secassoc->keylen);
240     ADVANCE(cp, secassoc->keylen);
241   }
242
243   DPRINTF(IDL_FINISHED, ("sa2msghdr: 5\n"));
244   keyinfo->iv = cp;
245   keyinfo->ivlen = secassoc->ivlen;
246   if (secassoc->ivlen) {
247     bcopy((char *)(secassoc->iv), cp, secassoc->ivlen);
248     ADVANCE(cp, secassoc->ivlen);
249   }
250
251   DDO(IDL_FINISHED,printf("msgbuf(len=%d):\n",(char *)cp - (char *)km));
252   DDO(IDL_FINISHED,dump_buf((char *)km, (char *)cp - (char *)km));
253   DPRINTF(IDL_FINISHED, ("sa2msghdr: 6\n"));
254   return(0);
255 }
256
257
258 /*----------------------------------------------------------------------
259  * key_msghdr2secassoc():
260  *      Copy info from a key message buffer into a key_secassoc 
261  *      structure
262  ----------------------------------------------------------------------*/
263 int
264 key_msghdr2secassoc(struct key_secassoc *secassoc,
265                     struct key_msghdr *km,
266                     struct key_msgdata *keyinfo)
267 {
268   DPRINTF(IDL_FINISHED, ("Entering key_msghdr2secassoc\n"));
269
270   if ((km == 0) || (keyinfo == 0) || (secassoc == 0))
271     return(-1);
272
273   secassoc->len = sizeof(*secassoc);
274   secassoc->type = km->type;
275   secassoc->state = km->state;
276   secassoc->label = km->label;
277   secassoc->spi = km->spi;
278   secassoc->keylen = km->keylen;
279   secassoc->ivlen = km->ivlen;
280   secassoc->algorithm = km->algorithm;
281   secassoc->lifetype = km->lifetype;
282   secassoc->lifetime1 = km->lifetime1;
283   secassoc->lifetime2 = km->lifetime2;
284
285   if (keyinfo->src) {
286     KMALLOC(secassoc->src, SOCKADDR *, keyinfo->src->sa_len);
287     if (!secassoc->src) {
288       DPRINTF(IDL_ERROR,("msghdr2secassoc: can't allocate mem for src\n"));
289       return(-1);
290     }
291     bcopy((char *)keyinfo->src, (char *)secassoc->src,
292           keyinfo->src->sa_len);
293   } else
294     secassoc->src = NULL;
295
296   if (keyinfo->dst) {
297     KMALLOC(secassoc->dst, SOCKADDR *, keyinfo->dst->sa_len);
298     if (!secassoc->dst) {
299       DPRINTF(IDL_ERROR,("msghdr2secassoc: can't allocate mem for dst\n"));
300       return(-1);
301     }
302     bcopy((char *)keyinfo->dst, (char *)secassoc->dst,
303           keyinfo->dst->sa_len);
304   } else
305     secassoc->dst = NULL;
306
307   if (keyinfo->from) {
308     KMALLOC(secassoc->from, SOCKADDR *, keyinfo->from->sa_len);
309     if (!secassoc->from) {
310       DPRINTF(IDL_ERROR,("msghdr2secassoc: can't allocate mem for from\n"));
311       return(-1);
312     }
313     bcopy((char *)keyinfo->from, (char *)secassoc->from,
314           keyinfo->from->sa_len);
315   } else
316     secassoc->from = NULL;
317
318   /*
319    *  Make copies of key and iv
320    */
321   if (secassoc->ivlen) {
322     KMALLOC(secassoc->iv, caddr_t, secassoc->ivlen);
323     if (secassoc->iv == 0) {
324       DPRINTF(IDL_ERROR,("msghdr2secassoc: can't allocate mem for iv\n"));
325       return(-1);
326     }
327     bcopy((char *)keyinfo->iv, (char *)secassoc->iv, secassoc->ivlen);
328   } else
329     secassoc->iv = NULL;
330              
331   if (secassoc->keylen) {
332     KMALLOC(secassoc->key, caddr_t, secassoc->keylen);
333     if (secassoc->key == 0) {
334       DPRINTF(IDL_ERROR,("msghdr2secassoc: can't allocate mem for key\n"));
335       if (secassoc->iv)
336         KFREE(secassoc->iv);
337       return(-1);
338     }
339     bcopy((char *)keyinfo->key, (char *)secassoc->key, secassoc->keylen);
340   } else
341     secassoc->key = NULL;
342   return(0);
343 }
344
345
346 /*----------------------------------------------------------------------
347  * addrpart_equal():
348  *      Determine if the address portion of two sockaddrs are equal.
349  *      Currently handles only AF_INET and AF_INET6 address families.
350  ----------------------------------------------------------------------*/
351 static int
352 addrpart_equal(SOCKADDR *sa1, SOCKADDR *sa2)
353 {
354   if ((sa1->sa_family != sa2->sa_family) ||
355       (sa1->sa_len != sa2->sa_len))
356     return 0;
357
358   switch(sa1->sa_family) {
359   case AF_INET:
360     return (((struct sockaddr_in *)sa1)->sin_addr.s_addr == 
361             ((struct sockaddr_in *)sa2)->sin_addr.s_addr);
362 #ifdef INET6
363   case AF_INET6:
364     return (IN6_ADDR_EQUAL(((struct sockaddr_in6 *)sa1)->sin6_addr, 
365                            ((struct sockaddr_in6 *)sa2)->sin6_addr));
366 #endif /* INET6 */
367   }
368   return(0);
369 }
370
371 /*----------------------------------------------------------------------
372  * key_inittables():
373  *      Allocate space and initialize key engine tables
374  ----------------------------------------------------------------------*/
375 int
376 key_inittables(void)
377 {
378   int i;
379
380   KMALLOC(keyregtable, struct key_registry *, sizeof(struct key_registry));
381   if (!keyregtable)
382     return -1;
383   bzero((char *)keyregtable, sizeof(struct key_registry));
384   KMALLOC(key_acquirelist, struct key_acquirelist *, 
385            sizeof(struct key_acquirelist));
386   if (!key_acquirelist)
387     return -1;
388   bzero((char *)key_acquirelist, sizeof(struct key_acquirelist));
389   for (i = 0; i < KEYTBLSIZE; i++) 
390     bzero((char *)&keytable[i], sizeof(struct key_tblnode));
391   for (i = 0; i < KEYALLOCTBLSIZE; i++)
392     bzero((char *)&keyalloctbl[i], sizeof(struct key_allocnode));
393   for (i = 0; i < SO2SPITBLSIZE; i++)
394     bzero((char *)&so2spitbl[i], sizeof(struct key_so2spinode));
395
396   return 0;
397 }
398
399 static int
400 key_freetables(void)
401 {
402   KFREE(keyregtable);
403   keyregtable = NULL;
404   KFREE(key_acquirelist);
405   key_acquirelist = NULL;
406   return 0;
407 }
408
409 /*----------------------------------------------------------------------
410  * key_gethashval():
411  *      Determine keytable hash value.
412  ----------------------------------------------------------------------*/
413 static int
414 key_gethashval(char *buf, int len, int tblsize)
415 {
416   int i, j = 0;
417
418   /* 
419    * Todo: Use word size xor and check for alignment
420    *       and zero pad if necessary.  Need to also pick 
421    *       a good hash function and table size.
422    */
423   if (len <= 0) {
424     DPRINTF(IDL_ERROR,("key_gethashval got bogus len!\n"));
425     return(-1);
426   }
427   for(i = 0; i < len; i++) {
428     j ^=  (u_int8_t)(*(buf + i));
429   }
430   return (j % tblsize);
431 }
432
433
434 /*----------------------------------------------------------------------
435  * key_createkey():
436  *      Create hash key for hash function
437  *      key is: type+src+dst if keytype = 1
438  *              type+src+dst+spi if keytype = 0
439  *      Uses only the address portion of the src and dst sockaddrs to 
440  *      form key.  Currently handles only AF_INET and AF_INET6 sockaddrs
441  ----------------------------------------------------------------------*/
442 static int
443 key_createkey(char *buf, u_int type, SOCKADDR *src, SOCKADDR *dst,
444               u_int32_t spi, u_int keytype)
445 {
446   char *cp, *p;
447
448   DPRINTF(IDL_FINISHED,("Entering key_createkey\n"));
449
450   if (!buf || !src || !dst)
451     return(-1);
452
453   cp = buf;
454   bcopy((char *)&type, cp, sizeof(type));
455   cp += sizeof(type);
456
457 #ifdef INET6
458   /*
459    * Assume only IPv4 and IPv6 addresses.
460    */
461 #define ADDRPART(a) \
462     ((a)->sa_family == AF_INET6) ? \
463     (char *)&(((struct sockaddr_in6 *)(a))->sin6_addr) : \
464     (char *)&(((struct sockaddr_in *)(a))->sin_addr)
465
466 #define ADDRSIZE(a) \
467     ((a)->sa_family == AF_INET6) ? sizeof(struct in_addr6) : \
468     sizeof(struct in_addr)  
469 #else /* INET6 */
470 #define ADDRPART(a) (char *)&(((struct sockaddr_in *)(a))->sin_addr)
471 #define ADDRSIZE(a) sizeof(struct in_addr)  
472 #endif /* INET6 */
473
474   DPRINTF(IDL_FINISHED,("src addr:\n"));
475   DDO(IDL_FINISHED,dump_smart_sockaddr(src));
476   DPRINTF(IDL_FINISHED,("dst addr:\n"));
477   DDO(IDL_FINISHED,dump_smart_sockaddr(dst)); 
478
479   p = ADDRPART(src);
480   bcopy(p, cp, ADDRSIZE(src));
481   cp += ADDRSIZE(src);
482
483   p = ADDRPART(dst);
484   bcopy(p, cp, ADDRSIZE(dst));
485   cp += ADDRSIZE(dst);
486
487 #undef ADDRPART
488 #undef ADDRSIZE
489
490   if (keytype == 0) {
491     bcopy((char *)&spi, cp, sizeof(spi));
492     cp += sizeof(spi);
493   }
494
495   DPRINTF(IDL_FINISHED,("hash key:\n"));
496   DDO(IDL_FINISHED, dump_buf(buf, cp - buf));
497   return(cp - buf);
498 }
499
500
501 /*----------------------------------------------------------------------
502  * key_sosearch():
503  *      Search the so2spi table for the security association allocated to 
504  *      the socket.  Returns pointer to a struct key_so2spinode which can
505  *      be used to locate the security association entry in the keytable.
506  ----------------------------------------------------------------------*/
507 static struct key_so2spinode *
508 key_sosearch(u_int type, SOCKADDR *src, SOCKADDR *dst, struct socket *so)
509 {
510   struct key_so2spinode *np = 0;
511
512   if (!(src && dst)) {
513     DPRINTF(IDL_ERROR,("key_sosearch: got null src or dst pointer!\n"));
514     return(NULL);
515   }
516
517   for (np = so2spitbl[((u_int32_t)so) % SO2SPITBLSIZE].next; np; np = np->next) {
518     if ((so == np->socket) && (type == np->keynode->secassoc->type)
519         && addrpart_equal(src, np->keynode->secassoc->src)
520         && addrpart_equal(dst, np->keynode->secassoc->dst))
521       return(np);
522   }  
523   return(NULL);
524 }
525
526
527 /*----------------------------------------------------------------------
528  * key_sodelete():
529  *      Delete entries from the so2spi table.
530  *        flag = 1  purge all entries
531  *        flag = 0  delete entries with socket pointer matching socket  
532  ----------------------------------------------------------------------*/
533 static void
534 key_sodelete(struct socket *socket, int flag)
535 {
536   struct key_so2spinode *prevnp, *np;
537   CRITICAL_DCL
538
539   CRITICAL_START;
540
541   DPRINTF(IDL_EVENT,("Entering keysodelete w/so=0x%x flag=%d\n",
542                      (unsigned int)socket,flag));
543
544   if (flag) {
545     int i;
546
547     for (i = 0; i < SO2SPITBLSIZE; i++)
548       for(np = so2spitbl[i].next; np; np = np->next) {
549         KFREE(np);
550       }
551     CRITICAL_END;
552     return;
553   }
554
555   prevnp = &so2spitbl[((u_int32_t)socket) % SO2SPITBLSIZE];
556   for(np = prevnp->next; np; np = np->next) {
557     if (np->socket == socket) {
558       struct socketlist *socklp, *prevsocklp;
559
560       (np->keynode->alloc_count)--;
561
562       /* 
563        * If this socket maps to a unique secassoc,
564        * we go ahead and delete the secassoc, since it
565        * can no longer be allocated or used by any other 
566        * socket.
567        */
568       if (np->keynode->secassoc->state & K_UNIQUE) {
569         if (key_delete(np->keynode->secassoc) != 0)
570           panic("key_sodelete");
571         np = prevnp;
572         continue;
573       }
574
575       /*
576        * We traverse the socketlist and remove the entry
577        * for this socket
578        */
579       DPRINTF(IDL_FINISHED,("keysodelete: deleting from socklist..."));
580       prevsocklp = np->keynode->solist;
581       for (socklp = prevsocklp->next; socklp; socklp = socklp->next) {
582         if (socklp->socket == socket) {
583           prevsocklp->next = socklp->next;
584           KFREE(socklp);
585           break;
586         }
587         prevsocklp = socklp;
588       }
589       DPRINTF(IDL_FINISHED,("done\n"));
590       prevnp->next = np->next;
591       KFREE(np);
592       np = prevnp;
593     }
594     prevnp = np;  
595   }
596   CRITICAL_END;
597 }
598
599
600 /*----------------------------------------------------------------------
601  * key_deleteacquire():
602  *      Delete an entry from the key_acquirelist
603  ----------------------------------------------------------------------*/
604 static void
605 key_deleteacquire(u_int type, SOCKADDR *target)
606 {
607   struct key_acquirelist *ap, *prev;
608
609   prev = key_acquirelist;
610   for(ap = key_acquirelist->next; ap; ap = ap->next) {
611     if (addrpart_equal(target, (SOCKADDR *)&(ap->target)) &&
612         (type == ap->type)) {
613       DPRINTF(IDL_EVENT,("Deleting entry from acquire list!\n"));
614       prev->next = ap->next;
615       KFREE(ap);
616       ap = prev;
617     }
618     prev = ap;
619   }
620 }
621
622
623 /*----------------------------------------------------------------------
624  * key_search():
625  *      Search the key table for an entry with same type, src addr, dest
626  *      addr, and spi.  Returns a pointer to struct key_tblnode if found
627  *      else returns null.
628  ----------------------------------------------------------------------*/
629 static struct key_tblnode *
630 key_search(u_int type, SOCKADDR *src, SOCKADDR *dst, u_int32_t spi, 
631            int indx, struct key_tblnode **prevkeynode)
632 {
633   struct key_tblnode *keynode, *prevnode;
634
635   if (indx > KEYTBLSIZE || indx < 0)
636     return (NULL);
637   if (!(&keytable[indx]))
638     return (NULL);
639
640 #define sec_type keynode->secassoc->type
641 #define sec_spi keynode->secassoc->spi
642 #define sec_src keynode->secassoc->src
643 #define sec_dst keynode->secassoc->dst
644
645   prevnode = &keytable[indx];
646   for (keynode = keytable[indx].next; keynode; keynode = keynode->next) {
647     if ((type == sec_type) && (spi == sec_spi) && 
648         addrpart_equal(src, sec_src)
649         && addrpart_equal(dst, sec_dst))
650       break;
651     prevnode = keynode;
652   }
653   *prevkeynode = prevnode;
654   return(keynode);
655 }
656
657
658 /*----------------------------------------------------------------------
659  * key_addnode():
660  *      Insert a key_tblnode entry into the key table.  Returns a pointer 
661  *      to the newly created key_tblnode.
662  ----------------------------------------------------------------------*/
663 static struct key_tblnode *
664 key_addnode(int indx, struct key_secassoc *secassoc)
665 {
666   struct key_tblnode *keynode;
667
668   DPRINTF(IDL_FINISHED,("Entering key_addnode w/indx=%d secassoc=0x%x\n",
669                         indx, (unsigned int)secassoc));
670
671   if (!(&keytable[indx]))
672     return(NULL);
673   if (!secassoc) {
674     panic("key_addnode: Someone passed in a null secassoc!\n");
675   }
676
677   KMALLOC(keynode, struct key_tblnode *, sizeof(struct key_tblnode));
678   if (keynode == 0)
679     return(NULL);
680   bzero((char *)keynode, sizeof(struct key_tblnode));
681
682   KMALLOC(keynode->solist, struct socketlist *, sizeof(struct socketlist));
683   if (keynode->solist == 0) {
684     KFREE(keynode);
685     return(NULL);
686   }
687   bzero((char *)(keynode->solist), sizeof(struct socketlist));
688
689   keynode->secassoc = secassoc;
690   keynode->solist->next = NULL;
691   keynode->next = keytable[indx].next;
692   keytable[indx].next = keynode;
693   return(keynode);
694 }
695
696
697 /*----------------------------------------------------------------------
698  * key_add():
699  *      Add a new security association to the key table.  Caller is
700  *      responsible for allocating memory for the key_secassoc as  
701  *      well as the buffer space for the key,  iv.  Assumes the security 
702  *      association passed in is well-formed.
703  ----------------------------------------------------------------------*/
704 int
705 key_add(struct key_secassoc *secassoc)
706 {
707   char buf[MAXHASHKEYLEN];
708   int len, indx;
709   int inbound = 0;
710   int outbound = 0;
711   struct key_tblnode *keynode, *prevkeynode;
712   struct key_allocnode *np = NULL;
713   CRITICAL_DCL
714
715   DPRINTF(IDL_FINISHED, ("Entering key_add w/secassoc=0x%x\n",
716                          (unsigned int)secassoc));
717
718   if (!secassoc) {
719     panic("key_add: who the hell is passing me a null pointer");
720   }
721
722   /*
723    * Should we allow a null key to be inserted into the table ? 
724    * or can we use null key to indicate some policy action...
725    */
726
727 #if 0
728   /*
729    *  For esp using des-cbc or tripple-des we call 
730    * des_set_odd_parity.
731    */
732   if (secassoc->key && (secassoc->type == KEY_TYPE_ESP) && 
733       ((secassoc->algorithm == IPSEC_ALGTYPE_ESP_DES_CBC) ||
734        (secassoc->algorithm == IPSEC_ALGTYPE_ESP_3DES)))
735     des_set_odd_parity(secassoc->key);
736 #endif /* 0 */
737
738   /*
739    *  Check if secassoc with same spi exists before adding
740    */
741   bzero((char *)&buf, sizeof(buf));
742   len = key_createkey((char *)&buf, secassoc->type, secassoc->src,
743                       secassoc->dst, secassoc->spi, 0);
744   indx = key_gethashval((char *)&buf, len, KEYTBLSIZE);
745   DPRINTF(IDL_FINISHED,("keyadd: keytbl hash position=%d\n", indx));
746   keynode = key_search(secassoc->type, secassoc->src, secassoc->dst,
747                        secassoc->spi, indx, &prevkeynode);
748   if (keynode) {
749     DPRINTF(IDL_EVENT,("keyadd: secassoc already exists!\n"));
750     return(-2);
751   }
752
753   inbound = my_addr(secassoc->dst);
754   outbound = my_addr(secassoc->src);
755   DPRINTF(IDL_FINISHED,("inbound=%d outbound=%d\n", inbound, outbound));
756
757   /*
758    * We allocate mem for an allocation entry if needed.
759    * This is done here instead of in the allocaton code 
760    * segment so that we can easily recover/cleanup from a 
761    * memory allocation error.
762    */
763   if (outbound || (!inbound && !outbound)) {
764     KMALLOC(np, struct key_allocnode *, sizeof(struct key_allocnode));
765     if (np == 0) {
766       DPRINTF(IDL_ERROR,("keyadd: can't allocate allocnode!\n"));
767       return(-1);
768     }
769   }
770
771   CRITICAL_START;
772
773   if ((keynode = key_addnode(indx, secassoc)) == NULL) {
774     DPRINTF(IDL_ERROR,("keyadd: key_addnode failed!\n"));
775     if (np)
776       KFREE(np);
777     CRITICAL_END;
778     return(-1);
779   }
780   DPRINTF(IDL_GROSS_EVENT,("Added new keynode:\n"));
781   DDO(IDL_FINISHED, dump_keytblnode(keynode));
782   DDO(IDL_FINISHED, dump_secassoc(keynode->secassoc));
783  
784   /*
785    *  We add an entry to the allocation table for
786    *  this secassoc if the interfaces are up, 
787    *  the secassoc is outbound.  In the case 
788    *  where the interfaces are not up, we go ahead
789    * ,  do it anyways.  This wastes an allocation
790    *  entry if the secassoc later turned out to be
791    *  inbound when the interfaces are ifconfig up.
792    */
793   if (outbound || (!inbound && !outbound)) {
794     len = key_createkey((char *)&buf, secassoc->type, secassoc->src,
795                         secassoc->dst, 0, 1);
796     indx = key_gethashval((char *)&buf, len, KEYALLOCTBLSIZE);
797     DPRINTF(IDL_FINISHED,("keyadd: keyalloc hash position=%d\n", indx));
798     np->keynode = keynode;
799     np->next = keyalloctbl[indx].next;
800     keyalloctbl[indx].next = np;
801   }
802   if (inbound)
803     secassoc->state |= K_INBOUND;
804   if (outbound)
805     secassoc->state |= K_OUTBOUND;
806
807   key_deleteacquire(secassoc->type, secassoc->dst);
808
809   CRITICAL_END;
810   return 0;
811 }
812
813
814 /*----------------------------------------------------------------------
815  * key_get():
816  *      Get a security association from the key table.
817  ----------------------------------------------------------------------*/
818 int
819 key_get(u_int type, SOCKADDR *src, SOCKADDR *dst, u_int32_t spi, 
820         struct key_secassoc **secassoc)
821 {
822   char buf[MAXHASHKEYLEN];
823   struct key_tblnode *keynode, *prevkeynode;
824   int len, indx;
825
826   bzero(&buf, sizeof(buf));
827   *secassoc = NULL;
828   len = key_createkey((char *)&buf, type, src, dst, spi, 0);
829   indx = key_gethashval((char *)&buf, len, KEYTBLSIZE);
830   DPRINTF(IDL_FINISHED,("keyget: indx=%d\n",indx));
831   keynode = key_search(type, src, dst, spi, indx, &prevkeynode);
832   if (keynode) {
833     DPRINTF(IDL_GROSS_EVENT,("keyget: found it! keynode=0x%x",
834                              (unsigned int)keynode));
835     *secassoc = keynode->secassoc;
836     return(0);
837   } else
838     return(-1);  /* Not found */
839 }
840
841
842 /*----------------------------------------------------------------------
843  * key_dump():
844  *      Dump all valid entries in the keytable to a pf_key socket.  Each
845  *      security associaiton is sent one at a time in a pf_key message.  A
846  *      message with seqno = 0 signifies the end of the dump transaction.
847  ----------------------------------------------------------------------*/
848 int
849 key_dump(struct socket *so)
850 {
851   int len, i;
852   int seq = 1;
853   struct key_msgdata keyinfo;
854   struct key_msghdr *km;
855   struct key_tblnode *keynode;
856
857   /*
858    * Routine to dump the key table to a routing socket
859    * Use for debugging only!
860    */
861
862   KMALLOC(km, struct key_msghdr *, sizeof(struct key_msghdr) +
863           3 * MAX_SOCKADDR_SZ + MAX_KEY_SZ + MAX_IV_SZ);
864   if (!km)
865     return(ENOBUFS);
866
867   DPRINTF(IDL_FINISHED,("Entering key_dump()"));
868   /* 
869    * We need to speed this up later.  Fortunately, key_dump 
870    * messages are not sent often.
871    */
872   for (i = 0; i < KEYTBLSIZE; i++) {
873     for (keynode = keytable[i].next; keynode; keynode = keynode->next) {
874       /*
875        * We exclude dead/larval/zombie security associations for now
876        * but it may be useful to also send these up for debugging purposes
877        */
878       if (keynode->secassoc->state & (K_DEAD | K_LARVAL | K_ZOMBIE))
879         continue;
880
881       len = (sizeof(struct key_msghdr) +
882              ROUNDUP(keynode->secassoc->src->sa_len) + 
883              ROUNDUP(keynode->secassoc->dst->sa_len) +
884              ROUNDUP(keynode->secassoc->from->sa_len) +
885              ROUNDUP(keynode->secassoc->keylen) + 
886              ROUNDUP(keynode->secassoc->ivlen));
887
888       if (key_secassoc2msghdr(keynode->secassoc, km, &keyinfo) != 0)
889         panic("key_dump");
890
891       km->key_msglen = len;
892       km->key_msgvers = KEY_VERSION;
893       km->key_msgtype = KEY_DUMP;
894       km->key_pid = CURRENT_PID;
895       km->key_seq = seq++;
896       km->key_errno = 0;
897
898       key_sendup(so, km);
899     }
900   }
901   bzero((char *)km, sizeof(struct key_msghdr));
902   km->key_msglen = sizeof(struct key_msghdr);
903   km->key_msgvers = KEY_VERSION;
904   km->key_msgtype = KEY_DUMP;
905   km->key_pid = CURRENT_PID;
906   km->key_seq = 0;
907   km->key_errno = 0;
908
909   key_sendup(so, km);
910   KFREE(km);
911   DPRINTF(IDL_FINISHED,("Leaving key_dump()\n"));  
912   return(0);
913 }
914
915 /*----------------------------------------------------------------------
916  * key_delete():
917  *      Delete a security association from the key table.
918  ----------------------------------------------------------------------*/
919 int
920 key_delete(struct key_secassoc *secassoc)
921 {
922   char buf[MAXHASHKEYLEN];
923   int len, indx;
924   struct key_tblnode *keynode = 0;
925   struct key_tblnode *prevkeynode = 0;
926   struct socketlist *socklp, *deadsocklp;
927   struct key_so2spinode *np, *prevnp;
928   struct key_allocnode *ap, *prevap;
929   CRITICAL_DCL
930
931   DPRINTF(IDL_FINISHED,("Entering key_delete w/secassoc=0x%x\n",
932                         (unsigned int)secassoc));
933
934   bzero((char *)&buf, sizeof(buf));
935   len = key_createkey((char *)&buf, secassoc->type, secassoc->src,
936                       secassoc->dst, secassoc->spi, 0);
937   indx = key_gethashval((char *)&buf, len, KEYTBLSIZE);
938   DPRINTF(IDL_FINISHED,("keydelete: keytbl hash position=%d\n", indx));
939   keynode = key_search(secassoc->type, secassoc->src, secassoc->dst, 
940                        secassoc->spi, indx, &prevkeynode); 
941  
942   if (keynode) {
943     CRITICAL_START;
944     DPRINTF(IDL_GROSS_EVENT,("keydelete: found keynode to delete\n"));
945     keynode->secassoc->state |= K_DEAD;
946
947     if (keynode->ref_count > 0) {
948       DPRINTF(IDL_EVENT,("keydelete: secassoc still held, marking for deletion only!\n"));
949       CRITICAL_END;
950       return(0); 
951     }
952
953     prevkeynode->next = keynode->next;
954     
955     /*
956      *  Walk the socketlist,  delete the
957      *  entries mapping sockets to this secassoc
958      *  from the so2spi table.
959      */
960     DPRINTF(IDL_FINISHED,("keydelete: deleting socklist..."));
961     for(socklp = keynode->solist->next; socklp; ) {
962       prevnp = &so2spitbl[((u_int32_t)(socklp->socket)) % SO2SPITBLSIZE];
963       for(np = prevnp->next; np; np = np->next) {
964         if ((np->socket == socklp->socket) && (np->keynode == keynode)) {
965           prevnp->next = np->next;
966           KFREE(np);
967           break; 
968         }
969         prevnp = np;  
970       }
971       deadsocklp = socklp;
972       socklp = socklp->next;
973       KFREE(deadsocklp);
974     }
975     DPRINTF(IDL_FINISHED,("done\n"));
976     /*
977      * If an allocation entry exist for this
978      * secassoc, delete it.
979      */
980     bzero((char *)&buf, sizeof(buf));
981     len = key_createkey((char *)&buf, secassoc->type, secassoc->src,
982                         secassoc->dst, 0, 1);
983     indx = key_gethashval((char *)&buf, len, KEYALLOCTBLSIZE);
984     DPRINTF(IDL_FINISHED,("keydelete: alloctbl hash position=%d\n", indx));
985     prevap = &keyalloctbl[indx];
986     for (ap = prevap->next; ap; ap = ap->next) {
987       if (ap->keynode == keynode) {
988         prevap->next = ap->next;
989         KFREE(ap);
990         break; 
991       }
992       prevap = ap;
993     }    
994
995     if (keynode->secassoc->iv)
996       KFREE(keynode->secassoc->iv);
997     if (keynode->secassoc->key)
998       KFREE(keynode->secassoc->key);
999     KFREE(keynode->secassoc);
1000     if (keynode->solist)
1001       KFREE(keynode->solist);
1002     KFREE(keynode);
1003     CRITICAL_END;
1004     return(0);
1005   }
1006   return(-1);
1007 }
1008
1009
1010 /*----------------------------------------------------------------------
1011  * key_flush():
1012  *      Delete all entries from the key table.
1013  ----------------------------------------------------------------------*/
1014 void
1015 key_flush(void)
1016 {
1017   struct key_tblnode *keynode;
1018   int i;
1019
1020   /* 
1021    * This is slow, but simple.
1022    */
1023   DPRINTF(IDL_FINISHED,("Flushing key table..."));
1024   for (i = 0; i < KEYTBLSIZE; i++) {
1025     while ((keynode = keytable[i].next))
1026       if (key_delete(keynode->secassoc) != 0)
1027         panic("key_flush");
1028   }
1029   DPRINTF(IDL_FINISHED,("done\n"));
1030 }
1031
1032
1033 /*----------------------------------------------------------------------
1034  * key_getspi():
1035  *      Get a unique spi value for a key management daemon/program.  The 
1036  *      spi value, once assigned, cannot be assigned again (as long as the 
1037  *      entry with that same spi value remains in the table).
1038  ----------------------------------------------------------------------*/
1039 int
1040 key_getspi(u_int type, SOCKADDR *src, SOCKADDR *dst, u_int32_t lowval, 
1041            u_int32_t highval, u_int32_t *spi)
1042 {
1043   struct key_secassoc *secassoc;
1044   struct key_tblnode *keynode, *prevkeynode;
1045   int count, done, len, indx;
1046   int maxcount = 1000;
1047   u_int32_t val;
1048   char buf[MAXHASHKEYLEN];
1049   CRITICAL_DCL
1050   
1051   DPRINTF(IDL_EVENT,("Entering getspi w/type=%d,low=%u,high=%u\n",
1052                            type, lowval, highval));
1053   if (!(src && dst))
1054     return(EINVAL);
1055
1056   if ((lowval == 0) || (highval == 0))
1057     return(EINVAL);
1058
1059   if (lowval > highval) {
1060     u_int32_t temp;
1061     temp = lowval;
1062     lowval = highval;
1063     highval = lowval;
1064   }
1065
1066   done = count = 0;
1067   do {
1068     count++;
1069     /* 
1070      *  This may not be "random enough".
1071      */
1072     val = lowval + (random() % (highval - lowval + 1));
1073
1074     if (lowval == highval)
1075       count = maxcount;
1076     DPRINTF(IDL_FINISHED,("%u ",val));
1077     if (val) {
1078       DPRINTF(IDL_FINISHED,("\n"));
1079       bzero(&buf, sizeof(buf));
1080       len = key_createkey((char *)&buf, type, src, dst, val, 0);
1081       indx = key_gethashval((char *)&buf, len, KEYTBLSIZE);
1082       if (!key_search(type, src, dst, val, indx, &prevkeynode)) {
1083         CRITICAL_START;
1084         KMALLOC(secassoc, struct key_secassoc *, sizeof(struct key_secassoc));
1085         if (secassoc == 0) {
1086           DPRINTF(IDL_ERROR,("key_getspi: can't allocate memory\n"));
1087           CRITICAL_END;
1088           return(ENOBUFS);
1089         }
1090         bzero((char *)secassoc, sizeof(*secassoc));
1091
1092         DPRINTF(IDL_FINISHED,("getspi: indx=%d\n",indx));
1093         secassoc->len = sizeof(struct key_secassoc);
1094         secassoc->type = type;
1095         secassoc->spi = val;
1096         secassoc->state |= K_LARVAL;
1097         if (my_addr(secassoc->dst))
1098           secassoc->state |= K_INBOUND;
1099         if (my_addr(secassoc->src))
1100           secassoc->state |= K_OUTBOUND;
1101
1102         bcopy((char *)src, (char *)secassoc->src, src->sa_len);
1103         bcopy((char *)dst, (char *)secassoc->dst, dst->sa_len);
1104
1105         /* We fill this in with a plausable value now to insure
1106            that other routines don't break. These will get
1107            overwritten later with the correct values. */
1108 #ifdef INET6
1109         secassoc->from->sa_family = AF_INET6;
1110         secassoc->from->sa_len = sizeof(struct sockaddr_in6);
1111 #else /* INET6 */
1112         secassoc->from->sa_family = AF_INET;
1113         secassoc->from->sa_len = sizeof(struct sockaddr_in);
1114 #endif /* INET6 */
1115
1116         /* 
1117          * We need to add code to age these larval key table
1118          * entries so they don't linger forever waiting for
1119          * a KEY_UPDATE message that may not come for various
1120          * reasons.  This is another task that key_reaper can
1121          * do once we have it coded.
1122          */
1123         secassoc->lifetime1 += TIME_SECONDS + maxlarvallifetime;
1124
1125         if (!(keynode = key_addnode(indx, secassoc))) {
1126           DPRINTF(IDL_ERROR,("key_getspi: can't add node\n"));
1127           CRITICAL_END;
1128           return(ENOBUFS);
1129         } 
1130         DPRINTF(IDL_FINISHED,("key_getspi: added node 0x%x\n",
1131                               (unsigned int)keynode));
1132         done++;
1133         CRITICAL_END;
1134       }
1135     }
1136   } while ((count < maxcount) && !done);
1137   DPRINTF(IDL_EVENT,("getspi returns w/spi=%u,count=%d\n",val,count));
1138   if (done) {
1139     *spi = val;
1140     return(0);
1141   } else {
1142     *spi = 0;
1143     return(EADDRNOTAVAIL);
1144   }
1145 }
1146
1147
1148 /*----------------------------------------------------------------------
1149  * key_update():
1150  *      Update a keytable entry that has an spi value assigned but is 
1151  *      incomplete (e.g. no key/iv).
1152  ----------------------------------------------------------------------*/
1153 int
1154 key_update(struct key_secassoc *secassoc)
1155 {
1156   struct key_tblnode *keynode, *prevkeynode;
1157   struct key_allocnode *np = 0;
1158   u_int8_t newstate;
1159   int len, indx, inbound, outbound;
1160   char buf[MAXHASHKEYLEN];
1161   CRITICAL_DCL
1162
1163   bzero(&buf, sizeof(buf));
1164   len = key_createkey((char *)&buf, secassoc->type, secassoc->src,
1165                       secassoc->dst, secassoc->spi, 0);
1166   indx = key_gethashval((char *)&buf, len, KEYTBLSIZE);
1167   if(!(keynode = key_search(secassoc->type, secassoc->src, secassoc->dst, 
1168                             secassoc->spi, indx, &prevkeynode))) {  
1169     return(ESRCH);
1170   }
1171   if (keynode->secassoc->state & K_DEAD)
1172     return(ESRCH);
1173
1174   /* Should we also restrict updating of only LARVAL entries ? */
1175
1176   CRITICAL_START;
1177
1178   inbound = my_addr(secassoc->dst);
1179   outbound = my_addr(secassoc->src);
1180
1181   newstate = keynode->secassoc->state;
1182   newstate &= ~K_LARVAL;
1183
1184   if (inbound)
1185     newstate |= K_INBOUND;
1186   if (outbound)
1187     newstate |= K_OUTBOUND;
1188
1189   if (outbound || (!inbound && !outbound)) {
1190     KMALLOC(np, struct key_allocnode *, sizeof(struct key_allocnode));
1191     if (np == 0) {
1192       DPRINTF(IDL_ERROR,("keyupdate: can't allocate allocnode!\n"));
1193       CRITICAL_END;
1194       return(ENOBUFS);
1195     }
1196   }
1197
1198   /*
1199    *  Free the old key,  iv if they're there.
1200    */
1201   if (keynode->secassoc->key)
1202     KFREE(keynode->secassoc->key);
1203   if (keynode->secassoc->iv)
1204     KFREE(keynode->secassoc->iv);
1205
1206   /*
1207    *  We now copy the secassoc over. We don't need to copy
1208    *  the key,  iv into new buffers since the calling routine
1209    *  does that already.  
1210    */
1211
1212   *(keynode->secassoc) = *secassoc;
1213   keynode->secassoc->state = newstate;
1214
1215   /*
1216    * Should we allow a null key to be inserted into the table ? 
1217    * or can we use null key to indicate some policy action...
1218    */
1219
1220 #if 0  
1221   if (keynode->secassoc->key &&
1222        (keynode->secassoc->type == KEY_TYPE_ESP) &&
1223        ((keynode->secassoc->algorithm == IPSEC_ALGTYPE_ESP_DES_CBC) ||
1224         (keynode->secassoc->algorithm == IPSEC_ALGTYPE_ESP_3DES)))
1225       des_set_odd_parity(keynode->secassoc->key);
1226 #endif /* 0 */
1227
1228   /*
1229    *  We now add an entry to the allocation table for this 
1230    *  updated key table entry.
1231    */
1232   if (outbound || (!inbound && !outbound)) {
1233     len = key_createkey((char *)&buf, secassoc->type, secassoc->src,
1234                         secassoc->dst, 0, 1);
1235     indx = key_gethashval((char *)&buf, len, KEYALLOCTBLSIZE);
1236     DPRINTF(IDL_FINISHED,("keyupdate: keyalloc hash position=%d\n", indx));
1237     np->keynode = keynode;
1238     np->next = keyalloctbl[indx].next;
1239     keyalloctbl[indx].next = np;
1240   }
1241
1242   key_deleteacquire(secassoc->type, (SOCKADDR *)&(secassoc->dst));
1243
1244   CRITICAL_END;
1245   return(0);
1246 }
1247
1248 /*----------------------------------------------------------------------
1249  * key_register():
1250  *      Register a socket as one capable of acquiring security associations
1251  *      for the kernel.
1252  ----------------------------------------------------------------------*/
1253 int
1254 key_register(struct socket *socket, u_int type)
1255 {
1256   struct key_registry *p, *new;
1257   CRITICAL_DCL
1258
1259   CRITICAL_START;
1260
1261   DPRINTF(IDL_EVENT,("Entering key_register w/so=0x%x,type=%d\n",
1262                      (unsigned int)socket,type));
1263
1264   if (!(keyregtable && socket))
1265     panic("key_register");
1266   
1267   /*
1268    * Make sure entry is not already in table
1269    */
1270   for(p = keyregtable->next; p; p = p->next) {
1271     if ((p->type == type) && (p->socket == socket)) {
1272       CRITICAL_END;
1273       return(EEXIST);
1274     }
1275   }
1276
1277   KMALLOC(new, struct key_registry *, sizeof(struct key_registry));  
1278   if (new == 0) {
1279     CRITICAL_END;
1280     return(ENOBUFS);
1281   }
1282   new->type = type;
1283   new->socket = socket;
1284   new->next = keyregtable->next;
1285   keyregtable->next = new;
1286   CRITICAL_END;
1287   return(0);
1288 }
1289
1290 /*----------------------------------------------------------------------
1291  * key_unregister():
1292  *      Delete entries from the registry list.
1293  *         allflag = 1 : delete all entries with matching socket
1294  *         allflag = 0 : delete only the entry matching socket,  type
1295  ----------------------------------------------------------------------*/
1296 void
1297 key_unregister(struct socket *socket, u_int type, int allflag)
1298 {
1299   struct key_registry *p, *prev;
1300   CRITICAL_DCL
1301
1302   CRITICAL_START;
1303
1304   DPRINTF(IDL_EVENT,("Entering key_unregister w/so=0x%x,type=%d,flag=%d\n",
1305                      (unsigned int)socket, type, allflag));
1306
1307   if (!(keyregtable && socket))
1308     panic("key_register");
1309   prev = keyregtable;
1310   for(p = keyregtable->next; p; p = p->next) {
1311     if ((allflag && (p->socket == socket)) ||
1312         ((p->type == type) && (p->socket == socket))) {
1313       prev->next = p->next;
1314       KFREE(p);
1315       p = prev;
1316     }
1317     prev = p;
1318   }
1319   CRITICAL_END;
1320 }
1321
1322
1323 /*----------------------------------------------------------------------
1324  * key_acquire():
1325  *      Send a key_acquire message to all registered key mgnt daemons 
1326  *      capable of acquire security association of type type.
1327  *
1328  *      Return: 0 if succesfully called key mgnt. daemon(s)
1329  *              -1 if not successfull.
1330  ----------------------------------------------------------------------*/
1331 int
1332 key_acquire(u_int type, SOCKADDR *src, SOCKADDR *dst)
1333 {
1334   struct key_registry *p;
1335   struct key_acquirelist *ap, *prevap;
1336   int success = 0, created = 0;
1337   u_int etype;
1338   struct key_msghdr *km = NULL;
1339   int len;
1340
1341   DPRINTF(IDL_EVENT,("Entering key_acquire()\n"));
1342
1343   if (!keyregtable || !src || !dst)
1344     return (-1);
1345
1346   /*
1347    * We first check the acquirelist to see if a key_acquire
1348    * message has been sent for this destination.
1349    */
1350   etype = type;
1351   prevap = key_acquirelist;
1352   for(ap = key_acquirelist->next; ap; ap = ap->next) {
1353     if (addrpart_equal(dst, ap->target) &&
1354         (etype == ap->type)) {
1355       DPRINTF(IDL_EVENT,("acquire message previously sent!\n"));
1356       if (ap->expiretime < TIME_SECONDS) {
1357         DPRINTF(IDL_EVENT,("acquire message has expired!\n"));
1358         ap->count = 0;
1359         break;
1360       }
1361       if (ap->count < maxkeyacquire) {
1362         DPRINTF(IDL_EVENT,("max acquire messages not yet exceeded!\n"));
1363         break;
1364       }
1365       return(0);
1366     } else if (ap->expiretime < TIME_SECONDS) {
1367       /*
1368        *  Since we're already looking at the list, we may as
1369        *  well delete expired entries as we scan through the list.
1370        *  This should really be done by a function like key_reaper()
1371        *  but until we code key_reaper(), this is a quick,  dirty
1372        *  hack.
1373        */
1374       DPRINTF(IDL_EVENT,("found an expired entry...deleting it!\n"));
1375       prevap->next = ap->next;
1376       KFREE(ap);
1377       ap = prevap;
1378     }
1379     prevap = ap;
1380   }
1381
1382   /*
1383    * Scan registry,  send KEY_ACQUIRE message to 
1384    * appropriate key management daemons.
1385    */  
1386   for(p = keyregtable->next; p; p = p->next) {
1387     if (p->type != type) 
1388       continue;
1389
1390     if (!created) {      
1391       len = sizeof(struct key_msghdr) + ROUNDUP(src->sa_len) + 
1392         ROUNDUP(dst->sa_len);
1393       KMALLOC(km, struct key_msghdr *, len);
1394       if (!km) {
1395         DPRINTF(IDL_ERROR,("key_acquire: no memory\n"));
1396         return(-1);
1397       }
1398       DPRINTF(IDL_FINISHED,("key_acquire/created: 1\n"));
1399       bzero((char *)km, len);
1400       km->key_msglen = len;
1401       km->key_msgvers = KEY_VERSION;
1402       km->key_msgtype = KEY_ACQUIRE;
1403       km->type = type;
1404       DPRINTF(IDL_FINISHED,("key_acquire/created: 2\n"));
1405       /*
1406        * This is inefficient,  slow.
1407        */
1408
1409       /*
1410        * We zero out sin_zero here for AF_INET addresses because
1411        * ip_output() currently does not do it for performance reasons.
1412        */
1413       if (src->sa_family == AF_INET)
1414         bzero((char *)(((struct sockaddr_in *)src)->sin_zero),
1415               sizeof(((struct sockaddr_in *)src)->sin_zero));
1416       if (dst->sa_family == AF_INET)
1417         bzero((char *)(((struct sockaddr_in *)dst)->sin_zero), 
1418               sizeof(((struct sockaddr_in *)dst)->sin_zero));
1419
1420       bcopy((char *)src, (char *)(km + 1), src->sa_len);
1421       bcopy((char *)dst, (char *)((int)(km + 1) + ROUNDUP(src->sa_len)),
1422             dst->sa_len);
1423       DPRINTF(IDL_FINISHED,("key_acquire/created: 3\n"));
1424       created++; 
1425     }
1426     if (key_sendup(p->socket, km))
1427       success++;
1428   }
1429
1430   if (km)
1431     KFREE(km);
1432       
1433   /*
1434    *  Update the acquirelist 
1435    */
1436   if (success) {
1437     if (!ap) {
1438       DPRINTF(IDL_EVENT,("Adding new entry in acquirelist\n"));
1439       KMALLOC(ap, struct key_acquirelist *, sizeof(struct key_acquirelist));
1440       if (ap == 0)
1441         return(success ? 0 : -1);
1442       bzero((char *)ap, sizeof(struct key_acquirelist));
1443       bcopy((char *)dst, (char *)ap->target, dst->sa_len);
1444       ap->type = etype;
1445       ap->next = key_acquirelist->next;
1446       key_acquirelist->next = ap;
1447     }
1448     DPRINTF(IDL_GROSS_EVENT,("Updating acquire counter,  expiration time\n"));
1449     ap->count++;
1450     ap->expiretime = TIME_SECONDS + maxacquiretime;
1451   }
1452   DPRINTF(IDL_EVENT,("key_acquire: done! success=%d\n",success));
1453   return(success ? 0 : -1);
1454 }
1455
1456 /*----------------------------------------------------------------------
1457  * key_alloc():
1458  *      Allocate a security association to a socket.  A socket requesting 
1459  *      unique keying (per-socket keying) is assigned a security assocation
1460  *      exclusively for its use.  Sockets not requiring unique keying are
1461  *      assigned the first security association which may or may not be
1462  *      used by another socket.
1463  ----------------------------------------------------------------------*/
1464 static int
1465 key_alloc(u_int type, SOCKADDR *src, SOCKADDR *dst, struct socket *socket, 
1466           u_int  unique_key, struct key_tblnode **keynodep)
1467 {
1468   struct key_tblnode *keynode;
1469   char buf[MAXHASHKEYLEN];
1470   struct key_allocnode *np, *prevnp;
1471   struct key_so2spinode *newnp;
1472   int len;
1473   int indx;
1474
1475   DPRINTF(IDL_FINISHED,("Entering key_alloc w/type=%u!\n",type));
1476   if (!(src && dst)) {
1477     DPRINTF(IDL_ERROR,("key_alloc: received null src or dst!\n"));
1478     return(-1);
1479   }
1480
1481   /*
1482    * Search key allocation table
1483    */
1484   bzero((char *)&buf, sizeof(buf));
1485   len = key_createkey((char *)&buf, type, src, dst, 0, 1);
1486   indx = key_gethashval((char *)&buf, len, KEYALLOCTBLSIZE);  
1487
1488 #define np_type np->keynode->secassoc->type
1489 #define np_state np->keynode->secassoc->state
1490 #define np_src np->keynode->secassoc->src
1491 #define np_dst np->keynode->secassoc->dst
1492   
1493   prevnp = &keyalloctbl[indx];
1494   for (np = keyalloctbl[indx].next; np; np = np->next) {
1495     if ((type == np_type) && addrpart_equal(src, np_src) &&
1496         addrpart_equal(dst, np_dst) &&
1497         !(np_state & (K_LARVAL | K_DEAD | K_UNIQUE))) {
1498       if (!(unique_key))
1499         break;
1500       if (!(np_state & K_USED)) 
1501         break;
1502     }
1503     prevnp = np;
1504   }
1505
1506   if (np) {
1507     struct socketlist *newsp;
1508     CRITICAL_DCL
1509
1510     CRITICAL_START;
1511
1512     DPRINTF(IDL_EVENT,("key_alloc: found node to allocate\n"));
1513     keynode = np->keynode;
1514
1515     KMALLOC(newnp, struct key_so2spinode *, sizeof(struct key_so2spinode));
1516     if (newnp == 0) {
1517       DPRINTF(IDL_ERROR,("key_alloc: Can't alloc mem for so2spi node!\n"));
1518       CRITICAL_END;
1519       return(ENOBUFS);
1520     }
1521     KMALLOC(newsp, struct socketlist *, sizeof(struct socketlist));
1522     if (newsp == 0) {
1523       DPRINTF(IDL_ERROR,("key_alloc: Can't alloc mem for socketlist!\n"));
1524       if (newnp)
1525         KFREE(newnp);
1526       CRITICAL_END;
1527       return(ENOBUFS);
1528     }
1529
1530     /*
1531      * Add a hash entry into the so2spi table to
1532      * map socket to allocated secassoc.
1533      */
1534     DPRINTF(IDL_FINISHED,("key_alloc: adding entry to so2spi table..."));
1535     newnp->keynode = keynode;
1536     newnp->socket = socket;
1537     newnp->next = so2spitbl[((u_int32_t)socket) % SO2SPITBLSIZE].next; 
1538     so2spitbl[((u_int32_t)socket) % SO2SPITBLSIZE].next = newnp;
1539     DPRINTF(IDL_FINISHED,("done\n"));
1540
1541     if (unique_key) {
1542       /*
1543        * Need to remove the allocation entry
1544        * since the secassoc is now unique,  
1545        * can't be allocated to any other socket
1546        */
1547       DPRINTF(IDL_EVENT,("key_alloc: making keynode unique..."));
1548       keynode->secassoc->state |= K_UNIQUE;
1549       prevnp->next = np->next;
1550       KFREE(np);
1551       DPRINTF(IDL_EVENT,("done\n"));
1552     }
1553     keynode->secassoc->state |= K_USED;
1554     keynode->secassoc->state |= K_OUTBOUND;
1555     keynode->alloc_count++;
1556
1557     /*
1558      * Add socket to list of socket using secassoc.
1559      */
1560     DPRINTF(IDL_FINISHED,("key_alloc: adding so to solist..."));
1561     newsp->socket = socket;
1562     newsp->next = keynode->solist->next;
1563     keynode->solist->next = newsp;
1564     DPRINTF(IDL_FINISHED,("done\n"));
1565     *keynodep = keynode;
1566     CRITICAL_END;
1567     return(0);
1568   } 
1569   *keynodep = NULL;
1570   return(0);
1571 }
1572
1573
1574 /*----------------------------------------------------------------------
1575  * key_free():
1576  *      Decrement the refcount for a key table entry.  If the entry is 
1577  *      marked dead,,  the refcount is zero, we go ahead,  delete it.
1578  ----------------------------------------------------------------------*/
1579 void
1580 key_free(struct key_tblnode *keynode)
1581 {
1582   DPRINTF(IDL_GROSS_EVENT,("Entering key_free w/keynode=0x%x\n",
1583                            (unsigned int)keynode));
1584   if (!keynode) {
1585     DPRINTF(IDL_ERROR,("Warning: key_free got null pointer\n"));
1586     return;
1587   }
1588   (keynode->ref_count)--;
1589   if (keynode->ref_count < 0) {
1590     DPRINTF(IDL_ERROR,("Warning: key_free decremented refcount to %d\n",keynode->ref_count));
1591   }
1592   if ((keynode->secassoc->state & K_DEAD) && (keynode->ref_count <= 0)) {
1593     DPRINTF(IDL_GROSS_EVENT,("key_free: calling key_delete\n"));
1594     key_delete(keynode->secassoc);
1595   }
1596 }
1597
1598 /*----------------------------------------------------------------------
1599  * getassocbyspi():
1600  *      Get a security association for a given type, src, dst,,  spi.
1601  *
1602  *      Returns: 0 if sucessfull
1603  *               -1 if error/not found
1604  *
1605  *      Caller must convert spi to host order.  Function assumes spi is  
1606  *      in host order!
1607  ----------------------------------------------------------------------*/
1608 int
1609 getassocbyspi(u_int type, SOCKADDR *src, SOCKADDR *dst, u_int32_t spi, 
1610               struct key_tblnode **keyentry)
1611 {
1612   char buf[MAXHASHKEYLEN];
1613   int len, indx;
1614   struct key_tblnode *keynode, *prevkeynode = 0;
1615
1616   DPRINTF(IDL_FINISHED,("Entering getassocbyspi w/type=%u spi=%u\n",type,spi));
1617
1618   *keyentry = NULL;
1619   bzero(&buf, sizeof(buf));
1620   len = key_createkey((char *)&buf, type, src, dst, spi, 0);
1621   indx = key_gethashval((char *)&buf, len, KEYTBLSIZE);
1622   DPRINTF(IDL_FINISHED,("getassocbyspi: indx=%d\n",indx));
1623   DDO(IDL_FINISHED,dump_sockaddr(src);dump_sockaddr(dst));
1624   keynode = key_search(type, src, dst, spi, indx, &prevkeynode);
1625   DPRINTF(IDL_FINISHED,("getassocbyspi: keysearch ret=0x%x\n",
1626                         (unsigned int)keynode));
1627   if (keynode && !(keynode->secassoc->state & (K_DEAD | K_LARVAL))) {
1628     DPRINTF(IDL_GROSS_EVENT,("getassocbyspi: found secassoc!\n"));
1629     (keynode->ref_count)++;
1630     keynode->secassoc->state |= K_USED;
1631     *keyentry = keynode;
1632   } else {
1633     DPRINTF(IDL_EVENT,("getassocbyspi: secassoc not found!\n"));
1634     return (-1);
1635   }
1636   return(0);
1637 }
1638
1639
1640 /*----------------------------------------------------------------------
1641  * getassocbysocket():
1642  *      Get a security association for a given type, src, dst,,  socket.
1643  *      If not found, try to allocate one.
1644  *      Returns: 0 if successfull
1645  *              -1 if error condition/secassoc not found (*keyentry = NULL)
1646  *               1 if secassoc temporarily unavailable (*keynetry = NULL)
1647  *                 (e.g., key mgnt. daemon(s) called)
1648  ----------------------------------------------------------------------*/
1649 int
1650 getassocbysocket(u_int type, SOCKADDR *src, SOCKADDR *dst, 
1651                  struct socket *socket, u_int unique_key, 
1652                  struct key_tblnode **keyentry)
1653 {
1654   struct key_tblnode *keynode = 0;
1655   struct key_so2spinode *np;
1656   u_int realtype;
1657  
1658   DPRINTF(IDL_FINISHED,("Entering getassocbysocket w/type=%u so=0x%x\n",
1659                         type,(unsigned int)socket));
1660
1661   /*
1662    *  We treat esp-transport mode,  esp-tunnel mode 
1663    *  as a single type in the keytable.  This has a side
1664    *  effect that socket using both esp-transport, 
1665    *  esp-tunnel will use the same security association
1666    *  for both modes.  Is this a problem?
1667    */
1668   realtype = type;
1669   if ((np = key_sosearch(type, src, dst, socket))) {
1670     if (np->keynode && np->keynode->secassoc && 
1671         !(np->keynode->secassoc->state & (K_DEAD | K_LARVAL))) {
1672       DPRINTF(IDL_FINISHED,("getassocbysocket: found secassoc!\n"));
1673       (np->keynode->ref_count)++;
1674       *keyentry = np->keynode;
1675       return(0);
1676     }
1677   }
1678
1679   /*
1680    * No secassoc has been allocated to socket, 
1681    * so allocate one, if available
1682    */
1683   DPRINTF(IDL_GROSS_EVENT,("getassocbyso: can't find it, trying to allocate!\n"));
1684   if (key_alloc(realtype, src, dst, socket, unique_key, &keynode) == 0) {
1685     if (keynode) {
1686       DPRINTF(IDL_GROSS_EVENT,("getassocbyso: key_alloc found secassoc!\n"));
1687       keynode->ref_count++;
1688       *keyentry = keynode;
1689       return(0);
1690     } else {
1691       /* 
1692        * Kick key mgnt. daemon(s) 
1693        * (this should be done in ipsec_output_policy() instead or
1694        * selectively called based on a flag value)
1695        */
1696       DPRINTF(IDL_FINISHED,("getassocbyso: calling key mgnt daemons!\n"));
1697       *keyentry = NULL;
1698       if (key_acquire(realtype, src, dst) == 0)
1699         return (1);
1700       else
1701         return(-1);
1702     }
1703   }
1704   *keyentry = NULL;
1705   return(-1);
1706 }
1707
1708 /*----------------------------------------------------------------------
1709  * key_xdata():
1710  *      Parse message buffer for src/dst/from/iv/key if parseflag = 0
1711  *      else parse for src/dst only.
1712  ----------------------------------------------------------------------*/
1713 static int
1714 key_xdata(struct key_msghdr *km, struct key_msgdata *kip, int parseflag)
1715 {
1716   char *cp, *cpmax;
1717
1718   if (!km || (km->key_msglen <= 0))
1719     return (-1);
1720
1721   cp = (caddr_t)(km + 1);
1722   cpmax = (caddr_t)km + km->key_msglen;
1723
1724   /*
1725    * Assumes user process passes message with 
1726    * correct word alignment.
1727    */
1728
1729   /* 
1730    * Need to clean up this code later.  
1731    */
1732
1733   /* Grab src addr */
1734   kip->src = (SOCKADDR *)cp;
1735   if (!kip->src->sa_len) {
1736     DPRINTF(IDL_MAJOR_EVENT,("key_xdata couldn't parse src addr\n"));
1737     return(-1);
1738   }
1739
1740   ADVANCE(cp, kip->src->sa_len);
1741
1742   /* Grab dest addr */
1743   kip->dst = (SOCKADDR *)cp;
1744   if (!kip->dst->sa_len) {
1745     DPRINTF(IDL_MAJOR_EVENT,("key_xdata couldn't parse dest addr\n"));
1746     return(-1);
1747   }
1748
1749   ADVANCE(cp, kip->dst->sa_len);
1750   if (parseflag == 1) {
1751     kip->from = 0;
1752     kip->key = kip->iv = 0;
1753     kip->keylen = kip->ivlen = 0;
1754     return(0);
1755   }
1756  
1757   /* Grab from addr */
1758   kip->from = (SOCKADDR *)cp;
1759   if (!kip->from->sa_len) {
1760     DPRINTF(IDL_MAJOR_EVENT,("key_xdata couldn't parse from addr\n"));
1761     return(-1);
1762   }
1763
1764   ADVANCE(cp, kip->from->sa_len);
1765  
1766   /* Grab key */
1767   if ((kip->keylen = km->keylen)) {
1768     kip->key = cp;
1769     ADVANCE(cp, km->keylen);
1770   } else 
1771     kip->key = 0;
1772
1773   /* Grab iv */
1774   if ((kip->ivlen = km->ivlen))
1775     kip->iv = cp;
1776   else
1777     kip->iv = 0;
1778
1779   return (0);
1780 }
1781
1782
1783 int
1784 key_parse(struct key_msghdr **kmp, struct socket *so, int *dstfamily)
1785 {
1786   int error = 0, keyerror = 0;
1787   struct key_msgdata keyinfo;
1788   struct key_secassoc *secassoc = NULL;
1789   struct key_msghdr *km = *kmp;
1790
1791   DPRINTF(IDL_MAJOR_EVENT, ("Entering key_parse\n"));
1792
1793 #define senderr(e) \
1794   { error = (e); goto flush; }
1795
1796   if (km->key_msgvers != KEY_VERSION) {
1797     DPRINTF(IDL_CRITICAL,("keyoutput: Unsupported key message version!\n"));
1798     senderr(EPROTONOSUPPORT);
1799   }
1800
1801   km->key_pid = CURRENT_PID;
1802
1803   DDO(IDL_MAJOR_EVENT, printf("keymsghdr:\n"); dump_keymsghdr(km));
1804
1805   /*
1806    * Parse buffer for src addr, dest addr, from addr, key, iv
1807    */
1808   bzero((char *)&keyinfo, sizeof(keyinfo));
1809
1810   switch (km->key_msgtype) {
1811   case KEY_ADD:
1812     DPRINTF(IDL_MAJOR_EVENT,("key_output got KEY_ADD msg\n"));
1813
1814     if (key_xdata(km, &keyinfo, 0) < 0)
1815       goto parsefail;
1816
1817     /*
1818      * Allocate the secassoc structure to insert 
1819      * into key table here.
1820      */
1821     KMALLOC(secassoc, struct key_secassoc *, sizeof(struct key_secassoc)); 
1822     if (secassoc == 0) {
1823       DPRINTF(IDL_CRITICAL,("keyoutput: No more memory!\n"));
1824       senderr(ENOBUFS);
1825     }
1826
1827     if (key_msghdr2secassoc(secassoc, km, &keyinfo) < 0) {
1828       DPRINTF(IDL_CRITICAL,("keyoutput: key_msghdr2secassoc failed!\n"));
1829       KFREE(secassoc);
1830       senderr(EINVAL);
1831     }
1832     DPRINTF(IDL_MAJOR_EVENT,("secassoc to add:\n"));
1833     DDO(IDL_MAJOR_EVENT,dump_secassoc(secassoc));
1834
1835     if ((keyerror = key_add(secassoc)) != 0) {
1836       DPRINTF(IDL_CRITICAL,("keyoutput: key_add failed\n"));
1837       if (secassoc->key)
1838         KFREE(secassoc->key);
1839       if (secassoc->iv)
1840         KFREE(secassoc->iv);
1841       KFREE(secassoc);
1842       if (keyerror == -2) {
1843         senderr(EEXIST);
1844       } else {
1845         senderr(ENOBUFS);
1846       }
1847     }
1848     break;
1849   case KEY_DELETE:
1850     DPRINTF(IDL_MAJOR_EVENT,("key_output got KEY_DELETE msg\n"));
1851
1852     if (key_xdata(km, &keyinfo, 1) < 0)
1853       goto parsefail;
1854
1855     KMALLOC(secassoc, struct key_secassoc *, sizeof(struct key_secassoc)); 
1856     if (secassoc == 0) {
1857       senderr(ENOBUFS);
1858     }
1859     if (key_msghdr2secassoc(secassoc, km, &keyinfo) < 0) {
1860       KFREE(secassoc);
1861       senderr(EINVAL);
1862     }
1863     if (key_delete(secassoc) != 0) {
1864       if (secassoc->iv)
1865         KFREE(secassoc->iv);
1866       if (secassoc->key)
1867         KFREE(secassoc->key);
1868       KFREE(secassoc);
1869       senderr(ESRCH);
1870     }
1871     if (secassoc->iv)
1872       KFREE(secassoc->iv);
1873     if (secassoc->key)
1874       KFREE(secassoc->key);
1875     KFREE(secassoc);
1876     break;
1877   case KEY_UPDATE:
1878     DPRINTF(IDL_EVENT,("key_output got KEY_UPDATE msg\n"));
1879
1880     if (key_xdata(km, &keyinfo, 0) < 0)
1881       goto parsefail;
1882
1883     KMALLOC(secassoc, struct key_secassoc *, sizeof(struct key_secassoc)); 
1884     if (secassoc == 0) {
1885       senderr(ENOBUFS);
1886     }
1887     if (key_msghdr2secassoc(secassoc, km, &keyinfo) < 0) {
1888       KFREE(secassoc);
1889       senderr(EINVAL);
1890     }
1891     if ((keyerror = key_update(secassoc)) != 0) {
1892       DPRINTF(IDL_CRITICAL,("Error updating key entry\n"));
1893       if (secassoc->iv)
1894         KFREE(secassoc->iv);
1895       if (secassoc->key)
1896         KFREE(secassoc->key);
1897       KFREE(secassoc);
1898       senderr(keyerror);
1899     }
1900     KFREE(secassoc);
1901     break;
1902   case KEY_GET:
1903     DPRINTF(IDL_EVENT,("key_output got KEY_GET msg\n"));
1904
1905     if (key_xdata(km, &keyinfo, 1) < 0)
1906       goto parsefail;
1907
1908     if (key_get(km->type, (SOCKADDR *)keyinfo.src, 
1909                 (SOCKADDR *)keyinfo.dst, 
1910                 km->spi, &secassoc) != 0) {
1911       DPRINTF(IDL_EVENT,("keyoutput: can't get key\n"));
1912       senderr(ESRCH);
1913     }
1914
1915     if (secassoc) {
1916       int newlen;
1917
1918       DPRINTF(IDL_EVENT,("keyoutput: Found secassoc!\n"));
1919       newlen = sizeof(struct key_msghdr) + ROUNDUP(secassoc->src->sa_len) +
1920         ROUNDUP(secassoc->dst->sa_len) + ROUNDUP(secassoc->from->sa_len) +
1921           ROUNDUP(secassoc->keylen) + ROUNDUP(secassoc->ivlen);
1922       DPRINTF(IDL_EVENT,("keyoutput: newlen=%d\n", newlen));
1923       if (newlen > km->key_msglen) {
1924         struct key_msghdr *newkm;
1925
1926         DPRINTF(IDL_EVENT,("keyoutput: Allocating new buffer!\n"));
1927         KMALLOC(newkm, struct key_msghdr *, newlen); 
1928         if (newkm == 0) {
1929           senderr(ENOBUFS);
1930         }
1931         bcopy((char *)km, (char *)newkm, km->key_msglen);
1932         DPRINTF(IDL_FINISHED,("keyoutput: 1\n"));
1933         KFREE(km);
1934         *kmp = km = newkm;
1935         DPRINTF(IDL_CRITICAL, ("km->key_msglen = %d, newlen = %d\n",
1936                                km->key_msglen, newlen));
1937         km->key_msglen = newlen;
1938       }
1939       DPRINTF(IDL_FINISHED,("keyoutput: 2\n"));
1940       if (key_secassoc2msghdr(secassoc, km, &keyinfo)) {
1941         DPRINTF(IDL_CRITICAL,("keyoutput: Can't create msghdr!\n"));
1942         senderr(EINVAL);
1943       }
1944       DPRINTF(IDL_FINISHED,("keyoutput: 3\n"));
1945     }
1946     break;
1947   case KEY_GETSPI:
1948     DPRINTF(IDL_EVENT,("key_output got KEY_GETSPI msg\n"));
1949
1950     if (key_xdata(km, &keyinfo, 1) < 0)
1951       goto parsefail;
1952
1953     if ((keyerror = key_getspi(km->type, keyinfo.src, keyinfo.dst, 
1954                                km->lifetime1, km->lifetime2, 
1955                                &(km->spi))) != 0) {
1956       DPRINTF(IDL_CRITICAL,("keyoutput: getspi failed error=%d\n", keyerror));
1957       senderr(keyerror);
1958     }
1959     break;
1960   case KEY_REGISTER:
1961     DPRINTF(IDL_EVENT,("key_output got KEY_REGISTER msg\n"));
1962     key_register(so, km->type);
1963     break;
1964   case KEY_DUMP:
1965     DPRINTF(IDL_EVENT,("key_output got KEY_DUMP msg\n"));
1966     error = key_dump(so);
1967     return(error);
1968     break;
1969   case KEY_FLUSH:
1970     DPRINTF(IDL_EVENT,("key_output got KEY_FLUSH msg\n"));
1971     key_flush();
1972     break;
1973   default:
1974     DPRINTF(IDL_CRITICAL,("key_output got unsupported msg type=%d\n", 
1975                              km->key_msgtype));
1976     senderr(EOPNOTSUPP);
1977   }
1978
1979   goto flush;
1980
1981 parsefail:
1982   keyinfo.dst = NULL;
1983   error = EINVAL;
1984
1985 flush:
1986   if (km)
1987     km->key_errno = error;
1988
1989   if (dstfamily)
1990     *dstfamily = keyinfo.dst ? keyinfo.dst->sa_family : 0;
1991
1992   DPRINTF(IDL_MAJOR_EVENT, ("key_parse exiting with error=%d\n", error));
1993   return error;
1994 }
1995
1996 /*
1997  * Definitions of protocols supported in the KEY domain.
1998  */
1999
2000 struct  sockaddr key_addr = { 2, PF_KEY, };
2001 struct  sockproto key_proto = { PF_KEY, };
2002
2003 #define KEYREAPERINT 120
2004
2005 #define ROUNDUP(a) \
2006   ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
2007
2008 static int
2009 key_sendup(s, km)
2010         struct socket *s;
2011         struct key_msghdr *km;
2012 {
2013   struct mbuf *m;
2014   MGETHDR(m, M_WAIT, MT_DATA);
2015   m->m_len = m->m_pkthdr.len = 0;
2016   m->m_next = 0;
2017   m->m_nextpkt = 0;
2018   m->m_pkthdr.rcvif = 0;
2019   m_copyback(m, 0, km->key_msglen, (caddr_t)km);
2020   
2021   if (sbappendaddr(&(s->so_rcv), &key_addr, m, NULL)) {
2022     sorwakeup(s);
2023     return 1;
2024   } else 
2025     m_freem(m);
2026
2027   return(0);
2028 }
2029
2030 #ifdef notyet
2031 /*----------------------------------------------------------------------
2032  * key_reaper():
2033  *      Scan key table,  nuke unwanted entries
2034  ----------------------------------------------------------------------*/
2035 static void
2036 key_reaper(whocares)
2037      void *whocares;
2038 {
2039   DPRINTF(IDL_GROSS_EVENT,("Entering key_reaper()\n"));
2040
2041   timeout(key_reaper, NULL, KEYREAPERINT * HZ);
2042 }
2043 #endif /* notyet */
2044
2045 /*----------------------------------------------------------------------
2046  * key_init():
2047  *      Init routine for key socket,  key engine
2048  ----------------------------------------------------------------------*/
2049 static void
2050 key_init(void)
2051 {
2052   DPRINTF(IDL_EVENT,("Called key_init().\n"));
2053   if (key_inittables())
2054     panic("key_inittables failed!\n");
2055 #ifdef notyet
2056   timeout(key_reaper, NULL, HZ);
2057 #endif /* notyet */
2058   bzero((char *)&keyso_cb, sizeof(keyso_cb));
2059 }
2060
2061 /*----------------------------------------------------------------------
2062  * my_addr():
2063  *      Determine if an address belongs to one of my configured interfaces.
2064  *      Currently handles only AF_INET,  AF_INET6 addresses.
2065  ----------------------------------------------------------------------*/
2066 static int
2067 my_addr(sa)
2068      SOCKADDR *sa;
2069 {
2070   struct in6_ifaddr *i6a = 0;
2071   struct in_ifaddr *ia = 0;
2072
2073   switch(sa->sa_family) {
2074 #ifdef INET6
2075   case AF_INET6:
2076     for (i6a = in6_ifaddr; i6a; i6a = i6a->i6a_next) {
2077       if (IN6_ADDR_EQUAL(((struct sockaddr_in6 *)sa)->sin6_addr, 
2078                          i6a->i6a_addr.sin6_addr))
2079         return(1);
2080     }
2081     break;
2082 #endif /* INET6 */
2083   case AF_INET:
2084     for (ia = in_ifaddr; ia; ia = ia->ia_next) {
2085       if (((struct sockaddr_in *)sa)->sin_addr.s_addr == 
2086            ia->ia_addr.sin_addr.s_addr) 
2087         return(1);
2088     }
2089     break;
2090   }
2091   return(0);
2092 }
2093
2094 /*----------------------------------------------------------------------
2095  * key_output():
2096  *      Process outbound pf_key message.
2097  ----------------------------------------------------------------------*/
2098 static int
2099 key_output(struct mbuf *m, struct socket *so)
2100 {
2101   struct key_msghdr *km = 0;
2102   caddr_t cp, cplimit;
2103   int len;
2104   int error = 0;
2105   int dstfamily = 0;
2106
2107   DPRINTF(IDL_EVENT,("key_output() got a message len=%d.\n", m->m_pkthdr.len));
2108
2109 #undef senderr
2110 #define senderr(e) \
2111   { error = (e); if (km) km->key_errno = error; goto flush; }
2112
2113   if (m == 0 || ((m->m_len < sizeof(long)) && 
2114                  (m = m_pullup(m, sizeof(long))) == 0)) {
2115     DPRINTF(IDL_CRITICAL,("key_output can't pullup mbuf\n"));
2116     return (ENOBUFS);
2117   }
2118   if ((m->m_flags & M_PKTHDR) == 0)
2119     panic("key_output");
2120
2121   DDO(IDL_FINISHED,dump_mbuf(m));  
2122   
2123   len = m->m_pkthdr.len;
2124   if (len < sizeof(*km) || len != mtod(m, struct key_msghdr *)->key_msglen) {
2125     DPRINTF(IDL_CRITICAL,("keyout: Invalid length field/length mismatch!\n"));
2126     senderr(EINVAL); 
2127   }
2128   KMALLOC(km, struct key_msghdr *, len); 
2129   if (km == 0) {
2130     DPRINTF(IDL_CRITICAL,("keyoutput: Can't malloc memory!\n"));
2131     senderr(ENOBUFS);
2132   }
2133
2134   m_copydata(m, 0, len, (caddr_t)km);
2135
2136   km->key_errno = error = key_parse(&km, so, &dstfamily);
2137   DPRINTF(IDL_MAJOR_EVENT, ("Back from key_parse\n"));
2138 flush:
2139   key_sendup(so, km);
2140 #if 0
2141   {
2142     struct rawcb *rp = 0;
2143     struct mbuf *m;
2144
2145     if ((so->so_options & SO_USELOOPBACK) == 0) {
2146       if (keyso_cb.any_count <= 1) {
2147         if (km)
2148           KFREE(km);
2149         return (error);
2150       }
2151       rp = sotorawcb(so);
2152     }
2153
2154   DPRINTF(IDL_MAJOR_EVENT, ("key_output: foo\n"));
2155     key_proto.sp_protocol = dstfamily;
2156
2157     if (km) {
2158       m = m_devget(km, len, 0, NULL, NULL);
2159       KFREE(km);
2160     }
2161
2162   DPRINTF(IDL_MAJOR_EVENT, ("key_output: bar\n"));
2163     if (rp)
2164       rp->rcb_proto.sp_family = 0;   /* Prevent us from receiving message */
2165
2166     raw_input(m, &key_proto, &key_addr, &key_addr);
2167
2168     if (rp)
2169       rp->rcb_proto.sp_family = PF_KEY;
2170   }
2171   DPRINTF(IDL_MAJOR_EVENT, ("key_output: baz\n"));
2172 #endif /* 0 */
2173   return (error);
2174 }
2175
2176
2177 /*----------------------------------------------------------------------
2178  * key_usrreq():
2179  *      Handles PRU_* for pf_key sockets.
2180  ----------------------------------------------------------------------*/
2181 static int
2182 key_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
2183            struct mbuf *control)
2184 {
2185   register int error = 0;
2186   register struct rawcb *rp = sotorawcb(so);
2187   int s;
2188
2189   DPRINTF(IDL_EVENT,("Entering key_usrreq, req = %d.\n",req));
2190
2191   if (req == PRU_ATTACH) {
2192     MALLOC(rp, struct rawcb *, sizeof(*rp), M_PCB, M_WAITOK);
2193     if (so->so_pcb = (caddr_t)rp)
2194       bzero(so->so_pcb, sizeof(*rp));
2195   }
2196
2197   if (req == PRU_DETACH && rp) {
2198     int af = rp->rcb_proto.sp_protocol;
2199     if (af == AF_INET)
2200       keyso_cb.ip4_count--;
2201 #ifdef INET6
2202     else if (af == AF_INET6)
2203       keyso_cb.ip6_count--;
2204 #endif /* INET6 */
2205     keyso_cb.any_count--;
2206   }
2207   s = splnet();
2208   error = raw_usrreq(so, req, m, nam, control);
2209   rp = sotorawcb(so);
2210
2211   if (req == PRU_ATTACH && rp) {
2212     int af = rp->rcb_proto.sp_protocol;
2213     if (error) {
2214       free((caddr_t)rp, M_PCB);
2215       splx(s);
2216       return error;
2217     }
2218     if (af == AF_INET)
2219       keyso_cb.ip4_count++;
2220 #ifdef INET6
2221     else if (af == AF_INET6)
2222       keyso_cb.ip6_count++;
2223 #endif /* INET6 */
2224     keyso_cb.any_count++;
2225     rp->rcb_faddr = &key_addr;
2226     soisconnected(so);   /* Key socket, like routing socket, must be
2227                             connected. */
2228
2229     /* Possibly set other needed flags/options at creation time in here. */
2230     so->so_options |= SO_USELOOPBACK; /* Like routing socket, we turn this */
2231                                       /* on by default                     */
2232   }
2233   splx(s);
2234   return error;
2235 }
2236
2237 /*----------------------------------------------------------------------
2238  * key_cbinit():
2239  *      Control block init routine for key socket
2240  ----------------------------------------------------------------------*/
2241 static void
2242 key_cbinit(void)
2243 {
2244  /*
2245   *  This is equivalent to raw_init for the routing socket. 
2246   *  The key socket uses the same control block as the routing 
2247   *  socket.
2248   */
2249   DPRINTF(IDL_EVENT,("Called key_cbinit().\n"));
2250 }
2251
2252 /*
2253  * Protoswitch entry for pf_key 
2254  */
2255
2256 extern  struct domain keydomain;                /* or at least forward */
2257
2258 struct protosw keysw[] = {
2259 { SOCK_RAW,     &keydomain,     0,              PR_ATOMIC|PR_ADDR,
2260   raw_input,    key_output,     raw_ctlinput,   0,
2261   key_usrreq,
2262   key_cbinit
2263 }
2264 };
2265
2266 struct domain keydomain =
2267     { PF_KEY, "key", key_init, 0, 0,
2268       keysw, &keysw[sizeof(keysw)/sizeof(keysw[0])] };
2269
2270 DOMAIN_SET(key)