void Generate4adic(int op, int len, AMODE *ap1, AMODE *ap2, AMODE *ap3, AMODE *ap4) { struct ocode *cd; cd = (struct ocode *)allocx(sizeof(struct ocode)); cd->predop = 1; cd->pregreg = 15; cd->opcode = op; cd->length = len; cd->oper1 = copy_addr(ap1); cd->oper2 = copy_addr(ap2); cd->oper3 = copy_addr(ap3); cd->oper4 = copy_addr(ap4); AddToPeepList(cd); }
void GeneratePredicatedDiadic(int pop, int pr, int op, int len, AMODE *ap1, AMODE *ap2) { struct ocode *cd; cd = (struct ocode *)allocx(sizeof(struct ocode)); cd->predop = pop; cd->pregreg = pr; cd->opcode = op; cd->length = len; cd->oper1 = copy_addr(ap1); cd->oper2 = copy_addr(ap2); cd->oper3 = NULL; cd->oper4 = NULL; currentFn->UsesPredicate = TRUE; AddToPeepList(cd); }
int mgetsockname(Entry *e, void *p1, void *p2, void *p3, void *p4, void *p5) { xsockaddr_in tmp; xsockaddr_in *addr = (xsockaddr_in *)p3; int *addrlen = (int *)p4; if (Debug > 0) { s16_debug_printf("getsockname"); } if (!addrlen || !addr) return EINVAL; if (!*addrlen) return 0; tmp.sin_family = AF_INET; IncBusy(); tmp.sin_port = TCPIPGetSourcePort(e->ipid); tmp.sin_addr = TCPIPGetMyIPAddress(); DecBusy(); copy_addr(&tmp, addr, addrlen); return 0; }
void PeepoptLea(struct ocode *ip) { struct ocode *ip2; int whop; whop = 0; ip2 = ip->fwd; if (!ip2) return; if (ip2->opcode != op_push) return; whop = ((ip2->oper1 != NULL) ? 1 : 0) + ((ip2->oper2 != NULL) ? 1 : 0) + ((ip2->oper3 != NULL) ? 1 : 0) + ((ip2->oper4 != NULL) ? 1 : 0); if (whop > 1) return; // Pushing a single register if (ip2->oper1->mode != am_reg) return; // And it's the same register as the LEA if (ip2->oper1->preg != ip->oper1->preg) return; ip->opcode = op_pea; ip->oper1 = copy_addr(ip->oper2); ip->oper2 = NULL; ip->fwd = ip2->fwd; }
static void add_flow_list P4 (FLOWLISTENTRY **, RegUsage, REG, reg, ADDRESS *, ap, ITYPE, type) { FLOWLISTENTRY *Entry; ADDRESS *ap1; IVAL offset; if ((ap->mode == am_ainc) || (ap->mode == am_adec)) { /* ainc could be treated as am_indx with offset = -increment * in list, sinc addressregister points increment farther than * value was written * except it was stored with itself (arn, *arn++) */ if ((ap->preg == reg) || (ap->u.offset->nodetype != en_icon)) { return; } ap1 = copy_addr (ap, am_indx); offset = (ap->mode == am_ainc) ? -ap->u.offset->v.i : ap->u.offset->v.i; ap1->u.offset = mk_const ((long) offset); ap = ap1; } if ((ap->mode == am_preinc) || (ap->mode == am_predec)) { /* preinc could be treated as am_ind in list, sinc * addressregister points still to the same location * except it was stored with itself (arn, *++arn) */ if (ap->preg == reg) { return; } ap = copy_addr (ap, am_ind); } /* * check if equivalent entry is already in list */ if (search_flowlist_entry (*RegUsage, ap, type) == NULL) { Entry = (FLOWLISTENTRY *) xalloc ((size_t) sizeof (FLOWLISTENTRY)); Entry->ap = ap; #ifdef NO_MIX_WITH_FLOAT Entry->type = type; #endif Entry->next = *RegUsage; *RegUsage = Entry; } }
void *pkt_fill_mapping_record( lispd_pkt_mapping_record_t *rec, lispd_mapping_elt *mapping, lisp_addr_t *probed_rloc) { int cpy_len = 0; lispd_pkt_mapping_record_locator_t *loc_ptr = NULL; lispd_locators_list *locators_list[2] = {NULL,NULL}; lispd_locator_elt *locator = NULL; int ctr = 0; if ((rec == NULL) || (mapping == NULL)) return NULL; rec->ttl = htonl(DEFAULT_MAP_REGISTER_TIMEOUT); rec->locator_count = mapping->locator_count; rec->eid_prefix_length = mapping->eid_prefix_length; rec->action = 0; rec->authoritative = 1; rec->version_hi = 0; rec->version_low = 0; loc_ptr = (lispd_pkt_mapping_record_locator_t *)pkt_fill_eid(&(rec->eid_prefix_afi), mapping); if (loc_ptr == NULL){ return NULL; } locators_list[0] = mapping->head_v4_locators_list; locators_list[1] = mapping->head_v6_locators_list; for (ctr = 0 ; ctr < 2 ; ctr++){ while (locators_list[ctr]) { locator = locators_list[ctr]->locator; loc_ptr->priority = locator->priority; loc_ptr->weight = locator->weight; loc_ptr->mpriority = locator->mpriority; loc_ptr->mweight = locator->mweight; loc_ptr->local = 1; if (probed_rloc != NULL && compare_lisp_addr_t(locator->locator_addr,probed_rloc)==0){ loc_ptr->probed = 1; } loc_ptr->reachable = *(locator->state); loc_ptr->locator_afi = htons(get_lisp_afi(locator->locator_addr->afi,NULL)); if ((cpy_len = copy_addr((void *) CO(loc_ptr, sizeof(lispd_pkt_mapping_record_locator_t)), locator->locator_addr, 0)) == 0) { LISPD_LOG(LISP_LOG_DEBUG_3, "copy_addr failed for locator %s", get_char_from_lisp_addr_t(*(locator->locator_addr))); return(NULL); } loc_ptr = (lispd_pkt_mapping_record_locator_t *) CO(loc_ptr, (sizeof(lispd_pkt_mapping_record_locator_t) + cpy_len)); locators_list[ctr] = locators_list[ctr]->next; } } return (void *)loc_ptr; }
static void gen_netmask(struct sockaddr **r, int af, union sockany *sa, int prefixlen) { uint8_t addr[16] = {0}; int i; if (prefixlen > 8*sizeof(addr)) prefixlen = 8*sizeof(addr); i = prefixlen / 8; memset(addr, 0xff, i); if (i < sizeof(addr)) addr[i++] = 0xff << (8 - (prefixlen % 8)); copy_addr(r, af, sa, addr, sizeof(addr), 0); }
void GenerateDiadic(int op, int len, AMODE *ap1, AMODE *ap2) { struct ocode *cd; cd = (struct ocode *)xalloc(sizeof(struct ocode)); cd->predop = 1; cd->pregreg = 15; cd->opcode = op; cd->length = len; cd->oper1 = copy_addr(ap1); cd->oper2 = copy_addr(ap2); if (ap2) { if (ap2->mode == am_ind || ap2->mode==am_indx) { if (ap2->preg==regSP || ap2->preg==regBP) cd->opcode |= op_ss; } } cd->oper3 = NULL; cd->oper4 = NULL; AddToPeepList(cd); }
static int sock_accept( Entry *e, int *newfd, selwakeupfx fx, xsockaddr_in *addr, int *addrlen) { int ipid; Word t; Entry *child; IncBusy(); ipid = TCPIPAcceptTCP(e->ipid, 0); t = _toolErr; DecBusy(); if (t == terrNOINCOMING) return EAGAIN; if (t == terrNOTSERVER) return EINVAL; if (t) return ENETDOWN; // ? child = create_entry(ipid); if (!child) { TCPIPAbortTCP(ipid); TCPIPLogout(ipid); return ENOMEM; } // set up child options. child->_TYPE = SOCK_STREAM; child->select_fx = fx; // address... if (addr && addrlen && *addrlen) { destRec dr; xsockaddr_in tmp; IncBusy(); TCPIPGetDestination(ipid, &dr); DecBusy(); tmp.sin_family = AF_INET; tmp.sin_port = dr.drDestPort; tmp.sin_addr = dr.drDestIP; copy_addr(&tmp, addr, addrlen); } *newfd = ipid; return 0; }
void PeepoptPushPop(struct ocode *ip) { struct ocode *ip2,*ip3,*ip4; if (!isTable888) return; if (ip->oper1->mode == am_immed) return; ip2 = ip->fwd; if (!ip2) return; if (ip2->opcode!=ip->opcode) return; if (ip2->oper1->mode==am_immed) return; ip->oper2 = copy_addr(ip2->oper1); ip->fwd = ip2->fwd; ip3 = ip2->fwd; if (!ip3) return; if (ip3->opcode!=ip->opcode) return; if (ip3->oper1->mode==am_immed) return; ip->oper3 = copy_addr(ip3->oper1); ip->fwd = ip3->fwd; ip4 = ip3->fwd; if (!ip4) return; if (ip4->opcode!=ip->opcode) return; if (ip4->oper1->mode==am_immed) return; ip->oper4 = copy_addr(ip4->oper1); ip->fwd = ip4->fwd; }
static const response* validate_sender(str* sender, str* params) { struct rule* rule; const response* r; if (!loaded) return 0; copy_addr(sender, &saved_sender, &sender_domain); for (rule = sender_rules; rule != 0; rule = rule->next) if (matches(&rule->sender, &saved_sender, &sender_domain)) { r = apply_rule(rule); if (rule->code != 'n') return r; } return 0; (void)params; }
static const response* validate_recipient(str* recipient, str* params) { struct rule* rule; const response* r; if (!loaded) return 0; copy_addr(recipient, &laddr, &rdomain); for (rule = recip_rules; rule != 0; rule = rule->next) if (matches(&rule->sender, &saved_sender, &sender_domain) && matches(&rule->recipient, &laddr, &rdomain)) { str_cat(recipient, &rule->relayclient); r = apply_rule(rule); if (rule->code != 'n') return r; } return 0; (void)params; }
void PeepoptLc0i(struct ocode *ip) { struct ocode *ip2; if (!isFISA64) return; ip2 = ip->fwd; if (!ip2) return; if (ip2->opcode != op_push) return; if (ip->oper2->offset->i > 0x1fffLL || ip->oper2->offset->i <= -0x1fffLL) return; ip->opcode = op_push; ip->oper1 = copy_addr(ip->oper2); ip->oper2 = NULL; ip->fwd = ip2->fwd; }
void GenerateMonadic(int op, int len, AMODE *ap1) { dfs.printf("Enter GenerateMonadic\r\n"); struct ocode *cd; dfs.printf("A"); cd = (struct ocode *)allocx(sizeof(struct ocode)); dfs.printf("B"); cd->predop = 1; cd->pregreg = 15; cd->opcode = op; cd->length = len; cd->oper1 = copy_addr(ap1); dfs.printf("C"); cd->oper2 = NULL; cd->oper3 = NULL; cd->oper4 = NULL; dfs.printf("D"); AddToPeepList(cd); dfs.printf("Leave GenerateMonadic\r\n"); }
void PeepoptLdi(struct ocode *ip) { struct ocode *ip2; if (!isFISA64) return; ip2 = ip->fwd; if (!ip2) return; if (ip2->opcode != op_push) return; if (ip2->oper1->mode != am_reg) return; if (ip2->oper1->preg != ip->oper1->preg) return; ip->opcode = op_push; ip->oper1 = copy_addr(ip->oper2); ip->oper2 = NULL; ip->fwd = ip2->fwd; }
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(LISP_LOG_DEBUG_3, "copy_addr failed"); return NULL; } return CO(eid_ptr, eid_addr_len); }
/* * build_map_reply() * * Create the response packet given a locator chain and * destination address. */ lispd_pkt_map_reply_t *build_map_reply(uint32_t probe_source, int probe, lispd_locator_chain_t *loc_chain, char *nonce, int *len) { lispd_pkt_map_reply_t *reply_pkt; lispd_pkt_map_reply_eid_prefix_record_t *eid_rec; lispd_pkt_map_reply_locator_record_t *loc_rec; lisp_addr_t loc_addr; lispd_locator_chain_elt_t *locator_chain_elt; lispd_if_t *intf; uint32_t total_loc_length = 0; uint32_t eid_afi = 0; uint32_t pkt_length = 0; uint32_t addr_len = 0; uint32_t afi_len = 0; uint32_t loc_count = 0; uint32_t loc_afi = 0; /* * Like in map registers, assume one record with * several locators. */ locator_chain_elt = loc_chain->head; total_loc_length = get_locator_length_and_count(locator_chain_elt, &loc_count); eid_afi = get_lisp_afi(loc_chain->eid_prefix.afi, &afi_len); pkt_length = sizeof(lispd_pkt_map_reply_t) + sizeof(lispd_pkt_map_reply_eid_prefix_record_t) + // XXX Just one for now afi_len + (loc_count * sizeof(lispd_pkt_map_reply_locator_record_t)) + total_loc_length; if ((reply_pkt = (lispd_pkt_map_reply_t *)malloc(pkt_length)) == NULL) { log_msg(INFO, "malloc (map-reply packet): %s", strerror(errno)); return NULL; } memset(reply_pkt, 0, pkt_length); reply_pkt->type = LISP_MAP_REPLY; reply_pkt->probe = probe; reply_pkt->echononce = 0; reply_pkt->count = 1; memcpy(&reply_pkt->nonce, nonce, sizeof(uint64_t)); eid_rec = (lispd_pkt_map_reply_eid_prefix_record_t *)CO(reply_pkt, sizeof(lispd_pkt_map_reply_t)); eid_rec->act = 0; eid_rec->authoritative = 1; eid_rec->loc_count = loc_count; eid_rec->eid_afi = htons(eid_afi); eid_rec->eid_masklen = loc_chain->eid_prefix_length; eid_rec->ttl = htonl(DEFAULT_MAP_REGISTER_TIMEOUT); // Should be different for Map-replies? eid_rec->version = 0; /* * Advance to the prefix */ if ((addr_len = copy_addr((void *)CO(eid_rec, sizeof(lispd_pkt_map_reply_eid_prefix_record_t)), &(loc_chain->eid_prefix), loc_chain->eid_prefix.afi, 0)) == 0) { log_msg(INFO, "eid prefix (%s) has an unknown afi (%d)", loc_chain->eid_name, loc_chain->eid_prefix.afi); return NULL; } /* * skip over the fixed part and eid prefix, and build * the locators */ loc_rec = (lispd_pkt_map_reply_locator_record_t *) CO(eid_rec,(sizeof(lispd_pkt_mapping_record_t) + addr_len)); while (locator_chain_elt) { intf = locator_chain_elt->interface; /* * Check interface status and get the address */ if (intf && (intf->flags & IFF_UP)) { if (intf->nat_type != NATOff) { if (is_nat_complete(intf)) { // Skip untranslated NAT interfaces memcpy(&loc_addr, &intf->nat_address.address.ip.s_addr, sizeof(lisp_addr_t)); } else { locator_chain_elt = locator_chain_elt->next; continue; } } else if (intf->address.address.ip.s_addr != 0) { // IPV4 only and local interface only XXX memcpy(&loc_addr, &intf->address, sizeof(lisp_addr_t)); } else { locator_chain_elt = locator_chain_elt->next; continue; // No address? Not included. } } else { locator_chain_elt = locator_chain_elt->next; continue; } // Need to handle non-local locators XXX loc_rec->priority = locator_chain_elt->priority; loc_rec->weight = locator_chain_elt->weight; loc_rec->mpriority = locator_chain_elt->mpriority; loc_rec->mweight = locator_chain_elt->mweight; loc_rec->reachable = 1; loc_rec->probe = probe; loc_rec->local = 1; if (intf) { loc_afi = intf->address.afi; } else { loc_afi = locator_chain_elt->locator_afi; } loc_rec->loc_afi = htons(get_lisp_afi(loc_afi, NULL)); /* * skip over the mapping record locator, and copy the locator * to that address... */ if ((addr_len = copy_addr((void *) CO(loc_rec, sizeof(lispd_pkt_map_reply_locator_record_t)), &(loc_addr), loc_afi, 0)) == 0) { log_msg(INFO, "locator (%s) has an unknown afi (%d)", locator_chain_elt->locator_name, locator_chain_elt->locator_afi); return NULL; } /* * get the next locator in the chain and wind * loc_rec to the right place */ loc_rec = (lispd_pkt_map_reply_locator_record_t *) CO(loc_rec, (sizeof(lispd_pkt_map_reply_locator_record_t) + addr_len)); locator_chain_elt = locator_chain_elt->next; } *len = pkt_length; return reply_pkt; }
static void new_flow_list P4 (FLOWLISTENTRY **, RegUsage, REG, reg, ADDRESS *, ap, ITYPE, type) { FLOWLISTENTRY *Entry; ADDRESS *ap1; IVAL offset; switch (ap->mode) { case am_indx2: case am_indxs: if (ap->sreg == reg) { *RegUsage = NULL; return; } /*FALLTHRU */ case am_ind: case am_const_ind: case am_indx: if (ap->preg == reg) { *RegUsage = NULL; return; } break; case am_preinc: case am_predec: /* * preinc could be treated as am_ind in list, sinc * addressregister points still to the same location * except it was loaded with itself (*++arn, arn) */ if (ap->preg == reg) { *RegUsage = NULL; return; } ap = copy_addr (ap, am_ind); break; case am_ainc: case am_adec: /* * ainc could be treated as am_indx with offset = -increment * in list, sinc addressregister points increment farther than * value was written * except it was loaded with itself (*arn++, arn) */ if ((ap->preg == reg) || (ap->u.offset->nodetype != en_icon)) { *RegUsage = NULL; return; } ap1 = copy_addr (ap, am_indx); offset = (ap->mode == am_ainc) ? -ap->u.offset->v.i : ap->u.offset->v.i; ap1->u.offset = mk_const (offset); ap = ap1; break; default: break; } Entry = (FLOWLISTENTRY *) xalloc ((size_t) sizeof (FLOWLISTENTRY)); Entry->ap = ap; #ifdef NO_MIX_WITH_FLOAT Entry->type = type; #endif Entry->next = NULL; *RegUsage = Entry; }
static int netlink_msg_to_ifaddr(void* pctx, struct nlmsghdr* h) { struct ifaddrs_ctx* ctx = pctx; struct ifaddrs_storage *ifs, *ifs0; struct ifinfomsg* ifi = NLMSG_DATA(h); struct ifaddrmsg* ifa = NLMSG_DATA(h); struct rtattr* rta; int stats_len = 0; if (h->nlmsg_type == RTM_NEWLINK) { for (rta = NLMSG_RTA(h, sizeof(*ifi)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) { if (rta->rta_type != IFLA_STATS) continue; stats_len = RTA_DATALEN(rta); break; } } else { for (ifs0 = ctx->hash[ifa->ifa_index % IFADDRS_HASH_SIZE]; ifs0; ifs0 = ifs0->hash_next) if (ifs0->index == ifa->ifa_index) break; if (!ifs0) return 0; } ifs = calloc(1, sizeof(struct ifaddrs_storage) + stats_len); if (ifs == 0) return -1; if (h->nlmsg_type == RTM_NEWLINK) { ifs->index = ifi->ifi_index; ifs->ifa.ifa_flags = ifi->ifi_flags; for (rta = NLMSG_RTA(h, sizeof(*ifi)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) { switch (rta->rta_type) { case IFLA_IFNAME: if (RTA_DATALEN(rta) < sizeof(ifs->name)) { memcpy(ifs->name, RTA_DATA(rta), RTA_DATALEN(rta)); ifs->ifa.ifa_name = ifs->name; } break; case IFLA_ADDRESS: copy_lladdr(&ifs->ifa.ifa_addr, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifi->ifi_index, ifi->ifi_type); break; case IFLA_BROADCAST: copy_lladdr(&ifs->ifa.ifa_broadaddr, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifi->ifi_index, ifi->ifi_type); break; case IFLA_STATS: ifs->ifa.ifa_data = (void*)(ifs + 1); memcpy(ifs->ifa.ifa_data, RTA_DATA(rta), RTA_DATALEN(rta)); break; } } if (ifs->ifa.ifa_name) { unsigned int bucket = ifs->index % IFADDRS_HASH_SIZE; ifs->hash_next = ctx->hash[bucket]; ctx->hash[bucket] = ifs; } } else { ifs->ifa.ifa_name = ifs0->ifa.ifa_name; ifs->ifa.ifa_flags = ifs0->ifa.ifa_flags; for (rta = NLMSG_RTA(h, sizeof(*ifa)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) { switch (rta->rta_type) { case IFA_ADDRESS: /* If ifa_addr is already set we, received an IFA_LOCAL before * so treat this as destination address */ if (ifs->ifa.ifa_addr) copy_addr(&ifs->ifa.ifa_dstaddr, ifa->ifa_family, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index); else copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_family, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index); break; case IFA_BROADCAST: copy_addr(&ifs->ifa.ifa_broadaddr, ifa->ifa_family, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index); break; case IFA_LOCAL: /* If ifa_addr is set and we get IFA_LOCAL, assume we have * a point-to-point network. Move address to correct field. */ if (ifs->ifa.ifa_addr) { ifs->ifu = ifs->addr; ifs->ifa.ifa_dstaddr = &ifs->ifu.sa; memset(&ifs->addr, 0, sizeof(ifs->addr)); } copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_family, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index); break; case IFA_LABEL: if (RTA_DATALEN(rta) < sizeof(ifs->name)) { memcpy(ifs->name, RTA_DATA(rta), RTA_DATALEN(rta)); ifs->ifa.ifa_name = ifs->name; } break; } } if (ifs->ifa.ifa_addr) gen_netmask(&ifs->ifa.ifa_netmask, ifa->ifa_family, &ifs->netmask, ifa->ifa_prefixlen); } if (ifs->ifa.ifa_name) { if (!ctx->first) ctx->first = ifs; if (ctx->last) ctx->last->ifa.ifa_next = &ifs->ifa; ctx->last = ifs; } else { free(ifs); } return 0; }
uint8_t *pkt_fill_mapping_record( lispd_pkt_mapping_record_t *rec, lispd_mapping_elt *mapping, lisp_addr_t *probed_rloc) { uint8_t *cur_ptr = NULL; int cpy_len = 0; lispd_pkt_mapping_record_locator_t *loc_ptr = NULL; lispd_locators_list *locators_list[2] = {NULL,NULL}; lispd_locator_elt *locator = NULL; lcl_locator_extended_info *lct_extended_info = NULL; lisp_addr_t *itr_address = NULL; int ctr = 0; if ((rec == NULL) || (mapping == NULL)){ return NULL; } rec->ttl = htonl(DEFAULT_MAP_REGISTER_TIMEOUT); rec->locator_count = mapping->locator_count; rec->eid_prefix_length = mapping->eid_prefix_length; rec->action = 0; rec->authoritative = 1; rec->version_hi = 0; rec->version_low = 0; cur_ptr = (uint8_t *)&(rec->eid_prefix_afi); cur_ptr = pkt_fill_eid(cur_ptr, mapping); loc_ptr = (lispd_pkt_mapping_record_locator_t *)cur_ptr; if (loc_ptr == NULL){ return NULL; } locators_list[0] = mapping->head_v4_locators_list; locators_list[1] = mapping->head_v6_locators_list; for (ctr = 0 ; ctr < 2 ; ctr++){ while (locators_list[ctr]) { locator = locators_list[ctr]->locator; if (*(locator->state) == UP){ loc_ptr->priority = locator->priority; }else{ /* If the locator is DOWN, set the priority to 255 -> Locator should not be used */ loc_ptr->priority = UNUSED_RLOC_PRIORITY; } loc_ptr->weight = locator->weight; loc_ptr->mpriority = locator->mpriority; loc_ptr->mweight = locator->mweight; loc_ptr->local = 1; if (probed_rloc != NULL && compare_lisp_addr_t(locator->locator_addr,probed_rloc)==0){ loc_ptr->probed = 1; } loc_ptr->reachable = *(locator->state); loc_ptr->locator_afi = htons(get_lisp_afi(locator->locator_addr->afi,NULL)); lct_extended_info = (lcl_locator_extended_info *)(locator->extended_info); if (lct_extended_info->rtr_locators_list != NULL){ itr_address = &(lct_extended_info->rtr_locators_list->locator->address); }else{ itr_address = locator->locator_addr; } if ((cpy_len = copy_addr((void *) CO(loc_ptr, sizeof(lispd_pkt_mapping_record_locator_t)), itr_address, 0)) == 0) { lispd_log_msg(LISP_LOG_DEBUG_3, "pkt_fill_mapping_record: copy_addr failed for locator %s", get_char_from_lisp_addr_t(*(locator->locator_addr))); return(NULL); } loc_ptr = (lispd_pkt_mapping_record_locator_t *) CO(loc_ptr, (sizeof(lispd_pkt_mapping_record_locator_t) + cpy_len)); locators_list[ctr] = locators_list[ctr]->next; } } return ((void *)loc_ptr); }
uint8_t *build_map_request_pkt( lispd_mapping_elt *requested_mapping, lisp_addr_t *src_eid, uint8_t encap, uint8_t probe, uint8_t solicit_map_request,/* boolean really */ uint8_t smr_invoked, int *len, /* return length here */ uint64_t *nonce) /* return nonce here */ { uint8_t *packet = NULL; uint8_t *mr_packet = NULL; lispd_pkt_map_request_t *mrp = NULL; lispd_pkt_mapping_record_t *rec = NULL; lispd_pkt_map_request_itr_rloc_t *itr_rloc = NULL; lispd_pkt_map_request_eid_prefix_record_t *request_eid_record = NULL; uint8_t *cur_ptr = NULL; int map_request_msg_len = 0; int ctr = 0; int cpy_len = 0; int locators_ctr = 0; lispd_mapping_elt *src_mapping = NULL; lispd_locators_list *locators_list[2] = {NULL,NULL}; lispd_locator_elt *locator = NULL; lisp_addr_t *ih_src_ip = NULL; /* * Lookup the local EID prefix from where we generate the message. * src_eid is null for RLOC probing and refreshing map_cache -> Source-EID AFI = 0 */ if (src_eid != NULL){ src_mapping = lookup_eid_in_db(*src_eid); if (!src_mapping){ lispd_log_msg(LISP_LOG_DEBUG_2,"build_map_request_pkt: Source EID address not found in local data base - %s -", get_char_from_lisp_addr_t(*src_eid)); return (NULL); } } /* Calculate the packet size and reserve memory */ map_request_msg_len = get_map_request_length(requested_mapping,src_mapping); *len = map_request_msg_len; if ((packet = malloc(map_request_msg_len)) == NULL){ lispd_log_msg(LISP_LOG_WARNING,"build_map_request_pkt: Unable to allocate memory for Map Request (packet_len): %s", strerror(errno)); return (NULL); } memset(packet, 0, map_request_msg_len); cur_ptr = packet; mrp = (lispd_pkt_map_request_t *)cur_ptr; mrp->type = LISP_MAP_REQUEST; mrp->authoritative = 0; if (src_eid != NULL) mrp->map_data_present = 1; else mrp->map_data_present = 0; if (probe) mrp->rloc_probe = 1; else mrp->rloc_probe = 0; if (solicit_map_request) mrp->solicit_map_request = 1; else mrp->solicit_map_request = 0; if (smr_invoked) mrp->smr_invoked = 1; else mrp->smr_invoked = 0; mrp->additional_itr_rloc_count = 0; /* To be filled later */ mrp->record_count = 1; /* XXX: assume 1 record */ mrp->nonce = build_nonce((unsigned int) time(NULL)); *nonce = mrp->nonce; if (src_eid != NULL){ cur_ptr = pkt_fill_eid(&(mrp->source_eid_afi),src_mapping); /* Add itr-rlocs */ locators_list[0] = src_mapping->head_v4_locators_list; locators_list[1] = src_mapping->head_v6_locators_list; for (ctr=0 ; ctr < 2 ; ctr++){ while (locators_list[ctr]){ locator = locators_list[ctr]->locator; if (*(locator->state)==DOWN){ locators_list[ctr] = locators_list[ctr]->next; continue; } /* Remove ITR locators behind NAT: No control message (4342) can be received in these interfaces */ if (((lcl_locator_extended_info *)locator->extended_info)->rtr_locators_list != NULL){ locators_list[ctr] = locators_list[ctr]->next; continue; } itr_rloc = (lispd_pkt_map_request_itr_rloc_t *)cur_ptr; itr_rloc->afi = htons(get_lisp_afi(locator->locator_addr->afi,NULL)); /* Add rloc address */ cur_ptr = CO(itr_rloc,sizeof(lispd_pkt_map_request_itr_rloc_t)); cpy_len = copy_addr((void *) cur_ptr ,locator->locator_addr, 0); cur_ptr = CO(cur_ptr, cpy_len); locators_ctr ++; locators_list[ctr] = locators_list[ctr]->next; } } }else { // XXX If no source EID is used, then we only use one ITR-RLOC for IPv4 and one for IPv6-> Default control RLOC mrp->source_eid_afi = 0; cur_ptr = CO(mrp, sizeof(lispd_pkt_map_request_t)); if (default_ctrl_iface_v4 != NULL){ itr_rloc = (lispd_pkt_map_request_itr_rloc_t *)cur_ptr; itr_rloc->afi = htons((uint16_t)LISP_AFI_IP); cur_ptr = CO(itr_rloc,sizeof(lispd_pkt_map_request_itr_rloc_t)); cpy_len = copy_addr((void *) cur_ptr ,default_ctrl_iface_v4->ipv4_address, 0); cur_ptr = CO(cur_ptr, cpy_len); locators_ctr ++; } if (default_ctrl_iface_v6 != NULL){ itr_rloc = (lispd_pkt_map_request_itr_rloc_t *)cur_ptr; itr_rloc->afi = htons(get_lisp_afi(AF_INET6,NULL)); cur_ptr = CO(itr_rloc,sizeof(lispd_pkt_map_request_itr_rloc_t)); cpy_len = copy_addr((void *) cur_ptr ,default_ctrl_iface_v6->ipv6_address, 0); cur_ptr = CO(cur_ptr, cpy_len); locators_ctr ++; } } mrp->additional_itr_rloc_count = locators_ctr - 1; /* IRC = 0 --> 1 ITR-RLOC */ if (locators_ctr == 0){ lispd_log_msg(LISP_LOG_DEBUG_2,"build_map_request_pkt: No ITR RLOCs."); free(packet); return (NULL); } /* Requested EID record */ request_eid_record = (lispd_pkt_map_request_eid_prefix_record_t *)cur_ptr; request_eid_record->eid_prefix_length = requested_mapping->eid_prefix_length; cur_ptr = pkt_fill_eid(&(request_eid_record->eid_prefix_afi),requested_mapping); if (mrp->map_data_present == 1){ /* Map-Reply Record */ rec = (lispd_pkt_mapping_record_t *)cur_ptr; if ((pkt_fill_mapping_record(rec, src_mapping, NULL))== NULL) { lispd_log_msg(LISP_LOG_DEBUG_2,"build_map_request_pkt: Couldn't buil map reply record for map request. " "Map Request will not be send"); free(packet); return(NULL); } } /* Add Encapsulated (Inner) control header*/ if (encap){ /* * If no source EID is included (Source-EID-AFI = 0), The default RLOC address is used for * the source address in the inner IP header */ if (src_eid != NULL){ ih_src_ip = &(src_mapping->eid_prefix);; }else{ if (requested_mapping->eid_prefix.afi == AF_INET){ ih_src_ip = get_main_eid (AF_INET); }else{ ih_src_ip = get_main_eid (AF_INET6); } } mr_packet = packet; packet = build_control_encap_pkt(mr_packet, map_request_msg_len, ih_src_ip, &(requested_mapping->eid_prefix), LISP_CONTROL_PORT, LISP_CONTROL_PORT, len); if (packet == NULL){ lispd_log_msg(LISP_LOG_DEBUG_1,"build_map_request_pkt: Couldn't encapsulate the map request"); free (mr_packet); return (NULL); } } return (packet); }