isakmp_inf.c revision 1.1.1.3.2.3
1/*	$NetBSD: isakmp_inf.c,v 1.1.1.3.2.3 2005/05/11 12:17:19 tron Exp $	*/
2
3/* Id: isakmp_inf.c,v 1.14.4.2 2005/03/02 20:00:03 vanhu Exp */
4
5/*
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include "config.h"
35
36#include <sys/types.h>
37#include <sys/param.h>
38#include <sys/socket.h>
39
40#include <net/pfkeyv2.h>
41#include <netinet/in.h>
42#include <sys/queue.h>
43#ifndef HAVE_NETINET6_IPSEC
44#include <netinet/ipsec.h>
45#else
46#include <netinet6/ipsec.h>
47#endif
48
49#include <stdlib.h>
50#include <stdio.h>
51#include <string.h>
52#include <errno.h>
53#if TIME_WITH_SYS_TIME
54# include <sys/time.h>
55# include <time.h>
56#else
57# if HAVE_SYS_TIME_H
58#  include <sys/time.h>
59# else
60#  include <time.h>
61# endif
62#endif
63
64#include "libpfkey.h"
65
66#include "var.h"
67#include "vmbuf.h"
68#include "schedule.h"
69#include "str2val.h"
70#include "misc.h"
71#include "plog.h"
72#include "debug.h"
73
74#include "localconf.h"
75#include "remoteconf.h"
76#include "sockmisc.h"
77#include "isakmp_var.h"
78#include "evt.h"
79#include "isakmp.h"
80#ifdef ENABLE_HYBRID
81#include "isakmp_xauth.h"
82#include "isakmp_cfg.h"
83#endif
84#include "isakmp_inf.h"
85#include "oakley.h"
86#include "handler.h"
87#include "ipsec_doi.h"
88#include "crypto_openssl.h"
89#include "pfkey.h"
90#include "policy.h"
91#include "algorithm.h"
92#include "proposal.h"
93#include "admin.h"
94#include "strnames.h"
95
96/* information exchange */
97static int isakmp_info_recv_n __P((struct ph1handle *, vchar_t *));
98static int isakmp_info_recv_d __P((struct ph1handle *, vchar_t *));
99
100#ifdef ENABLE_DPD
101static int isakmp_info_recv_r_u __P((struct ph1handle *,
102	struct isakmp_pl_ru *, u_int32_t));
103static int isakmp_info_recv_r_u_ack __P((struct ph1handle *,
104	struct isakmp_pl_ru *, u_int32_t));
105static void isakmp_info_send_r_u __P((void *));
106#endif
107
108static void purge_isakmp_spi __P((int, isakmp_index *, size_t));
109static void purge_ipsec_spi __P((struct sockaddr *, int, u_int32_t *, size_t));
110static void info_recv_initialcontact __P((struct ph1handle *));
111
112/* %%%
113 * Information Exchange
114 */
115/*
116 * receive Information
117 */
118int
119isakmp_info_recv(iph1, msg0)
120	struct ph1handle *iph1;
121	vchar_t *msg0;
122{
123	vchar_t *msg = NULL;
124	int error = -1;
125	struct isakmp *isakmp;
126	struct isakmp_gen *gen;
127	u_int8_t np;
128	int encrypted;
129
130	plog(LLV_DEBUG, LOCATION, NULL, "receive Information.\n");
131
132	encrypted = ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E);
133
134	/* Use new IV to decrypt Informational message. */
135	if (encrypted) {
136
137		struct isakmp_ivm *ivm;
138
139		/* compute IV */
140		ivm = oakley_newiv2(iph1, ((struct isakmp *)msg0->v)->msgid);
141		if (ivm == NULL)
142			return -1;
143
144		msg = oakley_do_decrypt(iph1, msg0, ivm->iv, ivm->ive);
145		oakley_delivm(ivm);
146		if (msg == NULL)
147			return -1;
148
149	} else
150		msg = vdup(msg0);
151
152	isakmp = (struct isakmp *)msg->v;
153	gen = (struct isakmp_gen *)((caddr_t)isakmp + sizeof(struct isakmp));
154
155	if (isakmp->np != ISAKMP_NPTYPE_HASH) {
156		plog(LLV_ERROR, LOCATION, NULL,
157		    "ignore information because the message has no hash payload.\n");
158		goto end;
159	}
160
161	if (iph1->status != PHASE1ST_ESTABLISHED) {
162		plog(LLV_ERROR, LOCATION, NULL,
163		    "ignore information because ISAKMP-SA has not been established yet.\n");
164		goto end;
165	}
166
167	np = gen->np;
168
169	{
170		void *p;
171		vchar_t *hash, *payload;
172		struct isakmp_gen *nd;
173
174		p = (caddr_t) gen + sizeof(struct isakmp_gen);
175		nd = (struct isakmp_gen *) ((caddr_t) gen + ntohs(gen->len));
176
177		/* nd length check */
178		if (ntohs(nd->len) > msg->l - (sizeof(struct isakmp) +
179		    ntohs(gen->len))) {
180			plog(LLV_ERROR, LOCATION, NULL,
181				 "too long payload length (broken message?)\n");
182			goto end;
183		}
184
185		payload = vmalloc(ntohs(nd->len));
186		if (payload == NULL) {
187			plog(LLV_ERROR, LOCATION, NULL,
188			    "cannot allocate memory\n");
189			goto end;
190		}
191
192		memcpy(payload->v, (caddr_t) nd, ntohs(nd->len));
193
194		/* compute HASH */
195		hash = oakley_compute_hash1(iph1, isakmp->msgid, payload);
196		if (hash == NULL) {
197			plog(LLV_ERROR, LOCATION, NULL,
198			    "cannot compute hash\n");
199
200			vfree(payload);
201			goto end;
202		}
203
204		if (ntohs(gen->len) - sizeof(struct isakmp_gen) != hash->l) {
205			plog(LLV_ERROR, LOCATION, NULL,
206			    "ignore information due to hash length mismatch\n");
207
208			vfree(hash);
209			vfree(payload);
210			goto end;
211		}
212
213		if (memcmp(p, hash->v, hash->l) != 0) {
214			plog(LLV_ERROR, LOCATION, NULL,
215			    "ignore information due to hash mismatch\n");
216
217			vfree(hash);
218			vfree(payload);
219			goto end;
220		}
221
222		plog(LLV_DEBUG, LOCATION, NULL, "hash validated.\n");
223
224		vfree(hash);
225		vfree(payload);
226	}
227
228	/* make sure the packet were encrypted. */
229	if (!encrypted) {
230		switch (iph1->etype) {
231		case ISAKMP_ETYPE_AGG:
232		case ISAKMP_ETYPE_BASE:
233		case ISAKMP_ETYPE_IDENT:
234			if ((iph1->side == INITIATOR && iph1->status < PHASE1ST_MSG3SENT)
235			 || (iph1->side == RESPONDER && iph1->status < PHASE1ST_MSG2SENT)) {
236				break;
237			}
238			/*FALLTHRU*/
239		default:
240			plog(LLV_ERROR, LOCATION, iph1->remote,
241				"%s message must be encrypted\n",
242				s_isakmp_nptype(np));
243			goto end;
244		}
245	}
246
247	switch (np) {
248	case ISAKMP_NPTYPE_N:
249		if (isakmp_info_recv_n(iph1, msg) < 0)
250			goto end;
251		break;
252	case ISAKMP_NPTYPE_D:
253		if (isakmp_info_recv_d(iph1, msg) < 0)
254			goto end;
255		break;
256	case ISAKMP_NPTYPE_NONCE:
257		/* XXX to be 6.4.2 ike-01.txt */
258		/* XXX IV is to be synchronized. */
259		plog(LLV_ERROR, LOCATION, iph1->remote,
260			"ignore Acknowledged Informational\n");
261		break;
262	default:
263		/* don't send information, see isakmp_ident_r1() */
264		error = 0;
265		plog(LLV_ERROR, LOCATION, iph1->remote,
266			"reject the packet, "
267			"received unexpecting payload type %d.\n",
268			gen->np);
269		goto end;
270	}
271
272    end:
273	if (msg != NULL)
274		vfree(msg);
275
276	return 0;
277}
278
279/*
280 * send Delete payload (for ISAKMP SA) in Informational exchange.
281 */
282int
283isakmp_info_send_d1(iph1)
284	struct ph1handle *iph1;
285{
286	struct isakmp_pl_d *d;
287	vchar_t *payload = NULL;
288	int tlen;
289	int error = 0;
290
291	if (iph1->status != PHASE2ST_ESTABLISHED)
292		return 0;
293
294	/* create delete payload */
295
296	/* send SPIs of inbound SAs. */
297	/* XXX should send outbound SAs's ? */
298	tlen = sizeof(*d) + sizeof(isakmp_index);
299	payload = vmalloc(tlen);
300	if (payload == NULL) {
301		plog(LLV_ERROR, LOCATION, NULL,
302			"failed to get buffer for payload.\n");
303		return errno;
304	}
305
306	d = (struct isakmp_pl_d *)payload->v;
307	d->h.np = ISAKMP_NPTYPE_NONE;
308	d->h.len = htons(tlen);
309	d->doi = htonl(IPSEC_DOI);
310	d->proto_id = IPSECDOI_PROTO_ISAKMP;
311	d->spi_size = sizeof(isakmp_index);
312	d->num_spi = htons(1);
313	memcpy(d + 1, &iph1->index, sizeof(isakmp_index));
314
315	error = isakmp_info_send_common(iph1, payload,
316					ISAKMP_NPTYPE_D, 0);
317	vfree(payload);
318
319	return error;
320}
321
322/*
323 * send Delete payload (for IPsec SA) in Informational exchange, based on
324 * pfkey msg.  It sends always single SPI.
325 */
326int
327isakmp_info_send_d2(iph2)
328	struct ph2handle *iph2;
329{
330	struct ph1handle *iph1;
331	struct saproto *pr;
332	struct isakmp_pl_d *d;
333	vchar_t *payload = NULL;
334	int tlen;
335	int error = 0;
336	u_int8_t *spi;
337
338	if (iph2->status != PHASE2ST_ESTABLISHED)
339		return 0;
340
341	/*
342	 * don't send delete information if there is no phase 1 handler.
343	 * It's nonsensical to negotiate phase 1 to send the information.
344	 */
345	iph1 = getph1byaddr(iph2->src, iph2->dst);
346	if (iph1 == NULL)
347		return 0;
348
349	/* create delete payload */
350	for (pr = iph2->approval->head; pr != NULL; pr = pr->next) {
351
352		/* send SPIs of inbound SAs. */
353		/*
354		 * XXX should I send outbound SAs's ?
355		 * I send inbound SAs's SPI only at the moment because I can't
356		 * decode any more if peer send encoded packet without aware of
357		 * deletion of SA.  Outbound SAs don't come under the situation.
358		 */
359		tlen = sizeof(*d) + pr->spisize;
360		payload = vmalloc(tlen);
361		if (payload == NULL) {
362			plog(LLV_ERROR, LOCATION, NULL,
363				"failed to get buffer for payload.\n");
364			return errno;
365		}
366
367		d = (struct isakmp_pl_d *)payload->v;
368		d->h.np = ISAKMP_NPTYPE_NONE;
369		d->h.len = htons(tlen);
370		d->doi = htonl(IPSEC_DOI);
371		d->proto_id = pr->proto_id;
372		d->spi_size = pr->spisize;
373		d->num_spi = htons(1);
374		/*
375		 * XXX SPI bits are left-filled, for use with IPComp.
376		 * we should be switching to variable-length spi field...
377		 */
378		spi = (u_int8_t *)&pr->spi;
379		spi += sizeof(pr->spi);
380		spi -= pr->spisize;
381		memcpy(d + 1, spi, pr->spisize);
382
383		error = isakmp_info_send_common(iph1, payload,
384						ISAKMP_NPTYPE_D, 0);
385		vfree(payload);
386	}
387
388	return error;
389}
390
391/*
392 * send Notification payload (for without ISAKMP SA) in Informational exchange
393 */
394int
395isakmp_info_send_nx(isakmp, remote, local, type, data)
396	struct isakmp *isakmp;
397	struct sockaddr *remote, *local;
398	int type;
399	vchar_t *data;
400{
401	struct ph1handle *iph1 = NULL;
402	struct remoteconf *rmconf;
403	vchar_t *payload = NULL;
404	int tlen;
405	int error = -1;
406	struct isakmp_pl_n *n;
407	int spisiz = 0;		/* see below */
408
409	/* search appropreate configuration */
410	rmconf = getrmconf(remote);
411	if (rmconf == NULL) {
412		plog(LLV_ERROR, LOCATION, remote,
413			"no configuration found for peer address.\n");
414		goto end;
415	}
416
417	/* add new entry to isakmp status table. */
418	iph1 = newph1();
419	if (iph1 == NULL)
420		return -1;
421
422	memcpy(&iph1->index.i_ck, &isakmp->i_ck, sizeof(cookie_t));
423	isakmp_newcookie((char *)&iph1->index.r_ck, remote, local);
424	iph1->status = PHASE1ST_START;
425	iph1->rmconf = rmconf;
426	iph1->side = INITIATOR;
427	iph1->version = isakmp->v;
428	iph1->flags = 0;
429	iph1->msgid = 0;	/* XXX */
430#ifdef ENABLE_HYBRID
431	if ((iph1->mode_cfg = isakmp_cfg_mkstate()) == NULL)
432		return -1;
433#endif
434#ifdef ENABLE_FRAG
435	iph1->frag = 0;
436	iph1->frag_chain = NULL;
437#endif
438
439	/* copy remote address */
440	if (copy_ph1addresses(iph1, rmconf, remote, local) < 0)
441		return -1;
442
443	tlen = sizeof(*n) + spisiz;
444	if (data)
445		tlen += data->l;
446	payload = vmalloc(tlen);
447	if (payload == NULL) {
448		plog(LLV_ERROR, LOCATION, NULL,
449			"failed to get buffer to send.\n");
450		goto end;
451	}
452
453	n = (struct isakmp_pl_n *)payload->v;
454	n->h.np = ISAKMP_NPTYPE_NONE;
455	n->h.len = htons(tlen);
456	n->doi = htonl(IPSEC_DOI);
457	n->proto_id = IPSECDOI_KEY_IKE;
458	n->spi_size = spisiz;
459	n->type = htons(type);
460	if (spisiz)
461		memset(n + 1, 0, spisiz);	/*XXX*/
462	if (data)
463		memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l);
464
465	error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0);
466	vfree(payload);
467
468    end:
469	if (iph1 != NULL)
470		delph1(iph1);
471
472	return error;
473}
474
475/*
476 * send Notification payload (for ISAKMP SA) in Informational exchange
477 */
478int
479isakmp_info_send_n1(iph1, type, data)
480	struct ph1handle *iph1;
481	int type;
482	vchar_t *data;
483{
484	vchar_t *payload = NULL;
485	int tlen;
486	int error = 0;
487	struct isakmp_pl_n *n;
488	int spisiz;
489
490	/*
491	 * note on SPI size: which description is correct?  I have chosen
492	 * this to be 0.
493	 *
494	 * RFC2408 3.1, 2nd paragraph says: ISAKMP SA is identified by
495	 * Initiator/Responder cookie and SPI has no meaning, SPI size = 0.
496	 * RFC2408 3.1, first paragraph on page 40: ISAKMP SA is identified
497	 * by cookie and SPI has no meaning, 0 <= SPI size <= 16.
498	 * RFC2407 4.6.3.3, INITIAL-CONTACT is required to set to 16.
499	 */
500	if (type == ISAKMP_NTYPE_INITIAL_CONTACT)
501		spisiz = sizeof(isakmp_index);
502	else
503		spisiz = 0;
504
505	tlen = sizeof(*n) + spisiz;
506	if (data)
507		tlen += data->l;
508	payload = vmalloc(tlen);
509	if (payload == NULL) {
510		plog(LLV_ERROR, LOCATION, NULL,
511			"failed to get buffer to send.\n");
512		return errno;
513	}
514
515	n = (struct isakmp_pl_n *)payload->v;
516	n->h.np = ISAKMP_NPTYPE_NONE;
517	n->h.len = htons(tlen);
518	n->doi = htonl(iph1->rmconf->doitype);
519	n->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX to be configurable ? */
520	n->spi_size = spisiz;
521	n->type = htons(type);
522	if (spisiz)
523		memcpy(n + 1, &iph1->index, sizeof(isakmp_index));
524	if (data)
525		memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l);
526
527	error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph1->flags);
528	vfree(payload);
529
530	return error;
531}
532
533/*
534 * send Notification payload (for IPsec SA) in Informational exchange
535 */
536int
537isakmp_info_send_n2(iph2, type, data)
538	struct ph2handle *iph2;
539	int type;
540	vchar_t *data;
541{
542	struct ph1handle *iph1 = iph2->ph1;
543	vchar_t *payload = NULL;
544	int tlen;
545	int error = 0;
546	struct isakmp_pl_n *n;
547	struct saproto *pr;
548
549	if (!iph2->approval)
550		return EINVAL;
551
552	pr = iph2->approval->head;
553
554	/* XXX must be get proper spi */
555	tlen = sizeof(*n) + pr->spisize;
556	if (data)
557		tlen += data->l;
558	payload = vmalloc(tlen);
559	if (payload == NULL) {
560		plog(LLV_ERROR, LOCATION, NULL,
561			"failed to get buffer to send.\n");
562		return errno;
563	}
564
565	n = (struct isakmp_pl_n *)payload->v;
566	n->h.np = ISAKMP_NPTYPE_NONE;
567	n->h.len = htons(tlen);
568	n->doi = htonl(IPSEC_DOI);		/* IPSEC DOI (1) */
569	n->proto_id = pr->proto_id;		/* IPSEC AH/ESP/whatever*/
570	n->spi_size = pr->spisize;
571	n->type = htons(type);
572	*(u_int32_t *)(n + 1) = pr->spi;
573	if (data)
574		memcpy((caddr_t)(n + 1) + pr->spisize, data->v, data->l);
575
576	iph2->flags |= ISAKMP_FLAG_E;	/* XXX Should we do FLAG_A ? */
577	error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph2->flags);
578	vfree(payload);
579
580	return error;
581}
582
583/*
584 * send Information
585 * When ph1->skeyid_a == NULL, send message without encoding.
586 */
587int
588isakmp_info_send_common(iph1, payload, np, flags)
589	struct ph1handle *iph1;
590	vchar_t *payload;
591	u_int32_t np;
592	int flags;
593{
594	struct ph2handle *iph2 = NULL;
595	vchar_t *hash = NULL;
596	struct isakmp *isakmp;
597	struct isakmp_gen *gen;
598	char *p;
599	int tlen;
600	int error = -1;
601
602	/* add new entry to isakmp status table */
603	iph2 = newph2();
604	if (iph2 == NULL)
605		goto end;
606
607	iph2->dst = dupsaddr(iph1->remote);
608	iph2->src = dupsaddr(iph1->local);
609	switch (iph1->remote->sa_family) {
610	case AF_INET:
611#ifndef ENABLE_NATT
612		((struct sockaddr_in *)iph2->dst)->sin_port = 0;
613		((struct sockaddr_in *)iph2->src)->sin_port = 0;
614#endif
615		break;
616#ifdef INET6
617	case AF_INET6:
618		((struct sockaddr_in6 *)iph2->dst)->sin6_port = 0;
619		((struct sockaddr_in6 *)iph2->src)->sin6_port = 0;
620		break;
621#endif
622	default:
623		plog(LLV_ERROR, LOCATION, NULL,
624			"invalid family: %d\n", iph1->remote->sa_family);
625		delph2(iph2);
626		goto end;
627	}
628	iph2->ph1 = iph1;
629	iph2->side = INITIATOR;
630	iph2->status = PHASE2ST_START;
631	iph2->msgid = isakmp_newmsgid2(iph1);
632
633	/* get IV and HASH(1) if skeyid_a was generated. */
634	if (iph1->skeyid_a != NULL) {
635		iph2->ivm = oakley_newiv2(iph1, iph2->msgid);
636		if (iph2->ivm == NULL) {
637			delph2(iph2);
638			goto end;
639		}
640
641		/* generate HASH(1) */
642		hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, payload);
643		if (hash == NULL) {
644			delph2(iph2);
645			goto end;
646		}
647
648		/* initialized total buffer length */
649		tlen = hash->l;
650		tlen += sizeof(*gen);
651	} else {
652		/* IKE-SA is not established */
653		hash = NULL;
654
655		/* initialized total buffer length */
656		tlen = 0;
657	}
658	if ((flags & ISAKMP_FLAG_A) == 0)
659		iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_E);
660	else
661		iph2->flags = (hash == NULL ? 0 : ISAKMP_FLAG_A);
662
663	insph2(iph2);
664	bindph12(iph1, iph2);
665
666	tlen += sizeof(*isakmp) + payload->l;
667
668	/* create buffer for isakmp payload */
669	iph2->sendbuf = vmalloc(tlen);
670	if (iph2->sendbuf == NULL) {
671		plog(LLV_ERROR, LOCATION, NULL,
672			"failed to get buffer to send.\n");
673		goto err;
674	}
675
676	/* create isakmp header */
677	isakmp = (struct isakmp *)iph2->sendbuf->v;
678	memcpy(&isakmp->i_ck, &iph1->index.i_ck, sizeof(cookie_t));
679	memcpy(&isakmp->r_ck, &iph1->index.r_ck, sizeof(cookie_t));
680	isakmp->np = hash == NULL ? (np & 0xff) : ISAKMP_NPTYPE_HASH;
681	isakmp->v = iph1->version;
682	isakmp->etype = ISAKMP_ETYPE_INFO;
683	isakmp->flags = iph2->flags;
684	memcpy(&isakmp->msgid, &iph2->msgid, sizeof(isakmp->msgid));
685	isakmp->len   = htonl(tlen);
686	p = (char *)(isakmp + 1);
687
688	/* create HASH payload */
689	if (hash != NULL) {
690		gen = (struct isakmp_gen *)p;
691		gen->np = np & 0xff;
692		gen->len = htons(sizeof(*gen) + hash->l);
693		p += sizeof(*gen);
694		memcpy(p, hash->v, hash->l);
695		p += hash->l;
696	}
697
698	/* add payload */
699	memcpy(p, payload->v, payload->l);
700	p += payload->l;
701
702#ifdef HAVE_PRINT_ISAKMP_C
703	isakmp_printpacket(iph2->sendbuf, iph1->local, iph1->remote, 1);
704#endif
705
706	/* encoding */
707	if (ISSET(isakmp->flags, ISAKMP_FLAG_E)) {
708		vchar_t *tmp;
709
710		tmp = oakley_do_encrypt(iph2->ph1, iph2->sendbuf, iph2->ivm->ive,
711				iph2->ivm->iv);
712		VPTRINIT(iph2->sendbuf);
713		if (tmp == NULL)
714			goto err;
715		iph2->sendbuf = tmp;
716	}
717
718	/* HDR*, HASH(1), N */
719	if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0) {
720		VPTRINIT(iph2->sendbuf);
721		goto err;
722	}
723
724	plog(LLV_DEBUG, LOCATION, NULL,
725		"sendto Information %s.\n", s_isakmp_nptype(np));
726
727	/*
728	 * don't resend notify message because peer can use Acknowledged
729	 * Informational if peer requires the reply of the notify message.
730	 */
731
732	/* XXX If Acknowledged Informational required, don't delete ph2handle */
733	error = 0;
734	VPTRINIT(iph2->sendbuf);
735	goto err;	/* XXX */
736
737end:
738	if (hash)
739		vfree(hash);
740	return error;
741
742err:
743	unbindph12(iph2);
744	remph2(iph2);
745	delph2(iph2);
746	goto end;
747}
748
749/*
750 * add a notify payload to buffer by reallocating buffer.
751 * If buf == NULL, the function only create a notify payload.
752 *
753 * XXX Which is SPI to be included, inbound or outbound ?
754 */
755vchar_t *
756isakmp_add_pl_n(buf0, np_p, type, pr, data)
757	vchar_t *buf0;
758	u_int8_t **np_p;
759	int type;
760	struct saproto *pr;
761	vchar_t *data;
762{
763	vchar_t *buf = NULL;
764	struct isakmp_pl_n *n;
765	int tlen;
766	int oldlen = 0;
767
768	if (*np_p)
769		**np_p = ISAKMP_NPTYPE_N;
770
771	tlen = sizeof(*n) + pr->spisize;
772
773	if (data)
774		tlen += data->l;
775	if (buf0) {
776		oldlen = buf0->l;
777		buf = vrealloc(buf0, buf0->l + tlen);
778	} else
779		buf = vmalloc(tlen);
780	if (!buf) {
781		plog(LLV_ERROR, LOCATION, NULL,
782			"failed to get a payload buffer.\n");
783		return NULL;
784	}
785
786	n = (struct isakmp_pl_n *)(buf->v + oldlen);
787	n->h.np = ISAKMP_NPTYPE_NONE;
788	n->h.len = htons(tlen);
789	n->doi = htonl(IPSEC_DOI);		/* IPSEC DOI (1) */
790	n->proto_id = pr->proto_id;		/* IPSEC AH/ESP/whatever*/
791	n->spi_size = pr->spisize;
792	n->type = htons(type);
793	*(u_int32_t *)(n + 1) = pr->spi;	/* XXX */
794	if (data)
795		memcpy((caddr_t)(n + 1) + pr->spisize, data->v, data->l);
796
797	/* save the pointer of next payload type */
798	*np_p = &n->h.np;
799
800	return buf;
801}
802
803/*
804 * handling to receive Notification payload
805 */
806static int
807isakmp_info_recv_n(iph1, msg)
808	struct ph1handle *iph1;
809	vchar_t *msg;
810{
811	struct isakmp_pl_n *n = NULL;
812	u_int type;
813	vchar_t *pbuf;
814	struct isakmp_parse_t *pa, *pap;
815	char *spi;
816
817	if (!(pbuf = isakmp_parse(msg)))
818		return -1;
819	pa = (struct isakmp_parse_t *)pbuf->v;
820	for (pap = pa; pap->type; pap++) {
821		switch (pap->type) {
822		case ISAKMP_NPTYPE_HASH:
823			/* do something here */
824			break;
825		case ISAKMP_NPTYPE_NONCE:
826			/* send to ack */
827			break;
828		case ISAKMP_NPTYPE_N:
829			n = (struct isakmp_pl_n *)pap->ptr;
830			break;
831		default:
832			vfree(pbuf);
833			return -1;
834		}
835	}
836	vfree(pbuf);
837	if (!n)
838		return -1;
839
840	type = ntohs(n->type);
841
842	switch (type) {
843	case ISAKMP_NTYPE_CONNECTED:
844	case ISAKMP_NTYPE_RESPONDER_LIFETIME:
845	case ISAKMP_NTYPE_REPLAY_STATUS:
846		/* do something */
847		break;
848	case ISAKMP_NTYPE_INITIAL_CONTACT:
849		info_recv_initialcontact(iph1);
850		break;
851#ifdef ENABLE_DPD
852	case ISAKMP_NTYPE_R_U_THERE:
853		isakmp_info_recv_r_u(iph1, (struct isakmp_pl_ru *)n,
854				     ((struct isakmp *)msg->v)->msgid);
855		break;
856	case ISAKMP_NTYPE_R_U_THERE_ACK:
857		isakmp_info_recv_r_u_ack(iph1, (struct isakmp_pl_ru *)n,
858					 ((struct isakmp *)msg->v)->msgid);
859		break;
860#endif
861
862	default:
863	    {
864		u_int32_t msgid = ((struct isakmp *)msg->v)->msgid;
865		struct ph2handle *iph2;
866
867		/* XXX there is a potential of dos attack. */
868		if (msgid == 0) {
869			/* delete ph1 */
870			plog(LLV_ERROR, LOCATION, iph1->remote,
871				"delete phase1 handle.\n");
872			return -1;
873		} else {
874			iph2 = getph2bymsgid(iph1, msgid);
875			if (iph2 == NULL) {
876				plog(LLV_ERROR, LOCATION, iph1->remote,
877					"unknown notify message, "
878					"no phase2 handle found.\n");
879			} else {
880				/* delete ph2 */
881				unbindph12(iph2);
882				remph2(iph2);
883				delph2(iph2);
884			}
885		}
886	    }
887		break;
888	}
889
890	/* get spi and allocate */
891	if (ntohs(n->h.len) < sizeof(*n) + n->spi_size) {
892		plog(LLV_ERROR, LOCATION, iph1->remote,
893			"invalid spi_size in notification payload.\n");
894		return -1;
895	}
896	spi = val2str((u_char *)(n + 1), n->spi_size);
897
898	plog(LLV_DEBUG, LOCATION, iph1->remote,
899		"notification message %d:%s, "
900		"doi=%d proto_id=%d spi=%s(size=%d).\n",
901		type, s_isakmp_notify_msg(type),
902		ntohl(n->doi), n->proto_id, spi, n->spi_size);
903
904	racoon_free(spi);
905
906	return(0);
907}
908
909void
910purge_isakmp_spi(proto, spi, n)
911	int proto;
912	isakmp_index *spi;	/*network byteorder*/
913	size_t n;
914{
915	struct ph1handle *iph1;
916	size_t i;
917
918	for (i = 0; i < n; i++) {
919		iph1 = getph1byindex(&spi[i]);
920		if (!iph1)
921			continue;
922
923		plog(LLV_INFO, LOCATION, NULL,
924			"purged ISAKMP-SA proto_id=%s spi=%s.\n",
925			s_ipsecdoi_proto(proto),
926			isakmp_pindex(&spi[i], 0));
927
928		if (iph1->sce)
929			SCHED_KILL(iph1->sce);
930		iph1->status = PHASE1ST_EXPIRED;
931		iph1->sce = sched_new(1, isakmp_ph1delete_stub, iph1);
932	}
933}
934
935static void
936purge_ipsec_spi(dst0, proto, spi, n)
937	struct sockaddr *dst0;
938	int proto;
939	u_int32_t *spi;	/*network byteorder*/
940	size_t n;
941{
942	vchar_t *buf = NULL;
943	struct sadb_msg *msg, *next, *end;
944	struct sadb_sa *sa;
945	struct sockaddr *src, *dst;
946	struct ph2handle *iph2;
947	size_t i;
948	caddr_t mhp[SADB_EXT_MAX + 1];
949
950	buf = pfkey_dump_sadb(ipsecdoi2pfkey_proto(proto));
951	if (buf == NULL) {
952		plog(LLV_DEBUG, LOCATION, NULL,
953			"pfkey_dump_sadb returned nothing.\n");
954		return;
955	}
956
957	msg = (struct sadb_msg *)buf->v;
958	end = (struct sadb_msg *)(buf->v + buf->l);
959
960	while (msg < end) {
961		if ((msg->sadb_msg_len << 3) < sizeof(*msg))
962			break;
963		next = (struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3));
964		if (msg->sadb_msg_type != SADB_DUMP) {
965			msg = next;
966			continue;
967		}
968
969		if (pfkey_align(msg, mhp) || pfkey_check(mhp)) {
970			plog(LLV_ERROR, LOCATION, NULL,
971				"pfkey_check (%s)\n", ipsec_strerror());
972			msg = next;
973			continue;
974		}
975
976		sa = (struct sadb_sa *)(mhp[SADB_EXT_SA]);
977		if (!sa
978		 || !mhp[SADB_EXT_ADDRESS_SRC]
979		 || !mhp[SADB_EXT_ADDRESS_DST]) {
980			msg = next;
981			continue;
982		}
983		src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
984		dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
985
986		if (sa->sadb_sa_state != SADB_SASTATE_MATURE
987		 && sa->sadb_sa_state != SADB_SASTATE_DYING) {
988			msg = next;
989			continue;
990		}
991
992		/* XXX n^2 algorithm, inefficient */
993
994		/* don't delete inbound SAs at the moment */
995		/* XXX should we remove SAs with opposite direction as well? */
996		if (CMPSADDR(dst0, dst)) {
997			msg = next;
998			continue;
999		}
1000
1001		for (i = 0; i < n; i++) {
1002			plog(LLV_DEBUG, LOCATION, NULL,
1003				"check spi(packet)=%u spi(db)=%u.\n",
1004				ntohl(spi[i]), ntohl(sa->sadb_sa_spi));
1005			if (spi[i] != sa->sadb_sa_spi)
1006				continue;
1007
1008			pfkey_send_delete(lcconf->sock_pfkey,
1009				msg->sadb_msg_satype,
1010				IPSEC_MODE_ANY,
1011				src, dst, sa->sadb_sa_spi);
1012
1013			/*
1014			 * delete a relative phase 2 handler.
1015			 * continue to process if no relative phase 2 handler
1016			 * exists.
1017			 */
1018			iph2 = getph2bysaidx(src, dst, proto, spi[i]);
1019			if (iph2) {
1020				delete_spd(iph2);
1021				unbindph12(iph2);
1022				remph2(iph2);
1023				delph2(iph2);
1024			}
1025
1026			plog(LLV_INFO, LOCATION, NULL,
1027				"purged IPsec-SA proto_id=%s spi=%u.\n",
1028				s_ipsecdoi_proto(proto),
1029				ntohl(spi[i]));
1030		}
1031
1032		msg = next;
1033	}
1034
1035	if (buf)
1036		vfree(buf);
1037}
1038
1039/*
1040 * delete all phase2 sa relatived to the destination address.
1041 * Don't delete Phase 1 handlers on INITIAL-CONTACT, and don't ignore
1042 * an INITIAL-CONTACT if we have contacted the peer.  This matches the
1043 * Sun IKE behavior, and makes rekeying work much better when the peer
1044 * restarts.
1045 */
1046static void
1047info_recv_initialcontact(iph1)
1048	struct ph1handle *iph1;
1049{
1050	vchar_t *buf = NULL;
1051	struct sadb_msg *msg, *next, *end;
1052	struct sadb_sa *sa;
1053	struct sockaddr *src, *dst;
1054	caddr_t mhp[SADB_EXT_MAX + 1];
1055	int proto_id, i;
1056	struct ph2handle *iph2;
1057#if 0
1058	char *loc, *rem;
1059#endif
1060
1061	if (f_local)
1062		return;
1063
1064#if 0
1065	loc = strdup(saddrwop2str(iph1->local));
1066	rem = strdup(saddrwop2str(iph1->remote));
1067
1068	/*
1069	 * Purge all IPSEC-SAs for the peer.  We can do this
1070	 * the easy way (using a PF_KEY SADB_DELETE extension)
1071	 * or we can do it the hard way.
1072	 */
1073	for (i = 0; i < pfkey_nsatypes; i++) {
1074		proto_id = pfkey2ipsecdoi_proto(pfkey_satypes[i].ps_satype);
1075
1076		plog(LLV_INFO, LOCATION, NULL,
1077		    "purging %s SAs for %s -> %s\n",
1078		    pfkey_satypes[i].ps_name, loc, rem);
1079		if (pfkey_send_delete_all(lcconf->sock_pfkey,
1080		    pfkey_satypes[i].ps_satype, IPSEC_MODE_ANY,
1081		    iph1->local, iph1->remote) == -1) {
1082			plog(LLV_ERROR, LOCATION, NULL,
1083			    "delete_all %s -> %s failed for %s (%s)\n",
1084			    loc, rem,
1085			    pfkey_satypes[i].ps_name, ipsec_strerror());
1086			goto the_hard_way;
1087		}
1088
1089		deleteallph2(iph1->local, iph1->remote, proto_id);
1090
1091		plog(LLV_INFO, LOCATION, NULL,
1092		    "purging %s SAs for %s -> %s\n",
1093		    pfkey_satypes[i].ps_name, rem, loc);
1094		if (pfkey_send_delete_all(lcconf->sock_pfkey,
1095		    pfkey_satypes[i].ps_satype, IPSEC_MODE_ANY,
1096		    iph1->remote, iph1->local) == -1) {
1097			plog(LLV_ERROR, LOCATION, NULL,
1098			    "delete_all %s -> %s failed for %s (%s)\n",
1099			    rem, loc,
1100			    pfkey_satypes[i].ps_name, ipsec_strerror());
1101			goto the_hard_way;
1102		}
1103
1104		deleteallph2(iph1->remote, iph1->local, proto_id);
1105	}
1106
1107	racoon_free(loc);
1108	racoon_free(rem);
1109	return;
1110
1111 the_hard_way:
1112	racoon_free(loc);
1113	racoon_free(rem);
1114#endif
1115
1116	buf = pfkey_dump_sadb(SADB_SATYPE_UNSPEC);
1117	if (buf == NULL) {
1118		plog(LLV_DEBUG, LOCATION, NULL,
1119			"pfkey_dump_sadb returned nothing.\n");
1120		return;
1121	}
1122
1123	msg = (struct sadb_msg *)buf->v;
1124	end = (struct sadb_msg *)(buf->v + buf->l);
1125
1126	while (msg < end) {
1127		if ((msg->sadb_msg_len << 3) < sizeof(*msg))
1128			break;
1129		next = (struct sadb_msg *)((caddr_t)msg + (msg->sadb_msg_len << 3));
1130		if (msg->sadb_msg_type != SADB_DUMP) {
1131			msg = next;
1132			continue;
1133		}
1134
1135		if (pfkey_align(msg, mhp) || pfkey_check(mhp)) {
1136			plog(LLV_ERROR, LOCATION, NULL,
1137				"pfkey_check (%s)\n", ipsec_strerror());
1138			msg = next;
1139			continue;
1140		}
1141
1142		if (mhp[SADB_EXT_SA] == NULL
1143		 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
1144		 || mhp[SADB_EXT_ADDRESS_DST] == NULL) {
1145			msg = next;
1146			continue;
1147		}
1148		sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
1149		src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]);
1150		dst = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]);
1151
1152		if (sa->sadb_sa_state != SADB_SASTATE_MATURE
1153		 && sa->sadb_sa_state != SADB_SASTATE_DYING) {
1154			msg = next;
1155			continue;
1156		}
1157
1158		/*
1159		 * RFC2407 4.6.3.3 INITIAL-CONTACT is the message that
1160		 * announces the sender of the message was rebooted.
1161		 * it is interpreted to delete all SAs which source address
1162		 * is the sender of the message.
1163		 * racoon only deletes SA which is matched both the
1164		 * source address and the destination accress.
1165		 */
1166		if (CMPSADDR(iph1->local, src) == 0 &&
1167		    CMPSADDR(iph1->remote, dst) == 0)
1168			;
1169		else if (CMPSADDR(iph1->remote, src) == 0 &&
1170		    CMPSADDR(iph1->local, dst) == 0)
1171			;
1172		else {
1173			msg = next;
1174			continue;
1175		}
1176
1177		/*
1178		 * Make sure this is an SATYPE that we manage.
1179		 * This is gross; too bad we couldn't do it the
1180		 * easy way.
1181		 */
1182		for (i = 0; i < pfkey_nsatypes; i++) {
1183			if (pfkey_satypes[i].ps_satype ==
1184			    msg->sadb_msg_satype)
1185				break;
1186		}
1187		if (i == pfkey_nsatypes) {
1188			msg = next;
1189			continue;
1190		}
1191
1192		plog(LLV_INFO, LOCATION, NULL,
1193			"purging spi=%u.\n", ntohl(sa->sadb_sa_spi));
1194		pfkey_send_delete(lcconf->sock_pfkey,
1195			msg->sadb_msg_satype,
1196			IPSEC_MODE_ANY, src, dst, sa->sadb_sa_spi);
1197
1198		/*
1199		 * delete a relative phase 2 handler.
1200		 * continue to process if no relative phase 2 handler
1201		 * exists.
1202		 */
1203		proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype);
1204		iph2 = getph2bysaidx(src, dst, proto_id, sa->sadb_sa_spi);
1205		if (iph2) {
1206			delete_spd(iph2);
1207			unbindph12(iph2);
1208			remph2(iph2);
1209			delph2(iph2);
1210		}
1211
1212		msg = next;
1213	}
1214
1215	vfree(buf);
1216}
1217
1218/*
1219 * handling to receive Deletion payload
1220 */
1221static int
1222isakmp_info_recv_d(iph1, msg)
1223	struct ph1handle *iph1;
1224	vchar_t *msg;
1225{
1226	struct isakmp_pl_d *d;
1227	int tlen, num_spi;
1228	vchar_t *pbuf;
1229	struct isakmp_parse_t *pa, *pap;
1230	int protected = 0;
1231	union {
1232		u_int32_t spi32;
1233		u_int16_t spi16[2];
1234	} spi;
1235
1236	/* validate the type of next payload */
1237	if (!(pbuf = isakmp_parse(msg)))
1238		return -1;
1239	pa = (struct isakmp_parse_t *)pbuf->v;
1240	for (pap = pa; pap->type; pap++) {
1241		switch (pap->type) {
1242		case ISAKMP_NPTYPE_D:
1243			break;
1244		case ISAKMP_NPTYPE_HASH:
1245			if (pap == pa) {
1246				protected++;
1247				break;
1248			}
1249			plog(LLV_ERROR, LOCATION, iph1->remote,
1250				"received next payload type %d "
1251				"in wrong place (must be the first payload).\n",
1252				pap->type);
1253			vfree(pbuf);
1254			return -1;
1255		default:
1256			/* don't send information, see isakmp_ident_r1() */
1257			plog(LLV_ERROR, LOCATION, iph1->remote,
1258				"reject the packet, "
1259				"received unexpecting payload type %d.\n",
1260				pap->type);
1261			vfree(pbuf);
1262			return 0;
1263		}
1264	}
1265
1266	if (!protected) {
1267		plog(LLV_ERROR, LOCATION, NULL,
1268			"delete payload is not proteted, "
1269			"ignored.\n");
1270		vfree(pbuf);
1271		return -1;
1272	}
1273
1274	/* process a delete payload */
1275	for (pap = pa; pap->type; pap++) {
1276		if (pap->type != ISAKMP_NPTYPE_D)
1277			continue;
1278
1279		d = (struct isakmp_pl_d *)pap->ptr;
1280
1281		if (ntohl(d->doi) != IPSEC_DOI) {
1282			plog(LLV_ERROR, LOCATION, iph1->remote,
1283				"delete payload with invalid doi:%d.\n",
1284				ntohl(d->doi));
1285#ifdef ENABLE_HYBRID
1286			/*
1287			 * At deconnexion time, Cisco VPN client does this
1288			 * with a zero DOI. Don't give up in that situation.
1289			 */
1290			if (((iph1->mode_cfg->flags &
1291			    ISAKMP_CFG_VENDORID_UNITY) == 0) || (d->doi != 0))
1292				continue;
1293#else
1294			continue;
1295#endif
1296		}
1297
1298		num_spi = ntohs(d->num_spi);
1299		tlen = ntohs(d->h.len) - sizeof(struct isakmp_pl_d);
1300
1301		if (tlen != num_spi * d->spi_size) {
1302			plog(LLV_ERROR, LOCATION, iph1->remote,
1303				"deletion payload with invalid length.\n");
1304			vfree(pbuf);
1305			return -1;
1306		}
1307
1308		switch (d->proto_id) {
1309		case IPSECDOI_PROTO_ISAKMP:
1310			if (d->spi_size != sizeof(isakmp_index)) {
1311				plog(LLV_ERROR, LOCATION, iph1->remote,
1312					"delete payload with strange spi "
1313					"size %d(proto_id:%d)\n",
1314					d->spi_size, d->proto_id);
1315				continue;
1316			}
1317
1318			if (iph1->scr)
1319				SCHED_KILL(iph1->scr);
1320
1321			purge_remote(iph1);
1322			break;
1323
1324		case IPSECDOI_PROTO_IPSEC_AH:
1325		case IPSECDOI_PROTO_IPSEC_ESP:
1326			if (d->spi_size != sizeof(u_int32_t)) {
1327				plog(LLV_ERROR, LOCATION, iph1->remote,
1328					"delete payload with strange spi "
1329					"size %d(proto_id:%d)\n",
1330					d->spi_size, d->proto_id);
1331				continue;
1332			}
1333			EVT_PUSH(iph1->local, iph1->remote,
1334			    EVTT_PEER_DELETE, NULL);
1335			purge_ipsec_spi(iph1->remote, d->proto_id,
1336			    (u_int32_t *)(d + 1), num_spi);
1337			break;
1338
1339		case IPSECDOI_PROTO_IPCOMP:
1340			/* need to handle both 16bit/32bit SPI */
1341			memset(&spi, 0, sizeof(spi));
1342			if (d->spi_size == sizeof(spi.spi16[1])) {
1343				memcpy(&spi.spi16[1], d + 1,
1344				    sizeof(spi.spi16[1]));
1345			} else if (d->spi_size == sizeof(spi.spi32))
1346				memcpy(&spi.spi32, d + 1, sizeof(spi.spi32));
1347			else {
1348				plog(LLV_ERROR, LOCATION, iph1->remote,
1349					"delete payload with strange spi "
1350					"size %d(proto_id:%d)\n",
1351					d->spi_size, d->proto_id);
1352				continue;
1353			}
1354			purge_ipsec_spi(iph1->remote, d->proto_id,
1355			    &spi.spi32, num_spi);
1356			break;
1357
1358		default:
1359			plog(LLV_ERROR, LOCATION, iph1->remote,
1360				"deletion message received, "
1361				"invalid proto_id: %d\n",
1362				d->proto_id);
1363			continue;
1364		}
1365
1366		plog(LLV_DEBUG, LOCATION, NULL, "purged SAs.\n");
1367	}
1368
1369	vfree(pbuf);
1370
1371	return 0;
1372}
1373
1374void
1375isakmp_check_notify(gen, iph1)
1376	struct isakmp_gen *gen;		/* points to Notify payload */
1377	struct ph1handle *iph1;
1378{
1379	struct isakmp_pl_n *notify = (struct isakmp_pl_n *)gen;
1380
1381	plog(LLV_DEBUG, LOCATION, iph1->remote,
1382		"Notify Message received\n");
1383
1384	switch (ntohs(notify->type)) {
1385	case ISAKMP_NTYPE_CONNECTED:
1386		plog(LLV_WARNING, LOCATION, iph1->remote,
1387			"ignore CONNECTED notification.\n");
1388		break;
1389	case ISAKMP_NTYPE_RESPONDER_LIFETIME:
1390		plog(LLV_WARNING, LOCATION, iph1->remote,
1391			"ignore RESPONDER-LIFETIME notification.\n");
1392		break;
1393	case ISAKMP_NTYPE_REPLAY_STATUS:
1394		plog(LLV_WARNING, LOCATION, iph1->remote,
1395			"ignore REPLAY-STATUS notification.\n");
1396		break;
1397	case ISAKMP_NTYPE_INITIAL_CONTACT:
1398		plog(LLV_WARNING, LOCATION, iph1->remote,
1399			"ignore INITIAL-CONTACT notification, "
1400			"because it is only accepted after phase1.\n");
1401		break;
1402	case ISAKMP_NTYPE_HEARTBEAT:
1403		plog(LLV_WARNING, LOCATION, iph1->remote,
1404			"ignore HEARTBEAT notification\n");
1405		break;
1406	default:
1407		isakmp_info_send_n1(iph1, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE, NULL);
1408		plog(LLV_ERROR, LOCATION, iph1->remote,
1409			"received unknown notification type %u.\n",
1410		    ntohs(notify->type));
1411	}
1412
1413	return;
1414}
1415
1416
1417#ifdef ENABLE_DPD
1418static int
1419isakmp_info_recv_r_u (iph1, ru, msgid)
1420	struct ph1handle *iph1;
1421	struct isakmp_pl_ru *ru;
1422	u_int32_t msgid;
1423{
1424	struct isakmp_pl_ru *ru_ack;
1425	vchar_t *payload = NULL;
1426	int tlen;
1427	int error = 0;
1428
1429	plog(LLV_DEBUG, LOCATION, iph1->remote,
1430		 "DPD R-U-There received\n");
1431
1432	/* XXX should compare cookies with iph1->index?
1433	   Or is this already done by calling function?  */
1434	tlen = sizeof(*ru_ack);
1435	payload = vmalloc(tlen);
1436	if (payload == NULL) {
1437		plog(LLV_ERROR, LOCATION, NULL,
1438			"failed to get buffer to send.\n");
1439		return errno;
1440	}
1441
1442	ru_ack = (struct isakmp_pl_ru *)payload->v;
1443	ru_ack->h.np = ISAKMP_NPTYPE_NONE;
1444	ru_ack->h.len = htons(tlen);
1445	ru_ack->doi = htonl(IPSEC_DOI);
1446	ru_ack->type = htons(ISAKMP_NTYPE_R_U_THERE_ACK);
1447	ru_ack->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX ? */
1448	ru_ack->spi_size = sizeof(isakmp_index);
1449	memcpy(ru_ack->i_ck, ru->i_ck, sizeof(cookie_t));
1450	memcpy(ru_ack->r_ck, ru->r_ck, sizeof(cookie_t));
1451	ru_ack->data = ru->data;
1452
1453	/* XXX Should we do FLAG_A ?  */
1454	error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N,
1455					ISAKMP_FLAG_E);
1456	vfree(payload);
1457
1458	plog(LLV_DEBUG, LOCATION, NULL, "received a valid R-U-THERE, ACK sent\n");
1459
1460	/* Should we mark tunnel as active ? */
1461	return error;
1462}
1463
1464static int
1465isakmp_info_recv_r_u_ack (iph1, ru, msgid)
1466	struct ph1handle *iph1;
1467	struct isakmp_pl_ru *ru;
1468	u_int32_t msgid;
1469{
1470
1471	plog(LLV_DEBUG, LOCATION, iph1->remote,
1472		 "DPD R-U-There-Ack received\n");
1473
1474	/* XXX Maintain window of acceptable sequence numbers ?
1475	 * => ru->data <= iph2->dpd_seq &&
1476	 *    ru->data >= iph2->dpd_seq - iph2->dpd_fails ? */
1477	if (ntohl(ru->data) != iph1->dpd_seq-1) {
1478		plog(LLV_ERROR, LOCATION, iph1->remote,
1479			 "Wrong DPD sequence number (%d, %d expected).\n",
1480			 ntohl(ru->data), iph1->dpd_seq-1);
1481		return 0;
1482	}
1483
1484	if (memcmp(ru->i_ck, iph1->index.i_ck, sizeof(cookie_t)) ||
1485	    memcmp(ru->r_ck, iph1->index.r_ck, sizeof(cookie_t))) {
1486		plog(LLV_ERROR, LOCATION, iph1->remote,
1487			 "Cookie mismatch in DPD ACK!.\n");
1488		return 0;
1489	}
1490
1491	iph1->dpd_fails = 0;
1492
1493	/* Useless ??? */
1494	iph1->dpd_lastack = time(NULL);
1495
1496	if (iph1->dpd_r_u != NULL)
1497		SCHED_KILL(iph1->dpd_r_u);
1498
1499	isakmp_sched_r_u(iph1, 0);
1500
1501	plog(LLV_DEBUG, LOCATION, NULL, "received an R-U-THERE-ACK\n");
1502
1503	return 0;
1504}
1505
1506
1507/*
1508 * send Delete payload (for ISAKMP SA) in Informational exchange.
1509 */
1510static void
1511isakmp_info_send_r_u(arg)
1512	void *arg;
1513{
1514	struct ph1handle *iph1 = arg;
1515
1516	/* create R-U-THERE payload */
1517	struct isakmp_pl_ru *ru;
1518	vchar_t *payload = NULL;
1519	int tlen;
1520	int error = 0;
1521
1522	plog(LLV_DEBUG, LOCATION, iph1->remote, "DPD monitoring....\n");
1523
1524	if (iph1->dpd_fails >= iph1->rmconf->dpd_maxfails) {
1525		EVT_PUSH(iph1->local, iph1->remote, EVTT_DPD_TIMEOUT, NULL);
1526		purge_remote(iph1);
1527		plog(LLV_DEBUG, LOCATION, iph1->remote,
1528			 "DPD: remote seems to be dead\n");
1529
1530		/* Do not reschedule here: phase1 is deleted,
1531		 * DPD will be reactivated when a new ph1 will be negociated
1532		 */
1533		return;
1534	}
1535
1536	/* TODO: check recent activity to avoid useless sends... */
1537
1538	/* XXX: why do we have a NULL LIST_FIRST even when a Phase2 exists ??? */
1539#if 0
1540	if (LIST_FIRST(&iph1->ph2tree) == NULL){
1541		/* XXX: No Ph2 => no need to test ph1 ?
1542		 */
1543		/* Reschedule the r_u_there....
1544		   XXX: reschedule when a new ph2 ?
1545		 */
1546		isakmp_sched_r_u(iph1, 0);
1547		plog(LLV_DEBUG, LOCATION, iph1->remote,
1548			 "no phase2 handler, rescheduling send_r_u (%d).\n", iph1->rmconf->dpd_interval);
1549		return 0;
1550	}
1551#endif
1552
1553	tlen = sizeof(*ru);
1554	payload = vmalloc(tlen);
1555	if (payload == NULL) {
1556		plog(LLV_ERROR, LOCATION, NULL,
1557			 "failed to get buffer for payload.\n");
1558		return;
1559	}
1560	ru = (struct isakmp_pl_ru *)payload->v;
1561	ru->h.np = ISAKMP_NPTYPE_NONE;
1562	ru->h.len = htons(tlen);
1563	ru->doi = htonl(IPSEC_DOI);
1564	ru->type = htons(ISAKMP_NTYPE_R_U_THERE);
1565	ru->proto_id = IPSECDOI_PROTO_ISAKMP; /* XXX ?*/
1566	ru->spi_size = sizeof(isakmp_index);
1567
1568	memcpy(ru->i_ck, iph1->index.i_ck, sizeof(cookie_t));
1569	memcpy(ru->r_ck, iph1->index.r_ck, sizeof(cookie_t));
1570
1571	if (iph1->dpd_seq == 0){
1572		/* generate a random seq which is not too big */
1573		srand(time(NULL));
1574		iph1->dpd_seq = rand() & 0x0fff;
1575	}
1576
1577	ru->data = htonl(iph1->dpd_seq);
1578
1579	error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, 0);
1580	vfree(payload);
1581
1582	plog(LLV_DEBUG, LOCATION, iph1->remote,
1583		 "DPD R-U-There sent (%d)\n", error);
1584
1585	/* will be decreased if ACK received... */
1586	iph1->dpd_fails++;
1587
1588	/* XXX should be increased only when ACKed ? */
1589	iph1->dpd_seq++;
1590
1591	/* Reschedule the r_u_there with a short delay,
1592	 * will be deleted/rescheduled if ACK received before */
1593	isakmp_sched_r_u(iph1, 1);
1594
1595	plog(LLV_DEBUG, LOCATION, iph1->remote,
1596		 "rescheduling send_r_u (%d).\n", iph1->rmconf->dpd_retry);
1597}
1598
1599/* Schedule a new R-U-THERE */
1600int
1601isakmp_sched_r_u(iph1, retry)
1602	struct ph1handle *iph1;
1603	int retry;
1604{
1605	if(iph1 == NULL ||
1606	   iph1->rmconf == NULL)
1607		return 1;
1608
1609
1610	if(iph1->dpd_support == 0 ||
1611	   iph1->rmconf->dpd_interval == 0)
1612		return 0;
1613
1614	if(retry)
1615		iph1->dpd_r_u = sched_new(iph1->rmconf->dpd_retry,
1616					  isakmp_info_send_r_u, iph1);
1617	else
1618		sched_new(iph1->rmconf->dpd_interval,
1619			  isakmp_info_send_r_u, iph1);
1620
1621	return 0;
1622}
1623#endif
1624