--- old/iked/ike_pfkey.c Fri Mar 27 12:09:51 2009 +++ new/iked/ike_pfkey.c Fri Mar 27 12:09:51 2009 @@ -69,6 +69,7 @@ static int sadb_getspi(struct rcpfk_msg *); static int sadb_acquire_error(struct rcpfk_msg *); +static int sadb_inverse_acquire(struct rcpfk_msg *); static int sadb_update(struct rcpfk_msg *); static int sadb_get(struct rcpfk_msg *); static int sadb_add(struct rcpfk_msg *); @@ -89,6 +90,9 @@ sadb_add, sadb_delete, sadb_get, +#ifdef sun + null_proc, +#endif /* sun/OpenSolaris */ }; /* sadb_responder_request_method for use when receiving IKE_SA_INIT packet */ @@ -99,6 +103,9 @@ sadb_add, sadb_delete, sadb_get, +#ifdef sun + sadb_inverse_acquire, +#endif /* sun/OpenSolaris */ }; /* sadb_rekey_request_method for use when rekeying soft-expired IPsec SA */ @@ -114,6 +121,9 @@ /* sadb_null_method for informational exchange SA */ struct sadb_request_method sadb_null_method = { null_proc, null_proc, null_proc, null_proc, null_proc, null_proc +#ifdef sun + , null_proc +#endif /* sun/OpenSolaris */ }; /* sadb_force_initiate_method for use with isakmp_force_initiate() */ @@ -124,12 +134,15 @@ sadb_add, sadb_delete, sadb_get, +#ifdef sun + null_proc, +#endif /* sun/OpenSolaris */ }; static SADB_LIST_HEAD(sadb_request_list_head, sadb_request) sadb_request_list_head; static int pfkey_socket; -static uint32_t sadb_msg_seq; +static uint32_t my_sadb_seqnum; static int sadb_getspi_callback(struct rcpfk_msg *param); static int sadb_update_callback(struct rcpfk_msg *param); @@ -166,6 +179,8 @@ { struct rcpfk_msg param; + (void) memset(¶m, 0, sizeof (param)); + SADB_LIST_INIT(&sadb_request_list_head); if (debug_pfkey) return 0; @@ -207,7 +222,7 @@ uint32_t sadb_new_seq(void) { - return ++sadb_msg_seq; + return ++my_sadb_seqnum; } static void @@ -229,6 +244,7 @@ { struct rcpfk_msg rcpfk_param; + (void) memset(&rcpfk_param, 0, sizeof (rcpfk_param)); rcpfk_param.so = pfkey_socket; rcpfk_param.flags = 0; if (rcpfk_handler(&rcpfk_param) != 0) { @@ -298,15 +314,45 @@ return err; } +#ifdef sun +static int +sadb_inverse_acquire(struct rcpfk_msg *param) +{ + int err; + + TRACE((PLOGLOC, "sadb_inverse_acquire: seq=%d\n", param->seq)); + + /* param: so, satype, seq, eno */ + param->so = pfkey_socket; + param->flags = 0; + err = rcpfk_send_inverse_acquire(param); + if (err) + log_rcpfk_error("sadb_inverse_acquire", param); + return (err); +} +#endif /* sun/OpenSolaris */ + +#define sa2str_chk(sa) (((sa) == NULL) ? "" : rcs_sa2str(sa)) + static void sadb_log_add(char *op, struct rcpfk_msg *param) { if (param->satype == RCT_SATYPE_ESP) { INFO((PLOGLOC, - "%s ul_proto=%d src=%s dst=%s satype=%s samode=%s spi=0x%08x authtype=%s enctype=%s lifetime soft time=%" + "%s ul_proto=%d src=%s dst=%s " +#ifdef sun + "isrc=%s idst=%s nlc=%s nrm=%s" +#endif + "satype=%s samode=%s spi=0x%08x authtype=%s enctype=%s lifetime soft time=%" PRIu64 " bytes=%" PRIu64 " hard time=%" PRIu64 " bytes=%" PRIu64 "\n", op, param->ul_proto, rcs_sa2str(param->sa_src), - rcs_sa2str(param->sa_dst), rct2str(param->satype), + rcs_sa2str(param->sa_dst), +#ifdef sun + sa2str_chk(param->sa_isrc), sa2str_chk(param->sa_idst), + sa2str_chk(param->sa_natlocal), + sa2str_chk(param->sa_natremote), +#endif + rct2str(param->satype), rct2str(param->samode), ntohl(param->spi), rct2str(param->authtype), rct2str(param->enctype), param->lft_soft_time, param->lft_soft_bytes, @@ -313,10 +359,20 @@ param->lft_hard_time, param->lft_hard_bytes)); } else { INFO((PLOGLOC, - "%s ul_proto=%d src=%s dst=%s satype=%s samode=%s spi=0x%08x authtype=%s lifetime soft time=%" + "%s ul_proto=%d src=%s dst=%s " +#ifdef sun + "isrc=%s idst=%s nlc=%s nrm=%s" +#endif + "satype=%s samode=%s spi=0x%08x authtype=%s lifetime soft time=%" PRIu64 " bytes=%" PRIu64 " hard time=%" PRIu64 " bytes=%" PRIu64 "\n", op, param->ul_proto, rcs_sa2str(param->sa_src), - rcs_sa2str(param->sa_dst), rct2str(param->satype), + rcs_sa2str(param->sa_dst), +#ifdef sun + sa2str_chk(param->sa_isrc), sa2str_chk(param->sa_idst), + sa2str_chk(param->sa_natlocal), + sa2str_chk(param->sa_natremote), +#endif + rct2str(param->satype), rct2str(param->samode), ntohl(param->spi), rct2str(param->authtype), param->lft_soft_time, param->lft_soft_bytes, param->lft_hard_time, @@ -612,6 +668,8 @@ static int sadb_acquire_callback(struct rcpfk_msg *param) { + struct sadb_request *req; + invacq_t *invacq; /* param: seq, satype, sa_src, sa_dst, samode, selid */ /* address(P)??? pid?? identity??? proposal??? */ @@ -620,16 +678,20 @@ param->seq, param->satype, rcs_sa2str(param->sa_src), rcs_sa2str(param->sa_dst), param->samode, param->slid)); - if (sadb_find_by_seq(param->seq)) { - TRACE((PLOGLOC, "duplicate seq %u\n", param->seq)); - return 0; + req = sadb_find_by_seq(param->seq); + if (req != NULL) { + /* Inverse-ACQUIRE. */ + invacq = (invacq_t *)req->sa; + invacq->answer = param; + return (invacq->receiver(invacq)); } - isakmp_initiate(&sadb_initiator_request_method, - param->slid, - param->seq, param->satype, - param->sa_src, param->sa_dst, - param->sa2_src); + if (param->eno != 0) { + /* inverse-ACQUIRE error with no outstanding request. Drop. */ + return (-1); + } + + isakmp_initiate(&sadb_initiator_request_method, param); return 0; }