diff -ruN freeswan-1.5.orig/pluto/ipsec_doi.c freeswan-1.5/pluto/ipsec_doi.c
--- freeswan-1.5.orig/pluto/ipsec_doi.c	Wed Jun 21 14:24:32 2000
+++ freeswan-1.5/pluto/ipsec_doi.c	Thu Oct  5 09:08:12 2000
@@ -53,6 +53,15 @@
 #define RETURN_STF_FAILURE(f) \
     { int r = (f); if (r != NOTHING_WRONG) return STF_FAIL + r; }
 
+stf_status send_delete(struct state *p2st, ipsec_spi_t *spi, bool ESP);
+static bool encrypt_message(pb_stream *pbs, struct state *st);
+
+/* needed for PGPnet Vendor ID */
+char pgp_vid[] = { 0x4f, 0x70, 0x65, 0x6e, 
+		   0x50, 0x47, 0x50, 0x31, 
+		   0x30, 0x31, 0x37, 0x31};
+	
+
 /* if we haven't already done so, compute a local DH secret (st->st_sec) and
  * the corresponding public value (g).  This is emitted as a KE payload.
  */
@@ -257,6 +266,121 @@
 //    }
 //}
 #endif /* not currently used */
+
+
+ stf_status
+ send_delete(struct state *p2st, ipsec_spi_t *spi, bool ESP)
+ {
+     
+     pb_stream reply_pbs;
+     pb_stream r_hdr_pbs;
+     msgid_t	msgid;
+     u_char 	old_new_iv[MAX_DIGEST_LEN];
+     u_char 	old_iv[MAX_DIGEST_LEN];         
+     u_char buffer[8192];
+     struct state *p1st;
+     
+     u_char spilen = sizeof(ipsec_spi_t);
+     u_char
+ 	*r_hashval,	/* where in reply to jam hash value */
+ 	*r_hash_start;	/* start of what is to be hashed */
+     
+     memset(buffer, '\0', sizeof(buffer));
+     init_pbs(&reply_pbs, buffer, sizeof(buffer), "delete msg");
+ 
+     /* find the related P1-State to the calling P2-state */
+     p1st = find_state(p2st->st_icookie, p2st->st_rcookie, 
+     			p2st->st_connection->that.host_addr, 0);
+     if (p1st == NULL) 
+     {
+ 	DBG_log("no phase 1 state where one should be");
+	return STF_INTERNAL_ERROR;
+     }
+ 
+     msgid = generate_msgid(p1st);
+
+     /* HDR* */
+     {
+ 	struct isakmp_hdr hdr;
+ 
+ 	hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;
+ 	hdr.isa_np = ISAKMP_NEXT_HASH;
+ 	hdr.isa_xchg = ISAKMP_XCHG_INFO;
+ 	hdr.isa_msgid = msgid;
+ 	hdr.isa_flags = ISAKMP_FLAG_ENCRYPTION;
+ 	memcpy(hdr.isa_icookie, p1st->st_icookie, COOKIE_SIZE);
+ 	memcpy(hdr.isa_rcookie, p1st->st_rcookie, COOKIE_SIZE);
+ 	if (!out_struct(&hdr, &isakmp_hdr_desc, &reply_pbs, &r_hdr_pbs))
+ 	    return STF_INTERNAL_ERROR;
+     }
+ 
+     /* HASH -- space to be filled later */
+     {
+ 	pb_stream hash_pbs;
+ 
+ 	if (!out_generic(ISAKMP_NEXT_D, &isakmp_hash_desc, &r_hdr_pbs, &hash_pbs))
+     	    return STF_INTERNAL_ERROR;
+ 	r_hashval = hash_pbs.cur;	/* remember where to plant value */
+ 	if (!out_zero(p1st->st_oakley.hasher->hash_digest_len, &hash_pbs, "HASH(1)"))
+ 	    return STF_INTERNAL_ERROR;
+ 	close_output_pbs(&hash_pbs);
+ 	r_hash_start = r_hdr_pbs.cur;	/* hash from after HASH(1) */
+     }
+ 
+     /* DELETE PAYLOAD */
+     {
+ 	pb_stream del_pbs;
+ 	struct isakmp_delete isad;
+ 	
+        isad.isad_doi = ISAKMP_DOI_IPSEC;
+ 	isad.isad_np = ISAKMP_NEXT_NONE;
+ 	isad.isad_spisize = spilen;
+        if (ESP) isad.isad_protoid = PROTO_IPSEC_ESP;
+        else isad.isad_protoid = PROTO_IPSEC_AH;
+ 	isad.isad_nospi = 0x0001;
+         if (!out_struct(&isad, &isakmp_delete_desc, &r_hdr_pbs, &del_pbs))
+ 	    return STF_INTERNAL_ERROR;
+ 	if (!out_raw(spi, spilen, &del_pbs, "delete payload"))
+ 	    return STF_INTERNAL_ERROR;;
+         close_output_pbs(&del_pbs);
+     }
+     
+     {
+         struct hmac_ctx ctx;
+ 	hmac_init_chunk(&ctx, p1st->st_oakley.hasher, p1st->st_skeyid_a);
+         hmac_update(&ctx, (u_char *) &msgid, sizeof(msgid_t));
+         hmac_update(&ctx, r_hash_start, r_hdr_pbs.cur-r_hash_start);
+ 	hmac_final(r_hashval, &ctx);
+ 
+         DBG(DBG_CRYPT,
+     	    DBG_log("HASH(1) computed:");
+ 	    DBG_dump("", r_hashval, ctx.hmac_digest_len));
+     }
+ 
+     /* save old IV (this prevents from copying a whole new state object 
+      * for NOTIFICATION / DELETE messages we don't need to maintain a state
+      * because there are no retransmissions...
+      */
+      
+     memcpy(old_new_iv, p1st->st_new_iv, p1st->st_new_iv_len);
+     memcpy(old_iv, p1st->st_iv, p1st->st_iv_len);
+     init_phase2_iv(p1st, &msgid);
+ 
+     if(!encrypt_message(&r_hdr_pbs, p1st)) passert(FALSE);
+     
+     clonetochunk(p1st->st_tpacket, reply_pbs.start, pbs_offset(&reply_pbs)
+ 	, "reply packet for main_outI1");
+ 
+     send_packet(p1st, "delete notify");
+     
+     /* get back old IV for this state */
+     memcpy(p1st->st_new_iv, old_new_iv, p1st->st_new_iv_len);
+     memcpy(p1st->st_iv, old_iv, p1st->st_iv_len);    
+     
+     return STF_IGNORE; 
+}
+ 
+
 
 /* The whole message must be a multiple of 4 octets.
  * I'm not sure where this is spelled out, but look at
diff -ruN freeswan-1.5.orig/pluto/kernel.c freeswan-1.5/pluto/kernel.c
--- freeswan-1.5.orig/pluto/kernel.c	Wed Jun 21 14:24:33 2000
+++ freeswan-1.5/pluto/kernel.c	Thu Oct  5 09:08:12 2000
@@ -48,6 +48,7 @@
 #include "server.h"
 #include "whack.h"	/* for RC_LOG_SERIOUS */
 
+extern int send_delete(struct state *st, ipsec_spi_t *spi, bool ESP);
 
 bool no_klips = FALSE;	/* don't actually use KLIPS */
 
@@ -1003,6 +1004,8 @@
     {
 	passert(FALSE);	/* neither AH nor ESP in outbound SA bundle! */
     }
+
+    send_delete(st, &f->our_spi, proto==SA_ESP?TRUE:FALSE);
 
     return inbound
 	? del_spi(f->our_spi, proto, c->that.host_addr, c->this.host_addr)
