8f49cc5c197c0a69d3f04de628f268208917f76f
[bcm963xx.git] / userapps / opensource / ipsec-tools / src / racoon / handler.c
1 /* $Id: handler.c,v 1.13 2004/11/21 19:36:26 manubsd Exp $ */
2
3 /*
4  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5  * All rights reserved.
6  * 
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the project nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  * 
19  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31
32 #include "config.h"
33
34 #include <sys/types.h>
35 #include <sys/param.h>
36 #include <sys/socket.h>
37
38 #include <stdlib.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include <time.h>
42 #include <errno.h>
43
44 #include "var.h"
45 #include "misc.h"
46 #include "vmbuf.h"
47 #include "plog.h"
48 #include "sockmisc.h"
49 #include "debug.h"
50
51 #include "schedule.h"
52 #include "grabmyaddr.h"
53 #include "algorithm.h"
54 #include "crypto_openssl.h"
55 #include "policy.h"
56 #include "proposal.h"
57 #include "isakmp_var.h"
58 #include "evt.h"
59 #include "isakmp.h"
60 #ifdef ENABLE_HYBRID
61 #include "isakmp_xauth.h"  
62 #include "isakmp_cfg.h"
63 #endif
64 #include "isakmp_inf.h"
65 #include "oakley.h"
66 #include "remoteconf.h"
67 #include "localconf.h"
68 #include "handler.h"
69 #include "gcmalloc.h"
70 #include "nattraversal.h"
71
72 #ifdef HAVE_GSSAPI
73 #include "gssapi.h"
74 #endif
75
76 static LIST_HEAD(_ph1tree_, ph1handle) ph1tree;
77 static LIST_HEAD(_ph2tree_, ph2handle) ph2tree;
78 static LIST_HEAD(_ctdtree_, contacted) ctdtree;
79 static LIST_HEAD(_rcptree_, recvdpkt) rcptree;
80
81 static void del_recvdpkt __P((struct recvdpkt *));
82 static void rem_recvdpkt __P((struct recvdpkt *));
83 static void sweep_recvdpkt __P((void *));
84
85 /*
86  * functions about management of the isakmp status table
87  */
88 /* %%% management phase 1 handler */
89 /*
90  * search for isakmpsa handler with isakmp index.
91  */
92
93 extern caddr_t val2str(const char *, size_t);
94
95 struct ph1handle *
96 getph1byindex(index)
97         isakmp_index *index;
98 {
99         struct ph1handle *p;
100
101         LIST_FOREACH(p, &ph1tree, chain) {
102                 if (p->status == PHASE1ST_EXPIRED)
103                         continue;
104                 if (memcmp(&p->index, index, sizeof(*index)) == 0)
105                         return p;
106         }
107
108         return NULL;
109 }
110
111 /*
112  * search for isakmp handler by i_ck in index.
113  */
114 struct ph1handle *
115 getph1byindex0(index)
116         isakmp_index *index;
117 {
118         struct ph1handle *p;
119
120         LIST_FOREACH(p, &ph1tree, chain) {
121                 if (p->status == PHASE1ST_EXPIRED)
122                         continue;
123                 if (memcmp(&p->index, index, sizeof(cookie_t)) == 0)
124                         return p;
125         }
126
127         return NULL;
128 }
129
130 /*
131  * search for isakmpsa handler by source and remote address.
132  * don't use port number to search because this function search
133  * with phase 2's destinaion.
134  */
135 struct ph1handle *
136 getph1byaddr(local, remote)
137         struct sockaddr *local, *remote;
138 {
139         struct ph1handle *p;
140
141         LIST_FOREACH(p, &ph1tree, chain) {
142                 if (p->status == PHASE1ST_EXPIRED)
143                         continue;
144                 if (cmpsaddrwop(local, p->local) == 0
145                  && cmpsaddrwop(remote, p->remote) == 0)
146                         return p;
147         }
148
149         return NULL;
150 }
151
152 /*
153  * search for isakmpsa handler by remote address.
154  * don't use port number to search because this function search
155  * with phase 2's destinaion.
156  */
157 struct ph1handle *
158 getph1bydstaddr(remote)
159         struct sockaddr *remote;
160 {
161         struct ph1handle *p;
162
163         LIST_FOREACH(p, &ph1tree, chain) {
164                 if (p->status == PHASE1ST_EXPIRED)
165                         continue;
166                 if (cmpsaddrwop(remote, p->remote) == 0)
167                         return p;
168         }
169
170         return NULL;
171 }
172
173 /*
174  * dump isakmp-sa
175  */
176 vchar_t *
177 dumpph1()
178 {
179         struct ph1handle *iph1;
180         struct ph1dump *pd;
181         int cnt = 0;
182         vchar_t *buf;
183
184         /* get length of buffer */
185         LIST_FOREACH(iph1, &ph1tree, chain)
186                 cnt++;
187
188         buf = vmalloc(cnt * sizeof(struct ph1dump));
189         if (buf == NULL) {
190                 plog(LLV_ERROR, LOCATION, NULL,
191                         "failed to get buffer\n");
192                 return NULL;
193         }
194         pd = (struct ph1dump *)buf->v;
195
196         LIST_FOREACH(iph1, &ph1tree, chain) {
197                 memcpy(&pd->index, &iph1->index, sizeof(iph1->index));
198                 pd->status = iph1->status;
199                 pd->side = iph1->side;
200                 memcpy(&pd->remote, iph1->remote, sysdep_sa_len(iph1->remote));
201                 memcpy(&pd->local, iph1->local, sysdep_sa_len(iph1->local));
202                 pd->version = iph1->version;
203                 pd->etype = iph1->etype;
204                 pd->created = iph1->created;
205                 pd->ph2cnt = iph1->ph2cnt;
206                 pd++;
207         }
208
209         return buf;
210 }
211
212 /*
213  * create new isakmp Phase 1 status record to handle isakmp in Phase1
214  */
215 struct ph1handle *
216 newph1()
217 {
218         struct ph1handle *iph1;
219
220         /* create new iph1 */
221         iph1 = racoon_calloc(1, sizeof(*iph1));
222         if (iph1 == NULL)
223                 return NULL;
224
225         iph1->status = PHASE1ST_SPAWN;
226
227 #ifdef ENABLE_DPD
228         iph1->dpd_support = 0;
229         iph1->dpd_lastack = 0;
230         iph1->dpd_seq = 0;
231         iph1->dpd_fails = 0;
232         iph1->dpd_r_u = NULL;
233 #endif
234
235         return iph1;
236 }
237
238 /*
239  * delete new isakmp Phase 1 status record to handle isakmp in Phase1
240  */
241 void
242 delph1(iph1)
243         struct ph1handle *iph1;
244 {
245         /* SA down shell script hook */
246         if (iph1 != NULL)
247                 script_hook(iph1, SCRIPT_PHASE1_DOWN);
248
249         EVT_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_DOWN, NULL);
250
251 #ifdef ENABLE_NATT
252         if (iph1->natt_flags & NAT_KA_QUEUED)
253                 natt_keepalive_remove (iph1->local, iph1->remote);
254
255         if (iph1->natt_options) {
256                 racoon_free(iph1->natt_options);
257                 iph1->natt_options = NULL;
258         }
259 #endif
260
261         if (iph1->remote) {
262                 racoon_free(iph1->remote);
263                 iph1->remote = NULL;
264         }
265         if (iph1->local) {
266                 racoon_free(iph1->local);
267                 iph1->local = NULL;
268         }
269
270 #ifdef ENABLE_HYBRID
271         if (iph1->mode_cfg)
272                 isakmp_cfg_rmstate(iph1);
273 #endif
274
275         VPTRINIT(iph1->authstr);
276
277         sched_scrub_param(iph1);
278         iph1->sce = NULL;
279         iph1->scr = NULL;
280
281         VPTRINIT(iph1->sendbuf);
282
283         VPTRINIT(iph1->dhpriv);
284         VPTRINIT(iph1->dhpub);
285         VPTRINIT(iph1->dhpub_p);
286         VPTRINIT(iph1->dhgxy);
287         VPTRINIT(iph1->nonce);
288         VPTRINIT(iph1->nonce_p);
289         VPTRINIT(iph1->skeyid);
290         VPTRINIT(iph1->skeyid_d);
291         VPTRINIT(iph1->skeyid_a);
292         VPTRINIT(iph1->skeyid_e);
293         VPTRINIT(iph1->key);
294         VPTRINIT(iph1->hash);
295         VPTRINIT(iph1->sig);
296         VPTRINIT(iph1->sig_p);
297         oakley_delcert(iph1->cert);
298         iph1->cert = NULL;
299         oakley_delcert(iph1->cert_p);
300         iph1->cert_p = NULL;
301         oakley_delcert(iph1->crl_p);
302         iph1->crl_p = NULL;
303         oakley_delcert(iph1->cr_p);
304         iph1->cr_p = NULL;
305         VPTRINIT(iph1->id);
306         VPTRINIT(iph1->id_p);
307
308         if (iph1->ivm) {
309                 oakley_delivm(iph1->ivm);
310                 iph1->ivm = NULL;
311         }
312
313         VPTRINIT(iph1->sa);
314         VPTRINIT(iph1->sa_ret);
315
316 #ifdef HAVE_GSSAPI
317         VPTRINIT(iph1->gi_i);
318         VPTRINIT(iph1->gi_r);
319
320         gssapi_free_state(iph1);
321 #endif
322
323         racoon_free(iph1);
324 }
325
326 /*
327  * create new isakmp Phase 1 status record to handle isakmp in Phase1
328  */
329 int
330 insph1(iph1)
331         struct ph1handle *iph1;
332 {
333         /* validity check */
334         if (iph1->remote == NULL) {
335                 plog(LLV_ERROR, LOCATION, NULL,
336                         "invalid isakmp SA handler. no remote address.\n");
337                 return -1;
338         }
339         LIST_INSERT_HEAD(&ph1tree, iph1, chain);
340
341         return 0;
342 }
343
344 void
345 remph1(iph1)
346         struct ph1handle *iph1;
347 {
348         LIST_REMOVE(iph1, chain);
349 }
350
351 /*
352  * flush isakmp-sa
353  */
354 void
355 flushph1()
356 {
357         struct ph1handle *p, *next;
358
359         for (p = LIST_FIRST(&ph1tree); p; p = next) {
360                 next = LIST_NEXT(p, chain);
361
362                 /* send delete information */
363                 if (p->status == PHASE1ST_ESTABLISHED) 
364                         isakmp_info_send_d1(p);
365
366                 remph1(p);
367                 delph1(p);
368         }
369 }
370
371 void
372 initph1tree()
373 {
374         LIST_INIT(&ph1tree);
375 }
376
377 /* %%% management phase 2 handler */
378 /*
379  * search ph2handle with policy id.
380  */
381 struct ph2handle *
382 getph2byspid(spid)
383       u_int32_t spid;
384 {
385         struct ph2handle *p;
386
387         LIST_FOREACH(p, &ph2tree, chain) {
388                 /*
389                  * there are ph2handle independent on policy
390                  * such like informational exchange.
391                  */
392                 if (p->spid == spid)
393                         return p;
394         }
395
396         return NULL;
397 }
398
399 /*
400  * search ph2handle with sequence number.
401  */
402 struct ph2handle *
403 getph2byseq(seq)
404         u_int32_t seq;
405 {
406         struct ph2handle *p;
407
408         LIST_FOREACH(p, &ph2tree, chain) {
409                 if (p->seq == seq)
410                         return p;
411         }
412
413         return NULL;
414 }
415
416 /*
417  * search ph2handle with message id.
418  */
419 struct ph2handle *
420 getph2bymsgid(iph1, msgid)
421         struct ph1handle *iph1;
422         u_int32_t msgid;
423 {
424         struct ph2handle *p;
425
426         LIST_FOREACH(p, &ph2tree, chain) {
427                 if (p->msgid == msgid)
428                         return p;
429         }
430
431         return NULL;
432 }
433
434 /*
435  * call by pk_recvexpire().
436  */
437 struct ph2handle *
438 getph2bysaidx(src, dst, proto_id, spi)
439         struct sockaddr *src, *dst;
440         u_int proto_id;
441         u_int32_t spi;
442 {
443         struct ph2handle *iph2;
444         struct saproto *pr;
445
446         LIST_FOREACH(iph2, &ph2tree, chain) {
447                 if (iph2->proposal == NULL && iph2->approval == NULL)
448                         continue;
449                 if (iph2->approval != NULL) {
450                         for (pr = iph2->approval->head; pr != NULL;
451                              pr = pr->next) {
452                                 if (proto_id != pr->proto_id)
453                                         break;
454                                 if (spi == pr->spi || spi == pr->spi_p)
455                                         return iph2;
456                         }
457                 } else if (iph2->proposal != NULL) {
458                         for (pr = iph2->proposal->head; pr != NULL;
459                              pr = pr->next) {
460                                 if (proto_id != pr->proto_id)
461                                         break;
462                                 if (spi == pr->spi)
463                                         return iph2;
464                         }
465                 }
466         }
467
468         return NULL;
469 }
470
471 /*
472  * create new isakmp Phase 2 status record to handle isakmp in Phase2
473  */
474 struct ph2handle *
475 newph2()
476 {
477         struct ph2handle *iph2 = NULL;
478
479         /* create new iph2 */
480         iph2 = racoon_calloc(1, sizeof(*iph2));
481         if (iph2 == NULL)
482                 return NULL;
483
484         iph2->status = PHASE1ST_SPAWN;
485
486         return iph2;
487 }
488
489 /*
490  * initialize ph2handle
491  * NOTE: don't initialize src/dst.
492  *       SPI in the proposal is cleared.
493  */
494 void
495 initph2(iph2)
496         struct ph2handle *iph2;
497 {
498         sched_scrub_param(iph2);
499         iph2->sce = NULL;
500         iph2->scr = NULL;
501
502         VPTRINIT(iph2->sendbuf);
503         VPTRINIT(iph2->msg1);
504
505         /* clear spi, keep variables in the proposal */
506         if (iph2->proposal) {
507                 struct saproto *pr;
508                 for (pr = iph2->proposal->head; pr != NULL; pr = pr->next)
509                         pr->spi = 0;
510         }
511
512         /* clear approval */
513         if (iph2->approval) {
514                 flushsaprop(iph2->approval);
515                 iph2->approval = NULL;
516         }
517
518         /* clear the generated policy */
519         if (iph2->spidx_gen) {
520                 delsp_bothdir((struct policyindex *)iph2->spidx_gen);
521                 racoon_free(iph2->spidx_gen);
522                 iph2->spidx_gen = NULL;
523         }
524
525         if (iph2->pfsgrp) {
526                 oakley_dhgrp_free(iph2->pfsgrp);
527                 iph2->pfsgrp = NULL;
528         }
529
530         VPTRINIT(iph2->dhpriv);
531         VPTRINIT(iph2->dhpub);
532         VPTRINIT(iph2->dhpub_p);
533         VPTRINIT(iph2->dhgxy);
534         VPTRINIT(iph2->id);
535         VPTRINIT(iph2->id_p);
536         VPTRINIT(iph2->nonce);
537         VPTRINIT(iph2->nonce_p);
538         VPTRINIT(iph2->sa);
539         VPTRINIT(iph2->sa_ret);
540
541         if (iph2->ivm) {
542                 oakley_delivm(iph2->ivm);
543                 iph2->ivm = NULL;
544         }
545 }
546
547 /*
548  * delete new isakmp Phase 2 status record to handle isakmp in Phase2
549  */
550 void
551 delph2(iph2)
552         struct ph2handle *iph2;
553 {
554         initph2(iph2);
555
556         if (iph2->src) {
557                 racoon_free(iph2->src);
558                 iph2->src = NULL;
559         }
560         if (iph2->dst) {
561                 racoon_free(iph2->dst);
562                 iph2->dst = NULL;
563         }
564         if (iph2->src_id) {
565               racoon_free(iph2->src_id);
566               iph2->src_id = NULL;
567         }
568         if (iph2->dst_id) {
569               racoon_free(iph2->dst_id);
570               iph2->dst_id = NULL;
571         }
572
573         if (iph2->proposal) {
574                 flushsaprop(iph2->proposal);
575                 iph2->proposal = NULL;
576         }
577
578         racoon_free(iph2);
579 }
580
581 /*
582  * create new isakmp Phase 2 status record to handle isakmp in Phase2
583  */
584 int
585 insph2(iph2)
586         struct ph2handle *iph2;
587 {
588         LIST_INSERT_HEAD(&ph2tree, iph2, chain);
589
590         return 0;
591 }
592
593 void
594 remph2(iph2)
595         struct ph2handle *iph2;
596 {
597         LIST_REMOVE(iph2, chain);
598 }
599
600 void
601 initph2tree()
602 {
603         LIST_INIT(&ph2tree);
604 }
605
606 void
607 flushph2()
608 {
609         struct ph2handle *p, *next;
610
611         for (p = LIST_FIRST(&ph2tree); p; p = next) {
612                 next = LIST_NEXT(p, chain);
613
614                 /* send delete information */
615                 if (p->status == PHASE2ST_ESTABLISHED) 
616                         isakmp_info_send_d2(p);
617
618                 unbindph12(p);
619                 remph2(p);
620                 delph2(p);
621         }
622 }
623
624 /*
625  * Delete all Phase 2 handlers for this src/dst/proto.  This
626  * is used during INITIAL-CONTACT processing (so no need to
627  * send a message to the peer).
628  */
629 void
630 deleteallph2(src, dst, proto_id)
631         struct sockaddr *src, *dst;
632         u_int proto_id;
633 {
634         struct ph2handle *iph2, *next;
635         struct saproto *pr;
636
637         for (iph2 = LIST_FIRST(&ph2tree); iph2 != NULL; iph2 = next) {
638                 next = LIST_NEXT(iph2, chain);
639                 if (iph2->proposal == NULL && iph2->approval == NULL)
640                         continue;
641                 if (iph2->approval != NULL) {
642                         for (pr = iph2->approval->head; pr != NULL;
643                              pr = pr->next) {
644                                 if (proto_id == pr->proto_id)
645                                         goto zap_it;
646                         }
647                 } else if (iph2->proposal != NULL) {
648                         for (pr = iph2->proposal->head; pr != NULL;
649                              pr = pr->next) {
650                                 if (proto_id == pr->proto_id)
651                                         goto zap_it;
652                         }
653                 }
654                 continue;
655  zap_it:
656                 unbindph12(iph2);
657                 remph2(iph2);
658                 delph2(iph2);
659         }
660 }
661
662 /* %%% */
663 void
664 bindph12(iph1, iph2)
665         struct ph1handle *iph1;
666         struct ph2handle *iph2;
667 {
668         iph2->ph1 = iph1;
669         LIST_INSERT_HEAD(&iph1->ph2tree, iph2, ph1bind);
670 }
671
672 void
673 unbindph12(iph2)
674         struct ph2handle *iph2;
675 {
676         if (iph2->ph1 != NULL) {
677                 iph2->ph1 = NULL;
678                 LIST_REMOVE(iph2, ph1bind);
679         }
680 }
681
682 /* %%% management contacted list */
683 /*
684  * search contacted list.
685  */
686 struct contacted *
687 getcontacted(remote)
688         struct sockaddr *remote;
689 {
690         struct contacted *p;
691
692         LIST_FOREACH(p, &ctdtree, chain) {
693                 if (cmpsaddrstrict(remote, p->remote) == 0)
694                         return p;
695         }
696
697         return NULL;
698 }
699
700 /*
701  * create new isakmp Phase 2 status record to handle isakmp in Phase2
702  */
703 int
704 inscontacted(remote)
705         struct sockaddr *remote;
706 {
707         struct contacted *new;
708
709         /* create new iph2 */
710         new = racoon_calloc(1, sizeof(*new));
711         if (new == NULL)
712                 return -1;
713
714         new->remote = dupsaddr(remote);
715
716         LIST_INSERT_HEAD(&ctdtree, new, chain);
717
718         return 0;
719 }
720
721 void
722 initctdtree()
723 {
724         LIST_INIT(&ctdtree);
725 }
726
727 /*
728  * check the response has been sent to the peer.  when not, simply reply
729  * the buffered packet to the peer.
730  * OUT:
731  *       0:     the packet is received at the first time.
732  *       1:     the packet was processed before.
733  *       2:     the packet was processed before, but the address mismatches.
734  *      -1:     error happened.
735  */
736 int
737 check_recvdpkt(remote, local, rbuf)
738         struct sockaddr *remote, *local;
739         vchar_t *rbuf;
740 {
741         vchar_t *hash;
742         struct recvdpkt *r;
743         time_t t;
744         int len, s;
745
746         /* set current time */
747         t = time(NULL);
748
749         hash = eay_md5_one(rbuf);
750         if (!hash) {
751                 plog(LLV_ERROR, LOCATION, NULL,
752                         "failed to allocate buffer.\n");
753                 return -1;
754         }
755
756         LIST_FOREACH(r, &rcptree, chain) {
757                 if (memcmp(hash->v, r->hash->v, r->hash->l) == 0)
758                         break;
759         }
760         vfree(hash);
761
762         /* this is the first time to receive the packet */
763         if (r == NULL)
764                 return 0;
765
766         /*
767          * the packet was processed before, but the remote address mismatches.
768          */
769         if (cmpsaddrstrict(remote, r->remote) != 0)
770                 return 2;
771
772         /*
773          * it should not check the local address because the packet
774          * may arrive at other interface.
775          */
776
777         /* check the previous time to send */
778         if (t - r->time_send < 1) {
779                 plog(LLV_WARNING, LOCATION, NULL,
780                         "the packet retransmitted in a short time from %s\n",
781                         saddr2str(remote));
782                 /*XXX should it be error ? */
783         }
784
785         /* select the socket to be sent */
786         s = getsockmyaddr(r->local);
787         if (s == -1)
788                 return -1;
789
790         /* resend the packet if needed */
791         len = sendfromto(s, r->sendbuf->v, r->sendbuf->l,
792                         r->local, r->remote, lcconf->count_persend);
793         if (len == -1) {
794                 plog(LLV_ERROR, LOCATION, NULL, "sendfromto failed\n");
795                 return -1;
796         }
797
798         /* check the retry counter */
799         r->retry_counter--;
800         if (r->retry_counter <= 0) {
801                 rem_recvdpkt(r);
802                 del_recvdpkt(r);
803                 plog(LLV_DEBUG, LOCATION, NULL,
804                         "deleted the retransmission packet to %s.\n",
805                         saddr2str(remote));
806         } else
807                 r->time_send = t;
808
809         return 1;
810 }
811
812 /*
813  * adding a hash of received packet into the received list.
814  */
815 int
816 add_recvdpkt(remote, local, sbuf, rbuf)
817         struct sockaddr *remote, *local;
818         vchar_t *sbuf, *rbuf;
819 {
820         struct recvdpkt *new = NULL;
821
822         if (lcconf->retry_counter == 0) {
823                 /* no need to add it */
824                 return 0;
825         }
826
827         new = racoon_calloc(1, sizeof(*new));
828         if (!new) {
829                 plog(LLV_ERROR, LOCATION, NULL,
830                         "failed to allocate buffer.\n");
831                 return -1;
832         }
833
834         new->hash = eay_md5_one(rbuf);
835         if (!new->hash) {
836                 plog(LLV_ERROR, LOCATION, NULL,
837                         "failed to allocate buffer.\n");
838                 del_recvdpkt(new);
839                 return -1;
840         }
841         new->remote = dupsaddr(remote);
842         if (new->remote == NULL) {
843                 plog(LLV_ERROR, LOCATION, NULL,
844                         "failed to allocate buffer.\n");
845                 del_recvdpkt(new);
846                 return -1;
847         }
848         new->local = dupsaddr(local);
849         if (new->local == NULL) {
850                 plog(LLV_ERROR, LOCATION, NULL,
851                         "failed to allocate buffer.\n");
852                 del_recvdpkt(new);
853                 return -1;
854         }
855         new->sendbuf = vdup(sbuf);
856         if (new->sendbuf == NULL) {
857                 plog(LLV_ERROR, LOCATION, NULL,
858                         "failed to allocate buffer.\n");
859                 del_recvdpkt(new);
860                 return -1;
861         }
862
863         new->retry_counter = lcconf->retry_counter;
864         new->time_send = 0;
865         new->created = time(NULL);
866
867         LIST_INSERT_HEAD(&rcptree, new, chain);
868
869         return 0;
870 }
871
872 void
873 del_recvdpkt(r)
874         struct recvdpkt *r;
875 {
876         if (r->remote)
877                 racoon_free(r->remote);
878         if (r->local)
879                 racoon_free(r->local);
880         if (r->hash)
881                 vfree(r->hash);
882         if (r->sendbuf)
883                 vfree(r->sendbuf);
884         racoon_free(r);
885 }
886
887 void
888 rem_recvdpkt(r)
889         struct recvdpkt *r;
890 {
891         LIST_REMOVE(r, chain);
892 }
893
894 void
895 sweep_recvdpkt(dummy)
896         void *dummy;
897 {
898         struct recvdpkt *r, *next;
899         time_t t, lt;
900
901         /* set current time */
902         t = time(NULL);
903
904         /* set the lifetime of the retransmission */
905         lt = lcconf->retry_counter * lcconf->retry_interval;
906
907         for (r = LIST_FIRST(&rcptree); r; r = next) {
908                 next = LIST_NEXT(r, chain);
909
910                 if (t - r->created > lt) {
911                         rem_recvdpkt(r);
912                         del_recvdpkt(r);
913                 }
914         }
915
916         sched_new(lt, sweep_recvdpkt, NULL);
917 }
918
919 void
920 init_recvdpkt()
921 {
922         time_t lt = lcconf->retry_counter * lcconf->retry_interval;
923
924         LIST_INIT(&rcptree);
925
926         sched_new(lt, sweep_recvdpkt, NULL);
927 }
928
929 #ifdef ENABLE_HYBRID
930 /* 
931  * Retruns 0 if the address was obtained by ISAKMP mode config, 1 otherwise
932  * This should be in isakmp_cfg.c but ph1tree being private, it must be there
933  */
934 int
935 exclude_cfg_addr(addr)
936         const struct sockaddr *addr;
937 {
938         struct ph1handle *p;
939         struct sockaddr_in *sin;
940
941         LIST_FOREACH(p, &ph1tree, chain) {
942                 if ((p->mode_cfg != NULL) &&
943                     (p->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) &&
944                     (addr->sa_family == AF_INET)) {
945                         sin = (struct sockaddr_in *)addr;
946                         if (sin->sin_addr.s_addr == p->mode_cfg->addr4.s_addr)
947                                 return 0;
948                 }
949         }
950
951         return 1;
952 }
953 #endif