⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 etharp.c

📁 lwip-1.4.0
💻 C
📖 第 1 页 / 共 4 页
字号:
  /* { we have no match } => try to create a new entry */     /* don't create new entry, only search? */  if (((flags & ETHARP_FLAG_FIND_ONLY) != 0) ||      /* or no empty entry found and not allowed to recycle? */      ((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_FLAG_TRY_HARD) == 0))) {    LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: no empty entry found and not allowed to recycle\n"));    return (s8_t)ERR_MEM;  }    /* b) choose the least destructive entry to recycle:   * 1) empty entry   * 2) oldest stable entry   * 3) oldest pending entry without queued packets   * 4) oldest pending entry with queued packets   *    * { ETHARP_FLAG_TRY_HARD is set at this point }   */   /* 1) empty entry available? */  if (empty < ARP_TABLE_SIZE) {    i = empty;    LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: selecting empty entry %"U16_F"\n", (u16_t)i));  } else {    /* 2) found recyclable stable entry? */    if (old_stable < ARP_TABLE_SIZE) {      /* recycle oldest stable*/      i = old_stable;      LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: selecting oldest stable entry %"U16_F"\n", (u16_t)i));      /* no queued packets should exist on stable entries */      LWIP_ASSERT("arp_table[i].q == NULL", arp_table[i].q == NULL);    /* 3) found recyclable pending entry without queued packets? */    } else if (old_pending < ARP_TABLE_SIZE) {      /* recycle oldest pending */      i = old_pending;      LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: selecting oldest pending entry %"U16_F" (without queue)\n", (u16_t)i));    /* 4) found recyclable pending entry with queued packets? */    } else if (old_queue < ARP_TABLE_SIZE) {      /* recycle oldest pending (queued packets are free in free_entry) */      i = old_queue;      LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: selecting oldest pending entry %"U16_F", freeing packet queue %p\n", (u16_t)i, (void *)(arp_table[i].q)));      /* no empty or recyclable entries found */    } else {      LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: no empty or recyclable entries found\n"));      return (s8_t)ERR_MEM;    }    /* { empty or recyclable entry found } */    LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);    free_entry(i);  }  LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE);  LWIP_ASSERT("arp_table[i].state == ETHARP_STATE_EMPTY",    arp_table[i].state == ETHARP_STATE_EMPTY);  /* IP address given? */  if (ipaddr != NULL) {    /* set IP address */    ip_addr_copy(arp_table[i].ipaddr, *ipaddr);  }  arp_table[i].ctime = 0;#if ETHARP_SUPPORT_STATIC_ENTRIES  arp_table[i].static_entry = 0;#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */  return (err_t)i;}/** * Send an IP packet on the network using netif->linkoutput * The ethernet header is filled in before sending. * * @params netif the lwIP network interface on which to send the packet * @params p the packet to send, p->payload pointing to the (uninitialized) ethernet header * @params src the source MAC address to be copied into the ethernet header * @params dst the destination MAC address to be copied into the ethernet header * @return ERR_OK if the packet was sent, any other err_t on failure */static err_tetharp_send_ip(struct netif *netif, struct pbuf *p, struct eth_addr *src, struct eth_addr *dst){  struct eth_hdr *ethhdr = (struct eth_hdr *)p->payload;  LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",              (netif->hwaddr_len == ETHARP_HWADDR_LEN));  ETHADDR32_COPY(&ethhdr->dest, dst);  ETHADDR16_COPY(&ethhdr->src, src);  ethhdr->type = PP_HTONS(ETHTYPE_IP);  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_send_ip: sending packet %p\n", (void *)p));  /* send the packet */  return netif->linkoutput(netif, p);}/** * 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_tupdate_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_tetharp_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_tetharp_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;}#endif /* ETHARP_SUPPORT_STATIC_ENTRIES *//** * Finds (stable) ethernet/IP address pair from ARP table * using interface and IP address index. * @note the addresses in the ARP table are in network order! * * @param netif points to interface index * @param ipaddr points to the (network order) IP address index * @param eth_ret points to return pointer * @param ip_ret points to return pointer * @return table index if found, -1 otherwise */s8_tetharp_find_addr(struct netif *netif, ip_addr_t *ipaddr,         struct eth_addr **eth_ret, ip_addr_t **ip_ret){  s8_t i;  LWIP_ASSERT("eth_ret != NULL && ip_ret != NULL",    eth_ret != NULL && ip_ret != NULL);  LWIP_UNUSED_ARG(netif);  i = find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY);  if((i >= 0) && arp_table[i].state == ETHARP_STATE_STABLE) {      *eth_ret = &arp_table[i].ethaddr;      *ip_ret = &arp_table[i].ipaddr;      return i;  }  return -1;}#if ETHARP_TRUST_IP_MAC/** * Updates the ARP table using the given IP packet. * * Uses the incoming IP packet's source address to update the * ARP cache for the local network. The function does not alter * or free the packet. This function must be called before the * packet p is passed to the IP layer. * * @param netif The lwIP network interface on which the IP packet pbuf arrived. * @param p The IP packet that arrived on netif. * * @return NULL * * @see pbuf_free() */static voidetharp_ip_input(struct netif *netif, struct pbuf *p){  struct eth_hdr *ethhdr;  struct ip_hdr *iphdr;  ip_addr_t iphdr_src;  LWIP_ERROR("netif != NULL", (netif != NULL), return;);  /* Only insert an entry if the source IP address of the     incoming IP packet comes from a host on the local network. */  ethhdr = (struct eth_hdr *)p->payload;  iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR);#if ETHARP_SUPPORT_VLAN  if (ethhdr->type == PP_HTONS(ETHTYPE_VLAN)) {    iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR);  }#endif /* ETHARP_SUPPORT_VLAN */  ip_addr_copy(iphdr_src, iphdr->src);  /* source is not on the local network? */  if (!ip_addr_netcmp(&iphdr_src, &(netif->ip_addr), &(netif->netmask))) {    /* do nothing */    return;  }  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_ip_input: updating ETHARP table.\n"));  /* update the source IP address in the cache, if present */  /* @todo We could use ETHARP_FLAG_TRY_HARD if we think we are going to talk   * back soon (for example, if the destination IP address is ours. */  update_arp_entry(netif, &iphdr_src, &(ethhdr->src), ETHARP_FLAG_FIND_ONLY);}#endif /* ETHARP_TRUST_IP_MAC *//** * Responds to ARP requests to us. Upon ARP replies to us, add entry to cache   * send out queued IP packets. Updates cache with snooped address pairs. * * Should be called for incoming ARP packets. The pbuf in the argument * is freed by this function. * * @param netif The lwIP network interface on which the ARP packet pbuf arrived. * @param ethaddr Ethernet address of netif.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -