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

📄 windrv.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
📖 第 1 页 / 共 2 页
字号:
            i++;
         }
         tmpa++;
      }
   }
   ethernets = i;

   if (ethernets < 1)
      return "no ethernet NDIS drivers found";

   if (ethernets >= 2)
   {
      /* got more than one alleged ethernet, let user choose */
      Printu_Net("Multiple devices are listed as ethernet; please choose\n");
      for (i = 0; i < ethernets; i++)
         Printu_Net("\n%d - %s\n", ndnames[i].selection+1, ndnames[i].description);
      getdev:
      Printu_Net("enter 1 - %d\n", ethernets);
      while (!kbhit())
         tk_yield();
      i = getch();
      if ((i < '1') || (i > ethernets+'0'))
         goto getdev;
      *nic = i - '1';
   }
   else
      *nic = 0;

   /* Open the chosen adapter and ensure that it is an Ethernet adapter */
   
   lpAdapter = (LPADAPTER)PacketOpenAdapter((char *)ndnames[*nic].description);
   ndnames[*nic].lpAdapter = lpAdapter;
   if (!lpAdapter || (lpAdapter->hFile == INVALID_HANDLE_VALUE))
   {
      dwErrorCode = GetLastError();
      dprintf("Unable to open the driver, Error Code : %1x\n",dwErrorCode);
      return (0);
   }
   if (PacketGetNetType(lpAdapter, &type) == FALSE)
      return ("Cannot determine the network type\n");
   if (type.LinkType != NdisMedium802_3)
      return ("LinkType is not ethernet\n");
   
   /* Set the hardware filter and get the MAC address */
    
   PacketSetHwFilter(ndnames[*nic].lpAdapter, NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_BROADCAST);
   oid_data.Oid = OID_802_3_CURRENT_ADDRESS;
   oid_data.Length = 6;
   if (PacketRequest(ndnames[*nic].lpAdapter, FALSE, (PPACKET_OID_DATA)&oid_data) == FALSE)
      return "PacketRequest failed\n";
      
   /* Allocate the packet for this Adapter */
    
   if ((ndnames[*nic].packet = PacketAllocatePacket()) == NULL)
      return "Cannot allocate NDIS packet structure\n";
   nstat.receives = 0;
   return NULL;

}



#ifdef INICHE_TASKS
/* FUNCTION: packet_task()
 * 
 * PARAM1: int parm
 *
 * RETURNS: 0
 *
 * The packet task is in an infinite loop waiting for packets and demultiplexes the
 * received packets to a higher layer.
 *
 */

int
packet_task(int parm)
{
   struct ndis_mac  *   nd;
   struct net *   ifp;
   IFMIB    mib;
   struct ndis_name *   ndname;

   ifp = ndis_ifp;
   nd = (struct ndis_mac *)ifp->n_local;
   ndname = &ndnames[nd->nic_index];
   mib = ifp->n_mib;

   PacketSetBuff(ndname->lpAdapter, 512000);
   PacketSetReadTimeout(ndname->lpAdapter, 1);
   PacketInitPacket(ndname->packet, (char *)&rcvbuf[0], 512000);

   for (;;)
   {
      while (mib->ifAdminStatus != 1)
      {
         tk_sleep(1);
      }
      tk_yield();    /* let rest of system spin */

      PacketInitPacket(ndname->packet, (char *)&rcvbuf[0],25000);

      if (PacketReceivePacket(ndname->lpAdapter, ndname->packet,TRUE) == FALSE) 
      {
         dprintf("read error: PacketReceivePacket failed\n");
      }
      PacketDemuxwCopy(ndname->packet,nd);

   }

   USE_ARG(parm);
   return 0;
}

#else 

/* For SUPERLOOP, packet_init() is called at the beginning to initialize
 * the packet driver. And then packet_chk() is called periodically to
 * check for incoming packets. 
 */

/* FUNCTION: packet_init()
 * 
 * PARAM1: int parm
 *
 * RETURNS: 0
 *
 * Initialize the packet driver. 
 */

int
packet_init(void)
{
   struct ndis_mac  *   nd;
   struct net *   ifp;
   struct ndis_name *   ndname;

   ifp = ndis_ifp;
   nd = (struct ndis_mac *)ifp->n_local;
   ndname = &ndnames[nd->nic_index];

   PacketSetBuff(ndname->lpAdapter, 512000);
   PacketSetReadTimeout(ndname->lpAdapter, 1);
   PacketInitPacket(ndname->packet, (char *)&rcvbuf[0], 512000);

#ifdef MINI_IP
   clock_init();

   /* The mini version of IP has no reg_type() primitive (it assumes
    * the drivers know to support IP and ARP), so we must call the NDIS
    * driver reg_type() routine as part of the port.
    */
#ifndef USE_PPP
#ifdef  WIN2K
   wd_reg_type(ET_ARP, nets[0]);
   wd_reg_type(IP_TYPE, nets[0]);
#endif /* WIN2K */
#endif   /* USE_PPP */
#endif   /* MINI_IP */

   packet_init_done = TRUE;
   return 0;
}

/* FUNCTION: packet_chk()
 * 
 * PARAM1: int parm
 *
 * RETURNS: 0
 *
 * Check for received packets. Demultiplexes the
 * received packets to a higher layer.
 *
 */

int
packet_chk(void)
{
   struct ndis_mac  *   nd;
   struct net *   ifp;
   struct ndis_name *   ndname;

   if (packet_init_done != TRUE)
      return 0;

   ifp = ndis_ifp;
   nd = (struct ndis_mac *)ifp->n_local;
   ndname = &ndnames[nd->nic_index];

   PacketInitPacket(ndname->packet, (char *)&rcvbuf[0],25000);

   if (PacketReceivePacket(ndname->lpAdapter, ndname->packet,TRUE) == FALSE) 
   {
      dprintf("read error: PacketReceivePacket failed\n");
   }
   PacketDemuxwCopy(ndname->packet,nd);

   return 0;
}
#endif


/* FUNCTION: PacketDemuxwCopy()
 * 
 * PARAM1: LPPACKET lpPacket
 * PARAM2: struct ndis_mac  * nd
 *
 * RETURNS: void
 *
 * PacketDemuxwCopy copies packets that have the type we want into local stack
 * buffers and passes them up to the ip layer.  The packets are copied from the
 * big Packet.dll receive buffer into Iniche buffers.
 */

void
PacketDemuxwCopy(LPPACKET lpPacket, struct ndis_mac  * nd)
{
   int      i=0;
   PACKET   newpkt;     /* copy into stack packet */
   u_short  type;    /* local endian type from eth header */
   struct ethhdr *   eth;  /* ethernet header, overlay on receives */
   struct ip * pip;     /* IP header to overlay for addr check */
   struct net *   ifp;

   u_int ulBytesReceived;
   u_int off=0;
   u_int tlen,tlen1;
   struct bpf_hdr *  hdr;

   ifp = ndis_ifp;

   ulBytesReceived = lpPacket->ulBytesReceived;
   if (ulBytesReceived == 0) return;

      nstat.receives++;
   while ( off < ulBytesReceived)
   {
      hdr = (struct bpf_hdr *)((char *)lpPacket->Buffer+off);
      tlen1=hdr->bh_datalen;
      tlen=hdr->bh_caplen;
      off+=hdr->bh_hdrlen;


      /* See if we want this type  */
      eth = (struct ethhdr *)((char *)hdr+(hdr->bh_hdrlen));
      type = eth->e_type;     /* leave in net endian */


#ifdef IEEE_802_3
      /* See if sender is legacy IEEE machine. If we were not using the 
       * NF_NBPROT bit in this device we could skip this step and the packet
       * would get trapped by the logic in pktdemux.c
       */
      if (htons(type) <= 0x0600)
      {
         struct snap_hdr * snap;
         snap = (struct snap_hdr *)((char *)hdr + (hdr->bh_hdrlen)
          + (ETHHDR_SIZE-ETHHDR_BIAS));
         type = snap->type;

      }
      else
#endif

      for (i = 0; i < MAXTYPES; i++)
      {
         if (nd->types[i] == 0)
            break;
         if (type == nd->types[i]) 
            break;
      }

      if (type == nd->types[i])
      {
         if (type == IPTP) /* if it's an IP packet */
         {
         /* filter for our IP address. This makes the iface 
          * useless for routing, but solves problems dealing 
          * with the crusty NDIS system.
          */
            pip = (struct ip *)((char *)hdr+ (hdr->bh_hdrlen)
             + (ETHHDR_SIZE-ETHHDR_BIAS));
            if ((pip->ip_dest != ifp->n_ipaddr) &&    /* not unicast to us... */
#ifdef IP_MULTICAST
             ( !IN_MULTICAST(ntohl(pip->ip_dest))) &&  /* & not multicast */
#endif   /* IP_MULTICAST */
             ((pip->ip_dest & ifp->snmask) != ifp->snmask))  /* & not bcast */
            {
               /* mib->ifInDiscards++; ??? */
               nstat.bad_ips++;
               nstat.last_bad = pip->ip_dest;
               off = Packet_WORDALIGN(off+tlen1);
               continue;
            }
         }

         newpkt = pk_alloc(RXPKTSIZE-sizeof(struct bpf_hdr));  /* get another rx buffer */
         if (newpkt == NULL)              /* test for new pkt */
         {
            nstat.no_rxbuf++;                /* count alloc failures */

            /* If we are out of big free buffers then don't give back the one
             * we have for receives. Copy the packet to a small buffer if it 
             * fits, else drop it.
             */
            /* See if the received data can fit in a little buffer */
            if (tlen1 < lilbufsiz)
            {
               newpkt = pk_alloc(tlen1);  /* try to get a little buf */
               if (newpkt)
               {
                  nstat.rxcopy++;               /* count alloc failures */
                  /* copy the data and pointers from the big rx buffer to the new
                   * smaller buffer.
                   */
                  MEMCPY(newpkt->nb_buff + ETHHDR_BIAS, (char *)hdr + sizeof(struct bpf_hdr), tlen1);
                  newpkt->nb_plen= tlen1 - (ETHHDR_SIZE - ETHHDR_BIAS);
                  newpkt->nb_prot = newpkt->nb_buff + ETHHDR_SIZE;
                  newpkt->nb_tstamp = cticks;
                  newpkt->net = ifp;
                  newpkt->type = type;
                  putq(&rcvdq, newpkt);               /* post rx packet in rx que */
                  SignalPktDemux();                   /* wake the net task */
                  off = Packet_WORDALIGN(off+tlen1);
                  continue;
               }
            }
            /* packet too big for little buffer, or couldn't get little buffer */
            ifp->n_mib->ifInDiscards++;      /* count drops */
            return;
         }
         MEMCPY(newpkt->nb_buff + ETHHDR_BIAS, (char *)hdr + (hdr->bh_hdrlen), tlen1);
         newpkt->nb_plen= tlen1 - (ETHHDR_SIZE - ETHHDR_BIAS);
         newpkt->nb_prot = newpkt->nb_buff + ETHHDR_SIZE;
         newpkt->nb_tstamp = cticks;
         newpkt->net = ifp;
         newpkt->type = type;
         putq(&rcvdq, newpkt);            /* post rx packet in rx que */
         SignalPktDemux();                /* wake the net task */
      }
      else  /* it's a type we dont want */
      {
         /* count discarded packets */
         ifp->mib.ifInDiscards++;
      }
      off = Packet_WORDALIGN(off+tlen1);
   }
}




/* FUNCTION: wd_reg_type()
 * 
 * PARAM1: unshort type
 * PARAM2: struct net * netp
 *
 * RETURNS: 0
 *
 * Register the packet types wanted
 */

int
wd_reg_type(unshort type, struct net * netp)
{
   int   slot;
   struct ndis_mac * nd;

   nd = ndmacs[if_netnumber(netp)];

   /* find an empty type slot */
   for (slot = 0; slot < MAXTYPES; slot++)
   {
      if (nd->types[slot] == type)  /* already set? */
         return 0;      /* return - no error */
      if (nd->types[slot] == 0)
         break;
   }
   if (slot >= MAXTYPES)
      return ENP_RESOURCE;

   nd->types[slot] = type;

   return 0;
}




/* FUNCTION: wd_stats()
 * 
 * PARAM1: void * pio
 * PARAM2: int iface
 *
 * RETURNS: void
 *
 * Display statistics
 */

void
wd_stats(void * pio, int iface)
{
   NET      ifp;
   int      nic;
   struct ndis_name *   ndname;


   ifp = nets[iface];
   nic = ndmacs[iface]->nic_index;
   ndname = &ndnames[nic];

   ns_printf(pio, "NDIS Device: %s(%d)\n",
    ndnames[nic].description,  ndnames[nic].selection);
   ns_printf(pio, "LI: sends; started:%d, done:%d, delayed:%d\n",
    nstat.sends_started, nstat.sends_done, nstat.sends_delayed);
   ns_printf(pio, "LI: receive: total:%d, ioctl: %d, delayed:%d\n",
    nstat.receives, nstat.rx_ioctl, nstat.rx_delayed );
   ns_printf(pio, "LI: receive: bad_ip:%d, last_bad:%u.%u.%u.%u\n", 
    nstat.bad_ips, PUSH_IPADDR(nstat.last_bad));
   ns_printf(pio, "LI: resets:%d\n", nstat.resets);
   ns_printf(pio, "LI: no_rxbuf:%d missed_posts:%d\n",
    nstat.no_rxbuf, nstat.missed_posts);

   PacketGetStats(ndname->lpAdapter, &adapter_stats);
   ns_printf(pio, "NDIS Adapter: received: %d dropped: %d\n",
    adapter_stats.bs_recv, adapter_stats.bs_drop);
}

#endif   /* WIN2K */

⌨️ 快捷键说明

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