/**
 * This function stores the LOCATOR parameter into the hadb entry
 * of a connection in question. The whole LOCATOR is stored and
 * handled later as the LOCATOR is received before the connection
 * state has reached ESTABLISHED (UPDATEs are not allowed before
 * the state is ESTABLISHED) and the address verification is
 * handled later during the BEX (after receiving the R2).
 *
 * @param packet_type The packet type of the control message (RFC 5201, 5.3.)
 * @param ha_state The host association state (RFC 5201, 4.4.1.)
 * @param ctx Pointer to the packet context, containing all information for
 *            the packet handling (received message, source and destination
 *            address, the ports and the corresponding entry from the host
 *            association database).
 *
 * @return zero on success, or negative error value on error.
 */
int hip_handle_locator(UNUSED const uint8_t packet_type,
                       UNUSED const uint32_t ha_state,
                       struct hip_packet_context *ctx)
{
    const struct hip_locator *locator = NULL;
    int                       n_addrs = 0, loc_size = 0, err = 0;

    locator = hip_get_param(ctx->input_msg, HIP_PARAM_LOCATOR);
    if (locator) {
        n_addrs  = hip_get_locator_addr_item_count(locator);
        loc_size = sizeof(struct hip_locator) +
                   (n_addrs * sizeof(struct hip_locator_info_addr_item));

        /* this handle function is called during BEX, there should be no
         * locators yet. */
        HIP_ASSERT(!ctx->hadb_entry->locator);

        HIP_IFEL(!(ctx->hadb_entry->locator = malloc(loc_size)),
                 -1, "Malloc for entry->locators failed\n");
        memcpy(ctx->hadb_entry->locator, locator, loc_size);
    } else {
        HIP_DEBUG("R1 did not have locator\n");
    }

out_err:
    return err;
}
Exemple #2
0
/**
 * handle_locator_value - This function copies the 2nd address (ipv4) from
 * the locator from packet returned from lookup
 * 
 * @param *packet response returned from the lookup service
 * @param *locator_ipv4 opaque pointer passed to point to the ipv4 address
 * @return status of the operation 0 on success, -1 on failure
 */
int handle_locator_value (unsigned char *packet, void *locator_ipv4)
{
	struct hip_locator *locator;
	struct hip_locator_info_addr_item *locator_address_item = NULL;
	int locator_item_count = 0;
	struct in6_addr addr6;
	struct in_addr addr4;
   
	locator = hip_get_param((struct hip_common *)packet, HIP_PARAM_LOCATOR);

	if (locator) {
		locator_item_count = hip_get_locator_addr_item_count(locator);
		locator_item_count--;
		locator_address_item = hip_get_locator_first_addr_item(locator);
		memcpy(&addr6, 
			(struct in6_addr*)&locator_address_item[locator_item_count].address, 
				sizeof(struct in6_addr));
		if (IN6_IS_ADDR_V4MAPPED(&addr6)) {
			IPV6_TO_IPV4_MAP(&addr6, &addr4);
			sprintf((char*)locator_ipv4, "%s", inet_ntoa(addr4));
		} else {
			hip_in6_ntop(&addr6, (char*)locator_ipv4);
			_HIP_DEBUG("Value: %s\n", (char*)locator_ipv4);
		}
		return 0 ;
	} else
		return -1;	
}
/**
 * Handle LOCATOR parameter in first update packet.
 *
 * @param packet_type The packet type of the control message (RFC 5201, 5.3.)
 * @param ha_state The host association state (RFC 5201, 4.4.1.)
 * @param ctx Pointer to the packet context, containing all information for
 *             the packet handling (received message, source and destination
 *             address, the ports and the corresponding entry from the host
 *             association database).
 *
 * @return zero on success, or negative error value on error.
 */
int hip_handle_locator_parameter(UNUSED const uint8_t packet_type,
                                 UNUSED const uint32_t ha_state,
                                 struct hip_packet_context *ctx)
{
    int                                locator_addr_count   = 0;
    union hip_locator_info_addr       *locator_info_addr    = NULL;
    struct hip_locator_info_addr_item *locator_address_item = NULL;
    struct update_state               *localstate           = NULL;
    struct hip_locator                *locator              = NULL;

    if (hip_classify_update_type(ctx->input_msg) == FIRST_UPDATE_PACKET) {
        if (!(locator = hip_get_param_readwrite(ctx->input_msg,
                                                HIP_PARAM_LOCATOR))) {
            HIP_ERROR("no LOCATOR parameter found\n");
            return -1;
        }

        locator_addr_count = hip_get_locator_addr_item_count(locator);

        HIP_DEBUG("LOCATOR has %d address(es), loc param len=%d\n",
                  locator_addr_count, hip_get_param_total_len(locator));

        // Empty the addresses_to_send_echo_request list before adding the
        // new addresses
        localstate = lmod_get_state_item(ctx->hadb_entry->hip_modular_state,
                                         "update");

        HIP_DEBUG("hip_get_state_item returned localstate: %p\n", localstate);
        hip_remove_addresses_to_send_echo_request(localstate);

        locator_address_item = (struct hip_locator_info_addr_item *) (locator + 1);

        HIP_DEBUG_IN6ADDR("Adding IP source address to locator set",
                          &ctx->src_addr);

        if (!hip_add_address_to_send_echo_request(localstate, ctx->src_addr)) {
            HIP_ERROR("Adding source address to the container for update locators failed!\n");
            return -1;
        }

        for (int i = 0; i < locator_addr_count; i++) {
            locator_info_addr = hip_get_locator_item(locator_address_item, i);
            const struct in6_addr *const peer_addr = hip_get_locator_item_address(locator_info_addr);

            if (ipv6_addr_cmp(&ctx->src_addr, peer_addr) != 0) {
                HIP_DEBUG_IN6ADDR("adding locator", peer_addr);
                if (!hip_add_address_to_send_echo_request(localstate, *peer_addr)) {
                    HIP_ERROR("Adding an address to the container for update locators failed!\n");
                    return -1;
                }
            }
        }

        hip_print_addresses_to_send_update_request(ctx->hadb_entry);
    }

    return 0;
}