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

📄 arp.c

📁 用于嵌入式系统的TCP/IP协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
    if (memcmp(&ip_addr, SenderPA(arp), IP_ALEN))      add_entry(ni, arp);  }  /*-------------------------------------------------------------------*/  /* Else if entry was pending, mark resolved and send queued packets. */  /*-------------------------------------------------------------------*/  else if (arp_entry->state == AES_PENDING)  {    arp_entry->state = AES_RESOLVED;    for (; arp_entry->qhead; arp_entry->qhead = arp_entry->qhead->next)      arp_entry->ni->transmit(arp_entry->qhead, arp_entry->hw_addr);    arp_entry->qcount = 0;  }  /*-------------------------------------------------------------------*/  /* Reply if packet is ARP request and interface address is valid.    */  /*-------------------------------------------------------------------*/  if (ni->ip_addr && (arp->operation == htons(ARP_REQUEST)))    arp_reply(ni, SenderHA(arp), SenderPA(arp), UNICAST);}/***********************************************************************//*  DhcpArpReq: Broadcast ARP request to see if address is being used  *//*                                                                     *//*      Inputs: ni = pointer to network interface                      *//*              ip_addr = address to check for use by other hosts      *//*                                                                     *//***********************************************************************/void DhcpArpReq(Ni *ni, ui32 ip_addr){  ArpEntry arp_entry;  /*-------------------------------------------------------------------*/  /* Initialize ARP entry and send request.                            */  /*-------------------------------------------------------------------*/  arp_entry.ni = ni;  arp_entry.pr_addr = ip_addr;  arp_entry.state = AES_FREE;  arp_entry.qhead = NULL;  arp_entry.qcount = 0;  arp_entry.timer.running = FALSE;  arp_entry.timer.action = arp_timeout;  arp_entry.timer.object = &arp_entry;  INIT_TMR(arp_entry.timer);  send_request(&arp_entry);  /*-------------------------------------------------------------------*/  /* Stop ARP timer before exiting since it was created on the stack.  */  /*-------------------------------------------------------------------*/  NetTimerStop(&arp_entry.timer);}/***********************************************************************//* DhcpArpCached: Check if specified IP address is in ARP cache        *//*                                                                     *//*       Input: ip_addr = IP address to search for                     *//*                                                                     *//***********************************************************************/int DhcpArpCached(ui32 ip_addr){  return find_entry(ip_addr) != NULL;}/***********************************************************************//* DhcpArpReply: Broadcast ARP reply to clear outdated entries         *//*                                                                     *//*       Input: ni = pointer to network interface                      *//*                                                                     *//***********************************************************************/void DhcpArpReply(Ni *ni){  arp_reply(ni, ni->hw_addr, (ui8 *)&ni->ip_addr, BROADCAST);}/***********************************************************************//*      RarpIn: Handle incoming RARP packets, replies and requests     *//*                                                                     *//***********************************************************************/void RarpIn(void){  Arp *rarp;  Ni *ni = RxBuf->ni;  ui8 *aligned;  /*-------------------------------------------------------------------*/  /* Align RARP packet to even byte boundary and assign pointer.       */  /*-------------------------------------------------------------------*/  aligned = (ui8 *)((ui32)RxBuf->ip_pkt & ~1);  if (aligned != RxBuf->ip_pkt)  {    memmove(aligned, RxBuf->ip_pkt, RxBuf->length);    RxBuf->ip_pkt = aligned;  }  rarp = (Arp *)RxBuf->ip_pkt;#if TCP_PROBE  /*-------------------------------------------------------------------*/  /* Decode RARP packet if global decode flag is TRUE.                 */  /*-------------------------------------------------------------------*/  if (NetProbeFlag)    got_arp(rarp);#endif  /*-------------------------------------------------------------------*/  /* Verify hardware and protocol type.                                */  /*-------------------------------------------------------------------*/  if (ntohs(rarp->hw_type) != ni->hw_type ||      rarp->pr_type != htons(IP_TYPE))    return;  /*-------------------------------------------------------------------*/  /* Attempt response if packet is RARP request.                       */  /*-------------------------------------------------------------------*/  if (rarp->operation == htons(RARP_REQUEST))  {#if RARP_SERVER    NetBuf *buf;    Arp *reply;    ui32 ip_addr;    HostDesc *host;    /*-----------------------------------------------------------------*/    /* Use hardware address to look up protocol address.               */    /*-----------------------------------------------------------------*/    for (host = &HostsTable[0];; ++host)    {      /*---------------------------------------------------------------*/      /* Return if end of list reached.                                */      /*---------------------------------------------------------------*/      if (host->ip_addr == 0)        return;      /*---------------------------------------------------------------*/      /* Break if hardware address match is found.                     */      /*---------------------------------------------------------------*/      if ((host->hw_type == ni->ha_type) && host->hw_addr &&          (memcmp(SenderHA(rarp), host->hw_addr, ni->ha_len) == 0))      {        ip_addr = host->ip_addr;        break;      }    }    /*-----------------------------------------------------------------*/    /* 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 RARP 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(RARP_REPLY);    /*-----------------------------------------------------------------*/    /* Supply target addresses.                                        */    /*-----------------------------------------------------------------*/    memcpy(TargetHA(reply), SenderHA(rarp), ni->ha_len);    memcpy(TargetPA(reply), &ip_addr, 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 RARP 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(RARP_TYPE);    ni->transmit(buf, SenderHA(rarp));#endif /* RARP_SERVER */  }  /*-------------------------------------------------------------------*/  /* Else process RARP reply.                                          */  /*-------------------------------------------------------------------*/  else  {    ui32 server;    ArpEntry *arp_entry;    /*-----------------------------------------------------------------*/    /* Use this packet to update ARP cache.                            */    /*-----------------------------------------------------------------*/    memcpy(&server, SenderPA(rarp), IP_ALEN);    arp_entry = find_entry(server);    if (arp_entry)    {      memcpy(arp_entry->hw_addr, SenderHA(rarp), rarp->ha_len);      NetTimerStart(&arp_entry->timer, ARP_TIMEOUT);    }    else      add_entry(ni, rarp);    /*-----------------------------------------------------------------*/    /* Return if interface is not waiting for a RARP reply.            */    /*-----------------------------------------------------------------*/    if (ni->ip_addr || ((ni->flags & NIF_USE_RARP) == FALSE))      return;    /*-----------------------------------------------------------------*/    /* Return if this packet is not directed at us.                    */    /*-----------------------------------------------------------------*/    if (memcmp(ni->hw_addr, TargetHA(rarp), rarp->ha_len))      return;    /*-----------------------------------------------------------------*/    /* Were waiting for this reply. Stop RARP retry timer.             */    /*-----------------------------------------------------------------*/    NetTimerStop(&RarpTimer);    /*-----------------------------------------------------------------*/    /* Assign IP address and mask, and add this network interface.     */    /*-----------------------------------------------------------------*/    memcpy(&ni->ip_addr, TargetPA(rarp), IP_ALEN);    ni->ip_mask = IpNetMask(ni->ip_addr);    NiRtAdd(ni);    /*-----------------------------------------------------------------*/    /* If requested, add RARP server as default gateway.               */    /*-----------------------------------------------------------------*/    if (ni->flags & NIF_DEF_GW)      RtAdd(server, 0, INADDR_ANY, ni, RT_GATEWAY);  }}/***********************************************************************//*     RarpAdd: Start IP address resolution using RARP client          *//*                                                                     *//*       Input: ni = pointer to network interface                      *//*                                                                     *//***********************************************************************/int RarpAdd(Ni *ni){  /*-------------------------------------------------------------------*/  /* Return error if RARP timer is in use.                             */  /*-------------------------------------------------------------------*/  if (RarpTimer.running)    return -1;  /*-------------------------------------------------------------------*/  /* Clear NI's IP address field and save NI pointer.                  */  /*-------------------------------------------------------------------*/  ni->ip_addr = 0;  RarpTimer.object = ni;  /*-------------------------------------------------------------------*/  /* Initialize retry count and schedule first RARP request.           */  /*-------------------------------------------------------------------*/  RarpRetries = 0;  NetTimerStart(&RarpTimer, rand() % K2_SECONDS);  return 0;}/***********************************************************************//* NetQueryArp: Display contents of ARP cache                          *//*                                                                     *//***********************************************************************/void NetQueryArp(void){  int n, i = 0;  ArpEntry *entry = Entry;  /*-------------------------------------------------------------------*/  /* Print ARP table heading.                                          */  /*-------------------------------------------------------------------*/  printf("IP Address       MAC Address\n"         "==========       ===========\n");  /*-------------------------------------------------------------------*/  /* Search through ARP table, checking each entry.                    */  /*-------------------------------------------------------------------*/  do  {    /*-----------------------------------------------------------------*/    /* If entry is valid, print IP address and MAC address.            */    /*-----------------------------------------------------------------*/    if (entry->state != AES_FREE)    {      n = printIP(entry->pr_addr);      while (++n < 18) putchar(' ');      printEth(entry->hw_addr);      putchar('\n');    }    /*-----------------------------------------------------------------*/    /* Increment entry pointer, wrapping when end is reached.          */    /*-----------------------------------------------------------------*/    if (++entry == &ArpTbl[ARP_TSIZE])      entry = &ArpTbl[0];  }  while (++i < ARP_TSIZE);}/***********************************************************************//* Local Function Definitions                                          *//***********************************************************************//***********************************************************************//* rarp_timeout: Process RARP request timeout                          *//*                                                                     *//*       Input: object = pointer to network interface                  *//*                                                                     *//***********************************************************************/static void rarp_timeout(void *object){  int timeout;  Ni *ni = object;  uint length = offsetof(Arp, addresses) + 2 * (IP_ALEN + ni->ha_len);  NetBuf *buf;  Arp *rarp;  /*-------------------------------------------------------------------*/  /* Broadcast RARP request if able to allocate transmit buffer.       */  /*-------------------------------------------------------------------*/  buf = tcpGetBuf(NIMHLEN + length);  if (buf)  {    /*-----------------------------------------------------------------*/    /* Get pointer to packet frame and complete RARP message fields.   */    /*-----------------------------------------------------------------*/    rarp = (Arp *)buf->ip_pkt;    rarp->hw_type = htons(ni->hw_type);    rarp->pr_type = htons(IP_TYPE);    rarp->ha_len = ni->ha_len;    rarp->pa_len = IP_ALEN;    rarp->operation = htons(RARP_REQUEST);    memcpy(SenderHA(rarp), ni->hw_addr, ni->ha_len);    memset(SenderPA(rarp), 0, IP_ALEN);    memcpy(TargetHA(rarp), ni->hw_addr, ni->ha_len);    memset(TargetPA(rarp), 0, IP_ALEN);#if TCP_PROBE    /*-----------------------------------------------------------------*/    /* Decode RARP packet if global decode flag is TRUE.               */    /*-----------------------------------------------------------------*/    if (NetProbeFlag)      got_arp(rarp);#endif    /*-----------------------------------------------------------------*/    /* Complete buffer data and request NI to transmit packet.         */    /*-----------------------------------------------------------------*/    buf->length = length;

⌨️ 快捷键说明

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