diff --git src/message.c src/message.c index 1892a33..3dea0d2 100644 --- src/message.c +++ src/message.c @@ -1306,8 +1306,33 @@ guint32 message_ike_auth_i_payload_next(struct session *session, guint32 curr) #ifdef MOBIKE case (N_MOBIKE_SUPPORTED << 8 | IKEV2_PAYLOAD_NOTIFY): - next = IKEV2_PAYLOAD_SA; + + if(session->local_ipv4_addresses_ptr) + next = (N_ADDITIONAL_IP4_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY); + else if(session->local_ipv6_addresses_ptr) + next = (N_ADDITIONAL_IP6_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY); + else + next = IKEV2_PAYLOAD_SA; break; + + case (N_ADDITIONAL_IP4_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY): + + if(session->local_ipv4_addresses_ptr->next) + next = (N_ADDITIONAL_IP4_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY); + else if(session->local_ipv6_addresses_ptr) + next = (N_ADDITIONAL_IP6_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY); + else + next = IKEV2_PAYLOAD_SA; + break; + + case (N_ADDITIONAL_IP6_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY): + + if(session->local_ipv6_addresses_ptr->next) + next = (N_ADDITIONAL_IP4_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY); + else + next = IKEV2_PAYLOAD_SA; + break; + #endif /* MOBIKE */ case IKEV2_PAYLOAD_SA: @@ -1360,9 +1385,26 @@ int message_send_ike_auth_i(struct session *session) guint32 enclen, ilen, payloadid_len = 0; GSList *certs_for_peer; GSList *sig_ca_items = NULL, *hash_ca_items = NULL; +#ifdef MOBIKE + /* + * IPv4 and IPv6 address buffers + */ + unsigned long addr; + char addr6[16]; + + struct network_address *addr_data; + + GSList *lcl4ptr, *lcl6ptr; +#endif /* MOBIKE */ LOG_FUNC_START(1); +#ifdef MOBIKE + session->ike_auth_exchange_counter++; + + session->local_ipv4_addresses_ptr = session->local_ipv4_addresses; + session->local_ipv6_addresses_ptr = session->local_ipv6_addresses; +#endif /* MOBIKE */ retval = -1; buffer = NULL; @@ -1597,6 +1639,33 @@ int message_send_ike_auth_i(struct session *session) LOG_DEBUG("Created MOBIKE_SUPPORTED notification"); LOG_TRACE("Created NOTIFY payload len = %u", len); break; + + case (N_ADDITIONAL_IP4_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY): + lcl4ptr = session->local_ipv4_addresses_ptr; + addr_data = (struct network_address *)(lcl4ptr->data); + addr = 0; + addr_data->netaddr; + /*->sin.sin_addr.s_addr;*/ + + len = payload_notify_mobike_create(next, N_ADDITIONAL_IP4_ADDRESS, + (char *)addr, (guint16)(htons(sizeof(addr))), p); + LOG_DEBUG("Created ADDITIONAL_IP4_ADDRESS notification"); + LOG_TRACE("Created NOTIFY payload len = %u", len); + session->local_ipv4_addresses_ptr = + session->local_ipv4_addresses_ptr->next; + break; + + case (N_ADDITIONAL_IP6_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY): + addr6 = + session->local_ipv6_addresses_ptr->data->netaddr->sin6.sin6_addr.s6_addr; + + len = payload_notify_mobike_create(next, N_ADDITIONAL_IP6_ADDRESS, + addr6, (guint16)(htons(sizeof(addr6))), p); + LOG_DEBUG("Created ADDITIONAL_IP6_ADDRESS notification"); + LOG_TRACE("Created NOTIFY payload len = %u", len); + session->local_ipv6_addresses_ptr = + session->local_ipv6_addresses_ptr->next; + break; #endif /* MOBIKE */ } @@ -1770,8 +1839,33 @@ guint32 message_ike_auth_r_payload_next(struct session *session, guint32 curr) #ifdef MOBIKE case (N_MOBIKE_SUPPORTED << 8 | IKEV2_PAYLOAD_NOTIFY): - next = IKEV2_PAYLOAD_SA; + + if(session->local_ipv4_addresses_ptr) + next = (N_ADDITIONAL_IP4_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY); + else if(session->local_ipv6_addresses_ptr) + next = (N_ADDITIONAL_IP6_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY); + else + next = IKEV2_PAYLOAD_SA; break; + + case (N_ADDITIONAL_IP4_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY): + + if(session->local_ipv4_addresses_ptr->next) + next = (N_ADDITIONAL_IP4_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY); + else if(session->local_ipv6_addresses_ptr) + next = (N_ADDITIONAL_IP6_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY); + else + next = IKEV2_PAYLOAD_SA; + break; + + case (N_ADDITIONAL_IP6_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY): + + if(session->local_ipv6_addresses_ptr->next) + next = (N_ADDITIONAL_IP4_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY); + else + next = IKEV2_PAYLOAD_SA; + break; + #endif /* MOBIKE */ case IKEV2_PAYLOAD_SA: @@ -1826,9 +1920,23 @@ int message_send_ike_auth_r(struct session *session, gpointer payloadid = NULL; int auth_payload_len, payloadid_len = 0; GSList *certs_for_peer; +#ifdef MOBIKE + /* + * IPv4 and IPv6 address buffers + */ + unsigned long addr; + char addr6[16]; + + struct network_address *addr_data; +#endif /* MOBIKE */ LOG_FUNC_START(1); +#ifdef MOBIKE + session->local_ipv4_addresses_ptr = session->local_ipv4_addresses; + session->local_ipv6_addresses_ptr = session->local_ipv6_addresses; +#endif /* MOBIKE */ + /* * Find corresponding CHILD SA structure */ @@ -2022,6 +2130,34 @@ int message_send_ike_auth_r(struct session *session, LOG_DEBUG("Created MOBIKE_SUPPORTED notification"); LOG_TRACE("Created NOTIFY payload len = %u", len); break; + + case (N_ADDITIONAL_IP4_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY): + /* addr_data = (struct netaddr *) */ +/* *((struct network_address *) + g_slist_nth_data(session->local_ipv4_addresses_ptr, 0)); + addr = 0; + addr_data; */ + /*->sin.sin_addr.s_addr;*/ + + len = payload_notify_mobike_create(next, N_ADDITIONAL_IP4_ADDRESS, + (char *)addr, (guint16)(htons(sizeof(addr))), p); + LOG_DEBUG("Created ADDITIONAL_IP4_ADDRESS notification"); + LOG_TRACE("Created NOTIFY payload len = %u", len); + session->local_ipv4_addresses_ptr = + session->local_ipv4_addresses_ptr->next; + break; + + case (N_ADDITIONAL_IP6_ADDRESS << 8 | IKEV2_PAYLOAD_NOTIFY): +/* addr6 = + session->local_ipv6_addresses_ptr->data->netaddr->sin6.sin6_addr.s6_addr; +*/ + len = payload_notify_mobike_create(next, N_ADDITIONAL_IP6_ADDRESS, + addr6, (guint16)(htons(sizeof(addr6))), p); + LOG_DEBUG("Created ADDITIONAL_IP6_ADDRESS notification"); + LOG_TRACE("Created NOTIFY payload len = %u", len); + session->local_ipv6_addresses_ptr = + session->local_ipv6_addresses_ptr->next; + break; #endif /* MOBIKE */ } @@ -4366,9 +4502,27 @@ gint message_parse_ike_auth_i(struct ikev2_header *hdr, gchar *p, guint32 r1, r2; struct cert *cert; struct certreq *certreq; +#ifdef MOBIKE + gboolean no_additional_addresses = FALSE; + struct netaddr *peer_addr; + guint16 mobike_notify_len; +#endif /* MOBIKE */ LOG_FUNC_START(1); +#ifdef MOBIKE + /* + * Create peer's address list of only one element at the moment - + * source address found in header. + */ + if(netaddr_get_family(msg->srcaddr) == AF_INET) + msg->ike_auth.peer_ipv4_addresses = + g_slist_append(NULL, msg->srcaddr); + else if(netaddr_get_family(msg->srcaddr) == AF_INET6) + msg->ike_auth.peer_ipv6_addresses = + g_slist_append(NULL, msg->srcaddr); +#endif /* MOBIKE */ + /* * Assume that error occured... */ @@ -4704,7 +4858,7 @@ gint message_parse_ike_auth_i(struct ikev2_header *hdr, gchar *p, } - LOG_DEBUG("Received N_MOBIKE_SUPPORTED notification!"); + LOG_DEBUG("Received MOBIKE_SUPPORTED notification!"); msg->ike_auth.peer_supports_mobike = TRUE; if ((r2 = message_find_next_payload(&p, &ptype, hdr))) { @@ -4715,6 +4869,63 @@ gint message_parse_ike_auth_i(struct ikev2_header *hdr, gchar *p, np = (struct payload_notify *)p; } + + /* + * Process ADDITIONAL_*_ADDRESS notify payloads + */ + while(ptype == IKEV2_PAYLOAD_NOTIFY && + (ntohs(np->n_type) == N_ADDITIONAL_IP4_ADDRESS || + ntohs(np->n_type) == N_ADDITIONAL_IP6_ADDRESS)) { + + if (payload_notify_check(p) < 0) { + r1 |= MSGPARSE_SEND_NOTIFY; + msg->notify = N_INVALID_SYNTAX; + goto out; + } + + payload_notify_parse(&peer_addr, &mobike_notify_len, p); + + if(ntohs(np->n_type) == N_ADDITIONAL_IP4_ADDRESS) { + LOG_DEBUG("Received ADDITIONAL_IP4_ADDRESS notification"); + msg->ike_auth.peer_ipv4_addresses = g_slist_prepend( + msg->ike_auth.peer_ipv4_addresses, peer_addr); + } + else { + LOG_DEBUG("Received ADDITIONAL_IP4_ADDRESS notification"); + msg->ike_auth.peer_ipv6_addresses = g_slist_prepend( + msg->ike_auth.peer_ipv6_addresses, peer_addr); + } + + if ((r2 = message_find_next_payload(&p, &ptype, hdr))) { + r1 |= (r2 & 0xFFFF0000); + msg->notify = r2 & 0xFFFF; + goto out; + } + + np = (struct payload_notify *)p; + } + + if (ptype == IKEV2_PAYLOAD_NOTIFY && + ntohs(np->n_type) == N_NO_ADDITIONAL_ADDRESSES) { + + if (payload_notify_check(p) < 0) { + r1 |= MSGPARSE_SEND_NOTIFY; + msg->notify = N_INVALID_SYNTAX; + goto out; + } + + no_additional_addresses = TRUE; + + LOG_DEBUG("Received NO_ADDITIONAL_ADDRESSES notification!"); + + if ((r2 = message_find_next_payload(&p, &ptype, hdr))) { + r1 |= (r2 & 0xFFFF0000); + msg->notify = r2 & 0xFFFF; + goto out; + } + + np = (struct payload_notify *)p; + } #endif /* MOBIKE */ if (ptype == IKEV2_PAYLOAD_SA) { @@ -4807,6 +5018,25 @@ gint message_parse_ike_auth_i(struct ikev2_header *hdr, gchar *p, } /* + * Check if we received N_NO_ADDITIONAL_ADDRESSES and if so, + * assert header source address is the only one, hence there was + * no ADDITIONAL_*_ADDRESS notify payload. + */ +#ifdef MOBIKE + if(no_additional_addresses == TRUE) + if((msg->ike_auth.peer_ipv4_addresses && + msg->ike_auth.peer_ipv4_addresses->next) || + (msg->ike_auth.peer_ipv6_addresses && + msg->ike_auth.peer_ipv6_addresses->next)) { + LOG_ERROR("Received notify payload for additional address as" + "well as NO_ADDITIONAL_ADDRESSES"); + r1 |= MSGPARSE_SEND_NOTIFY; + msg->notify = N_INVALID_SYNTAX; + goto out; + } +#endif MOBIKE + + /* * No error occured... */ r1 = 0; @@ -4896,9 +5126,27 @@ gint message_parse_ike_auth_r(struct ikev2_header *hdr, gchar *p, guint32 r1, r2; struct cert *cert; gboolean error; +#ifdef MOBIKE + gboolean no_additional_addresses = FALSE; + struct netaddr *peer_addr; + guint16 mobike_notify_len; +#endif /* MOBIKE */ LOG_FUNC_START(1); +#ifdef MOBIKE + /* + * Create peer's address list of only one element at the moment - + * source address found in header. + */ + if(netaddr_get_family(msg->srcaddr) == AF_INET) + msg->ike_auth.peer_ipv4_addresses = + g_slist_append(NULL, msg->srcaddr); + else if(netaddr_get_family(msg->srcaddr) == AF_INET6) + msg->ike_auth.peer_ipv6_addresses = + g_slist_append(NULL, msg->srcaddr); +#endif /* MOBIKE */ + /* * Assume that error occured... */ @@ -5126,6 +5374,23 @@ gint message_parse_ike_auth_r(struct ikev2_header *hdr, gchar *p, case N_MOBIKE_SUPPORTED: msg->ike_auth.peer_supports_mobike = TRUE; break; + + case N_ADDITIONAL_IP4_ADDRESS: + payload_notify_parse(&peer_addr, &mobike_notify_len, p); + msg->ike_auth.peer_ipv4_addresses = g_slist_prepend( + msg->ike_auth.peer_ipv4_addresses, peer_addr); + break; + + case N_ADDITIONAL_IP6_ADDRESS: + payload_notify_parse(&peer_addr, &mobike_notify_len, p); + msg->ike_auth.peer_ipv6_addresses = g_slist_prepend( + msg->ike_auth.peer_ipv6_addresses, peer_addr); + break; + + case N_NO_ADDITIONAL_ADDRESSES: + no_additional_addresses = TRUE; + break; + #endif /*MOBIKE */ default: @@ -5252,6 +5517,25 @@ out_finish: } /* + * Check if we received N_NO_ADDITIONAL_ADDRESSES and if so, + * assert header source address is the only one, hence there was + * no ADDITIONAL_*_ADDRESS notify payload. + */ +#ifdef MOBIKE + if(no_additional_addresses == TRUE) + if((msg->ike_auth.peer_ipv4_addresses && + msg->ike_auth.peer_ipv4_addresses->next) || + (msg->ike_auth.peer_ipv6_addresses && + msg->ike_auth.peer_ipv6_addresses->next)) { + LOG_ERROR("Received notify payload for additional address as" + "well as NO_ADDITIONAL_ADDRESSES"); + r1 |= MSGPARSE_SEND_NOTIFY; + msg->notify = N_INVALID_SYNTAX; + goto out; + } +#endif MOBIKE + + /* * No error occured... */ r1 = 0; diff --git src/message_msg.h src/message_msg.h index 35912bd..b6231a4 100644 --- src/message_msg.h +++ src/message_msg.h @@ -133,7 +133,7 @@ struct ike_sa_init { struct ike_auth { /** - * Does initiator requested transport mode? + * Has initiator requested transport mode? */ gint transport_mode:1; @@ -245,6 +245,14 @@ struct ike_auth { */ GSList *cert_list; GSList *certreq_list; + + /** + * Lists of remote peer's IPv4 and IPv6 addresses + */ +#ifdef MOBIKE + GSList *peer_ipv4_addresses; + GSList *peer_ipv6_addresses; +#endif /* MOBIKE */ }; /** diff --git src/network.c src/network.c index 342b5de..5069923 100644 --- src/network.c +++ src/network.c @@ -1676,3 +1676,182 @@ out: return retval; } +/** + * Compares two interfaces by name and index. + * + * @param ni1 First interface to compare + * @param ni2 Second interface to compare + * + * \return 1 If two interfaces differ by name or index or both + * 0 Otherwise + */ +int network_compare_interfaces(struct netif *ni1, struct netif *ni2) { + + LOG_FUNC_START(1); + + if(strcmp(netif_get_name(ni1), netif_get_name(ni2))) + return 1; + + LOG_FUNC_END(1); + + return ni1->if_index == ni2->if_index ? 0 : 1; +} + +/** + * Compares interfaces in two network_data structures. + * + * @param data1 First network_data data which interfaces are to be compared + * @param data2 Second network_data data to be compared to data1 interfaces + * + * \return 1 If interfaces in data1 and data2 differ + * 0 otherwise + */ +int network_compare_interface_lists(struct network_data *data1, + struct network_data *data2) { + + int retval; + GSList *list1, *list2; + + LOG_FUNC_START(1); + + retval = 0; + + list1 = data1->interfaces; + list2 = data2->interfaces; + + /* + * Iterate through both interface lists one interface at a time + */ + while(list1 && list2 && !retval) { + + if(network_compare_interfaces(list1->data, list2->data)) + retval = 1; + + list1 = list1->next; + list2 = list2->next; + } + + if(list1 || list2) + retval = 1; + + LOG_FUNC_END(1); + + return retval; +} + + +/** + * Compares addresses in two network_data structures. + * + * @param data1 First network_data data which addresses are to be compared + * @param data2 Second network_data data to be compared to data1 addresses + * + * \return 1 If addresses in data1 and data2 differ + * 0 otherwise + */ +int network_compare_address_lists(struct network_data *data1, + struct network_data *data2) { + + int retval; + GSList *list1, *list2; + struct network_address *a1, *a2; + + LOG_FUNC_START(1); + + retval = 0; + + list1 = data1->addresses; + list2 = data2->addresses; + + /* + * Iterate through both address lists one address at a time + */ + while(list1 && list2 && !retval) { + + a1 = (struct network_addresss *)(list1->data); + a2 = (struct network_addresss *)(list2->data); + + if(netaddr_same_family(a1->netaddr, a2->netaddr)) { + if(netaddr_cmp_ip2ip(a1->netaddr, a2->netaddr)) + retval = 1; + } + else + retval = 1; + + + list1 = list1->next; + list2 = list2->next; + } + + if(list1 || list2) + retval = 1; + + LOG_FUNC_END(1); + + return retval; +} + +/** + * Checks for changes in network interfaces and addresses. + */ +void network_check_links() { + + struct network_data *network_data_new; + gboolean queue_message; + + LOG_FUNC_START(1); + + network_data_new = g_malloc0(sizeof(struct network_data)); + queue_message = FALSE; + + /* + * TODO: what does context represent? + */ + network_data_new->context = NULL; + + /* + * Lock interfaces and addresses in network_data for reading + */ + g_static_rw_lock_reader_lock(&network_data->interfaces_lock); + g_static_rw_lock_reader_lock(&network_data->addresses_lock); + + if (network_enumerate_interfaces(network_data_new) < 0) + goto out; + + /* + * Search for IPv4 addresses + */ + if (network_enumerate_addresses(network_data_new, AF_INET) < 0) + goto out; + + /* + * Search for IPv6 addresses + */ + if (network_enumerate_addresses(network_data_new, AF_INET6) < 0) + goto out; + + /* + * Compare interfaces and addresses + */ + if(network_compare_interface_lists(network_data_new, network_data)) + queue_message = TRUE; + else if(network_compare_address_lists(network_data_new, network_data)) + queue_message = TRUE; + + /* + * Send message to some queue if interfaces or addresses have changed + */ + if(queue_message == TRUE) { + /* + * Tu treba poslati neku poruku (treba ju oblikovati) u neki red. + * Netko po primitku te poruke treba izbrisati postojei automat + * stanja parova IP adresa + */ + } + +out: + g_static_rw_lock_reader_unlock(&network_data->interfaces_lock); + g_static_rw_lock_reader_unlock(&network_data->addresses_lock); + + LOG_FUNC_END(1); +} diff --git src/network.h src/network.h index f928577..9a6d519 100644 --- src/network.h +++ src/network.h @@ -181,8 +181,8 @@ struct network_data { * * TODO: This has to be converted into hash indexed by interface name */ + GStaticRWLock interfaces_lock; GSList *interfaces; - }; #else /* __NETWORK_C */ diff --git src/payload.c src/payload.c index 1cd2f20..79e274f 100644 --- src/payload.c +++ src/payload.c @@ -1157,6 +1157,10 @@ gint32 payload_notify_parse(void **data, guint16 *notify_data_len, char *p) p += sizeof(struct payload_notify); ntype = ntohs(np->n_type); + /* + * Be careful about this check because MOBIKE introduces + * new notify payloads with ntype > 16395 + */ if (ntype == 0 || (ntype > 39 && ntype < 16384) || (ntype > 16395)) { @@ -1227,6 +1231,19 @@ gint32 payload_notify_parse(void **data, guint16 *notify_data_len, char *p) *((guint32 *)(*data)) = *((guint32 *)p); break; +#ifdef MOBIKE + case N_MOBIKE_SUPPORTED: + case NO_ADDITIONAL_ADDRESSES: + break; + + case N_ADDITIONAL_IP4_ADDRESS: + case N_ADDITIONAL_IP4_ADDRESS: + *data = p; + *notify_data_len = ntohs(np->length) - + sizeof(struct payload_notify); + break; +#endif /* MOBIKE */ + default: printf ("ERROR: Unknown/unsupported notify (0x%x) in " "%s:%s:%d\n", diff --git src/session.c src/session.c index 9569983..7c0aae9 100644 --- src/session.c +++ src/session.c @@ -123,6 +123,14 @@ struct session *session_new(void) session->embedded_sm_msg = NULL; + session->peer_addresses = NULL; + +#ifdef MOBIKE + ike_auth_exchange_counter = 0; + + session_local_addresses_init(session); +#endif /* MOBIKE */ + LOG_FUNC_END(2); return session; @@ -251,6 +259,7 @@ gboolean session_free(struct session *session) if (session->sent_resp_mux) g_mutex_free(session->sent_resp_mux); + if (session) g_free (session); } else { @@ -1093,3 +1102,47 @@ gboolean session_use_radius(struct session *session) #endif return FALSE; } + +#ifdef MOBIKE +GSList *session_add_address(GSList *list, + struct netaddr *addr) { + + GSList *new_address = NULL; + + LOG_FUNC_START(1); + + new_address = g_slist_prepend(new_address, addr); + new_address = g_slist_prepend(list, new_address); + + LOG_FUNC_END(1); + + return new_address; +} + +void session_local_addresses_init(struct session *session) { + + GSList *network_data_iterator; + struct network_address *addr; + + LOG_FUNC_START(1); + + network_data_iterator = network_data->addresses; + + session->local_ipv4_addresses = NULL; + session->local_ipv6_addresses = NULL; + + while(network_data_iterator) { + addr = (struct network_address *)network_data_iterator->data; + if(addr->netaddr->sin->sa.sa_family == AF_INET) + session->local_ipv4_addresses = + session_add_address(session->local_ipv4_addresses, addr); + else + session->local_ipv6_addresses = + session_add_address(session->local_ipv6_addresses, addr); + + network_data_iterator = network_data_iterator->next; + } + + LOG_FUNC_END(1); +} +#endif /* MOBIKE */ diff --git src/session.h src/session.h index ed6202e..0747754 100644 --- src/session.h +++ src/session.h @@ -92,6 +92,41 @@ #define MAX_HALF_OPENED_SESSIONS 2 /** + * Structure for holding local and remote addresses making pair of addresses + * in a IP addresses state machine. + */ +struct pair_of_addresses { + /** + * One of initiator's and one of responder's addresses. + * + * Those addresses also hold ports! + */ + struct netaddr *i_addr, *r_addr; + + /** + * State of address pair in IP Address Pair State Machine. + * + * Possible states are: + * + * ADDRESS_PAIR_INVALID 0 + * ADDRESS_PAIR_VALID 1 + * ADDRESS_PAIR_NEGOTIATING 2 + * ADDRESS_PAIR_ACTIVE 3 + * ADDRESS_PAIR_TRANSITING 4 + * ADDRESS_PAIR_INEXISTING 5 + * + * Default state is ADDRESS_PAIR_INVALID. + */ + guint8 state; + + /** + * These are the time fields for return routability check timeout. + */ + GTimeVal rrc_timeout; + timeout_t *to; +}; + +/** * In the following structure all the fields marked as transient are * valid only throughout some particular lifetime of IKE SA, e.g. * during cration, rekeying, reautentification, etc. @@ -288,6 +323,24 @@ struct session { */ struct netaddr *i_addr, *r_addr; + /** + * List of remote peer's IPv4 and IPv6 addresses + */ + GSList *peer_ipv4_addresses; + GSList *peer_ipv6_addresses; + + /** + * List of pair of addresses, their states and timeouts in + * IP address state machine in MOBIKE. + * One pair consists of initiator's address and of respodnder's address. + */ + GSList *pair_of_addresses_list; + /** + * Pointer to active address from pair_of_addresses_list list + * TODO: This variable should replace i_addr and r_addr variables. + */ + GSList *active_address_pair; + #ifdef SUPPLICANT /** * Pointer to a structure with EAP states @@ -452,6 +505,35 @@ struct session { */ #ifdef MOBIKE gboolean mobike_supported; + + /** + * Counter for IKE AUTH exchanges. It serves for determining if + * particular exchange contains SA payload, hence 1st IKE AUTH + * exchange. + */ + guint8 ike_auth_exchange_counter; + + /* + * Lists of local IP addresses initialized in network_init() function. + * Temporary pointers are needed for ADDITIONAL_*_ADDRESS notify + * payloads in IKE AUTH and INFORMATIONAL exchanges. + */ + GSList *local_ipv4_addresses; + GSList *local_ipv6_addresses; + + GSList *local_ipv4_addresses_ptr; + GSList *local_ipv6_addresses_ptr; + + /** + * FIXME + * If we are to switch to MOBIKE port (4500) to send IKE_AUTH and + * it turns out that remote peer does not support MOBIKE for this + * connection, we need to switch to ports set previously. That + * could be IKEV2_PORT_NATT (4500), default port (500) as well as + * any other set by any party + */ + guint16 previous_port_i; + guint16 previous_port_r; #endif /* MOBIKE */ #ifdef CFG_CLIENT @@ -537,19 +619,6 @@ struct session { * pass). This complicates code with many #ifdef's and if's. */ union sm_msg *embedded_sm_msg; - - /** - * FIXME - * If we are to switch to MOBIKE port (4500) to send IKE_AUTH and - * it turns out that remote peer does not support MOBIKE for this - * connection, we need to switch to ports set previously. That - * could be IKEV2_PORT_NATT (4500), default port (500) as well as - * any other set by any party - */ -#ifdef MOBIKE - guint16 previous_port_i; - guint16 previous_port_r; -#endif /* MOBIKE */ }; /******************************************************************************* @@ -661,6 +730,8 @@ struct sad_item *session_sad_item_find_by_msg_id(struct session *, guint32); int session_crypto_material(struct session *); gboolean session_use_radius(struct session *); + +GSList *session_add_peer_address(struct session *, struct netaddr *); /******************************************************************************* * DEBUG METHODS ******************************************************************************/ diff --git src/sm.c src/sm.c index 25df5f2..368a00d 100644 --- src/sm.c +++ src/sm.c @@ -4420,7 +4420,7 @@ int sm_ike_i_thread(struct session *session, union sm_msg *sm_msg) } /* - * Check if we received notify INVALID_SYNTAX. In that case + * Check if we received notify NO_PROPOSAL_CHOSEN. In that case * terminate IKE SA.. */ if (sm_msg->message_msg.ike_sa_init.no_proposal_chosen) {