示例#1
0
文件: Peepgen.cpp 项目: BigEd/Cores
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);
}
示例#2
0
文件: Peepgen.cpp 项目: BigEd/Cores
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);
}
示例#3
0
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;
}
示例#4
0
文件: Peepgen.cpp 项目: BigEd/Cores
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;
}
示例#5
0
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;
    }
}
示例#6
0
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;
}
示例#7
0
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);
}
示例#8
0
文件: Peepgen.cpp 项目: BigEd/Cores
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);
}
示例#9
0
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;
}
示例#10
0
文件: Peepgen.cpp 项目: BigEd/Cores
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;
}
示例#11
0
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;
}
示例#12
0
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;
}
示例#13
0
文件: Peepgen.cpp 项目: BigEd/Cores
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;
}
示例#14
0
文件: Peepgen.cpp 项目: BigEd/Cores
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");
}
示例#15
0
文件: Peepgen.cpp 项目: BigEd/Cores
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;
}
示例#16
0
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);
}
示例#17
0
/*
 * 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;
}
示例#18
0
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;
}
示例#19
0
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;
}
示例#20
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);
}
示例#21
0
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);
}