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

📄 windrv.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * FILENAME: windrv.c
 *
 * Copyright  2001 By InterNiche Technologies Inc. All rights reserved
 *
 *
 * MODULE: WIN32
 *
 * ROUTINES: wd_prep(), wd_init(), wd_pkt_send(), wd_close(), 
 * ROUTINES: select_ndis(), packet_task(), packet_init(), packet_chk(), 
 * ROUTINES: PacketDemuxwCopy(), wd_reg_type(), wd_stats(), 
 *
 * PORTABLE: no
 */

/* windrv.c
 *
 *
 * This file implements an interface to PACKET.LIB  which layers on top
 * of Microsoft NDIS drivers. PACKET.LIB was obtained from the winpcap
 * website.
 *
 */
/* Disable warnings */
#pragma warning(disable: 4244 4310 4115)

#define  _WINSOCKAPI_   1  /* and keep winsock out of this... */
#include <windows.h>

#include <stdio.h>
#include <string.h>

#undef FAR
#include "ipport.h"     /* interniche files */

#ifdef WIN2K            /* If this is a Windows 2000 driver */
#include "q.h"
#include "netbuf.h"
#include "net.h"
#include "ether.h"
#include "arp.h"
#include "ip.h"

#include "nvparms.h"
#include "task.h"

#include "packet32.h"

#define  IPRINTF   /* dprintf */ /* printf messages for debugging */
#define  RXPKTSIZE   1536

/* in this file */
int wd_init(int iface);          /* net initialization file */
int wd_pkt_send(struct netbuf *);   /* send packet on media */
int wd_close(int iface);         /* net close routine */
int wd_reg_type(unshort type, struct net*);  /* register a MAC type */
void  wd_stats(void * pio, int iface);   
char * select_ndis(int * index_to_set);

#ifdef SUPERLOOP
int packet_init_done = FALSE;
#endif   /* SUPERLOOP */

/* we use an array of these to build a list of NDIS devices in the 
 * system and present it to the console user. These do NOT map to
 * nets[] indexes!!
 */
struct ndis_name  {
   int   selection;     /* 0 for first, etc... */
   char  description[200]; /* descriptive name from registry */
   LPADAPTER   lpAdapter;  /* Adapter object */
   LPPACKET packet;        /* packet structure */
};

#define  MAX_NDIS 10
struct ndis_name  ndnames[MAX_NDIS];

#define  MAXTYPES 10 /* usually use 2 - IP and ARP */

/* these structs contain the NDIS specific information for the stack
 * to work with an NDIS device via Packet.DLL. These DO map to nets[]
 * indexes, e.g. nets[2] corresponds to ndms[2]
 */
struct ndis_mac
{
   HANDLE   fd;
   int      nic_index;        /* index into ndnames[] */
   u_char   macaddr[6];
   u_short  types[MAXTYPES];  /* e.g. 0x0800 for IP, 0x0806 for ARP */
};

/* Ndis_mac structures and their pointers */

struct ndis_mac   ndms[MAXNETS];
struct ndis_mac * ndmacs[MAXNETS];
PACKET_OID_DATA oid_data;



struct ndis_stats
{
   u_long   sends_done;
   u_long   sends_started;
   u_long   sends_delayed;
   u_long   receives;   /* total windrv layer receives */
   u_long   rx_delayed; /* received via overlapped call */
   u_long   rx_ioctl;   /* received via IoControl call */
   u_long   bad_ips;    /* receive with dest IP != us or bcast */
   u_long   last_bad;   /* address in last bad_ips */
   u_long   resets;
   u_long   no_rxbuf;   /* failed to get a free buffer for RX */
   u_long   missed_posts;  /* times we missed an RX post */
   u_long   rxcopy;     /* times we copied a receive to a little buffer */
}  nstat;

struct ndis_stats ndstats[MAX_NDIS];
NET ndis_ifp;
struct bpf_stat   adapter_stats;

#ifdef INICHE_TASKS
struct task *  tk_ndis;
#else
int packet_init(void);
int packet_chk(void);
#endif

char     rcvbuf[512000]; /* Packet.dll interface reads into this buffer */

/* Internal routines to deal with Packet.dll */

int  packet_task(int parm);
void PrintPackets(LPPACKET lpPacket);
void PacketDemux(LPPACKET lpPacket, struct ndis_mac * nd);
void PacketDemuxwCopy(LPPACKET lpPacket, struct ndis_mac * nd);

extern DWORD dwVersion;
extern DWORD dwWindowsMajorVersion;


/* FUNCTION: wd_prep()
 * 
 * PARAM1: int iface
 *
 * RETURNS: 
 *
 * Prepare the interfaces and select NDIS interface to use
 */

int
wd_prep(int iface)
{
   struct net *   ifp;
   struct ndis_mac * nmp;
   char *   errmsg;
   int      nic=0;   /* selected ndnames[] index */
   int      j=0;

   if (iface >= MAXNETS)
   {
      dprintf("wd_prep: MAXNETS\n");
      return iface;
   }
   ifp = nets[iface];
   nmp = ndmacs[iface] = &ndms[iface];

   /* figure out which NDIS device to use */
   errmsg = select_ndis(&nic);
   if (errmsg)
   {
      dprintf("NDIS selection: %s\n", errmsg);
      return iface;
   }

   Printu_Net("Using NDIS ethernet device %s\n", ndnames[nic].description);

   nmp->nic_index = nic;
   dprintf("Mac Address: ");
   for (j=0; j < 6; j++)
   {
      dprintf("%x ", oid_data.Data[j]);
      ndmacs[iface]->macaddr[j] = oid_data.Data[j];
   }
   dprintf ("\n");
   /* set up  an InterNiche net structure for a static interface */
   ifp->n_lnh = ETHHDR_SIZE;     /* space reserved for ethernet header */
#ifdef IEEE_802_3
   ifp->n_lnh += sizeof(struct snap_hdr);    /* Add IEEE bloat */
#endif
   ifp->n_hal = 6;                  /* hardware address length */
   ifp->n_mtu = 1514;               /* max frame size */
   ifp->n_haddr = (char*)&nmp->macaddr[0];
   ifp->n_flags = (NF_NBPROT | NF_BCAST);    /* driver capability flags */

   ifp->mib.ifAdminStatus = 2;   /* status = down */
   ifp->mib.ifOperStatus = 2;    /* will be set up in init()  */
   ifp->mib.ifLastChange = cticks * (100/TPS);
   ifp->mib.ifType = ETHERNET;
   ifp->mib.ifDescr = (u_char*)"Windows 2000/95/98 NDIS ethernet Hook";
   ifp->mib.ifPhysAddress = &nmp->macaddr[0];

   /* install our virtual driver routines */

   ifp->n_init = wd_init;
   ifp->pkt_send = wd_pkt_send;
   ifp->n_close = wd_close;
   ifp->n_reg_type = wd_reg_type;
   ifp->n_stats = wd_stats;

   /* set a custom name for ndis device */
   ifp->name[0] = 'n';
   ifp->name[1] = 'd';
   ifp->name[2] = '0';

   /* search the NV parameters for iface setup for our name. If this
    * fails we just default to what's already in the ifp.
    */
#ifdef INCLUDE_NVPARMS
   if_configbyname(ifp);
#endif

   ifp->n_local = (void*)nmp;    /* attach ndis pointer to iface */
   ndis_ifp = ifp;               /* save for task */
   IPRINTF("[wd_prep done] ");
   return (iface + 1);     /* OK return */
}




/* FUNCTION: wd_init()
 * 
 * PARAM1: int iface
 *
 * RETURNS: 
 *
 * Start a NicheTask thread and mark the interfaces UP
 */

int
wd_init(int iface)
{
   struct ndis_mac * nmp;
   NET      ifp;

#ifdef INICHE_TASKS
   /* start a NichTask thread to manage the Packet.DLL IO */
   tk_ndis = tk_new(tk_cur, packet_task, 8192, "NDIS", 0);
   if (!tk_ndis)
   {
      dprintf("can't fork NDIS task");
      return ENP_RESOURCE;
   }
#else
   packet_init();
#endif

   nmp = ndmacs[iface];

   if (nmp == NULL)
   {
      dtrap();
      return ENP_LOGIC;
   }
   ifp = nets[iface];

   /* The interface(s) or adapter(s) were opened and initialized in wd_prep logic */
   /* This code sets the admin and operational status as UP */

   ifp->n_mib->ifAdminStatus = 1;   /* Admin status UP */

   ifp->n_mib->ifOperStatus = 1;    /* mark as really UP */

   return 0;
}



/* FUNCTION: wd_pkt_send()
 * 
 * PARAM1: struct netbuf * pkt
 *
 * RETURNS: 0 if successful, else -1
 *
 * Send the packet via Packet.DLL
 */

int
wd_pkt_send(struct netbuf * pkt)
{
   struct ndis_mac * nmp;
   struct ndis_name *   ndname;

   /* Send the packet using PacketSendPacket */

   nmp = (struct ndis_mac *)pkt->net->n_local;  /* get struct */
   ndname = &ndnames[nmp->nic_index];

   PacketInitPacket(ndname->packet, (char *)pkt->nb_prot + ETHHDR_BIAS,pkt->nb_plen);
   if ((PacketSendPacket(ndname->lpAdapter, ndname->packet, TRUE)) == FALSE)
   {
      dprintf("Unable to send packet\n");
      return -1;
   }
   nstat.sends_done++;
   pk_free(pkt);
   return 0;
}



/* FUNCTION: wd_close()
 * 
 * PARAM1: int  iface
 *
 * RETURNS: 
 */

int
wd_close(int  iface)
{
   NET      ifp;
   struct ndis_mac * nd;

   ifp = nets[iface];
   nd = &ndms[iface];

   if (!ifp || !(ifp->n_mib) || (ifp->n_mib->ifAdminStatus == 2))
      return 0;
   ifp->n_mib->ifAdminStatus = 2;   /* Admin status DOWN */
#ifdef INICHE_TASKS
   tk_kill(tk_ndis); /* done with the NDIS task... */
   tk_ndis = NULL;
#endif
   PacketCloseAdapter(ndnames[nd->nic_index].lpAdapter);
   return 0;
}

extern   int  kbhit(void);
extern   int  getch(void);



/* FUNCTION: select_ndis()
 * 
 * PARAM1: int * nic
 *
 * RETURNS: 
 */

char *   
select_ndis(int * nic)
{
   ULONG NameLength = 1024;

   /* unicode strings (winnt) */
   static WCHAR AdapterNames[1024];
   WCHAR *tmp; WCHAR *tmp1;

   /* ascii strings (win95) */
   static char AdapterNamesa[1024];
   char *   tmpa, *  tmp1a;

   int   ethernets=0;   int   i  =0;   int   j  =  0;
   int   namelen  =  0;
   NetType type;
   DWORD dwErrorCode;
   LPADAPTER lpAdapter;

   /*
    * The data returned by PacketGetAdapterNames is different in Win95 and 
    * in WinNT/Win2000.  We have to check the os on which we are running 
    */
   if (!(dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4))
   { 
      /* Windows NT/2000 Version */

      PacketGetAdapterNames ((PTSTR) AdapterNames,(PULONG)&NameLength);
      tmp = AdapterNames;
      tmp1 = AdapterNames;

      while ((*tmp != '\0') || (*(tmp-1) != '\0'))
      {
         if (*tmp == '\0')
         {
            namelen = (tmp-tmp1)*2;
            for (j=0; j < namelen; j++)
            {
               ndnames[i].description[j] = *(char *)tmp1;
               (char *)tmp1++;
            }

            /* If the ascii name indicates it's one of those stupid "NdisWan" 
             * things then skip it. It's not Etherent and the system will
             * crash (blue-screen of death) if we try to use it.
             */
            if(strstr(ndnames[i].description, "Packet_NdisWan"))
            {
               tmp1 = ++tmp;
               continue;
            }

            ndnames[i].selection = i;
            tmp1 = tmp+1;
            i++;
         }
         tmp++;
      }
   }
   else
   {
      /* Windows 95/98 Version */

      PacketGetAdapterNames (AdapterNamesa, &NameLength);
      tmpa = AdapterNamesa;
      tmp1a = AdapterNamesa;
      while ((*tmpa != '\0') || (*(tmp1a) != '\0'))
      {
         if (*tmpa == '\0')
         {
            if(strstr(tmpa, "Packet_NdisWan"))
               continue;

            namelen = (tmpa-tmp1a)*2;
            for (j=0; j < namelen; j++)
            {
               ndnames[i].description[j] = *(char *)tmp1a;
               (char *)tmp1a++;
            }
            ndnames[i].selection = i;
            tmp1a = tmpa+1;

⌨️ 快捷键说明

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