Esempio n. 1
0
static void
refresh_cache(struct ip_addr *dst_ip)
{
    struct netif *netif;
    netif = ip_route(dst_ip);

    errval_t r = etharp_request(netif, dst_ip);
    assert(err_is_ok(r));

   while (is_ip_present_in_arp_cache(dst_ip) == false) {
        r = event_dispatch(ws);
        if (err_is_fail(r)) {
            DEBUG_ERR(r, "in event_dispatch");
            abort();
        }
   } // end while: till arp not present
}
Esempio n. 2
0
extern ipal_result_t ipal_arp_request(ipal_ipv4addr_t ip, ipal_arp_cachemode_t cm)
{
    int8_t ret;
    err_t err;
    ipal_eth_hid_netif * netif_ptr;
    struct ip_addr ipaddr;
    struct eth_addr *eth_ret;
    struct ip_addr  *ip_ret;
    
    
#warning: arp cache mode useless
    //in lwip i can not found something similar to cachemode.
    
    if(0 == ipal_sys_hid_started)
    {
        return(ipal_res_NOK_generic);
    }

    ipaddr.addr = ipal2lwip_ipv4addr(ip);
    
    ipal_base_hid_threadsafety_lock();

    netif_ptr = ipal_eth_hid_getnetif();
    ret = etharp_find_addr(&(netif_ptr->netif), &ipaddr, &eth_ret, &ip_ret);
    if(ret != -1 )
    {
        //ip addr presente in arp tbl, allora ritorno con sucesso
        ipal_base_hid_threadsafety_unlock();
        return(ipal_res_OK);
    }
      
    //se sopno qui ==> ip addr non presente in tbl arp ==> faccio una request
    err = etharp_request(&(netif_ptr->netif), &ipaddr);
    
    ipal_base_hid_threadsafety_unlock();

    return( (ERR_OK == err) ? (ipal_res_OK) : (ipal_res_NOK_generic) );
    //se sono qui vuol dire che devoi fare una arp request e che quindi la mia arp table non contiene ancora nessuna entry relatina a @ip
    //return(ipal_res_NOK_generic);
}
Esempio n. 3
0
/**
 * Clears expired entries in the ARP table.
 *
 * This function should be called every ARP_TMR_INTERVAL milliseconds (1 second),
 * in order to expire entries in the ARP table.
 */
void
etharp_tmr(void)
{
  u8_t i;

  LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n"));
  /* remove expired entries from the ARP table */
  for (i = 0; i < ARP_TABLE_SIZE; ++i) {
    u8_t state = arp_table[i].state;
    if (state != ETHARP_STATE_EMPTY
#if ETHARP_SUPPORT_STATIC_ENTRIES
      && (state != ETHARP_STATE_STATIC)
#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */
      ) {
      arp_table[i].ctime++;
      if ((arp_table[i].ctime >= ARP_MAXAGE) ||
          ((arp_table[i].state == ETHARP_STATE_PENDING)  &&
           (arp_table[i].ctime >= ARP_MAXPENDING))) {
        /* pending or stable entry has become old! */
        LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired %s entry %"U16_F".\n",
             arp_table[i].state >= ETHARP_STATE_STABLE ? "stable" : "pending", (u16_t)i));
        /* clean up entries that have just been expired */
        etharp_free_entry(i);
      } else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_1) {
        /* Don't send more than one request every 2 seconds. */
        arp_table[i].state = ETHARP_STATE_STABLE_REREQUESTING_2;
      } else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_2) {
        /* Reset state to stable, so that the next transmitted packet will
           re-send an ARP request. */
        arp_table[i].state = ETHARP_STATE_STABLE;
      } else if (arp_table[i].state == ETHARP_STATE_PENDING) {
        /* still pending, resend an ARP query */
        etharp_request(arp_table[i].netif, &arp_table[i].ipaddr);
      }
    }
  }
}
/**
 * Send an ARP request for the given IP address and/or queue a packet.
 *
 * If the IP address was not yet in the cache, a pending ARP cache entry
 * is added and an ARP request is sent for the given address. The packet
 * is queued on this entry.
 *
 * If the IP address was already pending in the cache, a new ARP request
 * is sent for the given address. The packet is queued on this entry.
 *
 * If the IP address was already stable in the cache, and a packet is
 * given, it is directly sent and no ARP request is sent out. 
 * 
 * If the IP address was already stable in the cache, and no packet is
 * given, an ARP request is sent out.
 * 
 * @param netif The lwIP network interface on which ipaddr
 * must be queried for.
 * @param ipaddr The IP address to be resolved.
 * @param q If non-NULL, a pbuf that must be delivered to the IP address.
 * q is not freed by this function.
 *
 * @return
 * - ERR_BUF Could not make room for Ethernet header.
 * - ERR_MEM Hardware address unknown, and no more ARP entries available
 *   to query for address or queue the packet.
 * - ERR_MEM Could not queue packet due to memory shortage.
 * - ERR_RTE No route to destination (no gateway to external networks).
 * - ERR_ARG Non-unicast address given, those will not appear in ARP cache.
 *
 */
err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
{
  struct eth_addr * srcaddr = (struct eth_addr *)netif->hwaddr;
  err_t result = ERR_MEM;
  s8_t i; /* ARP entry index */
  u8_t k; /* Ethernet address octet index */

  /* non-unicast address? */
  if (ip_addr_isbroadcast(ipaddr, netif) ||
      ip_addr_ismulticast(ipaddr) ||
      ip_addr_isany(ipaddr)) {
    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: will not add non-unicast IP address to ARP cache\n"));
    return ERR_ARG;
  }

  /* find entry in ARP cache, ask to create entry if queueing packet */
  i = find_entry(ipaddr, ETHARP_TRY_HARD);

  /* could not find or create entry? */
  if (i < 0)
  {
    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: could not create ARP entry\n"));
    if (q) LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: packet dropped\n"));
    return (err_t)i;
  }

  /* mark a fresh entry as pending (we just sent a request) */
  if (arp_table[i].state == ETHARP_STATE_EMPTY) {
    arp_table[i].state = ETHARP_STATE_PENDING;
  }

  /* { i is either a STABLE or (new or existing) PENDING entry } */
  LWIP_ASSERT("arp_table[i].state == PENDING or STABLE",
  ((arp_table[i].state == ETHARP_STATE_PENDING) ||
   (arp_table[i].state == ETHARP_STATE_STABLE)));

  /* do we have a pending entry? or an implicit query request? */
  if ((arp_table[i].state == ETHARP_STATE_PENDING) || (q == NULL)) {
    /* try to resolve it; send out ARP request */
    result = etharp_request(netif, ipaddr);
  }
  
  /* packet given? */
  if (q != NULL) {
    /* stable entry? */
    if (arp_table[i].state == ETHARP_STATE_STABLE) {
      /* we have a valid IP->Ethernet address mapping,
       * fill in the Ethernet header for the outgoing packet */
      struct eth_hdr *ethhdr = q->payload;
      for(k = 0; k < netif->hwaddr_len; k++) {
        ethhdr->dest.addr[k] = arp_table[i].ethaddr.addr[k];
        ethhdr->src.addr[k]  = srcaddr->addr[k];
      }
      ethhdr->type = htons(ETHTYPE_IP);
      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: sending packet %p\n", (void *)q));
      /* send the packet */
      result = netif->linkoutput(netif, q);
    /* pending entry? (either just created or already pending */
    } else if (arp_table[i].state == ETHARP_STATE_PENDING) {
#if ARP_QUEUEING /* queue the given q packet */
      struct pbuf *p;
      /* copy any PBUF_REF referenced payloads into PBUF_RAM */
      /* (the caller of lwIP assumes the referenced payload can be
       * freed after it returns from the lwIP call that brought us here) */
      p = pbuf_take(q);
      /* packet could be taken over? */
      if (p != NULL) {
        /* queue packet ... */
        if (arp_table[i].p == NULL) {
        	/* ... in the empty queue */
        	pbuf_ref(p);
        	arp_table[i].p = p;
#if 0 /* multi-packet-queueing disabled, see bug #11400 */
        } else {
        	/* ... at tail of non-empty queue */
          pbuf_queue(arp_table[i].p, p);
#endif
        }
        LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i));
        result = ERR_OK;
      } else {
        LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q));
        /* { result == ERR_MEM } through initialization */
      }
#else /* ARP_QUEUEING == 0 */
      /* q && state == PENDING && ARP_QUEUEING == 0 => result = ERR_MEM */
      /* { result == ERR_MEM } through initialization */
      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: Ethernet destination address unknown, queueing disabled, packet %p dropped\n", (void *)q));
#endif
    }
  }
  return result;
}
static int LinkLocal_IP_Query(uint32 IP, struct netif *netif){
	struct ip_addr ipaddr;
	
	ipaddr.addr = IP;
	return etharp_request(netif, &ipaddr);
}
Esempio n. 6
0
/**
 * Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds
 */
void
autoip_tmr ()
{
  struct netif *netif = netif_list;
  /* loop through netif's */
  while (netif != NULL)
    {
      /* only act on AutoIP configured interfaces */
      if (netif->autoip != NULL)
	{
	  if (netif->autoip->lastconflict > 0)
	    {
	      netif->autoip->lastconflict--;
	    }

	  LWIP_DEBUGF (AUTOIP_DEBUG | LWIP_DBG_TRACE,
		       ("autoip_tmr() AutoIP-State: %" U16_F ", ttw=%" U16_F
			"\n", (u16_t) (netif->autoip->state),
			netif->autoip->ttw));

	  switch (netif->autoip->state)
	    {
	    case AUTOIP_STATE_PROBING:
	      if (netif->autoip->ttw > 0)
		{
		  netif->autoip->ttw--;
		}
	      else
		{
		  if (netif->autoip->sent_num == PROBE_NUM)
		    {
		      netif->autoip->state = AUTOIP_STATE_ANNOUNCING;
		      netif->autoip->sent_num = 0;
		      netif->autoip->ttw =
			ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND;
		    }
		  else
		    {
		      etharp_request (netif, &(netif->autoip->llipaddr));
		      LWIP_DEBUGF (AUTOIP_DEBUG | LWIP_DBG_TRACE | 3,
				   ("autoip_tmr() PROBING Sent Probe\n"));
		      netif->autoip->sent_num++;
		      /* calculate time to wait to next probe */
		      netif->autoip->ttw =
			(u16_t) ((LWIP_AUTOIP_RAND (netif) %
				  ((PROBE_MAX -
				    PROBE_MIN) * AUTOIP_TICKS_PER_SECOND)) +
				 PROBE_MIN * AUTOIP_TICKS_PER_SECOND);
		    }
		}
	      break;

	    case AUTOIP_STATE_ANNOUNCING:
	      if (netif->autoip->ttw > 0)
		{
		  netif->autoip->ttw--;
		}
	      else
		{
		  if (netif->autoip->sent_num == 0)
		    {
		      /* We are here the first time, so we waited ANNOUNCE_WAIT seconds
		       * Now we can bind to an IP address and use it
		       */
		      autoip_bind (netif);
		    }

		  if (netif->autoip->sent_num == ANNOUNCE_NUM)
		    {
		      netif->autoip->state = AUTOIP_STATE_BOUND;
		      netif->autoip->sent_num = 0;
		      netif->autoip->ttw = 0;
		    }
		  else
		    {
		      autoip_arp_announce (netif);
		      LWIP_DEBUGF (AUTOIP_DEBUG | LWIP_DBG_TRACE | 3,
				   ("autoip_tmr() ANNOUNCING Sent Announce\n"));
		      netif->autoip->sent_num++;
		      netif->autoip->ttw =
			ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND;
		    }
		}
	      break;
	    }
	}
      /* proceed to next network interface */
      netif = netif->next;
    }
}