/** * Handle ECHO_REQUEST_UNSIGNED parameter. * * @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_echo_request_param(UNUSED const uint8_t packet_type, UNUSED const uint32_t ha_state, struct hip_packet_context *ctx) { const struct hip_echo_request *echo_request = NULL; int err = 0; if (!(echo_request = hip_get_param(ctx->input_msg, HIP_PARAM_ECHO_REQUEST))) { HIP_DEBUG("no ECHO_REQUEST parameter in UPDATE packet, skipping\n"); /* This condition is no error! There simply was no request by the peer * to add a ECHO_RESPONSE parameter to the outbound message. */ return 0; } HIP_DEBUG("echo opaque data len=%d\n", hip_get_param_contents_len(echo_request)); HIP_HEXDUMP("ECHO_REQUEST ", (const uint8_t *) echo_request + sizeof(struct hip_tlv_common), hip_get_param_contents_len(echo_request)); HIP_IFEL(hip_build_param_echo(ctx->output_msg, (const uint8_t *) echo_request + sizeof(struct hip_tlv_common), hip_get_param_contents_len(echo_request), 0, 0), -1, "Building of ECHO_RESPONSE failed\n"); out_err: return err; }
/** * Add ECHO_REQUEST parameter to second 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_add_echo_request_param(UNUSED const uint8_t packet_type, UNUSED const uint32_t ha_state, struct hip_packet_context *ctx) { int err = 0; if (hip_classify_update_type(ctx->input_msg) == FIRST_UPDATE_PACKET) { // Randomize the echo response opaque data before sending ECHO_REQUESTS. // Notice that we're using the same opaque value for the identical // UPDATE packets sent between different address combinations. RAND_bytes(ctx->hadb_entry->echo_data, sizeof(ctx->hadb_entry->echo_data)); HIP_HEXDUMP("ECHO_REQUEST in the host association", ctx->hadb_entry->echo_data, sizeof(ctx->hadb_entry->echo_data)); if (hip_build_param_echo(ctx->output_msg, ctx->hadb_entry->echo_data, sizeof(ctx->hadb_entry->echo_data), 1, 1)) { HIP_ERROR("Building of ECHO_REQUEST failed\n"); return -1; } } return err; }
/* getter function for a specific element of the given hash chain * * @param hash_chain hash chain from which the element should be returned * @param idx index to the hash chain element * @return element of the given hash chain */ static unsigned char *hchain_element_by_index(const struct hash_chain *hash_chain, const int idx) { unsigned char *element = NULL; int err = 0; HIP_ASSERT(hash_chain); if (idx >= 0 && idx < hash_chain->hchain_length) { element = &hash_chain->elements[idx * hash_chain->hash_length]; } else { HIP_ERROR("Element from uninited hash chain or out-of-bound element requested!"); err = -1; goto out_err; } HIP_HEXDUMP("Hash chain element: ", element, hash_chain->hash_length); out_err: if (err) { element = NULL; } return element; }
/** checks if a hash is verifiable by a hash chain * * @param current_hash the hash value to be verified * @param last_hash the last known hash value * @param hash_func the hash function to be used * @param hash_length length of the hash values * @param tolerance the maximum number of hash calculations * @param secret the potentially incorporated secret * @param secret_length length og the secret * @return hash distance if the hash authentication was successful, 0 otherwise */ int hchain_verify(const unsigned char *current_hash, const unsigned char *last_hash, const hash_function hash_func, const int hash_length, const int tolerance, const unsigned char *secret, const int secret_length) { /* stores intermediate hash results and allow to concat * with a secret at each step */ unsigned char buffer[MAX_HASH_LENGTH + secret_length]; int err = 0, i; HIP_ASSERT(current_hash != NULL && last_hash != NULL); HIP_ASSERT(hash_func != NULL); HIP_ASSERT(hash_length > 0 && tolerance >= 0); // init buffer with the hash we want to verify memcpy(buffer, current_hash, hash_length); if (secret && secret_length > 0) { HIP_HEXDUMP("secret: ", secret, secret_length); } for (i = 1; i <= tolerance; i++) { // add the secret if (secret != NULL && secret_length > 0) { memcpy(&buffer[hash_length], secret, secret_length); } hash_func(buffer, hash_length + secret_length, buffer); // compare the elements if (!(memcmp(buffer, last_hash, hash_length))) { HIP_DEBUG("hash verfied\n"); err = i; goto out_err; } } HIP_DEBUG("no matches found within tolerance: %i!\n", tolerance); out_err: return err; }
/** creates the anchor element message * * @param hcstore the BEX store * @param use_hash_trees indicates whether hash chains or hash trees are stored * @return the message on success, NULL on error * * @note this will only consider the first hchain item in each shelf, as only * this should be set up for the store containing the hchains for the BEX * @note the created message contains hash_length and anchors for each transform */ static struct hip_common *create_bex_store_update_msg(struct hchain_store *hcstore, const int use_hash_trees) { struct hip_common *msg = NULL; struct esp_prot_tfm *transform = NULL; struct hash_chain *hchain = NULL; struct hash_tree *htree = NULL; unsigned char *anchor = NULL; unsigned j = 0; uint8_t i = 0; int hash_length = 0, num_hchains = 0, err = 0, hash_item_length = 0; HIP_ASSERT(hcstore != NULL); HIP_IFEL(!(msg = malloc(HIP_MAX_PACKET)), -1, "failed to allocate memory\n"); hip_msg_init(msg); HIP_IFEL(hip_build_user_hdr(msg, HIP_MSG_BEX_STORE_UPDATE, 0), -1, "build hdr failed\n"); // first add hash_length and num_hchain for each transform for (i = 1; i <= NUM_TRANSFORMS; i++) { HIP_IFEL(!(transform = esp_prot_resolve_transform(token_transform)), -1, "failed to resolve transform\n"); HIP_IFEL((hash_length = esp_prot_get_hash_length(token_transform)) <= 0, -1, "hash_length <= 0, expecting something bigger\n"); HIP_IFEL((num_hchains = hip_ll_get_size(&hcstore->hchain_shelves[transform->hash_func_id] [transform->hash_length_id]. hchains[DEFAULT_HCHAIN_LENGTH_ID][NUM_BEX_HIERARCHIES - 1])) <= 0, -1, "num_hchains <= 0, expecting something higher\n"); // tell hipd about transform HIP_IFEL(hip_build_param_contents(msg, &token_transform, HIP_PARAM_UINT, sizeof(uint8_t)), -1, "build param contents failed\n"); HIP_DEBUG("added esp_transform: %u\n", token_transform); // add num_hchains for this transform, needed on receiver side HIP_IFEL(hip_build_param_contents(msg, &num_hchains, HIP_PARAM_INT, sizeof(int)), -1, "build param contents failed\n"); HIP_DEBUG("added num_hchains: %i\n", num_hchains); // add the hash_length for this transform, needed on receiver side HIP_IFEL(hip_build_param_contents(msg, &hash_length, HIP_PARAM_INT, sizeof(int)), -1, "build param contents failed\n"); HIP_DEBUG("added hash_length: %i\n", hash_length); } // now add the hchain anchors for (i = 1; i <= NUM_TRANSFORMS; i++) { HIP_IFEL(!(transform = esp_prot_resolve_transform(token_transform)), -1, "failed to resolve transform\n"); HIP_IFEL((hash_length = esp_prot_get_hash_length(token_transform)) <= 0, -1, "hash_length <= 0, expecting something bigger\n"); // ensure correct boundaries HIP_ASSERT(transform->hash_func_id >= 0 && transform->hash_func_id < NUM_HASH_FUNCTIONS); HIP_ASSERT(transform->hash_length_id >= 0 && transform->hash_length_id < NUM_HASH_LENGTHS); // add anchor with this transform for (j = 0; j < hip_ll_get_size(&hcstore->hchain_shelves[transform->hash_func_id] [transform->hash_length_id]. hchains[DEFAULT_HCHAIN_LENGTH_ID][NUM_BEX_HIERARCHIES - 1]); j++) { if (use_hash_trees) { HIP_IFEL(!(htree = hip_ll_get(&hcstore->hchain_shelves[transform->hash_func_id] [transform->hash_length_id].hchains[DEFAULT_HCHAIN_LENGTH_ID][NUM_BEX_HIERARCHIES - 1], j)), -1, "failed to retrieve htree\n"); anchor = htree->root; hash_item_length = htree->num_data_blocks; } else { HIP_IFEL(!(hchain = hip_ll_get(&hcstore->hchain_shelves[transform->hash_func_id] [transform->hash_length_id].hchains[DEFAULT_HCHAIN_LENGTH_ID][NUM_BEX_HIERARCHIES - 1], j)), -1, "failed to retrieve hchain\n"); anchor = hchain_get_anchor(hchain); hash_item_length = hchain->hchain_length; } HIP_IFEL(hip_build_param_contents(msg, anchor, HIP_PARAM_HCHAIN_ANCHOR, hash_length), -1, "build param contents failed\n"); HIP_HEXDUMP("added anchor: ", anchor, hash_length); // also send the hchain/htree length for each item HIP_IFEL(hip_build_param_contents(msg, &hash_item_length, HIP_PARAM_INT, sizeof(int)), -1, "build param contents failed\n"); HIP_DEBUG("added hash_item_length: %i\n", hash_item_length); } } out_err: if (err) { free(msg); msg = NULL; } return msg; }
/** handles the TPA specific parts in the setup of new IPsec SAs * * @param msg the HIP message * @param esp_prot_transform the TPA transform (return value) * @param num_anchors number of anchor in the array * @param esp_prot_anchors array storing the anchors * @param hash_item_length length of the employed hash structure at the peer (return value) * @return 0 on success, -1 on error */ int esp_prot_handle_sa_add_request(const struct hip_common *msg, uint8_t *esp_prot_transform, uint16_t *num_anchors, unsigned char (*esp_prot_anchors)[MAX_HASH_LENGTH], uint32_t *hash_item_length) { const struct hip_tlv_common *param = NULL; int hash_length = 0, err = 0; const unsigned char *anchor = NULL; uint16_t i; *num_anchors = 0; *esp_prot_transform = 0; HIP_ASSERT(msg != NULL); HIP_ASSERT(esp_prot_transform != NULL); HIP_ASSERT(num_anchors != NULL); HIP_IFEL(!(param = hip_get_param(msg, HIP_PARAM_ESP_PROT_TFM)), -1, "esp prot transform missing\n"); *esp_prot_transform = *((const uint8_t *) hip_get_param_contents_direct(param)); HIP_DEBUG("esp protection transform is %u\n", *esp_prot_transform); // this parameter is only included, if the esp extension is used if (*esp_prot_transform > ESP_PROT_TFM_UNUSED) { // retrieve hash length for the received transform HIP_IFEL((hash_length = esp_prot_get_hash_length(*esp_prot_transform)) <= 0, -1, "error or tried to resolve UNUSED transform\n"); HIP_IFEL(!(param = hip_get_param(msg, HIP_PARAM_ITEM_LENGTH)), -1, "transform suggests hash_item_length, but it is NOT included in msg\n"); *hash_item_length = *((const uint32_t *) hip_get_param_contents_direct(param)); HIP_DEBUG("esp protection item length: %u\n", *hash_item_length); HIP_IFEL(!(param = hip_get_next_param(msg, param)), -1, "transform suggests num_anchors, but it is NOT included in msg\n"); *num_anchors = *((const uint16_t *) hip_get_param_contents_direct(param)); HIP_DEBUG("esp protection number of transferred anchors: %u\n", *num_anchors); HIP_IFEL(!(param = hip_get_param(msg, HIP_PARAM_HCHAIN_ANCHOR)), -1, "transform suggests anchor, but it is NOT included in msg\n"); if (*num_anchors <= num_parallel_hchains) { for (i = 0; i < *num_anchors; i++) { anchor = hip_get_param_contents_direct(param); // store the current anchor memcpy(&esp_prot_anchors[i][0], anchor, hash_length); HIP_HEXDUMP("esp protection anchor is ", &esp_prot_anchors[i][0], hash_length); HIP_IFEL(!(param = hip_get_next_param(msg, param)), -1, "awaiting further anchor, but it is NOT included in msg\n"); } } } out_err: if (err) { *esp_prot_transform = 0; *num_anchors = 0; } return err; }
/** * Notifies the hipd about an anchor change in the hipfw * * @param entry the sadb entry for the outbound direction * @return 0 on success, -1 on error, 1 for inbound sadb entry */ int send_anchor_change_to_hipd(const struct hip_sa_entry *entry) { int err = 0; int hash_length = 0; long i = 0; unsigned char *anchor = NULL; struct hip_common *msg = NULL; struct hash_chain *hchain = NULL; struct hash_tree *htree = NULL; HIP_ASSERT(entry != NULL); HIP_ASSERT(entry->direction == HIP_SPI_DIRECTION_OUT); HIP_IFEL((hash_length = esp_prot_get_hash_length(entry->esp_prot_transform)) <= 0, -1, "error or tried to resolve UNUSED transform\n"); HIP_IFEL(!(msg = malloc(HIP_MAX_PACKET)), -1, "failed to allocate memory\n"); hip_msg_init(msg); HIP_IFEL(hip_build_user_hdr(msg, HIP_MSG_ANCHOR_CHANGE, 0), -1, "build hdr failed\n"); HIP_DEBUG_HIT("src_hit", &entry->inner_src_addr); HIP_IFEL(hip_build_param_contents(msg, &entry->inner_src_addr, HIP_PARAM_HIT, sizeof(struct in6_addr)), -1, "build param contents failed\n"); HIP_DEBUG_HIT("dst_hit", &entry->inner_dst_addr); HIP_IFEL(hip_build_param_contents(msg, &entry->inner_dst_addr, HIP_PARAM_HIT, sizeof(struct in6_addr)), -1, "build param contents failed\n"); HIP_DEBUG("direction: %i\n", entry->direction); HIP_IFEL(hip_build_param_contents(msg, &entry->direction, HIP_PARAM_INT, sizeof(int)), -1, "build param contents failed\n"); HIP_DEBUG("esp_prot_transform: %u\n", entry->esp_prot_transform); HIP_IFEL(hip_build_param_contents(msg, &entry->esp_prot_transform, HIP_PARAM_ESP_PROT_TFM, sizeof(uint8_t)), -1, "build param contents failed\n"); HIP_DEBUG("esp_prot_num_parallel_hchains: %i\n", num_parallel_hchains); HIP_IFEL(hip_build_param_contents(msg, &num_parallel_hchains, HIP_PARAM_INT, sizeof(int)), -1, "build param contents failed\n"); for (i = 0; i < num_parallel_hchains; i++) { // the anchor change has already occurred on fw-side if (entry->esp_prot_transform == ESP_PROT_TFM_TREE) { htree = entry->active_hash_items[i]; anchor = htree->root; } else { hchain = entry->active_hash_items[i]; anchor = hchain_get_anchor(hchain); } HIP_HEXDUMP("anchor: ", anchor, hash_length); HIP_IFEL(hip_build_param_contents(msg, anchor, HIP_PARAM_HCHAIN_ANCHOR, hash_length), -1, "build param contents failed\n"); } HIP_DUMP_MSG(msg); /* send msg to hipd and receive corresponding reply */ HIP_IFEL(hip_send_recv_daemon_info(msg, 1, hip_fw_sock), -1, "send_recv msg failed\n"); /* check error value */ HIP_IFEL(hip_get_msg_err(msg), -1, "hipd returned error message!\n"); HIP_DEBUG("send_recv msg succeeded\n"); out_err: free(msg); return err; }
/** * Invokes an UPDATE message containing an anchor element as a hook to * next hash structure to be used when the active one depletes * * @param entry the sadb entry for the outbound direction * @param anchors the anchor elements to be sent * @param hash_item_length length of the respective hash item * @param soft_update indicates if HHL-based updates should be used * @param anchor_offset the offset of the anchor element in the link tree * @param link_trees the link trees for the anchor elements, in case of HHL * @return 0 on success, -1 on error */ int send_trigger_update_to_hipd(const struct hip_sa_entry *entry, const unsigned char *anchors[MAX_NUM_PARALLEL_HCHAINS], const int hash_item_length, const int soft_update, const int *anchor_offset, struct hash_tree *link_trees[MAX_NUM_PARALLEL_HCHAINS]) { int err = 0; int i = 0; struct hip_common *msg = NULL; int hash_length = 0; struct hash_chain *hchain = NULL; struct hash_tree *htree = NULL; struct hash_tree *link_tree = NULL; int secret_length = 0; int branch_length = 0; int root_length = 0; const unsigned char *secret = NULL; unsigned char *branch_nodes = NULL; const unsigned char *root = NULL; HIP_ASSERT(entry != NULL); HIP_IFEL((hash_length = esp_prot_get_hash_length(entry->esp_prot_transform)) <= 0, -1, "error or tried to resolve UNUSED transform\n"); HIP_IFEL(!(msg = malloc(HIP_MAX_PACKET)), -1, "failed to allocate memory\n"); hip_msg_init(msg); HIP_IFEL(hip_build_user_hdr(msg, HIP_MSG_TRIGGER_UPDATE, 0), -1, "build hdr failed\n"); HIP_DEBUG_HIT("src_hit", &entry->inner_src_addr); HIP_IFEL(hip_build_param_contents(msg, &entry->inner_src_addr, HIP_PARAM_HIT, sizeof(struct in6_addr)), -1, "build param contents failed\n"); HIP_DEBUG_HIT("dst_hit", &entry->inner_dst_addr); HIP_IFEL(hip_build_param_contents(msg, &entry->inner_dst_addr, HIP_PARAM_HIT, sizeof(struct in6_addr)), -1, "build param contents failed\n"); HIP_DEBUG("esp_prot_transform: %u\n", entry->esp_prot_transform); HIP_IFEL(hip_build_param_contents(msg, &entry->esp_prot_transform, HIP_PARAM_ESP_PROT_TFM, sizeof(uint8_t)), -1, "build param contents failed\n"); // also send the hchain/htree length for all update items HIP_IFEL(hip_build_param_contents(msg, &hash_item_length, HIP_PARAM_INT, sizeof(int)), -1, "build param contents failed\n"); HIP_DEBUG("added hash_item_length: %i\n", hash_item_length); HIP_DEBUG("num_parallel_hchains: %u\n", num_parallel_hchains); HIP_IFEL(hip_build_param_contents(msg, &num_parallel_hchains, HIP_PARAM_INT, sizeof(long)), -1, "build param contents failed\n"); // add update anchors for (i = 0; i < num_parallel_hchains; i++) { HIP_HEXDUMP("anchor: ", anchors[i], hash_length); HIP_IFEL(hip_build_param_contents(msg, anchors[i], HIP_PARAM_HCHAIN_ANCHOR, hash_length), -1, "build param contents failed\n"); } // now transmit root for each next hash item for tree-based updates, if available for (i = 0; i < num_parallel_hchains; i++) { if (entry->esp_prot_transform == ESP_PROT_TFM_TREE) { htree = entry->next_hash_items[i]; link_tree = htree->link_tree; } else { hchain = entry->next_hash_items[i]; link_tree = hchain->link_tree; } if (link_tree) { /* if the next_hchain has got a link_tree, we need its root for * the verification of the next_hchain's elements */ root = htree_get_root(link_tree, &root_length); } // only transmit root length once if (i == 0) { HIP_DEBUG("root_length: %i\n", root_length); HIP_IFEL(hip_build_param_contents(msg, &root_length, HIP_PARAM_INT, sizeof(int)), -1, "build param contents failed\n"); } if (root) { HIP_HEXDUMP("root: ", root, root_length); HIP_IFEL(hip_build_param_contents(msg, root, HIP_PARAM_ROOT, root_length), -1, "build param contents failed\n"); } } HIP_DEBUG("soft_update: %i\n", soft_update); HIP_IFEL(hip_build_param_contents(msg, &soft_update, HIP_PARAM_INT, sizeof(int)), -1, "build param contents failed\n"); if (soft_update) { for (i = 0; i < num_parallel_hchains; i++) { secret = htree_get_secret(link_trees[i], anchor_offset[i], &secret_length); HIP_IFEL(!(branch_nodes = htree_get_branch(link_trees[i], anchor_offset[i], NULL, &branch_length)), -1, "failed to get branch nodes\n"); HIP_DEBUG("anchor_offset: %i\n", anchor_offset[i]); HIP_IFEL(hip_build_param_contents(msg, &anchor_offset[i], HIP_PARAM_INT, sizeof(int)), -1, "build param contents failed\n"); HIP_DEBUG("secret_length: %i\n", secret_length); HIP_IFEL(hip_build_param_contents(msg, &secret_length, HIP_PARAM_INT, sizeof(int)), -1, "build param contents failed\n"); HIP_DEBUG("branch_length: %i\n", branch_length); HIP_IFEL(hip_build_param_contents(msg, &branch_length, HIP_PARAM_INT, sizeof(int)), -1, "build param contents failed\n"); HIP_HEXDUMP("secret: ", secret, secret_length); HIP_IFEL(hip_build_param_contents(msg, secret, HIP_PARAM_SECRET, secret_length), -1, "build param contents failed\n"); HIP_HEXDUMP("branch_nodes: ", branch_nodes, branch_length); HIP_IFEL(hip_build_param_contents(msg, branch_nodes, HIP_PARAM_BRANCH_NODES, branch_length), -1, "build param contents failed\n"); } } HIP_DUMP_MSG(msg); /* send msg to hipd and receive corresponding reply */ HIP_IFEL(hip_send_recv_daemon_info(msg, 1, hip_fw_sock), -1, "send_recv msg failed\n"); /* check error value */ HIP_IFEL(hip_get_msg_err(msg), -1, "hipd returned error message!\n"); HIP_DEBUG("send_recv msg succeeded\n"); out_err: free(msg); free(branch_nodes); return err; }
/** Handle message from agent socket. */ int connhipd_handle_msg(struct hip_common *msg, struct sockaddr_un *addr) { /* Variables. */ struct hip_tlv_common *param = NULL, *param2 = NULL; struct hip_common *emsg; hip_hdr_type_t type; HIT_Remote hit, *r; HIT_Local *l; socklen_t alen; struct in6_addr *lhit, *rhit; int err = 0, ret, n, direction, check; char chit[128], *type_s; struct in6_addr hitr ; type = hip_get_msg_type(msg); if (type == SO_HIP_AGENT_PING_REPLY) { HIP_DEBUG("Received ping reply from daemon. Connection to daemon established.\n"); gui_set_info(lang_get("gui-info-000")); hip_agent_connected = 1; } else if (type == SO_HIP_SET_NAT_ON) { gui_update_nat(1); HIP_DEBUG("NAT extensions on.\n"); } else if (type == SO_HIP_SET_NAT_OFF) { gui_update_nat(0); HIP_DEBUG("NAT extensions off.\n"); } else if (type == SO_HIP_DAEMON_QUIT) { HIP_DEBUG("Daemon quit. Waiting daemon to wake up again...\n"); gui_set_info(lang_get("gui-info-001")); hip_agent_connected = 0; } else if (type == SO_HIP_ADD_DB_HI) { HIP_DEBUG("Message received successfully from daemon with type" " HIP_ADD_DB_HI (%d).\n", type); n = 0; while((param = hip_get_next_param(msg, param))) { if (hip_get_param_type(param) == HIP_PARAM_HIT) { lhit = (struct in6_addr *)hip_get_param_contents_direct(param); HIP_HEXDUMP("Adding local HIT:", lhit, 16); print_hit_to_buffer(chit, lhit); hit_db_add_local(chit, lhit); n++; } } } else if (type == SO_HIP_UPDATE_HIU) { n = 0; gui_hiu_clear(); while((param = hip_get_next_param(msg, param))) { /*param2 = hip_get_next_param(msg, param); if (param2 == NULL) break;*/ if (hip_get_param_type(param) == HIP_PARAM_HIT)/* && hip_get_param_type(param2) == HIP_PARAM_HIT)*/ { rhit = (struct in6_addr *)hip_get_param_contents_direct(param); //lhit = hip_get_param_contents_direct(param2); r = hit_db_find(NULL, rhit); if (r) { gui_hiu_add(r); n++; } } } gui_hiu_count(n); } else if (type == HIP_I1 || type == HIP_R1) { NAMECPY(hit.name, ""); URLCPY(hit.url, "<notset>"); URLCPY(hit.port, ""); HIP_DEBUG("Message from daemon, %d bytes.\n", hip_get_msg_total_len(msg)); /* Get original message, which is encapsulated inside received one. */ emsg = (struct hip_common *)hip_get_param_contents(msg, HIP_PARAM_ENCAPS_MSG); HIP_IFEL(!emsg, -1, "Could not get msg parameter!\n"); HIP_HEXDUMP("msg->hits: ", &emsg->hits, 16); HIP_HEXDUMP("msg->hitr: ", &emsg->hitr, 16); /* Find out, which of the HITs in the message is local HIT. */ l = hit_db_find_local(NULL, &emsg->hits); if (!l) { l = hit_db_find_local(NULL, &emsg->hitr); if (l) { memcpy(&hit.hit, &emsg->hits, sizeof(hit.hit)); } HIP_IFEL(!l, -1, "Did not find local HIT for message!\n"); } else { memcpy(&hit.hit, &emsg->hitr, sizeof(hit.hit)); } HIP_DEBUG("Received %s %s from daemon.\n", "incoming", type == HIP_I1 ? "I1" : "R1"); /* Check the remote HIT from database. */ if (l) { memcpy(&hitr,&hit.hit, sizeof(struct in6_addr)); ret = check_hit(&hit, 0); /*Send our hits -- peer hit to daemon*/ if (ret == 1) ret = 0; /*hit already exist in the database and is accepted so no need to send it to daemon*/ else if (ret == 0) connhipd_send_hitdata_to_daemon (msg, &hitr, &hit.g->l->lhit) ; /* Reset local HIT, if outgoing I1. */ /*HIP_HEXDUMP("Old local HIT: ", &msg->hits, 16); HIP_HEXDUMP("New local HIT: ", &hit.g->l->lhit, 16); HIP_HEXDUMP("Old remote HIT: ", &msg->hitr, 16); HIP_HEXDUMP("New remote HIT: ", &hit.hit, 16);*/ } /* If neither HIT in message was local HIT, then drop the packet! */ else { HIP_DEBUG("Failed to find local HIT from database for packet." " Rejecting packet automatically.\n"); HIP_HEXDUMP("msg->hits: ", &msg->hits, 16); HIP_HEXDUMP("msg->hitr: ", &msg->hits, 16); ret = -1; } /* Now either reject or accept the packet, according to previous results. */ if (ret == 0) { HIP_DEBUG("Message accepted, sending back to daemon, %d bytes.\n", hip_get_msg_total_len(msg)); n = hip_send_recv_daemon_info((char *)msg, 1, hip_agent_sock); HIP_IFEL(n < 0, -1, "Could not send message back to daemon" " (%d: %s).\n", errno, strerror(errno)); HIP_DEBUG("Reply sent successfully.\n"); } else if (type == HIP_R1) { HIP_DEBUG("Message rejected.\n"); n = 1; HIP_IFE(hip_build_param_contents(msg, &n, HIP_PARAM_AGENT_REJECT, sizeof(n)), -1); n = hip_send_recv_daemon_info((char *)msg, 1, hip_agent_sock); HIP_IFEL(n < 0, -1, "Could not send message back to daemon" " (%d: %s).\n", errno, strerror(errno)); HIP_DEBUG("Reply sent successfully.\n"); } else { HIP_DEBUG("Message rejected.\n"); } } out_err: // HIP_DEBUG("Message handled.\n"); return (err); }
/** handles a user-message sent by the firewall when the bex-store is updated * * @param msg the user-message sent by fw * @return 0 if ok, != 0 else */ int anchor_db_update(const struct hip_common *msg) { const struct hip_tlv_common *param = NULL; const unsigned char *anchor = NULL; int err = 0, i, j; uint8_t esp_transforms[MAX_NUM_TRANSFORMS]; HIP_ASSERT(msg != NULL); // if this function is called, the extension should be active if (esp_prot_active) { memset(esp_transforms, 0, MAX_NUM_TRANSFORMS * sizeof(uint8_t)); HIP_DEBUG("updating hchain anchorDB...\n"); /* XX TODO ineffcient -> only add non-existing elements instead of * uniniting and adding all elements again */ anchor_db_uninit(); /*** set up anchor_db.num_anchors and anchor_db.anchor_lengths ***/ // get first int value HIP_IFEL(!(param = hip_get_param(msg, HIP_PARAM_UINT)), -1, "parameter missing in user-message from fw\n"); // don't set up anything for UNUSED transform for (i = 0; i < esp_prot_num_transforms - 1; i++) { // needed for redirection to correct slot in anchor_db esp_transforms[i] = *(const uint8_t *) hip_get_param_contents_direct(param); HIP_DEBUG("esp_transform is %u\n", esp_transforms[i]); HIP_IFEL(!(param = hip_get_next_param(msg, param)), -1, "parameter missing in user-message from fw\n"); anchor_db.num_anchors[esp_transforms[i]] = *(const int *) hip_get_param_contents_direct(param); HIP_DEBUG("num_anchors is %i\n", anchor_db.num_anchors[esp_transforms[i]]); HIP_IFEL(!(param = hip_get_next_param(msg, param)), -1, "parameter missing in user-message from fw\n"); anchor_db.anchor_lengths[esp_transforms[i]] = *(const int *) hip_get_param_contents_direct(param); HIP_DEBUG("anchor_length is %i\n", anchor_db.anchor_lengths[esp_transforms[i]]); HIP_IFEL(!(param = hip_get_next_param(msg, param)), -1, "parameter missing in user-message from fw\n"); } for (i = 0; i < esp_prot_num_transforms - 1; i++) { HIP_DEBUG("transform %u:\n", esp_transforms[i]); for (j = 0; j < anchor_db.num_anchors[esp_transforms[i]]; j++) { HIP_IFEL(!(anchor_db.anchors[esp_transforms[i]][j] = malloc(anchor_db.anchor_lengths[esp_transforms[i]])), -1, "failed to allocate memory\n"); anchor = hip_get_param_contents_direct(param); memcpy(anchor_db.anchors[esp_transforms[i]][j], anchor, anchor_db.anchor_lengths[esp_transforms[i]]); HIP_HEXDUMP("adding anchor: ", anchor_db.anchors[esp_transforms[i]][j], anchor_db.anchor_lengths[esp_transforms[i]]); HIP_IFEL(!(param = hip_get_next_param(msg, param)), -1, "parameter missing in user-message from fw\n"); anchor_db.hash_item_length[esp_transforms[i]] = *(const int *) hip_get_param_contents_direct(param); HIP_DEBUG("adding hash_item_length: %i\n", anchor_db.hash_item_length[esp_transforms[i]]); // exclude getting the next param for the very last loop if (!(i == esp_prot_num_transforms - 2 && j == anchor_db.num_anchors[esp_transforms[i]] - 1)) { HIP_IFEL(!(param = hip_get_next_param(msg, param)), -1, "parameter missing in user-message from fw\n"); } } } HIP_DEBUG("anchor_db successfully updated\n"); } else { HIP_ERROR("received anchor_db update, but esp protection extension disabled\n"); err = -1; goto out_err; } out_err: return err; }