Beispiel #1
0
/**
 * Update (or insert) a IP/MAC address pair in the ARP cache.
 *
 * If a pending entry is resolved, any queued packets will be sent
 * at this point.
 * 
 * @param netif netif related to this entry (used for NETIF_ADDRHINT)
 * @param ipaddr IP address of the inserted ARP entry.
 * @param ethaddr Ethernet address of the inserted ARP entry.
 * @param flags @see definition of ETHARP_FLAG_*
 *
 * @return
 * - ERR_OK Succesfully updated ARP cache.
 * - ERR_MEM If we could not add a new ARP entry when ETHARP_FLAG_TRY_HARD was set.
 * - ERR_ARG Non-unicast address given, those will not appear in ARP cache.
 *
 * @see pbuf_free()
 */
static err_t
update_arp_entry(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags)
{
  s8_t i;
  LWIP_ASSERT("netif->hwaddr_len == ETHARP_HWADDR_LEN", netif->hwaddr_len == ETHARP_HWADDR_LEN);
  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n",
    ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
    ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
    ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
  /* non-unicast address? */
  if (ip_addr_isany(ipaddr) ||
      ip_addr_isbroadcast(ipaddr, netif) ||
      ip_addr_ismulticast(ipaddr)) {
    LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry: will not add non-unicast IP address to ARP cache\n"));
    return ERR_ARG;
  }
  /* find or create ARP entry */
  i = find_entry(ipaddr, flags);
  /* bail out if no entry could be found */
  if (i < 0) {
    return (err_t)i;
  }

#if ETHARP_SUPPORT_STATIC_ENTRIES
  if (flags & ETHARP_FLAG_STATIC_ENTRY) {
    /* record static type */
    arp_table[i].static_entry = 1;
  }
#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */

  /* mark it stable */
  arp_table[i].state = ETHARP_STATE_STABLE;

#if LWIP_SNMP
  /* record network interface */
  arp_table[i].netif = netif;
#endif /* LWIP_SNMP */
  /* insert in SNMP ARP index tree */
  snmp_insert_arpidx_tree(netif, &arp_table[i].ipaddr);

  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry: updating stable entry %"S16_F"\n", (s16_t)i));
  /* update address */
  ETHADDR32_COPY(&arp_table[i].ethaddr, ethaddr);
  /* reset time stamp */
  arp_table[i].ctime = 0;
#if ARP_QUEUEING
  /* this is where we will send out queued packets! */
  while (arp_table[i].q != NULL) {
    struct pbuf *p;
    /* remember remainder of queue */
    struct etharp_q_entry *q = arp_table[i].q;
    /* pop first item off the queue */
    arp_table[i].q = q->next;
    /* get the packet pointer */
    p = q->p;
    /* now queue entry can be freed */
    memp_free(MEMP_ARP_QUEUE, q);
    /* send the queued IP packet */
    etharp_send_ip(netif, p, (struct eth_addr*)(netif->hwaddr), ethaddr);
    /* free the queued IP packet */
    pbuf_free(p);
  }
#endif /* ARP_QUEUEING */
  return ERR_OK;
}
Beispiel #2
0
/**
 * Update (or insert) a IP/MAC address pair in the ARP cache.
 *
 * If a pending entry is resolved, any queued packets will be sent
 * at this point.
 *
 * @param netif netif related to this entry (used for NETIF_ADDRHINT)
 * @param ipaddr IP address of the inserted ARP entry.
 * @param ethaddr Ethernet address of the inserted ARP entry.
 * @param flags @see definition of ETHARP_FLAG_*
 *
 * @return
 * - ERR_OK Succesfully updated ARP cache.
 * - ERR_MEM If we could not add a new ARP entry when ETHARP_FLAG_TRY_HARD was set.
 * - ERR_ARG Non-unicast address given, those will not appear in ARP cache.
 *
 * @see pbuf_free()
 */
static err_t
update_arp_entry(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags)
{
	s8_t i;
	LWIP_ASSERT("netif->hwaddr_len == ETHARP_HWADDR_LEN", netif->hwaddr_len == ETHARP_HWADDR_LEN);
	LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n",
				ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
				ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
				ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
	/* non-unicast address? */
	if (ip_addr_isany(ipaddr) ||
		ip_addr_isbroadcast(ipaddr, netif) ||
		ip_addr_ismulticast(ipaddr)) {
		LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry: will not add non-unicast IP address to ARP cache\n"));
		return ERR_ARG;
	}
	/* find or create ARP entry */
	i = find_entry(ipaddr, flags);
	/* bail out if no entry could be found */
	if (i < 0) {
		return (err_t)i;
	}

#if ETHARP_SUPPORT_STATIC_ENTRIES
	if (flags & ETHARP_FLAG_STATIC_ENTRY) {
		/* record static type */
		arp_table[i].static_entry = 1;
	}
#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */

	/* mark it stable */
	arp_table[i].state = ETHARP_STATE_STABLE;

#if LWIP_SNMP
	/* record network interface */
	arp_table[i].netif = netif;
#endif /* LWIP_SNMP */
	/* insert in SNMP ARP index tree */
	snmp_insert_arpidx_tree(netif, &arp_table[i].ipaddr);

	LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry: updating stable entry %"S16_F"\n", (s16_t)i));
	/* update address */
	ETHADDR32_COPY(&arp_table[i].ethaddr, ethaddr);
	/* reset time stamp */
	arp_table[i].ctime = 0;
	/* this is where we will send out queued packets! */
#if ARP_QUEUEING
	while (arp_table[i].q != NULL) {
		struct pbuf *p;
		/* remember remainder of queue */
		struct etharp_q_entry *q = arp_table[i].q;
		/* pop first item off the queue */
		arp_table[i].q = q->next;
		/* get the packet pointer */
		p = q->p;
		/* now queue entry can be freed */
		memp_free(MEMP_ARP_QUEUE, q);
#else /* ARP_QUEUEING */
	if (arp_table[i].q != NULL) {
		struct pbuf *p = arp_table[i].q;
		arp_table[i].q = NULL;
#endif /* ARP_QUEUEING */
		/* send the queued IP packet */
		etharp_send_ip(netif, p, (struct eth_addr*)(netif->hwaddr), ethaddr);
		/* free the queued IP packet */
		pbuf_free(p);
	}
	return ERR_OK;
}

#if ETHARP_SUPPORT_STATIC_ENTRIES
/** Add a new static entry to the ARP table. If an entry exists for the
 * specified IP address, this entry is overwritten.
 * If packets are queued for the specified IP address, they are sent out.
 *
 * @param ipaddr IP address for the new static entry
 * @param ethaddr ethernet address for the new static entry
 * @return @see return values of etharp_add_static_entry
 */
err_t
etharp_add_static_entry(ip_addr_t *ipaddr, struct eth_addr *ethaddr)
{
	struct netif *netif;
	LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_add_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n",
				ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
				ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
				ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));

	netif = ip_route(ipaddr);
	if (netif == NULL) {
		return ERR_RTE;
	}

	return update_arp_entry(netif, ipaddr, ethaddr, ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY);
}

/** Remove a static entry from the ARP table previously added with a call to
 * etharp_add_static_entry.
 *
 * @param ipaddr IP address of the static entry to remove
 * @return ERR_OK: entry removed
 *         ERR_MEM: entry wasn't found
 *         ERR_ARG: entry wasn't a static entry but a dynamic one
 */
err_t
etharp_remove_static_entry(ip_addr_t *ipaddr)
{
	s8_t i;
	LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_remove_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
				ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));

	/* find or create ARP entry */
	i = find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY);
	/* bail out if no entry could be found */
	if (i < 0) {
		return (err_t)i;
	}

	if ((arp_table[i].state != ETHARP_STATE_STABLE) ||
		(arp_table[i].static_entry == 0)) {
		/* entry wasn't a static entry, cannot remove it */
		return ERR_ARG;
	}
	/* entry found, free it */
	free_entry(i);
	return ERR_OK;
}