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

📄 arp.c

📁 用于嵌入式系统的TCP/IP协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
    buf->type = htons(RARP_TYPE);    ni->broadcast(buf);  }  /*-------------------------------------------------------------------*/  /* Calculate next RARP timeout.                                      */  /*-------------------------------------------------------------------*/  if (++RarpRetries > 5)    RarpRetries = 0;  timeout = (rand() % K2_SECONDS) +            TICKS_PER_SEC * (3 + (1 << RarpRetries));  /*-------------------------------------------------------------------*/  /* Schedule next RARP request.                                       */  /*-------------------------------------------------------------------*/  NetTimerStart(&RarpTimer, timeout);}/***********************************************************************//*  find_entry: Search for matching ARP table entry                    *//*                                                                     *//*       Input: ip_addr = IP address to match                          *//*                                                                     *//*     Returns: pointer to ARP table entry or NULL                     *//*                                                                     *//***********************************************************************/static ArpEntry *find_entry(ui32 ip_addr){  int i = 0;  /*-------------------------------------------------------------------*/  /* Search through ARP table, resuming at the last entry found.       */  /*-------------------------------------------------------------------*/  do  {    /*-----------------------------------------------------------------*/    /* Return entry pointer if IP addresses match and entry is valid.  */    /*-----------------------------------------------------------------*/    if ((Entry->pr_addr == ip_addr) && (Entry->state != AES_FREE))      return Entry;    /*-----------------------------------------------------------------*/    /* Increment entry pointer, wrapping when end is reached.          */    /*-----------------------------------------------------------------*/    if (++Entry == &ArpTbl[ARP_TSIZE])      Entry = &ArpTbl[0];  }  while (++i < ARP_TSIZE);  /*-------------------------------------------------------------------*/  /* No match found. Return NULL.                                      */  /*-------------------------------------------------------------------*/  return NULL;}/***********************************************************************//*   add_entry: Initialize a new ARP cache entry                       *//*                                                                     *//*      Inputs: ni = pointer to network interface structure            *//*              arp = pointer to ARP packet                            *//*                                                                     *//***********************************************************************/static void add_entry(Ni *ni, Arp *arp){  ArpEntry *arp_entry = alloc_entry();  arp_entry->ni = ni;  memcpy(arp_entry->hw_addr, SenderHA(arp), arp->ha_len);  memcpy(&arp_entry->pr_addr, SenderPA(arp), IP_ALEN);  arp_entry->state = AES_RESOLVED;  NetTimerStart(&arp_entry->timer, ARP_TIMEOUT);}/***********************************************************************//* alloc_entry: Select an ARP cache entry, deleting old if necessary   *//*                                                                     *//***********************************************************************/static ArpEntry *alloc_entry(void){  ArpEntry *entry;  /*-------------------------------------------------------------------*/  /* Search ARP cache, starting at the oldest entry.                   */  /*-------------------------------------------------------------------*/  for (entry = OldestEntry;;)  {    /*-----------------------------------------------------------------*/    /* Allocate and return address if free entry is found.             */    /*-----------------------------------------------------------------*/    if (entry->state == AES_FREE)    {      ++ArpCacheSize;      entry->state = AES_PENDING;      return entry;    }    /*-----------------------------------------------------------------*/    /* Increment entry pointer, wrapping around end.                   */    /*-----------------------------------------------------------------*/    if (++entry == &ArpTbl[ARP_TSIZE])      entry = &ArpTbl[0];    /*-----------------------------------------------------------------*/    /* If oldest entry is reached, reuse it.                           */    /*-----------------------------------------------------------------*/    if (entry == OldestEntry)    {      /*---------------------------------------------------------------*/      /* Free any pending outbound packets and set entry state.        */      /*---------------------------------------------------------------*/      if (entry->qhead)        free_queue(entry);      entry->state = AES_PENDING;      /*---------------------------------------------------------------*/      /* Advance oldest entry pointer.                                 */      /*---------------------------------------------------------------*/      if (++OldestEntry == &ArpTbl[ARP_TSIZE])        OldestEntry = &ArpTbl[0];      /*---------------------------------------------------------------*/      /* Return pointer to entry.                                      */      /*---------------------------------------------------------------*/      return entry;    }  }}/***********************************************************************//*  free_queue: Free queue of expired ARP cache entries                *//*                                                                     *//*       Input: arp_entry = pointer to ARP cache entry                 *//*                                                                     *//***********************************************************************/static void free_queue(ArpEntry *arp_entry){  NetBuf *buf;  while (arp_entry->qhead)  {    buf = arp_entry->qhead;    arp_entry->qhead = arp_entry->qhead->next;    tcpRetBuf(&buf);  }  arp_entry->qcount = 0;}/***********************************************************************//* send_request: Broadcast an ARP request                              *//*                                                                     *//*       Input: arp_entry = pointer to an ARP cache entry              *//*                                                                     *//***********************************************************************/static void send_request(ArpEntry *arp_entry){  Ni *ni = arp_entry->ni;  int length = offsetof(Arp, addresses) + 2 * (IP_ALEN + ni->ha_len);  NetBuf *buf;  Arp *arp;  /*-------------------------------------------------------------------*/  /* Request a network buffer, exiting if none free.                   */  /*-------------------------------------------------------------------*/  buf = tcpGetBuf(NIMHLEN + length);  if (buf == NULL)    return;  /*-------------------------------------------------------------------*/  /* Schedule next resend and increment number of attempts.            */  /*-------------------------------------------------------------------*/  NetTimerStart(&arp_entry->timer, ARP_RESEND);  ++arp_entry->attempts;  /*-------------------------------------------------------------------*/  /* Get pointer to packet frame and complete the ARP message fields.  */  /*-------------------------------------------------------------------*/  arp = (Arp *)buf->ip_pkt;  arp->hw_type = htons(ni->hw_type);  arp->pr_type = htons(IP_TYPE);  arp->ha_len = ni->ha_len;  arp->pa_len = IP_ALEN;  arp->operation = htons(ARP_REQUEST);  memcpy(SenderHA(arp), ni->hw_addr, ni->ha_len);  memcpy(SenderPA(arp), &ni->ip_addr, IP_ALEN);  memset(TargetHA(arp), 0, ni->ha_len);  memcpy(TargetPA(arp), &arp_entry->pr_addr, IP_ALEN);#if TCP_PROBE  /*-------------------------------------------------------------------*/  /* Decode ARP packet if global decode flag is TRUE.                  */  /*-------------------------------------------------------------------*/  if (NetProbeFlag)    got_arp(arp);#endif  /*-------------------------------------------------------------------*/  /* Complete buffer data and request NI to transmit packet.           */  /*-------------------------------------------------------------------*/  buf->length = length;  buf->type = htons(ARP_TYPE);  ni->broadcast(buf);}/***********************************************************************//*   arp_reply: Send an ARP reply                                      *//*                                                                     *//*      Inputs: ni = pointer to network interface                      *//*              ha = pointer to target hardware address                *//*              pa = pointer to target protocol address                *//*              brdcst = broadcast if TRUE                             *//*                                                                     *//***********************************************************************/static void arp_reply(const Ni *ni, ui8 *ha, ui8 *pa, int brdcst){  NetBuf *buf;  Arp *reply;  /*-------------------------------------------------------------------*/  /* Request a network buffer, exiting if none free.                   */  /*-------------------------------------------------------------------*/  buf = tcpGetBuf(NIMHLEN + offsetof(Arp, addresses) +                          2 * (IP_ALEN + ni->ha_len));  if (buf == NULL)    return;  /*-------------------------------------------------------------------*/  /* Form ARP header.                                                  */  /*-------------------------------------------------------------------*/  reply = (Arp *)buf->ip_pkt;  reply->hw_type = htons(ni->hw_type);  reply->pr_type = htons(IP_TYPE);  reply->ha_len  = ni->ha_len;  reply->pa_len  = IP_ALEN;  reply->operation = htons(ARP_REPLY);  /*-------------------------------------------------------------------*/  /* Supply target addresses.                                          */  /*-------------------------------------------------------------------*/  memcpy(TargetHA(reply), ha, ni->ha_len);  memcpy(TargetPA(reply), pa, IP_ALEN);  /*-------------------------------------------------------------------*/  /* Fill in sender's hardware and protocol addresses (ours).          */  /*-------------------------------------------------------------------*/  memcpy(SenderHA(reply), ni->hw_addr, ni->ha_len);  memcpy(SenderPA(reply), &ni->ip_addr, IP_ALEN);#if TCP_PROBE  /*-------------------------------------------------------------------*/  /* Decode ARP packet if global decode flag is TRUE.                  */  /*-------------------------------------------------------------------*/  if (NetProbeFlag)    got_arp(reply);#endif  /*-------------------------------------------------------------------*/  /* Supply buffer header and request NI to send packet.               */  /*-------------------------------------------------------------------*/  buf->length = offsetof(Arp, addresses) + 2 * (IP_ALEN + ni->ha_len);  buf->type = htons(ARP_TYPE);  if (brdcst)    ni->broadcast(buf);  else    ni->transmit(buf, ha);}/***********************************************************************//* arp_timeout: Process ARP timeout                                    *//*                                                                     *//*       Input: timer = pointer to expired ARP timer                   *//*                                                                     *//***********************************************************************/static void arp_timeout(void *object){  ArpEntry *arp_entry = object;  /*-------------------------------------------------------------------*/  /* If arp entry was resolved, set its state to free.                 */  /*-------------------------------------------------------------------*/  if (arp_entry->state == AES_RESOLVED)  {    arp_entry->state = AES_FREE;    --ArpCacheSize;  }  /*-------------------------------------------------------------------*/  /* Else state was pending, free queue if max attempts exceeded.      */  /*-------------------------------------------------------------------*/  else if (arp_entry->attempts > ARP_ATTEMPTS)  {    arp_entry->state = AES_FREE;    free_queue(arp_entry);    --ArpCacheSize;  }  /*-------------------------------------------------------------------*/  /* Else resend ARP request.                                          */  /*-------------------------------------------------------------------*/  else    send_request(arp_entry);}#if TCP_PROBE/***********************************************************************//*     got_arp: Decode ARP/RARP requests and replies                   *//*                                                                     *//***********************************************************************/static void got_arp(Arp *arp){  ui32 ip_addr;  ui16 hw_type;  ui16 pr_type;  ui16 operation;  char *op_str;  /*-------------------------------------------------------------------*/  /* Convert ARP header fields to host byte order.                     */  /*-------------------------------------------------------------------*/  hw_type = ntohs(arp->hw_type);  pr_type = ntohs(arp->pr_type);  operation = ntohs(arp->operation);  /*-------------------------------------------------------------------*/  /* Display ARP fields.                                               */  /*-------------------------------------------------------------------*/  if (operation > 2)    putchar('R');  printf("ARP: hw_type = %u, hw_len = %u\n", hw_type, arp->ha_len);  if (operation > 2)    putchar('R');  printf("ARP: pr_type = 0x%04X, pa_len = %u\n", pr_type, arp->pa_len);  if (operation & 1)    op_str = "REQUEST";  else    op_str = "REPLY";  if (operation > 2)    putchar('R');  printf("ARP: operation = %u (%s)\n", operation, op_str);  memcpy(&ip_addr, SenderPA(arp), IP_ALEN);  if (operation > 2)    putchar('R');  printf("ARP: sender PA = "); printIP(ip_addr);  putchar('\n');  if (operation > 2)    putchar('R');  printf("ARP: sender HA = "); printEth(SenderHA(arp));  memcpy(&ip_addr, TargetPA(arp), IP_ALEN);  putchar('\n');  if (operation > 2)    putchar('R');  printf("ARP: target PA = "); printIP(ip_addr);  putchar('\n');  if (operation > 2)    putchar('R');  printf("ARP: target HA = "); printEth(TargetHA(arp));  printf("\n\n");}#endif

⌨️ 快捷键说明

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