return;
}
+int
+satrns_remove_from_list(struct satrns **listptr, struct satrns *trns)
+{
+
+ struct satrns **ptr = listptr;
+
+ if (ptr == NULL)
+ return -1;
+
+ while (*ptr) {
+ if (*ptr == trns) {
+ *ptr = trns->next;
+ ptr = &trns->next;
+ trns->next = NULL;
+ return 0;
+ }
+ ptr = &((*ptr)->next);
+ }
+ return -1;
+}
+
+#ifdef ENABLE_NATT
+static void
+saprop_udp_encap (struct saproto *pr)
+{
+ switch (pr->encmode) {
+ case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC:
+ case IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT:
+ pr->encmode = IPSECDOI_ATTR_ENC_MODE_TUNNEL;
+ pr->udp_encap = 1;
+ break;
+ case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC:
+ case IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT:
+ pr->encmode = IPSECDOI_ATTR_ENC_MODE_TRNS;
+ pr->udp_encap = 1;
+ break;
+ }
+}
+
+static void
+saprop_adjust_encmode (struct saproto *pr2, struct saproto *pr1)
+{
+ int prev;
+
+ if (natt_udp_encap(pr2->encmode)) {
+ prev = pr2->encmode;
+ saprop_udp_encap(pr2);
+ plog(ASL_LEVEL_INFO, "Adjusting my encmode %s(%d)->%s(%d)\n",
+ s_ipsecdoi_encmode(prev),
+ prev,
+ s_ipsecdoi_encmode(pr2->encmode),
+ pr2->encmode);
+ }
+ if (natt_udp_encap(pr1->encmode)) {
+ prev = pr1->encmode;
+ saprop_udp_encap(pr1);
+ plog(ASL_LEVEL_INFO, "Adjusting peer's encmode %s(%d)->%s(%d)\n",
+ s_ipsecdoi_encmode(prev),
+ prev,
+ s_ipsecdoi_encmode(pr1->encmode),
+ pr1->encmode);
+ }
+}
+#endif // ENABLE_NATT
+
/*
* take a single match between saprop. allocate a new proposal and return it
* for future use (like picking single proposal from a bundle).
*/
struct saprop *
cmpsaprop_alloc(ph1, pp1, pp2, side)
- struct ph1handle *ph1;
+ phase1_handle_t *ph1;
const struct saprop *pp1, *pp2;
int side;
{
newpp = newsaprop();
if (newpp == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to allocate saprop.\n");
return NULL;
}
case PROP_CHECK_STRICT:
if (pp1->lifetime > pp2->lifetime) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"long lifetime proposed: "
"my:%d peer:%d\n",
(int)pp2->lifetime, (int)pp1->lifetime);
goto err;
}
if (pp1->lifebyte > pp2->lifebyte) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"long lifebyte proposed: "
"my:%d peer:%d\n",
pp2->lifebyte, pp1->lifebyte);
prop_pfs_check:
if (pp2->pfs_group != 0 && pp1->pfs_group != pp2->pfs_group) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"pfs group mismatched: "
"my:%d peer:%d\n",
pp2->pfs_group, pp1->pfs_group);
} else {
newpp->lifetime = pp2->lifetime;
newpp->claim |= IPSECDOI_ATTR_SA_LD_TYPE_SEC;
- plog(LLV_NOTIFY, LOCATION, NULL,
+ plog(ASL_LEVEL_NOTICE,
"use own lifetime: "
"my:%d peer:%d\n",
(int)pp2->lifetime, (int)pp1->lifetime);
if (pp1->lifebyte > pp2->lifebyte) {
newpp->lifebyte = pp2->lifebyte;
newpp->claim |= IPSECDOI_ATTR_SA_LD_TYPE_SEC;
- plog(LLV_NOTIFY, LOCATION, NULL,
+ plog(ASL_LEVEL_NOTICE,
"use own lifebyte: "
"my:%d peer:%d\n",
pp2->lifebyte, pp1->lifebyte);
case PROP_CHECK_EXACT:
if (pp1->lifetime != pp2->lifetime) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"lifetime mismatched: "
"my:%d peer:%d\n",
(int)pp2->lifetime, (int)pp1->lifetime);
}
if (pp1->lifebyte != pp2->lifebyte) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"lifebyte mismatched: "
"my:%d peer:%d\n",
pp2->lifebyte, pp1->lifebyte);
goto err;
}
if (pp1->pfs_group != pp2->pfs_group) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"pfs group mismatched: "
"my:%d peer:%d\n",
pp2->pfs_group, pp1->pfs_group);
break;
default:
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"invalid pcheck_level why?.\n");
goto err;
}
break;
if (pr1->proto_id != pr2->proto_id) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"proto_id mismatched: "
"my:%s peer:%s\n",
s_ipsecdoi_proto(pr2->proto_id),
spisizematch = 1;
}
if (spisizematch) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"IPComp SPI size promoted "
"from 16bit to 32bit\n");
}
}
if (!spisizematch) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"spisize mismatched: "
"my:%d peer:%d\n",
(int)pr2->spisize, (int)pr1->spisize);
goto err;
}
-#ifdef ENABLE_NATT
- if ((ph1->natt_flags & NAT_DETECTED) &&
- natt_udp_encap (pr2->encmode))
- {
- plog(LLV_INFO, LOCATION, NULL, "Adjusting my encmode %s->%s\n",
- s_ipsecdoi_encmode(pr2->encmode),
- s_ipsecdoi_encmode(pr2->encmode - ph1->natt_options->mode_udp_diff));
- pr2->encmode -= ph1->natt_options->mode_udp_diff;
- pr2->udp_encap = 1;
- }
-
- if ((ph1->natt_flags & NAT_DETECTED) &&
- natt_udp_encap (pr1->encmode))
- {
- plog(LLV_INFO, LOCATION, NULL, "Adjusting peer's encmode %s(%d)->%s(%d)\n",
- s_ipsecdoi_encmode(pr1->encmode),
- pr1->encmode,
- s_ipsecdoi_encmode(pr1->encmode - ph1->natt_options->mode_udp_diff),
- pr1->encmode - ph1->natt_options->mode_udp_diff);
- pr1->encmode -= ph1->natt_options->mode_udp_diff;
- pr1->udp_encap = 1;
+#ifdef ENABLE_NATT
+ if (ph1->natt_flags & NAT_DETECTED) {
+ saprop_adjust_encmode(pr2, pr1);
}
#endif
if (pr1->encmode != pr2->encmode) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"encmode mismatched: "
"my:%s peer:%s\n",
s_ipsecdoi_encmode(pr2->encmode),
found:
newpr = newsaproto();
if (newpr == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to allocate saproto.\n");
goto err;
}
newtr = newsatrns();
if (newtr == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to allocate satrns.\n");
+ racoon_free(newpr);
goto err;
}
newtr->trns_no = tr1->trns_no;
const struct saprop *pp1, *pp2;
{
if (pp1->pfs_group != pp2->pfs_group) {
- plog(LLV_WARNING, LOCATION, NULL,
+ plog(ASL_LEVEL_WARNING,
"pfs_group mismatch. mine:%d peer:%d\n",
pp1->pfs_group, pp2->pfs_group);
/* FALLTHRU */
}
if (pp1->lifetime > pp2->lifetime) {
- plog(LLV_WARNING, LOCATION, NULL,
+ plog(ASL_LEVEL_WARNING,
"less lifetime proposed. mine:%d peer:%d\n",
(int)pp1->lifetime, (int)pp2->lifetime);
/* FALLTHRU */
}
if (pp1->lifebyte > pp2->lifebyte) {
- plog(LLV_WARNING, LOCATION, NULL,
+ plog(ASL_LEVEL_WARNING,
"less lifebyte proposed. mine:%d peer:%d\n",
pp1->lifebyte, pp2->lifebyte);
/* FALLTHRU */
const struct satrns *tr1, *tr2;
{
if (tr1->trns_id != tr2->trns_id) {
- plog(LLV_WARNING, LOCATION, NULL,
+ plog(ASL_LEVEL_DEBUG,
"trns_id mismatched: "
"my:%s peer:%s\n",
s_ipsecdoi_trns(proto_id, tr2->trns_id),
}
if (tr1->authtype != tr2->authtype) {
- plog(LLV_WARNING, LOCATION, NULL,
+ plog(ASL_LEVEL_DEBUG,
"authtype mismatched: "
"my:%s peer:%s\n",
s_ipsecdoi_attr_v(IPSECDOI_ATTR_AUTH, tr2->authtype),
* the initiator. It should be defined a notify message.
*/
if (tr1->encklen > tr2->encklen) {
- plog(LLV_WARNING, LOCATION, NULL,
+ plog(ASL_LEVEL_WARNING,
"less key length proposed, "
"mine:%d peer:%d. Use initiaotr's one.\n",
tr2->encklen, tr1->encklen);
}
int
-set_satrnsbysainfo(pr, sainfo)
- struct saproto *pr;
- struct sainfo *sainfo;
+set_satrnsbysainfo(struct saproto *pr, struct sainfo *sainfo, u_int8_t ike_version, int pfs_group)
{
struct sainfoalg *a, *b;
struct satrns *newtr;
switch (pr->proto_id) {
case IPSECDOI_PROTO_IPSEC_AH:
if (sainfo->algs[algclass_ipsec_auth] == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"no auth algorithm found\n");
goto err;
}
/* allocate satrns */
newtr = newsatrns();
if (newtr == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to allocate satrns.\n");
goto err;
}
newtr->trns_no = t++;
- newtr->trns_id = ipsecdoi_authalg2trnsid(a->alg);
+ newtr->trns_id = ipsecdoi_authalg2trnsid(a->alg); // IKEv1 only
newtr->authtype = a->alg;
inssatrns(pr, newtr);
break;
case IPSECDOI_PROTO_IPSEC_ESP:
if (sainfo->algs[algclass_ipsec_enc] == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"no encryption algorithm found\n");
goto err;
}
t = 1;
- for (a = sainfo->algs[algclass_ipsec_enc]; a; a = a->next) {
- for (b = sainfo->algs[algclass_ipsec_auth]; b; b = b->next) {
- /* allocate satrns */
- newtr = newsatrns();
- if (newtr == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
- "failed to allocate satrns.\n");
- goto err;
- }
-
- newtr->trns_no = t++;
- newtr->trns_id = a->alg;
- newtr->encklen = a->encklen;
- newtr->authtype = b->alg;
-
- inssatrns(pr, newtr);
- }
- }
+ if (ike_version == ISAKMP_VERSION_NUMBER_IKEV1) {
+ for (a = sainfo->algs[algclass_ipsec_enc]; a; a = a->next) {
+ for (b = sainfo->algs[algclass_ipsec_auth]; b; b = b->next) {
+ /* allocate satrns */
+ newtr = newsatrns();
+ if (newtr == NULL) {
+ plog(ASL_LEVEL_ERR,
+ "failed to allocate satrns.\n");
+ goto err;
+ }
+
+ newtr->trns_no = t++;
+ newtr->trns_id = a->alg;
+ newtr->encklen = a->encklen;
+ newtr->authtype = b->alg;
+
+ inssatrns(pr, newtr);
+ }
+ }
+ }
break;
case IPSECDOI_PROTO_IPCOMP:
if (sainfo->algs[algclass_ipsec_comp] == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"no ipcomp algorithm found\n");
goto err;
}
/* allocate satrns */
newtr = newsatrns();
if (newtr == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to allocate satrns.\n");
goto err;
}
}
break;
default:
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"unknown proto_id (%d).\n", pr->proto_id);
goto err;
}
-
+
/* no proposal found */
if (pr->head == NULL) {
- plog(LLV_ERROR, LOCATION, NULL, "no algorithms found.\n");
+ plog(ASL_LEVEL_ERR, "no algorithms found.\n");
return -1;
}
/* allocate ipsec a sa proposal */
newpp = newsaprop();
if (newpp == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to allocate saprop.\n");
return NULL;
}
/* allocate ipsec sa protocol */
newpr = newsaproto();
if (newpr == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to allocate saproto.\n");
goto err;
}
/* check spi size */
/* XXX should be handled isakmp cookie */
if (sizeof(newpr->spi) < p->prop->spi_size) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"invalid spi size %d.\n", p->prop->spi_size);
+ racoon_free(newpr);
goto err;
}
for (t = p; t; t = t->tnext) {
- plog(LLV_DEBUG, LOCATION, NULL,
+ plog(ASL_LEVEL_DEBUG,
"prop#=%d prot-id=%s spi-size=%d "
"#trns=%d trns#=%d trns-id=%s\n",
t->prop->p_no,
/* allocate ipsec sa transform */
newtr = newsatrns();
if (newtr == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to allocate satrns.\n");
+ racoon_free(newpr);
goto err;
}
- if (ipsecdoi_t2satrns(t->trns, newpp, newpr, newtr) < 0) {
+ if (ipsecdoi_t2satrns(t->trns,
+ newpp, newpr, newtr) < 0) {
flushsaprop(newpp);
+ racoon_free(newtr);
+ racoon_free(newpr);
return NULL;
}
const struct saprop *p;
if (pp == NULL) {
- plog(pri, LOCATION, NULL, "(null)");
+ plog(pri, "(null)");
return;
}
if (pr == NULL)
return;
- plog(pri, LOCATION, NULL,
+ plog(pri,
" (proto_id=%s spisize=%d spi=%08lx spi_p=%08lx "
"encmode=%s reqid=%d:%d)\n",
s_ipsecdoi_proto(pr->proto_id),
switch (proto_id) {
case IPSECDOI_PROTO_IPSEC_AH:
- plog(pri, LOCATION, NULL,
+ plog(pri,
" (trns_id=%s authtype=%s)\n",
s_ipsecdoi_trns(proto_id, tr->trns_id),
s_ipsecdoi_attr_v(IPSECDOI_ATTR_AUTH, tr->authtype));
break;
case IPSECDOI_PROTO_IPSEC_ESP:
- plog(pri, LOCATION, NULL,
+ plog(pri,
" (trns_id=%s encklen=%d authtype=%s)\n",
s_ipsecdoi_trns(proto_id, tr->trns_id),
tr->encklen,
s_ipsecdoi_attr_v(IPSECDOI_ATTR_AUTH, tr->authtype));
break;
case IPSECDOI_PROTO_IPCOMP:
- plog(pri, LOCATION, NULL,
+ plog(pri,
" (trns_id=%s)\n",
s_ipsecdoi_trns(proto_id, tr->trns_id));
break;
default:
- plog(pri, LOCATION, NULL,
+ plog(pri,
"(unknown proto_id %d)\n", proto_id);
}
spc[level] = '\0';
}
- plog(pri, LOCATION, NULL,
+ plog(pri,
"%s%p: next=%p tnext=%p\n", spc, p, p->next, p->tnext);
if (p->next)
print_proppair0(pri, p->next, level + 1);
int
set_proposal_from_policy(iph2, sp_main, sp_sub)
- struct ph2handle *iph2;
+ phase2_handle_t *iph2;
struct secpolicy *sp_main, *sp_sub;
{
struct saprop *newpp;
newpp = newsaprop();
if (newpp == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to allocate saprop.\n");
goto err;
}
newpp->prop_no = 1;
newpp->lifetime = iph2->sainfo->lifetime;
newpp->lifebyte = iph2->sainfo->lifebyte;
- newpp->pfs_group = iph2->sainfo->pfs_group;
+ newpp->pfs_group = iph2->sainfo->pfs_group;
+ //%%%% to do - verify DH group is OK - tried that here and iphone failed to connect
+
if (lcconf->complex_bundle)
goto skip1;
* me +--- SA1 ---+ peer1
* me +--- SA2 --------------+ peer2
*/
-#ifdef __linux__
- if (req->saidx.src.ss_family && req->saidx.dst.ss_family) {
-#else
if (req->saidx.src.ss_len && req->saidx.dst.ss_len) {
-#endif
/* check the end of ip addresses of SA */
if (iph2->side == INITIATOR)
paddr = (caddr_t)&req->saidx.dst;
/* allocate ipsec sa protocol */
newpr = newsaproto();
if (newpr == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to allocate saproto.\n");
goto err;
}
else
newpr->spisize = 4;
if (lcconf->complex_bundle) {
- newpr->encmode = pfkey2ipsecdoi_mode(req->saidx.mode);
+ encmodesv = newpr->encmode = pfkey2ipsecdoi_mode(req->saidx.mode);
#ifdef ENABLE_NATT
if (iph2->ph1 && (iph2->ph1->natt_flags & NAT_DETECTED))
newpr->encmode += iph2->ph1->natt_options->mode_udp_diff;
#endif
}
else
- newpr->encmode = encmodesv;
-
+ encmodesv = newpr->encmode = encmodesv;
if (iph2->side == INITIATOR)
newpr->reqid_out = req->saidx.reqid;
else
newpr->reqid_in = req->saidx.reqid;
- if (set_satrnsbysainfo(newpr, iph2->sainfo) < 0) {
- plog(LLV_ERROR, LOCATION, NULL,
+ if (set_satrnsbysainfo(newpr, iph2->sainfo, iph2->version, newpp->pfs_group) < 0) {
+ plog(ASL_LEVEL_ERR,
"failed to get algorithms.\n");
+ racoon_free(newpr);
goto err;
}
req = req->next;
}
if (pr || req) {
- plog(LLV_NOTIFY, LOCATION, NULL,
+ plog(ASL_LEVEL_NOTICE,
"There is a difference "
"between the in/out bound policies in SPD.\n");
}
iph2->proposal = newpp;
- printsaprop0(LLV_DEBUG, newpp);
+ ike_session_update_mode(iph2);
+
+ printsaprop0(ASL_LEVEL_DEBUG, newpp);
return 0;
err:
+ if (newpp)
+ flushsaprop(newpp);
return -1;
}
*/
int
set_proposal_from_proposal(iph2)
- struct ph2handle *iph2;
+ phase2_handle_t *iph2;
{
struct saprop *newpp = NULL, *pp0, *pp_peer = NULL;
struct saproto *newpr = NULL, *pr;
- struct prop_pair **pair;
+ struct prop_pair **pair = NULL;
int error = -1;
int i;
/* get proposal pair */
- pair = get_proppair(iph2->sa, IPSECDOI_TYPE_PH2);
+ if (iph2->version == ISAKMP_VERSION_NUMBER_IKEV1)
+ pair = get_proppair(iph2->sa, IPSECDOI_TYPE_PH2);
+
if (pair == NULL)
goto end;
for (i = 0; i < MAXPROPPAIRLEN; i++) {
if (pair[i] == NULL)
continue;
+
+ if (pp_peer != NULL)
+ flushsaprop(pp_peer);
+
pp_peer = aproppair2saprop(pair[i]);
if (pp_peer == NULL)
goto end;
pp0 = newsaprop();
if (pp0 == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to allocate saprop.\n");
goto end;
}
pp0->pfs_group = iph2->sainfo->pfs_group;
if (pp_peer->next != NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"pp_peer is inconsistency, ignore it.\n");
/*FALLTHROUGH*/
}
newpr = newsaproto();
if (newpr == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
+ plog(ASL_LEVEL_ERR,
"failed to allocate saproto.\n");
+ racoon_free(pp0);
goto end;
}
newpr->proto_id = pr->proto_id;
newpr->spi_p = pr->spi; /* copy peer's SPI */
newpr->reqid_in = 0;
newpr->reqid_out = 0;
- }
- if (set_satrnsbysainfo(newpr, iph2->sainfo) < 0) {
- plog(LLV_ERROR, LOCATION, NULL,
- "failed to get algorithms.\n");
- goto end;
+ if (set_satrnsbysainfo(newpr, iph2->sainfo, iph2->version, 0) < 0) {
+ plog(ASL_LEVEL_ERR,
+ "failed to get algorithms.\n");
+ racoon_free(newpr);
+ racoon_free(pp0);
+ goto end;
+ }
+ inssaproto(pp0, newpr);
}
- inssaproto(pp0, newpr);
inssaprop(&newpp, pp0);
}
- plog(LLV_DEBUG, LOCATION, NULL, "make a proposal from peer's:\n");
- printsaprop0(LLV_DEBUG, newpp);
+ plog(ASL_LEVEL_DEBUG, "make a proposal from peer's:\n");
+ printsaprop0(ASL_LEVEL_DEBUG, newpp);
iph2->proposal = newpp;
+ ike_session_update_mode(iph2);
+
error = 0;
end:
if (pp_peer)
flushsaprop(pp_peer);
- free_proppair(pair);
+ if (pair)
+ free_proppair(pair);
return error;
}
return 1;
return 0;
}
+
+struct satrns *
+dupsatrns_1(struct satrns *tr)
+{
+ struct satrns *newtr;
+
+ newtr = racoon_calloc(1, sizeof(*newtr));
+ if (newtr == NULL)
+ return NULL;
+ newtr->trns_no = tr->trns_no;
+ newtr->trns_id = tr->trns_id;
+ newtr->encklen = tr->encklen;
+ newtr->authtype = tr->authtype;
+
+ return newtr;
+}
+
+void
+dupsatrns(newpr, head)
+ struct saproto *newpr;
+ struct satrns *head;
+{
+ struct satrns *p, *newtr;
+
+ for (p = head; p != NULL; p = p->next) {
+ newtr = newsatrns();
+ if (newtr) {
+ newtr->trns_no = p->trns_no;
+ newtr->trns_id = p->trns_id;
+ newtr->encklen = p->encklen;
+ newtr->authtype = p->authtype;
+ inssatrns(newpr, newtr);
+ } else {
+ break;
+ }
+
+ }
+
+ return;
+}
+
+void
+dupsaproto(newpp, head, ignore_spis)
+ struct saprop *newpp;
+ struct saproto *head;
+ int ignore_spis;
+{
+ struct saproto *p, *newpr;
+
+ for (p = head; p != NULL; p = p->next) {
+ newpr = newsaproto();
+ if (newpr) {
+ newpr->proto_id = p->proto_id;
+ newpr->spisize = p->spisize;
+ newpr->encmode = p->encmode;
+ newpr->udp_encap = p->udp_encap;
+ if (!ignore_spis) {
+ newpr->spi = p->spi;
+ newpr->spi_p = p->spi_p;
+ newpr->reqid_in = p->reqid_in;
+ newpr->reqid_out = p->reqid_out;
+ }
+ dupsatrns(newpr, p->head);
+ inssaproto(newpp, newpr);
+ } else {
+ break;
+ }
+
+ }
+
+ return;
+}
+
+struct saprop *
+dupsaprop(head, ignore_spis)
+ struct saprop *head;
+ int ignore_spis;
+{
+ struct saprop *p, *newpp;
+
+ for (p = head, newpp = NULL; p != NULL; p = p->next) {
+ struct saprop *tmp = newsaprop();
+ if (tmp) {
+ tmp->prop_no = p->prop_no;
+ tmp->lifetime = p->lifetime;
+ tmp->lifebyte = p->lifebyte;
+ tmp->pfs_group = p->pfs_group;
+ tmp->claim = p->claim;
+ dupsaproto(tmp, p->head, ignore_spis);
+ inssaprop(&newpp, tmp);
+ } else {
+ break;
+ }
+ }
+
+ return newpp;
+}