/** * Change the state of hadb state cache in the firewall * * @param msg the message containing hadb cache information * * @return zero on success, non-zero on error */ static int hip_handle_bex_state_update(struct hip_common *msg) { const struct in6_addr *src_hit = NULL, *dst_hit = NULL; const struct hip_tlv_common *param = NULL; int err = 0, msg_type = 0; msg_type = hip_get_msg_type(msg); /* src_hit */ param = hip_get_param(msg, HIP_PARAM_HIT); src_hit = hip_get_param_contents_direct(param); HIP_DEBUG_HIT("Source HIT: ", src_hit); /* dst_hit */ param = hip_get_next_param(msg, param); dst_hit = hip_get_param_contents_direct(param); HIP_DEBUG_HIT("Destination HIT: ", dst_hit); /* update bex_state in firewalldb */ switch (msg_type) { case HIP_MSG_FW_BEX_DONE: err = hip_firewall_cache_set_bex_state(src_hit, dst_hit, HIP_STATE_ESTABLISHED); break; case HIP_MSG_FW_UPDATE_DB: err = hip_firewall_cache_set_bex_state(src_hit, dst_hit, HIP_STATE_NONE); break; default: break; } 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; }
/** 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; }
/** 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; }