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

📄 uip-arp.c

📁 這是一個實時嵌入式作業系統 實作了MCS51 ARM等MCU
💻 C
📖 第 1 页 / 共 2 页
字号:
  tabptr->at_time = g_arptime;}/**************************************************************************** * Public Functions ****************************************************************************//* Initialize the ARP module. */void uip_arp_init(void){  int i;  for (i = 0; i < CONFIG_NET_ARPTAB_SIZE; ++i)    {      memset(&arp_table[i].at_ipaddr, 0, sizeof(in_addr_t));    }}/* Periodic ARP processing function. * * This function performs periodic timer processing in the ARP module * and should be called at regular intervals. The recommended interval * is 10 seconds between the calls. */void uip_arp_timer(void){  struct arp_entry *tabptr;  int i;  ++g_arptime;  for (i = 0; i < CONFIG_NET_ARPTAB_SIZE; ++i)    {      tabptr = &arp_table[i];      if (tabptr->at_ipaddr != 0 && g_arptime - tabptr->at_time >= UIP_ARP_MAXAGE)        {          tabptr->at_ipaddr = 0;        }    }}/* ARP processing for incoming ARP packets. * * This function should be called by the device driver when an ARP * packet has been received. The function will act differently * depending on the ARP packet type: if it is a reply for a request * that we previously sent out, the ARP cache will be filled in with * the values from the ARP reply. If the incoming ARP packet is an ARP * request for our IP address, an ARP reply packet is created and put * into the d_buf[] buffer. * * When the function returns, the value of the field d_len * indicates whether the device driver should send out a packet or * not. If d_len is zero, no packet should be sent. If d_len is * non-zero, it contains the length of the outbound packet that is * present in the d_buf[] buffer. * * This function expects an ARP packet with a prepended Ethernet * header in the d_buf[] buffer, and the length of the packet in the * global variable d_len. */void uip_arp_arpin(struct uip_driver_s *dev){  in_addr_t ipaddr;  if (dev->d_len < (sizeof(struct arp_hdr) + UIP_LLH_LEN))    {      dev->d_len = 0;      return;    }  dev->d_len = 0;  ipaddr = uip_ip4addr_conv(ARPBUF->ah_dipaddr);  switch(ARPBUF->ah_opcode)    {      case HTONS(ARP_REQUEST):        /* ARP request. If it asked for our address, we send out a reply. */        if (uip_ipaddr_cmp(ipaddr, dev->d_ipaddr))          {            /* First, we register the one who made the request in our ARP             * table, since it is likely that we will do more communication             * with this host in the future.             */            uip_arp_update(ARPBUF->ah_sipaddr, ARPBUF->ah_shwaddr);            /* The reply opcode is 2. */            ARPBUF->ah_opcode = HTONS(2);            memcpy(ARPBUF->ah_dhwaddr, ARPBUF->ah_shwaddr, ETHER_ADDR_LEN);            memcpy(ARPBUF->ah_shwaddr, dev->d_mac.ether_addr_octet, ETHER_ADDR_LEN);            memcpy(ETHBUF->src, dev->d_mac.ether_addr_octet, ETHER_ADDR_LEN);            memcpy(ETHBUF->dest, ARPBUF->ah_dhwaddr, ETHER_ADDR_LEN);            ARPBUF->ah_dipaddr[0] = ARPBUF->ah_sipaddr[0];            ARPBUF->ah_dipaddr[1] = ARPBUF->ah_sipaddr[1];            uiphdr_ipaddr_copy(ARPBUF->ah_sipaddr, &dev->d_ipaddr);            uip_arp_dump(ARPBUF);            ETHBUF->type          = HTONS(UIP_ETHTYPE_ARP);            dev->d_len            = sizeof(struct arp_hdr) + UIP_LLH_LEN;          }        break;      case HTONS(ARP_REPLY):        /* ARP reply. We insert or update the ARP table if it was meant         * for us.         */        if (uip_ipaddr_cmp(ipaddr, dev->d_ipaddr))          {            uip_arp_update(ARPBUF->ah_sipaddr, ARPBUF->ah_shwaddr);          }        break;    }}/* Prepend Ethernet header to an outbound IP packet and see if we need * to send out an ARP request. * * This function should be called before sending out an IP packet. The * function checks the destination IP address of the IP packet to see * what Ethernet MAC address that should be used as a destination MAC * address on the Ethernet. * * If the destination IP address is in the local network (determined * by logical ANDing of netmask and our IP address), the function * checks the ARP cache to see if an entry for the destination IP * address is found. If so, an Ethernet header is prepended and the * function returns. If no ARP cache entry is found for the * destination IP address, the packet in the d_buf[] is replaced by * an ARP request packet for the IP address. The IP packet is dropped * and it is assumed that they higher level protocols (e.g., TCP) * eventually will retransmit the dropped packet. * * If the destination IP address is not on the local network, the IP * address of the default router is used instead. * * When the function returns, a packet is present in the d_buf[] * buffer, and the length of the packet is in the field d_len. */void uip_arp_out(struct uip_driver_s *dev){  struct arp_entry *tabptr;  in_addr_t         ipaddr;  in_addr_t         destipaddr;  int               i;  /* Find the destination IP address in the ARP table and construct   * the Ethernet header. If the destination IP addres isn't on the   * local network, we use the default router's IP address instead.   *   * If not ARP table entry is found, we overwrite the original IP   * packet with an ARP request for the IP address.   */  /* First check if destination is a local broadcast. */  if (uiphdr_ipaddr_cmp(IPBUF->eh_destipaddr, broadcast_ipaddr))    {      memcpy(ETHBUF->dest, broadcast_ethaddr.ether_addr_octet, ETHER_ADDR_LEN);    }  else    {      /* Check if the destination address is on the local network. */      destipaddr = uip_ip4addr_conv(IPBUF->eh_destipaddr);      if (!uip_ipaddr_maskcmp(destipaddr, dev->d_ipaddr, dev->d_netmask))        {          /* Destination address was not on the local network, so we need to           * use the default router's IP address instead of the destination           * address when determining the MAC address.           */          uip_ipaddr_copy(ipaddr, dev->d_draddr);        }      else        {          /* Else, we use the destination IP address. */          uip_ipaddr_copy(ipaddr, destipaddr);        }      /* Check if we already have this destination address in the ARP table */      for (i = 0; i < CONFIG_NET_ARPTAB_SIZE; ++i)        {          tabptr = &arp_table[i];          if (uip_ipaddr_cmp(ipaddr, tabptr->at_ipaddr))            {              break;            }        }      if (i == CONFIG_NET_ARPTAB_SIZE)        {          /* The destination address was not in our ARP table, so we           * overwrite the IP packet with an ARP request.           */          memset(ETHBUF->dest, 0xff, ETHER_ADDR_LEN);          memset(ARPBUF->ah_dhwaddr, 0x00, ETHER_ADDR_LEN);          memcpy(ETHBUF->src, dev->d_mac.ether_addr_octet, ETHER_ADDR_LEN);          memcpy(ARPBUF->ah_shwaddr, dev->d_mac.ether_addr_octet, ETHER_ADDR_LEN);          uiphdr_ipaddr_copy(ARPBUF->ah_dipaddr, &ipaddr);          uiphdr_ipaddr_copy(ARPBUF->ah_sipaddr, &dev->d_ipaddr);          ARPBUF->ah_opcode   = HTONS(ARP_REQUEST);          ARPBUF->ah_hwtype   = HTONS(ARP_HWTYPE_ETH);          ARPBUF->ah_protocol = HTONS(UIP_ETHTYPE_IP);          ARPBUF->ah_hwlen    = ETHER_ADDR_LEN;          ARPBUF->ah_protolen = 4;          uip_arp_dump(ARPBUF);          ETHBUF->type        = HTONS(UIP_ETHTYPE_ARP);          dev->d_len          = sizeof(struct arp_hdr) + UIP_LLH_LEN;          return;        }      /* Build an ethernet header. */      memcpy(ETHBUF->dest, tabptr->at_ethaddr.ether_addr_octet, ETHER_ADDR_LEN);    }  /* Finish populating the ethernet header */  memcpy(ETHBUF->src, dev->d_mac.ether_addr_octet, ETHER_ADDR_LEN);  ETHBUF->type = HTONS(UIP_ETHTYPE_IP);  dev->d_len  += UIP_LLH_LEN;}#endif /* CONFIG_NET */

⌨️ 快捷键说明

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