📄 pktdrv.c
字号:
buf = lpPacket->Buffer;
off=0;
while (off<ulBytesReceived)
{
//if (kbhit())return;
hdr=(struct bpf_hdr *)(buf+off);
tlen1=hdr->bh_datalen;
cur_length=tlen1;
tlen=hdr->bh_caplen;
off+=hdr->bh_hdrlen;
ulLines = (tlen + 15) / 16;
if (ulLines > 5) ulLines=5;
base =(char*)(buf+off);
cur_packet=base;
off=Packet_WORDALIGN(off+tlen);
process_input();
}
}
void update_adapter(void)
{
if (PacketReceivePacket(lpAdapter,lpPacket,TRUE)==TRUE)
ProcessPackets(lpPacket);
cur_length=0;
cur_packet=NULL;
}
/*-----------------------------------------------------------------------------------
* Hardware Emulation API
* The following code emulates a real hardware NIC.
* The registers of the NIC are defined in pktdrv.h
*---------------------------------------------------------------------------------*/
#ifdef NIC_EMU
#define PEXTERN extern
#include "pktdrv.h"
#include <port.h>
static unsigned long volatile intStatus;
static int volatile runtasks;
static int volatile rxtaskStopped;
static int volatile txtaskStopped;
static HANDLE rxWaitSemaphore;
static HANDLE txWaitSemaphore;
void _pk_notify(volatile unsigned long* reg, unsigned long v)
{
if (reg == &pkregister.notify_flags)
{
if (v & PK_NFLAG_TRANSMITNOW)
{
pkregister.txpsize[pkregister.txbuf_in] = pkregister.packetsize;
pkregister.txbuf_in = (pkregister.txbuf_in + 1) % PK_TXBUFFER;
ReleaseSemaphore(txWaitSemaphore, 1, NULL);
}
if (v & PK_NFLAG_RECEIVENEXT)
{
pkregister.rxbuf_out = (pkregister.rxbuf_out + 1) % PK_RXBUFFER;
ReleaseSemaphore(rxWaitSemaphore, 1, NULL);
}
pkregister.notify_flags = 0;
}
}
unsigned long _pk_readreg(volatile unsigned long* reg)
{
unsigned long ret;
long i;
if (reg == &pkregister.int_status)
{
singleThreadEnter();
ret = intStatus;
intStatus = 0;
singleThreadExit();
}
else
if (reg == &pkregister.fifo_status)
{
ret = 0;
i = (long)pkregister.txbuf_out - (long)pkregister.txbuf_in - 1;
if (i < 0) i += PK_TXBUFFER;
if (i > 0)
ret |= PK_FSTATUS_TXBFREE;
if (pkregister.rxbuf_in != pkregister.rxbuf_out)
ret |= PK_FSTATUS_RECEIVED;
}
else
if (reg == &pkregister.txbuf_adr)
{
ret = (unsigned long) &pkregister.txbuffer[pkregister.txbuf_in][0];
}
else
if (reg == &pkregister.rxbuf_adr)
{
ret = (unsigned long) &pkregister.rxbuffer[pkregister.rxbuf_out][0];
}
else
if (reg == &pkregister.packetsize)
{
ret = pkregister.rxpsize[pkregister.rxbuf_out];
}
else
{
ret = *reg;
}
return ret;
}
extern void nic_interrupt(void);
static void exec_interrupt(unsigned long irqstatus)
{
unsigned long newis;
if (((irqstatus & PK_ISTATUS_TX) && (pkregister.int_mask & PK_IMASK_TX)) ||
((irqstatus & PK_ISTATUS_RX) && (pkregister.int_mask & PK_IMASK_RX)))
{
newis = intStatus | irqstatus;
if (newis != intStatus)
{
intStatus = newis;
callInterruptHandler( nic_interrupt );
}
}
}
static void process_input(void)
{
static const unsigned char bcast[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
unsigned long i, o, n;
if ((memcmp(cur_packet, ethaddr, 6) == 0) ||
(memcmp(cur_packet, bcast, 6) == 0))
{
for (;;)
{
i = pkregister.rxbuf_in;
o = pkregister.rxbuf_out % PK_RXBUFFER;
n = (i + 1) % PK_RXBUFFER;
if ((n == o) && (runtasks > 0))
{
WaitForSingleObject(rxWaitSemaphore, 50);
}
else
{
break;
}
}
if (n != o)
{
if (cur_length > PK_TBUFSIZE)
cur_length = PK_TBUFSIZE;
memcpy(pkregister.rxbuffer[i], cur_packet, cur_length);
pkregister.rxpsize[i] = cur_length;
singleThreadEnter();
pkregister.rxbuf_in = n;
exec_interrupt(PK_ISTATUS_RX);
singleThreadExit();
}
}
}
static DWORD WINAPI rx_thread(LPVOID param)
{
(void) param;
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
while (runtasks == 0) Sleep(5);
while (runtasks > 0)
{
update_adapter();
}
rxtaskStopped = 1;
return 0;
}
static DWORD WINAPI tx_thread(LPVOID param)
{
unsigned long i;
(void) param;
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
while (runtasks == 0) Sleep(5);
while (runtasks > 0)
{
i = pkregister.txbuf_out;
if (i != pkregister.txbuf_in)
{
packet_send(pkregister.txbuffer[i], pkregister.txpsize[i]);
singleThreadEnter();
pkregister.txbuf_out = (i + 1) % PK_TXBUFFER;
exec_interrupt(PK_ISTATUS_TX);
singleThreadExit();
}
else
{
WaitForSingleObject(txWaitSemaphore, 50);
}
}
txtaskStopped = 1;
return 0;
}
int pktdrv_start(int adapter_num)
{
int status;
DWORD tid;
HANDLE th;
intStatus = 0;
memset(&pkregister, 0, sizeof(pkregister));
status = init_adapter(adapter_num);
if (status >= 0)
{
pkregister.mac_lo = *((unsigned long*) (ethaddr+2));
pkregister.mac_hi = *((unsigned long*) ethaddr) & 0xFFFF;
PacketSetMinToCopy(lpAdapter, 1);
PacketSetReadTimeout(lpAdapter, 50);
rxWaitSemaphore = CreateSemaphore(NULL, 0, 1, NULL);
if (rxWaitSemaphore == NULL)
{
shutdown_adapter();
return -1;
}
txWaitSemaphore = CreateSemaphore(NULL, 0, 1, NULL);
if (txWaitSemaphore == NULL)
{
CloseHandle(rxWaitSemaphore);
shutdown_adapter();
return -1;
}
runtasks = 0;
rxtaskStopped = 0;
txtaskStopped = 0;
th = CreateThread(NULL, 0, rx_thread, NULL, 0, &tid);
if (th == NULL)
{
CloseHandle(txWaitSemaphore);
CloseHandle(rxWaitSemaphore);
shutdown_adapter();
return -1;
}
th = CreateThread(NULL, 0, tx_thread, NULL, 0, &tid);
if (th == NULL)
{
runtasks = -1;
ReleaseSemaphore(rxWaitSemaphore, 1, NULL);
while (rxtaskStopped == 0) Sleep(10);
CloseHandle(txWaitSemaphore);
CloseHandle(rxWaitSemaphore);
shutdown_adapter();
return -1;
}
runtasks = 1;
Sleep(10);
}
return status;
}
void pktdrv_stop(void)
{
if (runtasks > 0)
{
runtasks = -1;
ReleaseSemaphore(txWaitSemaphore, 1, NULL);
ReleaseSemaphore(rxWaitSemaphore, 1, NULL);
while ((rxtaskStopped == 0) || (txtaskStopped == 0)) Sleep(50);
}
CloseHandle(txWaitSemaphore);
CloseHandle(rxWaitSemaphore);
shutdown_adapter();
}
#endif /* NIC_EMU */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -