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

📄 m_arp.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
📖 第 1 页 / 共 2 页
字号:
   {
      dtrap("m_arp 0\n");
      return;
   }
   outpkt->net = pkt->net;    /* send back out the iface it came from */

   in = (struct arp_hdr *)(pkt->nb_buff + ETHHDR_SIZE);
   out = (struct arp_hdr *)(outpkt->nb_buff + ETHHDR_SIZE);

   /* prepare outgoing arp packet */
   out->ar_hd = ARPHW;
   out->ar_pro = ARPIP;
   out->ar_hln = 6;
   out->ar_pln = 4;
   out->ar_op = ARREP;
   out->ar_tpa = in->ar_spa;     /* swap IP addresses */
   out->ar_spa = in->ar_tpa;
   MEMCPY(out->ar_tha, in->ar_sha, 6);    /* move his MAC address */
   MEMCPY(out->ar_sha, outpkt->net->n_mib->ifPhysAddress, 6);  /* fill in our mac address */

   /* prepend ethernet unicast header to arp reply */
   ethin = (struct ethhdr *)(pkt->nb_buff + ETHHDR_BIAS);
   ethout = (struct ethhdr *)(outpkt->nb_buff + ETHHDR_BIAS);
   MEMCPY(ethout->e_dst, ethin->e_src, 6);
   MEMCPY(ethout->e_src, outpkt->net->n_mib->ifPhysAddress, 6);
   ethout->e_type = ET_ARP;   /* 0x0806 - ARP type on ethernet */

#ifdef NO_CC_PACKING    /* move ARP fields to proper network boundaries */
   {
      struct arp_wire * arwp  =  (struct  arp_wire *)out;
      MEMMOVE(&arwp->data[AR_SHA], out->ar_sha, 6);
      MEMMOVE(&arwp->data[AR_SPA], &out->ar_spa, 4);
      MEMMOVE(&arwp->data[AR_THA], out->ar_tha, 6);
      MEMMOVE(&arwp->data[AR_TPA], &out->ar_tpa, 4);
   }
#endif   /* NO_CC_PACKING */

   outpkt->nb_plen = ETHHDR_SIZE + sizeof(struct arp_hdr);
   outpkt->nb_prot = outpkt->nb_buff;
   outpkt->net->pkt_send(outpkt);

   /* input 'pkt' will be freed by caller */
   arpRepsOut++;
}


/* FUNCTION: arprcv()
 *
 * arprcv(PACKET) - process an incoming arp packet. 
 *
 * 
 * PARAM1: PACKET pkt
 *
 * RETURNS: Returns 0 if it was for us, 
 * ENP_NOT_MINE (1) if the arp packet is not for my IP 
 * address, else a negative error code. 
 */

int
arprcv(PACKET pkt)
{
   struct arp_hdr *  arphdr;
   struct arptabent *   tp;

   arphdr = (struct arp_hdr *)(pkt->nb_buff + ETHHDR_SIZE);

#ifdef NO_CC_PACKING    /* force ARP fields to local CPU valid boundaries */
   {
      struct arp_wire * arwp  =  (struct  arp_wire *)arphdr;
      MEMMOVE(&arphdr->ar_tpa, &arwp->data[AR_TPA], 4);
      MEMMOVE(arphdr->ar_tha, &arwp->data[AR_THA], 6);
      MEMMOVE(&arphdr->ar_spa, &arwp->data[AR_SPA], 4);
      MEMMOVE(arphdr->ar_sha, &arwp->data[AR_SHA], 6);
   }
#endif   /* NO_CC_PACKING */

   /* check ARP's target IP against our net's: */
   if(arphdr->ar_tpa != pkt->net->n_ipaddr)
   {
      LOCK_NET_RESOURCE(FREEQ_RESID);
      pk_free(pkt);     /* not for us, dump & ret (proxy here later?) */
      UNLOCK_NET_RESOURCE(FREEQ_RESID);
      return(ENP_NOT_MINE);
   }

   if (arphdr->ar_op == ARREQ)   /* is it an arp request? */
   {
      arpReqsIn++;   /* count these */
      arpReply(pkt); /* send arp reply */
      /* make partial ARP table entry */
      make_arp_entry(arphdr->ar_spa, pkt->net);
      /* fall thru to arp reply logic to finish our table entry */
   }
   else     /* ARP reply, count and fall thru to logic to update table */
   {
      arpRepsIn++;
   }

   /* scan table for matching entry */
   /* check this for default gateway situations later, JB */
   for (tp = arp_table;   tp <= &arp_table[MAXARPS-1]; tp++)
   {
      if (tp->t_pro_addr == arphdr->ar_spa)     /* we found IP address, update entry */
      {
         MEMCPY(tp->t_phy_addr, arphdr->ar_sha, 6);   /* update MAC adddress */
         tp->lasttime = cticks;
         if (tp->pending)     /* packet waiting for this IP entry? */
         {
            PACKET outpkt = tp->pending;
            tp->pending = NULL;
            et_send(outpkt, tp);    /* try send again */
         }
         LOCK_NET_RESOURCE(FREEQ_RESID);
         pk_free(pkt);
         UNLOCK_NET_RESOURCE(FREEQ_RESID);
         return(0);
      }
   }
   /* fall to here if packet is not in table */
   LOCK_NET_RESOURCE(FREEQ_RESID);
   pk_free(pkt);
   UNLOCK_NET_RESOURCE(FREEQ_RESID);
   return ENP_NOT_MINE;
}



/* FUNCTION: send_via_arp()
 * 
 * send_via_arp() - Called when we want to send an IP packet on a 
 * media (i.e. ethernet) which supports ARP. packet is passed, along 
 * with target IP address, which may be the packet's dest_ip or a 
 * gateway/router. We check the ARP cache (and scan arp table if 
 * required) for MAC address matching the passed dest_ip address. If 
 * the MAC address is not already known, we broadcast an arp request 
 * for the missing IP address and attach the packet to the "pending" 
 * pointer. The packet will be sent when the ARP reply comes in, or 
 * freed if we time out. We flush the cache every second to force the 
 * regular freeing of any "pending" packets. We flush every entry on 
 * the ageout interval so bogus ARP addresses won't get permanently 
 * wedged in the table. This happens when someone replaces a PC's MAC 
 * adapter but does not change the PC's IP address. 
 *
 * PARAM1: PACKET pkt
 * PARAM2: ip_addr dest_ip
 *
 * RETURNS: Returns 0 if packet went to mac sender; ENP_SEND_PENDING
 * if awaiting arp reply, or SEND_FAILED if error 
 */

int
send_via_arp(PACKET pkt, ip_addr dest_ip)
{
   struct arptabent *   tp;

   /* Force refresh of cache once a second */
   if ((cachetime + TPS) < cticks)
      arpcache = NULL;

   /* look at the last ARP entry used. Good chance it's ours: */
   if (arpcache && arpcache->t_pro_addr == dest_ip)
      return(et_send(pkt, arpcache));

   /* scan arp table for an existing entry */
   for (tp = arp_table;   tp <= &arp_table[MAXARPS-1]; tp++)
   {
      /* age out pending entrys here: */
      if (tp->pending)
      {
         /* if over a second old.. */
         if (( cticks > TPS ) &&
             (tp->createtime < (cticks - TPS)))
         {
            LOCK_NET_RESOURCE(FREEQ_RESID);
            pk_free(tp->pending);   /* free the blocked IP packet */
            UNLOCK_NET_RESOURCE(FREEQ_RESID);
            tp->pending = NULL;     /* clear pointer */
            tp->t_pro_addr = 0;     /* marks entry as "unused" */
         }
      }

      /* See if it's time to age out this entry anyway. We don't kill 
       * entries we've referenced in the last second for 
       */
      if (((tp->createtime + (TPS * (u_long)arp_ageout)) < cticks) && 
          (tp->lasttime + TPS) < cticks)
      {
         tp->t_pro_addr = 0;     /* marks entry as "unused" */
      }

      if (tp->t_pro_addr == dest_ip)   /* we found our entry */
      {
         if (tp->pending)  /* arp already pending for this IP? */
         {
            LOCK_NET_RESOURCE(FREEQ_RESID);
            pk_free(pkt);  /* sorry, we have to dump this one.. */
            UNLOCK_NET_RESOURCE(FREEQ_RESID);
            return SEND_DROPPED;    /* packet already waiting for this IP entry */
         }
         else  /* just send it */
         {
            arpcache = tp;       /* cache this entry */
            cachetime = cticks;  /* mark time we cached */
            return(et_send(pkt, tp));
         }
      }
   }
   return(send_arp(pkt, dest_ip));
}

#ifdef NET_STATS

/* FUNCTION: arp_stats()
 * 
 * PARAM1: void * pio
 *
 * RETURNS: 
 */

int
arp_stats(void * pio)   /* passed output device */
{
   struct arptabent *   atp;
   int   i;
   int   arp_entrys  =  0;

   ns_printf(pio, "arp Requests In: %u,   out: %u\n", arpReqsIn, arpReqsOut);
   ns_printf(pio, "arp Replys   In: %u,   out: %u\n", arpRepsIn, arpRepsOut);

   /* count number of arp entrys in use: */
   for (i = 0; i < MAXARPS; i++)
   {
      if (arp_table[i].t_pro_addr)
         arp_entrys++;
   }

   if (arp_entrys)
   {
      ns_printf(pio, "X)  MAC Address   iface pend    IP      ctime  ltime\n");
      for (i = 0; i < MAXARPS; i++)
      {
         atp = &arp_table[i];
         if (atp->t_pro_addr)
         {
            ns_printf(pio, "%d)  ", i);

            ns_printf(pio, "%02x%02x%02x-%02x%02x%02x ",
            atp->t_phy_addr[0],
            atp->t_phy_addr[1],
            atp->t_phy_addr[2],
            atp->t_phy_addr[3],
            atp->t_phy_addr[4],
            atp->t_phy_addr[5]);

            ns_printf(pio, "  %d   %s   %u.%u.%u.%u   %lu  %lu\n",
            if_netnumber(atp->net)+1,
            atp->pending?"Y":"N",
            PUSH_IPADDR(atp->t_pro_addr),
            (long)atp->createtime,
            (long)atp->lasttime);
         }
      }
   }
   else
   {
      ns_printf(pio, "Currently no arp table entrys.\n");
   }

   return 0;
}
#endif   /* NET_STATS */

 /* end of file et_arp.c */


⌨️ 快捷键说明

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