📄 windrv.c
字号:
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 + -