int get_addr_len(int afi) { switch (afi) { /* == eid_afi */ case AF_UNSPEC: return (0); case AF_INET: return(sizeof(struct in_addr)); case AF_INET6: return(sizeof(struct in6_addr)); default: lispd_log_msg(LISP_LOG_DEBUG_2, "get_addr_len: unknown AFI (%d)", afi); return(ERR_AFI); } }
struct udphdr *build_ip_header( uint8_t *cur_ptr, lisp_addr_t *src_addr, lisp_addr_t *dst_addr, int ip_len) { struct ip *iph; struct ip6_hdr *ip6h; struct udphdr *udph; switch (src_addr->afi) { case AF_INET: ip_len = ip_len + sizeof(struct ip); iph = (struct ip *) cur_ptr; iph->ip_hl = 5; iph->ip_v = IPVERSION; iph->ip_tos = 0; iph->ip_len = htons(ip_len); iph->ip_id = htons(get_IP_ID()); iph->ip_off = 0; /* XXX Control packets can be fragmented */ iph->ip_ttl = 255; iph->ip_p = IPPROTO_UDP; iph->ip_src.s_addr = src_addr->address.ip.s_addr; iph->ip_dst.s_addr = dst_addr->address.ip.s_addr; iph->ip_sum = 0; iph->ip_sum = ip_checksum((uint16_t *)cur_ptr, sizeof(struct ip)); udph = (struct udphdr *) CO(iph,sizeof(struct ip)); break; case AF_INET6: ip6h = (struct ip6_hdr *) cur_ptr; ip6h->ip6_hops = 255; ip6h->ip6_vfc = (IP6VERSION << 4); ip6h->ip6_nxt = IPPROTO_UDP; ip6h->ip6_plen = htons(ip_len); memcpy(ip6h->ip6_src.s6_addr, src_addr->address.ipv6.s6_addr, sizeof(struct in6_addr)); memcpy(ip6h->ip6_dst.s6_addr, dst_addr->address.ipv6.s6_addr, sizeof(struct in6_addr)); udph = (struct udphdr *) CO(ip6h,sizeof(struct ip6_hdr)); break; default: lispd_log_msg(LISP_LOG_DEBUG_2,"build_ip_header: Uknown AFI of the source address: %d",src_addr->afi); return(NULL); } return(udph); }
/* * Fill the tuple with the 5 tuples of a packet: (SRC IP, DST IP, PROTOCOL, SRC PORT, DST PORT) */ int extract_5_tuples_from_packet ( uint8_t *packet , packet_tuple *tuple) { struct iphdr *iph = NULL; struct ip6_hdr *ip6h = NULL; struct udphdr *udp = NULL; struct tcphdr *tcp = NULL; int len = 0; iph = (struct iphdr *) packet; switch (iph->version) { case 4: tuple->src_addr.afi = AF_INET; tuple->dst_addr.afi = AF_INET; tuple->src_addr.address.ip.s_addr = iph->saddr; tuple->dst_addr.address.ip.s_addr = iph->daddr; tuple->protocol = iph->protocol; len = iph->ihl*4; break; case 6: ip6h = (struct ip6_hdr *) packet; tuple->src_addr.afi = AF_INET6; tuple->dst_addr.afi = AF_INET6; memcpy(&(tuple->src_addr.address.ipv6),&(ip6h->ip6_src),sizeof(struct in6_addr)); memcpy(&(tuple->dst_addr.address.ipv6),&(ip6h->ip6_dst),sizeof(struct in6_addr)); tuple->protocol = ip6h->ip6_ctlun.ip6_un1.ip6_un1_nxt; len = sizeof(struct ip6_hdr); break; default: lispd_log_msg(LISP_LOG_DEBUG_2,"extract_5_tuples_from_packet: No ip packet identified"); return (BAD); } if (tuple->protocol == IPPROTO_UDP){ udp = (struct udphdr *)CO(packet,len); tuple->src_port = ntohs(udp->source); tuple->dst_port = ntohs(udp->dest); }else if (tuple->protocol == IPPROTO_TCP){ tcp = (struct tcphdr *)CO(packet,len); tuple->src_port = ntohs(tcp->source); tuple->dst_port = ntohs(tcp->dest); }else{//If protocol is not TCP or UDP, ports of the tuple set to 0 tuple->src_port = 0; tuple->dst_port = 0; } return (GOOD); }
/* * Remove a referral and all its offspring */ int referral_expiry( timer *t, void *arg) { lispd_referral_cache_entry *referral_entry = (lispd_referral_cache_entry *)arg; lispd_log_msg(LISP_LOG_DEBUG_1,"referral_expiry: The referral entry with prefix %s/%d has expired. " "Removing it and all its offspring", get_char_from_lisp_addr_t(referral_entry->mapping->eid_prefix), referral_entry->mapping->eid_prefix_length); remove_referral_cache_entry_from_parent_node(referral_entry); del_referral_cache_entry_from_db(referral_entry); dump_referral_cache_db(LISP_LOG_DEBUG_3); return (GOOD); }
int lispd_get_iface_address_nl( char *ifacename, lisp_addr_t *addr, int afi) { int ifa_index = if_nametoindex(ifacename); if (request_address(ifa_index, afi)!=GOOD){ return (BAD); } if (read_address_nl(ifa_index, addr)!=GOOD){ lispd_log_msg(LISP_LOG_DEBUG_2,"lispd_get_iface_address_nl: Couldn't get iface address from afi"); return (BAD); } return (GOOD); }
lisp_addr_t *get_map_resolver() { lisp_addr_t *dst_rloc = NULL; if (default_ctrl_iface_v4 != NULL){ dst_rloc = get_server(map_resolvers, AF_INET); } if (dst_rloc == NULL && default_ctrl_iface_v6 != NULL){ dst_rloc = get_server(map_resolvers, AF_INET6); } if (dst_rloc == NULL){ lispd_log_msg(LISP_LOG_ERR,"No Map Resolver with a RLOC compatible with local RLOCs"); } return dst_rloc; }
int lisp2inetafi(uint16_t afi) { switch (afi) { case LISP_AFI_NO_ADDR: return(AF_UNSPEC); case LISP_AFI_IP: return(AF_INET); case LISP_AFI_IPV6: return(AF_INET6); case LISP_AFI_LCAF: return(LISP_AFI_LCAF); default: lispd_log_msg(LISP_LOG_DEBUG_2, "lisp2inetafi: unknown AFI (%d)", afi); return(ERR_AFI); } }
int inet2lispafi(int afi) { switch (afi) { case AF_UNSPEC: return (LISP_AFI_NO_ADDR); case AF_INET: return (LISP_AFI_IP); case AF_INET6: return (LISP_AFI_IPV6); case LISP_AFI_LCAF: return(LISP_AFI_LCAF); default: lispd_log_msg(LISP_LOG_DEBUG_2, "inet2lispafi: unknown AFI (%d)", afi); return (0); } }
int del_route( int afi, uint32_t ifindex, lisp_addr_t *dest, lisp_addr_t *src, lisp_addr_t *gw, uint32_t prefix_len, uint32_t metric, uint32_t table) { int result = BAD; result = modify_route(RTM_DELROUTE, afi, ifindex, dest, src, gw, prefix_len, metric, table); if (result == GOOD){ lispd_log_msg(LISP_LOG_DEBUG_1, "del_route: deleted route from the system"); } return (result); }
/* * Request to the kernel the routing table with the selected afi */ int request_route_table(uint32_t table, int afi) { struct nlmsghdr *nlh = NULL; struct rtmsg *rtm = NULL; char sndbuf[4096]; int rta_len = 0; int retval = 0; /* * Build the command */ memset(sndbuf, 0, 4096); nlh = (struct nlmsghdr *)sndbuf; rtm = (struct rtmsg *)(CO(sndbuf,sizeof(struct nlmsghdr))); rta_len = sizeof(struct rtmsg); nlh->nlmsg_len = NLMSG_LENGTH(rta_len); nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; nlh->nlmsg_type = RTM_GETROUTE; rtm->rtm_family = afi; if (table == 0){ rtm->rtm_table = RT_TABLE_MAIN; }else{ rtm->rtm_table = table; } rtm->rtm_protocol = RTPROT_STATIC; rtm->rtm_scope = RT_SCOPE_UNIVERSE; rtm->rtm_type = RTN_UNICAST; rtm->rtm_src_len = 0; rtm->rtm_tos = 0; rtm->rtm_dst_len = 0; retval = send(netlink_fd, sndbuf, NLMSG_LENGTH(rta_len), 0); if (retval < 0) { lispd_log_msg(LISP_LOG_CRIT, "request_route_table: send netlink command failed %s", strerror(errno)); exit_cleanup(); } return(GOOD); }
int add_pending_referral_cache_entry_to_list(lispd_pending_referral_cache_entry *pending_referral_cache_entry) { lispd_pending_referral_cache_list *pending_referral_list_elt = NULL; pending_referral_list_elt = (lispd_pending_referral_cache_list *)malloc(sizeof(lispd_pending_referral_cache_list)); if (pending_referral_list_elt == NULL){ lispd_log_msg(LISP_LOG_WARNING,"add_pending_referral_cache_entry_to_list: Unable to allocate memory for a lispd_pending_referral_cache_list"); return (BAD); } pending_referral_list_elt->pending_referral_cache_entry = pending_referral_cache_entry; if (pening_referrals_list == NULL){ pening_referrals_list = pending_referral_list_elt; pending_referral_list_elt->next = NULL; }else{ pending_referral_list_elt->next = pening_referrals_list; pening_referrals_list = pending_referral_list_elt; } return (GOOD); }
/* * Reseve and fill the memory required by a lcl_mapping_extended_info */ inline lcl_mapping_extended_info *new_lcl_mapping_extended_info() { lcl_mapping_extended_info *extended_info = NULL; if ((extended_info=(lcl_mapping_extended_info *)malloc(sizeof(lcl_mapping_extended_info)))==NULL){ lispd_log_msg(LISP_LOG_WARNING,"new_lcl_mapping_extended_info: Couldn't allocate memory for lcl_mapping_extended_info: %s", strerror(errno)); err = ERR_MALLOC; return (NULL); } extended_info->outgoing_balancing_locators_vecs.v4_balancing_locators_vec = NULL; extended_info->outgoing_balancing_locators_vecs.v6_balancing_locators_vec = NULL; extended_info->outgoing_balancing_locators_vecs.balancing_locators_vec = NULL; extended_info->outgoing_balancing_locators_vecs.v4_locators_vec_length = 0; extended_info->outgoing_balancing_locators_vecs.v6_locators_vec_length = 0; extended_info->outgoing_balancing_locators_vecs.locators_vec_length = 0; extended_info->head_not_init_locators_list = NULL; return(extended_info); }
uint8_t *build_map_reply_pkt( lispd_mapping_elt *mapping, lisp_addr_t *probed_rloc, map_reply_opts opts, uint64_t nonce, int *map_reply_msg_len) { uint8_t *packet; lispd_pkt_map_reply_t *map_reply_msg; lispd_pkt_mapping_record_t *mapping_record; *map_reply_msg_len = sizeof(lispd_pkt_map_reply_t) + pkt_get_mapping_record_length(mapping); if ((packet = malloc(*map_reply_msg_len)) == NULL) { lispd_log_msg(LISP_LOG_WARNING, "build_map_reply_pkt: Unable to allocate memory for Map Reply message(%d) %s", *map_reply_msg_len, strerror(errno)); return(NULL); } memset(packet, 0, *map_reply_msg_len); map_reply_msg = (lispd_pkt_map_reply_t *)packet; map_reply_msg->type = 2; if (opts.rloc_probe) map_reply_msg->rloc_probe = 1; if (opts.echo_nonce) map_reply_msg->echo_nonce = 1; map_reply_msg->record_count = 1; map_reply_msg->nonce = nonce; if (opts.send_rec) { mapping_record = (lispd_pkt_mapping_record_t *) CO(map_reply_msg, sizeof(lispd_pkt_map_reply_t)); if (pkt_fill_mapping_record(mapping_record, mapping, probed_rloc) == NULL) { free(packet); return(NULL); } } return(packet); }
int process_map_reply_probe_locator( uint8_t **offset, lispd_mapping_elt *mapping, uint64_t nonce, lispd_locator_elt **locator) { lispd_pkt_mapping_record_locator_t *pkt_locator = NULL; lispd_locator_elt *aux_locator = NULL; uint8_t *cur_ptr = NULL; *locator = NULL; cur_ptr = *offset; pkt_locator = (lispd_pkt_mapping_record_locator_t *)(cur_ptr); cur_ptr = (uint8_t *)&(pkt_locator->locator_afi); /* Extract locator from packet */ aux_locator = new_rmt_locator (&cur_ptr,UP, pkt_locator->priority, pkt_locator->weight, pkt_locator->mpriority, pkt_locator->mweight); if (aux_locator != NULL){ /* If the locator of the packed is probed, search the structure of the locator that represents the locator of tha packet */ if (pkt_locator->probed == TRUE){ *locator = get_locator_from_mapping(mapping, aux_locator->locator_addr); if (*locator == NULL){ lispd_log_msg(LISP_LOG_DEBUG_2,"get_map_reply_locator_from_mapping: The locator %s is not found in the mapping %s/%d", get_char_from_lisp_addr_t(*(aux_locator->locator_addr)), get_char_from_lisp_addr_t(mapping->eid_prefix), mapping->eid_prefix_length); return (ERR_NO_EXIST); } } }else{ if (err != ERR_AFI_LCAF_TYPE){ return (err); } } *offset = cur_ptr; return (GOOD); }
int process_ms_ack_reply( lispd_referral_cache_entry *referral_entry, lispd_pending_referral_cache_entry *pending_referral_entry) { lispd_referral_cache_entry *db_referral_entry = NULL; db_referral_entry = lookup_referral_cache_exact( referral_entry->mapping->eid_prefix, referral_entry->mapping->eid_prefix_length, DDT_END_PREFIX_DATABASES); /* Add referral cache entry to database */ if (db_referral_entry == NULL){ if (add_referral_cache_entry_to_db(referral_entry) != GOOD){ lispd_log_msg(LISP_LOG_DEBUG_1,"process_ms_ack_reply: Coudn't add referral cache entry for prefix %s/%d", get_char_from_lisp_addr_t(referral_entry->mapping->eid_prefix), referral_entry->mapping->eid_prefix_length); free_referral_cache_entry(referral_entry); remove_pending_referral_cache_entry_from_list(pending_referral_entry); return (BAD); } add_referral_cache_entry_to_tree(pending_referral_entry->previous_referral,referral_entry); }else{ /* Entry already exist. Replace it with the new data. Valid if the previous entry was a ms ack or ms not registered ack */ update_referral_cache_data(db_referral_entry, referral_entry); free_referral_cache_entry(referral_entry); referral_entry = db_referral_entry; } /* Program expiry time */ program_referral_expiry_timer(referral_entry); /* Finish process and remove the pending referral cache from the list */ if (pending_referral_entry->map_cache_entry->active == TRUE){ // We have received a map reply remove_pending_referral_cache_entry_from_list(pending_referral_entry); } else{ if (pending_referral_entry->ddt_request_retry_timer == NULL){ pending_referral_entry->ddt_request_retry_timer = create_timer (DDT_MAP_REQ_RETRY_MS_ACK_TIMER); } pending_referral_entry->previous_referral = referral_entry; start_timer(pending_referral_entry->ddt_request_retry_timer, LISPD_INITIAL_MRQ_TIMEOUT, send_map_request_ddt_map_reply_miss, (void *)pending_referral_entry); } return (GOOD); }
uint16_t get_lisp_afi( int afi, int *len) { switch (afi) { case AF_INET: if (len) *len = sizeof(struct in_addr); return((uint16_t)LISP_AFI_IP); case AF_INET6: if (len) *len = sizeof(struct in6_addr); return((uint16_t)LISP_AFI_IPV6); default: lispd_log_msg(LISP_LOG_DEBUG_2, "get_lisp_afi: unknown AFI (%d)", afi); return (BAD); } }
int copy_addr_from_sockaddr( struct sockaddr *addr, lisp_addr_t *lisp_addr) { lisp_addr->afi = addr->sa_family; switch(lisp_addr->afi ) { case AF_INET: lisp_addr->address.ip = ((struct sockaddr_in *)addr)->sin_addr; return (GOOD); case AF_INET6: lisp_addr->address.ipv6 = ((struct sockaddr_in6 *)addr)->sin6_addr; return (GOOD); } lispd_log_msg( LISP_LOG_WARNING, "copy_addr_from_sockaddr: Unknown address family %d", addr->sa_family); return (BAD); }
void exit_cleanup(void) { /* Remove source routing tables */ remove_created_rules(); /* Close timer file descriptors */ close(timers_fd); /* Close receive sockets */ close(tun_receive_fd); close(ipv4_data_input_fd); close(ipv4_control_input_fd); close(ipv6_data_input_fd); close(ipv6_control_input_fd); /* Close send sockets */ close_output_sockets(); /* Close netlink socket */ close(netlink_fd); lispd_log_msg(LISP_LOG_INFO,"Exiting ..."); exit(EXIT_SUCCESS); }
void dump_iface_list(int log_level) { lispd_iface_list_elt *interface_list = head_interface_list; lispd_iface_mappings_list *mapping_list = NULL; char str[4000]; if (head_interface_list == NULL || is_loggable(log_level) == FALSE){ return; } sprintf(str,"*** LISP RLOC Interfaces List ***\n\n"); while (interface_list){ sprintf(str + strlen(str),"== %s (%s)==\n",interface_list->iface->iface_name, interface_list->iface->status ? "Up" : "Down"); if (interface_list->iface->ipv4_address){ sprintf(str + strlen(str)," IPv4 RLOC: %s \n",get_char_from_lisp_addr_t(*(interface_list->iface->ipv4_address))); sprintf(str + strlen(str)," -- LIST mappings -- \n"); mapping_list = interface_list->iface->head_mappings_list; while (mapping_list){ if (mapping_list->use_ipv4_address == TRUE){ sprintf(str + strlen(str)," %s/%d\n",get_char_from_lisp_addr_t(mapping_list->mapping->eid_prefix), mapping_list->mapping->eid_prefix_length); } mapping_list = mapping_list->next; } } if (interface_list->iface->ipv6_address){ sprintf(str + strlen(str)," IPv6 RLOC: %s \n",get_char_from_lisp_addr_t(*(interface_list->iface->ipv6_address))); sprintf(str + strlen(str)," -- LIST mappings -- \n"); mapping_list = interface_list->iface->head_mappings_list; while (mapping_list){ if (mapping_list->use_ipv6_address == TRUE){ sprintf(str + strlen(str)," %s/%d\n",get_char_from_lisp_addr_t(mapping_list->mapping->eid_prefix), mapping_list->mapping->eid_prefix_length); } mapping_list = mapping_list->next; } } interface_list = interface_list->next; } lispd_log_msg(log_level,"%s",str); }
/* * Reseve and fill the memory required by a rmt_mapping_extended_info */ inline rmt_mapping_extended_info *new_rmt_mapping_extended_info() { rmt_mapping_extended_info *extended_info = NULL; if ((extended_info=(rmt_mapping_extended_info *)malloc(sizeof(rmt_mapping_extended_info)))==NULL){ lispd_log_msg(LISP_LOG_WARNING,"new_rmt_mapping_extended_info: Couldn't allocate memory for rmt_mapping_extended_info: %s", strerror(errno)); err = ERR_MALLOC; return (NULL); } extended_info->rmt_balancing_locators_vecs.v4_balancing_locators_vec = NULL; extended_info->rmt_balancing_locators_vecs.v6_balancing_locators_vec = NULL; extended_info->rmt_balancing_locators_vecs.balancing_locators_vec = NULL; extended_info->rmt_balancing_locators_vecs.v4_locators_vec_length = 0; extended_info->rmt_balancing_locators_vecs.v6_locators_vec_length = 0; extended_info->rmt_balancing_locators_vecs.locators_vec_length = 0; return (extended_info); }
int process_delegation_hole_reply( lispd_referral_cache_entry *referral_entry, lispd_pending_referral_cache_entry *pending_referral_entry) { lispd_referral_cache_entry *db_referral_entry = NULL; db_referral_entry = lookup_referral_cache_exact( referral_entry->mapping->eid_prefix, referral_entry->mapping->eid_prefix_length, DDT_END_PREFIX_DATABASES); if (db_referral_entry != NULL && db_referral_entry->act_entry_type != DELEGATION_HOLE){ del_referral_cache_entry_from_db(db_referral_entry); db_referral_entry = NULL; } if (db_referral_entry == NULL){ /* Add referral cache entry to database */ if (add_referral_cache_entry_to_db(referral_entry) != GOOD){ lispd_log_msg(LISP_LOG_DEBUG_1,"process_delegation_hole_reply: Coudn't add referral cache entry for prefix %s/%d", get_char_from_lisp_addr_t(referral_entry->mapping->eid_prefix), referral_entry->mapping->eid_prefix_length); free_referral_cache_entry(referral_entry); remove_pending_referral_cache_entry_from_list(pending_referral_entry); return (BAD); } add_referral_cache_entry_to_tree(pending_referral_entry->previous_referral,referral_entry); }else{ /* Entry already exist. Replace it with the new data.*/ update_referral_cache_data(db_referral_entry, referral_entry); free_referral_cache_entry(referral_entry); referral_entry = db_referral_entry; } /*Remove entry from pending list and activate map cache*/ if (activate_negative_map_cache (pending_referral_entry->map_cache_entry, referral_entry->mapping->eid_prefix, referral_entry->mapping->eid_prefix_length,referral_entry->ttl,MAPPING_ACT_NO_ACTION)!=GOOD){ del_map_cache_entry_from_db(pending_referral_entry->map_cache_entry->mapping->eid_prefix, pending_referral_entry->map_cache_entry->mapping->eid_prefix_length); } remove_pending_referral_cache_entry_from_list(pending_referral_entry); /* Program expiry time */ program_referral_expiry_timer(referral_entry); return(GOOD); }
void process_nl_add_address (struct nlmsghdr *nlh) { struct ifaddrmsg *ifa = NULL; struct rtattr *rth = NULL; int iface_index = 0; int rt_length = 0; lispd_iface_elt *iface = NULL; lisp_addr_t new_addr; char iface_name[IF_NAMESIZE]; /* * Get the new address from the net link message */ ifa = (struct ifaddrmsg *) NLMSG_DATA (nlh); iface_index = ifa->ifa_index; iface = get_interface_from_index(iface_index); if (iface == NULL) { if_indextoname(iface_index, iface_name); lispd_log_msg(LISP_LOG_DEBUG_2, "process_nl_add_address: the netlink message is not for any interface associated with RLOCs (%s / %d)", iface_name, iface_index); return; } rth = IFA_RTA (ifa); rt_length = IFA_PAYLOAD (nlh); for (; rt_length && RTA_OK (rth, rt_length); rth = RTA_NEXT (rth,rt_length)) { if (rth->rta_type == IFA_ADDRESS) { if (ifa->ifa_family == AF_INET) { memcpy (&(new_addr.address),(struct in_addr *)RTA_DATA(rth),sizeof(struct in_addr)); new_addr.afi = AF_INET; } else if (ifa->ifa_family == AF_INET6) { memcpy (&(new_addr.address),(struct in6_addr *)RTA_DATA(rth),sizeof(struct in6_addr)); new_addr.afi = AF_INET6; } process_address_change (iface, new_addr); } } }
int get_locators_length(lispd_locators_list *locators_list) { int sum = 0; while (locators_list) { switch (locators_list->locator->locator_addr->afi) { case AF_INET: sum += sizeof(struct in_addr); break; case AF_INET6: sum += sizeof(struct in6_addr); break; default: /* It should never happen*/ lispd_log_msg(LISP_LOG_DEBUG_2, "get_locators_length: Uknown AFI (%d) - It should never happen", locators_list->locator->locator_addr->afi); break; } locators_list = locators_list->next; } return(sum); }
/* * This function deletes a specific ip rule to * kernel's rule list */ int del_rule( int afi, int if_index, uint8_t table, uint32_t priority, uint8_t type, lisp_addr_t *src_addr, int src_plen, lisp_addr_t *dst_addr, int dst_plen, int flags) { int result = BAD; result = modify_rule(afi, if_index, RTM_DELRULE, table,priority, type, src_addr, src_plen, dst_addr, dst_plen, flags); if (result == GOOD){ lispd_log_msg(LISP_LOG_DEBUG_1, "del_rule: Removed rule for source routing of src addr: %s", get_char_from_lisp_addr_t(*src_addr)); } return (result); }
/* * Generates a basic mapping */ lispd_mapping_elt *new_mapping( lisp_addr_t eid_prefix, uint8_t eid_prefix_length, int iid) { lispd_mapping_elt *mapping = NULL; if ((mapping = (lispd_mapping_elt *)malloc(sizeof(lispd_mapping_elt)))==NULL){ lispd_log_msg(LISP_LOG_WARNING,"Couldn't allocate memory for lispd_mapping_elt: %s", strerror(errno)); return (NULL); } mapping->eid_prefix = eid_prefix; mapping->eid_prefix_length = eid_prefix_length; mapping->iid = iid; mapping->locator_count = 0; mapping->head_v4_locators_list = NULL; mapping->head_v6_locators_list = NULL; mapping->extended_info = NULL; return (mapping); }
void *pkt_fill_eid( void *offset, lispd_mapping_elt *mapping) { uint16_t *afi_ptr; lispd_pkt_lcaf_t *lcaf_ptr; lispd_pkt_lcaf_iid_t *iid_ptr; void *eid_ptr; int eid_addr_len; afi_ptr = (uint16_t *)offset; eid_addr_len = get_addr_len(mapping->eid_prefix.afi); /* For negative IID values, we skip LCAF/IID field */ if (mapping->iid < 0) { *afi_ptr = htons(get_lisp_afi(mapping->eid_prefix.afi, NULL)); eid_ptr = CO(offset, sizeof(uint16_t)); } else { *afi_ptr = htons(LISP_AFI_LCAF); lcaf_ptr = (lispd_pkt_lcaf_t *) CO(offset, sizeof(uint16_t)); iid_ptr = (lispd_pkt_lcaf_iid_t *) CO(lcaf_ptr, sizeof(lispd_pkt_lcaf_t)); eid_ptr = (void *) CO(iid_ptr, sizeof(lispd_pkt_lcaf_iid_t)); lcaf_ptr->rsvd1 = 0; lcaf_ptr->flags = 0; lcaf_ptr->type = 2; lcaf_ptr->rsvd2 = 0; /* This can be IID mask-len, not yet supported */ lcaf_ptr->len = htons(sizeof(lispd_pkt_lcaf_iid_t) + eid_addr_len); iid_ptr->iid = htonl(mapping->iid); iid_ptr->afi = htons(mapping->eid_prefix.afi); } if ((copy_addr(eid_ptr,&(mapping->eid_prefix), 0)) == 0) { lispd_log_msg(LISP_LOG_DEBUG_3, "pkt_fill_eid: copy_addr failed"); return NULL; } return CO(eid_ptr, eid_addr_len); }
lispd_referral_cache_entry *new_referral_cache_entry( lispd_mapping_elt *mapping, int act_entry_type, int ttl) { lispd_referral_cache_entry *referral_cache_entry = NULL; referral_cache_entry = (lispd_referral_cache_entry *)malloc(sizeof(lispd_referral_cache_entry)); if (referral_cache_entry == NULL){ lispd_log_msg(LISP_LOG_WARNING,"new_referral_cache_entry: Unable to allocate memory for a referral cache entry"); return (NULL); } referral_cache_entry->mapping = mapping; referral_cache_entry->act_entry_type = act_entry_type; referral_cache_entry->ttl = ttl; referral_cache_entry->parent_node = NULL; referral_cache_entry->children_nodes = NULL; referral_cache_entry->expiry_ddt_cache_timer = NULL; referral_cache_entry->src_inf_ddt_node_locator_addr.afi = AF_UNSPEC; return (referral_cache_entry); }
/* * Request to the kernel the address associated with the interface and afi selected */ int request_address( int ifa_index, int afi) { struct nlmsghdr *nlh = NULL; struct ifaddrmsg *addr_msg = NULL; char sndbuf[4096]; int addr_msg_len = 0; int retval = 0; /* * Build the command */ memset(sndbuf, 0, 4096); nlh = (struct nlmsghdr *)sndbuf; addr_msg = (struct ifaddrmsg *)(CO(sndbuf,sizeof(struct nlmsghdr))); addr_msg_len = sizeof(struct ifaddrmsg); nlh->nlmsg_len = NLMSG_LENGTH(addr_msg_len); nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; nlh->nlmsg_type = RTM_GETADDR; addr_msg->ifa_family = afi; addr_msg->ifa_prefixlen = 0; addr_msg->ifa_flags = IFA_F_PERMANENT; addr_msg->ifa_scope = IFA_LOCAL; addr_msg->ifa_index = ifa_index; retval = send(netlink_fd, sndbuf, NLMSG_LENGTH(addr_msg_len), 0); if (retval < 0) { lispd_log_msg(LISP_LOG_CRIT, "request_address: send netlink command failed %s", strerror(errno)); return(BAD); } return(GOOD); }
int copy_addr( void *a1, lisp_addr_t *a2, int convert) { switch (a2->afi) { case AF_INET: if (convert) ((struct in_addr *) a1)->s_addr = htonl(a2->address.ip.s_addr); else ((struct in_addr *) a1)->s_addr = a2->address.ip.s_addr; return(sizeof(struct in_addr)); case AF_INET6: memcpy(((struct in6_addr *) a1)->s6_addr, a2->address.ipv6.s6_addr, sizeof(struct in6_addr)); return(sizeof(struct in6_addr)); default: lispd_log_msg(LISP_LOG_DEBUG_2, "copy_addr: Unknown AFI (%d)", a2->afi); return(ERR_AFI); } }
int opent_netlink_socket() { int netlink_fd = 0; struct sockaddr_nl addr; memset(&addr, 0, sizeof(addr)); addr.nl_family = AF_NETLINK; addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR | RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE; netlink_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (netlink_fd < 0) { lispd_log_msg(LISP_LOG_ERR, "opent_netlink_socket: Failed to connect to netlink socket"); return(BAD); } bind(netlink_fd, (struct sockaddr *) &addr, sizeof(addr)); return (netlink_fd); }