- /* Create the Initiator Request */
- {
- ike_header_t *ike0;
- u32 bi0 = 0;
- ip_lookup_main_t *lm = &im->lookup_main;
- u32 if_add_index0;
- int len = sizeof (ike_header_t);
-
- /* Get own iface IP */
- if_add_index0 =
- lm->if_address_pool_index_by_sw_if_index[p->responder.sw_if_index];
- ip_interface_address_t *if_add =
- pool_elt_at_index (lm->if_address_pool, if_add_index0);
- ip4_address_t *if_ip = ip_interface_address_get_address (lm, if_add);
-
- bi0 = ikev2_get_new_ike_header_buff (vm, &ike0);
-
- /* Prepare the SA and the IKE payload */
- ikev2_sa_t sa;
- clib_memset (&sa, 0, sizeof (ikev2_sa_t));
- ikev2_payload_chain_t *chain = 0;
- ikev2_payload_new_chain (chain);
-
- /* Build the IKE proposal payload */
- ikev2_sa_proposal_t *proposals = 0;
- ikev2_set_initiator_proposals (vm, &sa, &p->ike_ts, &proposals, 1);
- proposals[0].proposal_num = 1;
- proposals[0].protocol_id = IKEV2_PROTOCOL_IKE;
-
- /* Add and then cleanup proposal data */
- ikev2_payload_add_sa (chain, proposals);
- ikev2_sa_free_proposal_vector (&proposals);
-
- sa.is_initiator = 1;
- sa.profile = p;
- sa.state = IKEV2_STATE_SA_INIT;
- ikev2_generate_sa_init_data (&sa);
- ikev2_payload_add_ke (chain, sa.dh_group, sa.i_dh_data);
- ikev2_payload_add_nonce (chain, sa.i_nonce);
-
- /* Build the child SA proposal */
- vec_resize (sa.childs, 1);
- ikev2_set_initiator_proposals (vm, &sa, &p->esp_ts,
- &sa.childs[0].i_proposals, 0);
- sa.childs[0].i_proposals[0].proposal_num = 1;
- sa.childs[0].i_proposals[0].protocol_id = IKEV2_PROTOCOL_ESP;
- RAND_bytes ((u8 *) & sa.childs[0].i_proposals[0].spi,
- sizeof (sa.childs[0].i_proposals[0].spi));
-
-
-
- /* Add NAT detection notification messages (mandatory) */
- u8 nat_detection_source[8 + 8 + 4 + 2];
- u8 *nat_detection_sha1 = vec_new (u8, 20);
-
- u64 tmpspi = clib_host_to_net_u64 (sa.ispi);
- clib_memcpy_fast (&nat_detection_source[0], &tmpspi, sizeof (tmpspi));
- tmpspi = clib_host_to_net_u64 (sa.rspi);
- clib_memcpy_fast (&nat_detection_source[8], &tmpspi, sizeof (tmpspi));
- u16 tmpport = clib_host_to_net_u16 (500);
- clib_memcpy_fast (&nat_detection_source[8 + 8 + 4], &tmpport,
- sizeof (tmpport));
- u32 tmpip = clib_host_to_net_u32 (if_ip->as_u32);
- clib_memcpy_fast (&nat_detection_source[8 + 8], &tmpip, sizeof (tmpip));
- SHA1 (nat_detection_source, sizeof (nat_detection_source),
- nat_detection_sha1);
- ikev2_payload_add_notify (chain, IKEV2_NOTIFY_MSG_NAT_DETECTION_SOURCE_IP,
- nat_detection_sha1);
- tmpip = clib_host_to_net_u32 (p->responder.ip4.as_u32);
- clib_memcpy_fast (&nat_detection_source[8 + 8], &tmpip, sizeof (tmpip));
- SHA1 (nat_detection_source, sizeof (nat_detection_source),
- nat_detection_sha1);
- ikev2_payload_add_notify (chain,
- IKEV2_NOTIFY_MSG_NAT_DETECTION_DESTINATION_IP,
- nat_detection_sha1);
- vec_free (nat_detection_sha1);
-
- u8 *sig_hash_algo = vec_new (u8, 8);
- u64 tmpsig = clib_host_to_net_u64 (0x0001000200030004);
- clib_memcpy_fast (sig_hash_algo, &tmpsig, sizeof (tmpsig));
- ikev2_payload_add_notify (chain,
- IKEV2_NOTIFY_MSG_SIGNATURE_HASH_ALGORITHMS,
- sig_hash_algo);
- vec_free (sig_hash_algo);
-
-
- /* Buffer update and boilerplate */
- len += vec_len (chain->data);
- ike0->nextpayload = chain->first_payload_type;
- ike0->length = clib_host_to_net_u32 (len);
- clib_memcpy_fast (ike0->payload, chain->data, vec_len (chain->data));
- ikev2_payload_destroy_chain (chain);
-
- ike0->version = IKE_VERSION_2;
- ike0->flags = IKEV2_HDR_FLAG_INITIATOR;
- ike0->exchange = IKEV2_EXCHANGE_SA_INIT;
- ike0->ispi = sa.ispi;
-
- /* store whole IKE payload - needed for PSK auth */
- vec_free (sa.last_sa_init_req_packet_data);
- vec_add (sa.last_sa_init_req_packet_data, ike0, len);
-
- /* add data to the SA then add it to the pool */
- sa.iaddr.as_u32 = if_ip->as_u32;
- sa.raddr.as_u32 = p->responder.ip4.as_u32;
- sa.i_id.type = p->loc_id.type;
- sa.i_id.data = vec_dup (p->loc_id.data);
- sa.i_auth.method = p->auth.method;
- sa.i_auth.hex = p->auth.hex;
- sa.i_auth.data = vec_dup (p->auth.data);
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
- clib_memcpy_fast (sa.i_auth.key, p->auth.key,
- EVP_PKEY_size (p->auth.key));
-#else
- sa.i_auth.key = vec_dup (p->auth.key);
-#endif
- vec_add (sa.childs[0].tsi, &p->loc_ts, 1);
- vec_add (sa.childs[0].tsr, &p->rem_ts, 1);