/** * tell firewall to turn on or off the ESP relay mode * * @param action HIP_MSG_OFFER_FULLRELAY or HIP_MSG_CANCEL_FULLRELAY * * @return zero on success or negative on failure */ int hip_firewall_set_esp_relay(int action) { struct hip_common *msg = NULL; int err = 0; int sent; HIP_DEBUG("Setting ESP relay to %d\n", action); if (!(msg = hip_msg_alloc())) { return -ENOMEM; } HIP_IFEL(hip_build_user_hdr(msg, action ? HIP_MSG_OFFER_FULLRELAY : HIP_MSG_CANCEL_FULLRELAY, 0), -1, "Build header failed\n"); sent = hip_sendto_firewall(msg); if (sent < 0) { HIP_PERROR("Send to firewall failed: "); err = -1; goto out_err; } HIP_DEBUG("Sent %d bytes to firewall.\n", sent); out_err: free(msg); return err; }
/** * verify_hddr_lib - It sends the dht response to hipdaemon * first appending one more user param for holding a structure hdrr_info * hdrr_info is used by daemon to mark signature and host id verification results to flags * Then adding user header for recognizing the message at daemon side * * @param *hipcommonmsg packet returned from the lookup service * @param *addrkey key used for the lookup * @return OR of the signature and host id verification, 0 in case of success */ int verify_hddr_lib (struct hip_common *hipcommonmsg,struct in6_addr *addrkey) { struct hip_hdrr_info hdrr_info; struct hip_hdrr_info *hdrr_info_response; int err = 0 ; memcpy(&hdrr_info.dht_key, addrkey, sizeof(struct in6_addr)); hdrr_info.sig_verified = -1; hdrr_info.hit_verified = -1; hip_build_param_hip_hdrr_info(hipcommonmsg, &hdrr_info); _HIP_DUMP_MSG (hipcommonmsg); HIP_INFO("Asking signature verification info from daemon...\n"); HIP_IFEL(hip_build_user_hdr(hipcommonmsg, SO_HIP_VERIFY_DHT_HDRR_RESP,0),-1, "Building daemon header failed\n"); HIP_IFEL(hip_send_recv_daemon_info(hipcommonmsg, 0, 0), -1, "Send recv daemon info failed\n"); hdrr_info_response = hip_get_param (hipcommonmsg, HIP_PARAM_HDRR_INFO); _HIP_DUMP_MSG (hipcommonmsg); HIP_DEBUG ("Sig verified (0=true): %d\nHit Verified (0=true): %d \n" ,hdrr_info_response->sig_verified, hdrr_info_response->hit_verified); return (hdrr_info_response->sig_verified | hdrr_info_response->hit_verified); out_err: return err; }
/** * No description. */ int hip_set_opportunistic_mode(const struct hip_common *msg){ int err = 0; unsigned int *mode = NULL; mode = hip_get_param_contents(msg, HIP_PARAM_UINT); if (!mode) { err = -EINVAL; goto out_err; } HIP_DEBUG("mode=%d\n", *mode); if(*mode == 0 || *mode == 1 || *mode == 2){ opportunistic_mode = *mode; } else { HIP_ERROR("Invalid value for opportunistic mode\n"); err = -EINVAL; goto out_err; } memset(msg, 0, HIP_MAX_PACKET); HIP_IFE(hip_build_user_hdr(msg, (opportunistic_mode == 2 ? SO_HIP_SET_OPPTCP_ON : SO_HIP_SET_OPPTCP_OFF), 0), -1); hip_set_opportunistic_tcp_status(msg); out_err: return err; }
/** * No description. */ int hip_query_ip_hit_mapping(struct hip_common *msg){ int err = 0; unsigned int mapping = 0; struct in6_addr *hit = NULL; hip_ha_t *entry = NULL; hit = (struct in6_addr *) hip_get_param_contents(msg, HIP_PARAM_PSEUDO_HIT); HIP_ASSERT(hit_is_opportunistic_hashed_hit(hit)); entry = hip_hadb_try_to_find_by_peer_hit(hit); if(entry) mapping = 1; else mapping = 0; hip_msg_init(msg); HIP_IFEL(hip_build_param_contents(msg, (void *) &mapping, HIP_PARAM_UINT, sizeof(unsigned int)), -1, "build param mapping failed\n"); HIP_IFEL(hip_build_user_hdr(msg, SO_HIP_ANSWER_IP_HIT_MAPPING_QUERY, 0), -1, "build user header failed\n"); out_err: return err; }
/** * Send the ip of a peer to hipd, so that it can: * - unblock the packets that are sent to a particular peer. * - add it to the blacklist database. * * @param peer_ip peer ip. * @return nothing */ int hip_fw_unblock_and_blacklist(const struct in6_addr *peer_ip){ struct hip_common *msg = NULL; int err = 0; HIP_DEBUG("\n"); HIP_IFE(!(msg = hip_msg_alloc()), -1); HIP_IFEL(hip_build_param_contents(msg, (void *)(peer_ip), HIP_PARAM_IPV6_ADDR, sizeof(struct in6_addr)), -1, "build param HIP_PARAM_IPV6_ADDR failed\n"); /* build the message header */ HIP_IFEL(hip_build_user_hdr(msg, SO_HIP_OPPTCP_UNBLOCK_AND_BLACKLIST, 0), -1, "build hdr failed\n"); HIP_DUMP_MSG(msg); /* send and receive msg to/from hipd */ HIP_IFEL(hip_send_recv_daemon_info(msg, 1, hip_fw_async_sock), -1, "send_recv msg failed\n"); _HIP_DEBUG("send_recv msg succeed\n"); /* check error value */ HIP_IFEL(hip_get_msg_err(msg), -1, "Got erroneous message!\n"); out_err: return err; }
/* * similar to the hip_request_peer_hit_from_hipd(...) function * */ int hip_request_peer_hit_from_hipd_at_firewall( const struct in6_addr *peer_ip, struct in6_addr *peer_hit, const struct in6_addr *local_hit, in_port_t *src_tcp_port, in_port_t *dst_tcp_port, int *fallback, int *reject){ struct hip_common *msg = NULL; struct in6_addr *hit_recv = NULL; hip_hit_t *ptr = NULL; int err = 0; int ret = 0; *fallback = 1; *reject = 0; HIP_IFE(!(msg = hip_msg_alloc()), -1); HIP_IFEL(hip_build_param_contents(msg, (void *)(local_hit), HIP_PARAM_HIT_LOCAL, sizeof(struct in6_addr)), -1, "build param HIP_PARAM_HIT failed\n"); if (hip_opptcp) { HIP_IFEL(hip_build_param_contents(msg, (void *)(src_tcp_port), HIP_PARAM_SRC_TCP_PORT, sizeof(in_port_t)), -1, "build param HIP_PARAM_SRC_TCP_PORT failed\n"); HIP_IFEL(hip_build_param_contents(msg, (void *)(dst_tcp_port), HIP_PARAM_DST_TCP_PORT, sizeof(in_port_t)), -1, "build param HIP_PARAM_DST_TCP_PORT failed\n"); } HIP_IFEL(hip_build_param_contents(msg, (void *)(peer_ip), HIP_PARAM_IPV6_ADDR_PEER, sizeof(struct in6_addr)), -1, "build param HIP_PARAM_IPV6_ADDR failed\n"); /* build the message header */ HIP_IFEL(hip_build_user_hdr(msg, SO_HIP_GET_PEER_HIT, 0), -1, "build hdr failed\n"); /* this message has to be delivered with the async socket because opportunistic mode responds asynchronously */ HIP_IFEL(hip_send_recv_daemon_info(msg, 1, hip_fw_async_sock), -1, "send msg failed\n"); _HIP_DEBUG("send_recv msg succeed\n"); out_err: if(msg) free(msg); return err; }
/** * Send the necessary data to hipd, so that a tcp packet is sent from there. This was done because it was not possible to send a packet directly from here. * * @param *hdr pointer to the packet that is to be sent. * @param packet_size the size of the packet. * @param ip_version ipv4 or ipv6. * @param addHit whether the local HIT is to be added at the tcp options * @param addOption whether the i1 option is to be added at the tcp options * @return nothing */ int hip_request_send_tcp_packet(void *hdr, int packet_size, int ip_version, int addHit, int addOption){ const struct hip_common *msg = NULL; int err = 0; HIP_DEBUG("\n"); HIP_IFE(!(msg = hip_msg_alloc()), -1); HIP_IFEL(hip_build_param_contents(msg, (void *)hdr, HIP_PARAM_IP_HEADER, packet_size), -1, "build param HIP_PARAM_IP_HEADER failed\n"); HIP_IFEL(hip_build_param_contents(msg, (int *)(&packet_size), HIP_PARAM_PACKET_SIZE, sizeof(int)), -1, "build param HIP_PARAM_PACKET_SIZE failed\n"); HIP_IFEL(hip_build_param_contents(msg, (int *)(&ip_version), HIP_PARAM_TRAFFIC_TYPE, sizeof(int)), -1, "build param HIP_PARAM_TRAFFIC_TYPE failed\n"); HIP_IFEL(hip_build_param_contents(msg, (int *)(&addHit), HIP_PARAM_ADD_HIT, sizeof(int)), -1, "build param HIP_PARAM_ADD_HIT failed\n"); HIP_IFEL(hip_build_param_contents(msg, (int *)(&addOption), HIP_PARAM_ADD_OPTION, sizeof(int)), -1, "build param HIP_PARAM_ADD_OPTION failed\n"); /* build the message header */ HIP_IFEL(hip_build_user_hdr(msg, SO_HIP_OPPTCP_SEND_TCP_PACKET, 0), -1, "build hdr failed\n"); HIP_DUMP_MSG(msg); /* send and receive msg to/from hipd */ HIP_IFEL(hip_send_recv_daemon_info(msg, 1, hip_fw_async_sock), -1, "send_recv msg failed\n"); _HIP_DEBUG("send_recv msg succeed\n"); /* check error value */ //HIP_IFEL(hip_get_msg_err(msg), -1, "Got erroneous message!\n"); out_err: return err; }
/** * No description. */ int hip_query_opportunistic_mode(struct hip_common *msg){ int err = 0; unsigned int opp_mode = opportunistic_mode; hip_msg_init(msg); HIP_IFEL(hip_build_param_contents(msg, (void *) &opp_mode, HIP_PARAM_UINT, sizeof(unsigned int)), -1, "build param opp_mode failed\n"); HIP_IFEL(hip_build_user_hdr(msg, SO_HIP_ANSWER_OPPORTUNISTIC_MODE_QUERY, 0), -1, "build user header failed\n"); out_err: return err; }
hip_lsi_t *hip_fw_get_default_lsi() { int err = 0; struct hip_common *msg = NULL; struct hip_tlv_common *param; /* Use cached LSI if possible */ if (local_lsi.s_addr != 0) { //memcpy(lsi, &local_lsi, sizeof(*lsi)); return &local_lsi; goto out_err; } /* Query hipd for the LSI */ HIP_IFE(!(msg = hip_msg_alloc()), -1); HIP_IFEL(hip_build_user_hdr(msg, SO_HIP_DEFAULT_HIT, 0), -1, "build hdr failed\n"); /* send and receive msg to/from hipd */ HIP_IFEL(hip_send_recv_daemon_info(msg, 0, hip_fw_sock), -1, "send_recv msg failed\n"); HIP_DEBUG("send_recv msg succeed\n"); /* check error value */ HIP_IFEL(hip_get_msg_err(msg), -1, "Got erroneous message!\n"); HIP_IFEL(!(param = hip_get_param(msg, HIP_PARAM_LSI)), -1, "Did not find LSI\n"); memcpy(&local_lsi, hip_get_param_contents_direct(param), sizeof(local_lsi)); //memcpy(lsi, &local_lsi, sizeof(*lsi)); out_err: if(msg) HIP_FREE(msg); if (err) return NULL; else return &local_lsi; }
/** * Update firewall on host association state. Currently used by the * LSI mode in the firewall. * * @param action HIP_MSG_FW_UPDATE_DB or HIP_MSG_FW_BEX_DONE * @param hit_s optional source HIT * @param hit_r optional destination HIT * * @return zero on success or negative on failure */ int hip_firewall_set_bex_data(int action, struct in6_addr *hit_s, struct in6_addr *hit_r) { struct hip_common *msg = NULL; int err = 0, n = 0, r_is_our; if (!hip_get_firewall_status()) { goto out_err; } /* Makes sure that the hits are sent always in the same order */ r_is_our = hip_hidb_hit_is_our(hit_r); HIP_IFEL(!(msg = malloc(HIP_MAX_PACKET)), -1, "alloc\n"); hip_msg_init(msg); HIP_IFEL(hip_build_user_hdr(msg, action, 0), -1, "Build hdr failed\n"); HIP_IFEL(hip_build_param_contents(msg, r_is_our ? hit_s : hit_r, HIP_PARAM_HIT, sizeof(struct in6_addr)), -1, "build param contents failed\n"); HIP_IFEL(hip_build_param_contents(msg, r_is_our ? hit_r : hit_s, HIP_PARAM_HIT, sizeof(struct in6_addr)), -1, "build param contents failed\n"); n = sendto(hip_firewall_sock_lsi_fd, (char *) msg, hip_get_msg_total_len(msg), 0, (struct sockaddr *) &hip_firewall_addr, sizeof(struct sockaddr_in6)); HIP_IFEL(n < 0, -1, "Send to firewall failed. str errno %s\n", strerror(errno)); HIP_DEBUG("BEX DATA Send to firewall OK.\n"); out_err: free(msg); 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; }
/** * 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; }
/** * Sends the preferred transform to hipd implicitely turning on * the esp protection extension there * * @param activate 1 to activate, 0 to deactivate the extension in the hipd * @return 0 on success, -1 on error */ int send_esp_prot_to_hipd(const int activate) { struct hip_common *msg = NULL; int num_transforms = 0; int err = 0, i; uint8_t transform = 0; HIP_ASSERT(activate >= 0); 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_ESP_PROT_TFM, 0), -1, "build hdr failed\n"); if (activate > 0) { /*** activation case ***/ HIP_DEBUG("sending preferred esp prot transforms to hipd...\n"); // all "in use" transforms + UNUSED num_transforms = NUM_TRANSFORMS + 1; HIP_DEBUG("adding activate: %i\n", activate); HIP_IFEL(hip_build_param_contents(msg, &activate, HIP_PARAM_INT, sizeof(int)), -1, "build param contents failed\n"); HIP_DEBUG("adding num_transforms: %i\n", num_transforms); HIP_IFEL(hip_build_param_contents(msg, &num_transforms, HIP_PARAM_INT, sizeof(int)), -1, "build param contents failed\n"); HIP_DEBUG("adding num_parallel_hchains: %i\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"); for (i = 0; i < num_transforms; i++) { HIP_DEBUG("adding transform %i: %u\n", i + 1, token_transform); HIP_IFEL(hip_build_param_contents(msg, &token_transform, HIP_PARAM_ESP_PROT_TFM, sizeof(uint8_t)), -1, "build param contents failed\n"); } } else { /*** deactivation case ***/ HIP_DEBUG("sending esp prot transform ESP_PROT_TFM_UNUSED to hipd...\n"); // we are only sending ESP_PROT_TFM_UNUSED num_transforms = 1; transform = ESP_PROT_TFM_UNUSED; HIP_DEBUG("adding activate: %i\n", activate); HIP_IFEL(hip_build_param_contents(msg, &activate, HIP_PARAM_INT, sizeof(int)), -1, "build param contents failed\n"); HIP_DEBUG("adding num_transforms: %i\n", num_transforms); HIP_IFEL(hip_build_param_contents(msg, &num_transforms, HIP_PARAM_INT, sizeof(int)), -1, "build param contents failed\n"); HIP_DEBUG("adding num_parallel_hchains: %i\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"); HIP_DEBUG("adding transform ESP_PROT_TFM_UNUSED: %u\n", transform); HIP_IFEL(hip_build_param_contents(msg, &transform, HIP_PARAM_ESP_PROT_TFM, sizeof(uint8_t)), -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; }
/** This thread keeps the HIP daemon connection alive. */ void *connhipd_thread(void *data) { /* Variables. */ int err = 0, n, len, ret, max_fd; struct sockaddr_in6 agent_addr; struct hip_common *msg = (struct hip_common *)data; socklen_t alen; fd_set read_fdset; struct timeval tv; HIP_DEBUG("Waiting messages...\n"); /* Start handling. */ hip_agent_thread_started = 1; while (hip_agent_thread_started) { FD_ZERO(&read_fdset); FD_SET(hip_agent_sock, &read_fdset); max_fd = hip_agent_sock; tv.tv_sec = 1; tv.tv_usec = 0; if (hip_agent_connected < 1) { /* Test connection. */ //HIP_IFEL(hip_agent_connected < -60, -1, "Could not connect to daemon.\n"); //HIP_DEBUG("Pinging daemon...\n"); hip_build_user_hdr(msg, SO_HIP_AGENT_PING, 0); n = hip_send_recv_daemon_info((char *)msg, 1, hip_agent_sock); //if (n < 0) HIP_DEBUG("Could not send ping to daemon, waiting.\n"); hip_agent_connected--; } /* Wait for incoming packets. */ if (select(max_fd + 1, &read_fdset, NULL,NULL, &tv) == -1) { HIP_ERROR("select() error: %s.\n", strerror(errno)); err = -1; goto out_err; } if (!hip_agent_thread_started) continue; if (!FD_ISSET(hip_agent_sock, &read_fdset)) continue; memset(&agent_addr, 0, sizeof(agent_addr)); alen = sizeof(agent_addr); n = recvfrom(hip_agent_sock, msg, sizeof(struct hip_common), MSG_PEEK, (struct sockaddr *)&agent_addr, &alen); if (n < 0) { HIP_ERROR("Error receiving message header from daemon.\n"); err = -1; goto out_err; } // HIP_DEBUG("Header received successfully\n"); alen = sizeof(agent_addr); len = hip_get_msg_total_len(msg); n = recvfrom(hip_agent_sock, msg, len, 0, (struct sockaddr *)&agent_addr, &alen); if (n < 0) { HIP_ERROR("Error receiving message parameters from daemon.\n"); err = -1; goto out_err; } //HIP_DEBUG("Received message from daemon (%d bytes)\n", n); //HIP_ASSERT(n == len); if (n != len) { HIP_ERROR("Received packet length and HIP msg len dont match %d != %d!!!\n", n, len); continue; } if (agent_addr.sin6_port != ntohs(HIP_DAEMON_LOCAL_PORT)) { HIP_DEBUG("Drop, message not from hipd"); continue; } connhipd_handle_msg(msg, &agent_addr); } out_err: /* Send quit message to daemon. */ hip_build_user_hdr(msg, SO_HIP_AGENT_QUIT, 0); n = hip_send_recv_daemon_info((char *)msg, 1, hip_agent_sock); if (n < 0) HIP_ERROR("Could not send quit message to daemon.\n"); if (hip_agent_sock) close(hip_agent_sock); if (msg != NULL) HIP_FREE(msg); hip_agent_thread_started = 0; agent_exit(); HIP_DEBUG("Connection thread exit.\n"); /* This function cannot have a returning value */ /*return (err);*/ }
/** * distribute a message from hipd to the respective extension handler * * @param msg pointer to the received user message * @return 0 on success, else -1 */ int hip_handle_msg(struct hip_common *msg) { int type, err = 0; struct hip_common *msg_out = NULL; HIP_DEBUG("Handling message from hipd\n"); type = hip_get_msg_type(msg); HIP_DEBUG("of type %d\n", type); switch (type) { case HIP_MSG_FW_BEX_DONE: case HIP_MSG_FW_UPDATE_DB: if (hip_lsi_support) { hip_handle_bex_state_update(msg); } break; case HIP_MSG_IPSEC_ADD_SA: HIP_DEBUG("Received add sa request from hipd\n"); HIP_IFEL(handle_sa_add_request(msg), -1, "hip userspace sadb add did NOT succeed\n"); break; case HIP_MSG_IPSEC_DELETE_SA: HIP_DEBUG("Received delete sa request from hipd\n"); HIP_IFEL(handle_sa_delete_request(msg), -1, "hip userspace sadb delete did NOT succeed\n"); break; case HIP_MSG_IPSEC_FLUSH_ALL_SA: HIP_DEBUG("Received flush all sa request from hipd\n"); hip_sadb_flush(); break; case HIP_MSG_RESET_FIREWALL_DB: hip_firewall_cache_delete_hldb(0); break; case HIP_MSG_OFFER_FULLRELAY: if (!esp_relay) { HIP_DEBUG("Enabling ESP relay\n"); hip_fw_init_esp_relay(); } else { HIP_DEBUG("ESP relay already enabled\n"); } break; case HIP_MSG_CANCEL_FULLRELAY: HIP_DEBUG("Disabling ESP relay\n"); hip_fw_uninit_esp_relay(); break; case HIP_MSG_FIREWALL_STATUS: msg_out = hip_msg_alloc(); HIP_IFEL(hip_build_user_hdr(msg_out, HIP_MSG_FIREWALL_START, 0), -1, "Couldn't build message to daemon\n"); HIP_IFEL(hip_send_recv_daemon_info(msg_out, 1, hip_fw_sock), -1, "Couldn't notify daemon of firewall presence\n"); break; case HIP_MSG_SIGNALING_HIPD_CONNECTION_CONFIRMATION: signaling_handle_hipd_connection_confirmation(msg); break; default: HIP_ERROR("Unhandled message type %d\n", type); err = -1; break; } out_err: free(msg_out); return err; }