📄 pktdrvr.c
字号:
LOCAL __inline BOOL CheckElement (RX_ELEMENT _far *rx)
#endif
{
WORD count_1, count_2;
/*
* We got an upcall to the same RMCB with wrong handle.
* This can happen if we failed to release handle at program exit
*/
if (rx->handle != pktInfo.handle)
{
pktInfo.error = "Wrong handle";
intStat.wrongHandle++;
PktReleaseHandle (rx->handle);
return (FALSE);
}
count_1 = rx->firstCount;
count_2 = rx->secondCount;
if (count_1 != count_2)
{
pktInfo.error = "Bad sync";
intStat.badSync++;
return (FALSE);
}
if (count_1 > ETH_MAX)
{
pktInfo.error = "Large esize";
intStat.tooLarge++;
return (FALSE);
}
#if 0
if (count_1 < ETH_MIN)
{
pktInfo.error = "Small esize";
intStat.tooSmall++;
return (FALSE);
}
#endif
return (TRUE);
}
/**************************************************************************/
PUBLIC BOOL PktTerminHandle (WORD handle)
{
reg.r_ax = 0x0500;
reg.r_bx = handle;
return PktInterrupt();
}
/**************************************************************************/
PUBLIC BOOL PktResetInterface (WORD handle)
{
reg.r_ax = 0x0700;
reg.r_bx = handle;
return PktInterrupt();
}
/**************************************************************************/
PUBLIC BOOL PktSetReceiverMode (PKT_RX_MODE mode)
{
if (pktInfo.class == PD_SLIP || pktInfo.class == PD_PPP)
return (TRUE);
reg.r_ax = 0x1400;
reg.r_bx = pktInfo.handle;
reg.r_cx = (WORD)mode;
if (!PktInterrupt())
return (FALSE);
receiveMode = mode;
return (TRUE);
}
/**************************************************************************/
PUBLIC BOOL PktGetReceiverMode (PKT_RX_MODE *mode)
{
reg.r_ax = 0x1500;
reg.r_bx = pktInfo.handle;
if (!PktInterrupt())
return (FALSE);
*mode = reg.r_ax;
return (TRUE);
}
/**************************************************************************/
static PKT_STAT initialStat; /* statistics at startup */
static BOOL resetStat = FALSE; /* statistics reset ? */
PUBLIC BOOL PktGetStatistics (WORD handle)
{
reg.r_ax = 0x1800;
reg.r_bx = handle;
if (!PktInterrupt())
return (FALSE);
#if (DOSX & PHARLAP)
ReadRealMem (&pktStat, DOS_ADDR(reg.ds,reg.esi), sizeof(pktStat));
#elif (DOSX & DJGPP)
dosmemget (DOS_ADDR(reg.x.ds,reg.x.si), sizeof(pktStat), &pktStat);
#elif (DOSX & DOS4GW)
memcpy (&pktStat, (void*)DOS_ADDR(reg.r_ds,reg.r_si), sizeof(pktStat));
#else
_fmemcpy (&pktStat, MK_FP(reg.r_ds,reg.r_si), sizeof(pktStat));
#endif
return (TRUE);
}
/**************************************************************************/
PUBLIC BOOL PktSessStatistics (WORD handle)
{
if (!PktGetStatistics(pktInfo.handle))
return (FALSE);
if (resetStat)
{
pktStat.inPackets -= initialStat.inPackets;
pktStat.outPackets -= initialStat.outPackets;
pktStat.inBytes -= initialStat.inBytes;
pktStat.outBytes -= initialStat.outBytes;
pktStat.inErrors -= initialStat.inErrors;
pktStat.outErrors -= initialStat.outErrors;
pktStat.outErrors -= initialStat.outErrors;
pktStat.lost -= initialStat.lost;
}
return (TRUE);
}
/**************************************************************************/
PUBLIC BOOL PktResetStatistics (WORD handle)
{
if (!PktGetStatistics(pktInfo.handle))
return (FALSE);
memcpy (&initialStat, &pktStat, sizeof(initialStat));
resetStat = TRUE;
return (TRUE);
}
/**************************************************************************/
PUBLIC BOOL PktGetAddress (ETHER *addr)
{
reg.r_ax = 0x0600;
reg.r_bx = pktInfo.handle;
reg.r_cx = sizeof (*addr);
#if (DOSX & DJGPP)
reg.x.es = rm_mem.rm_segment;
reg.x.di = pktTemp;
#elif (DOSX & DOS4GW)
reg.r_es = rm_base_seg;
reg.r_di = pktTemp;
#else
reg.r_es = FP_SEG (&pktTemp);
reg.r_di = FP_OFF (&pktTemp); /* ES:DI = address for result */
#endif
if (!PktInterrupt())
return (FALSE);
#if (DOSX & PHARLAP)
ReadRealMem (addr, realBase + (WORD)&pktTemp, sizeof(*addr));
#elif (DOSX & DJGPP)
dosmemget (realBase+pktTemp, sizeof(*addr), addr);
#elif (DOSX & DOS4GW)
memcpy (addr, (void*)(realBase+pktTemp), sizeof(*addr));
#else
memcpy ((void*)addr, &pktTemp, sizeof(*addr));
#endif
return (TRUE);
}
/**************************************************************************/
PUBLIC BOOL PktSetAddress (const ETHER *addr)
{
/* copy addr to real-mode scrath area */
#if (DOSX & PHARLAP)
WriteRealMem (realBase + (WORD)&pktTemp, (void*)addr, sizeof(*addr));
#elif (DOSX & DJGPP)
dosmemput (addr, sizeof(*addr), realBase+pktTemp);
#elif (DOSX & DOS4GW)
memcpy ((void*)(realBase+pktTemp), addr, sizeof(*addr));
#else
memcpy (&pktTemp, (void*)addr, sizeof(*addr));
#endif
reg.r_ax = 0x1900;
reg.r_cx = sizeof (*addr); /* address length */
#if (DOSX & DJGPP)
reg.x.es = rm_mem.rm_segment; /* DOS offset to param */
reg.x.di = pktTemp; /* DOS segment to param */
#elif (DOSX & DOS4GW)
reg.r_es = rm_base_seg;
reg.r_di = pktTemp;
#else
reg.r_es = FP_SEG (&pktTemp);
reg.r_di = FP_OFF (&pktTemp);
#endif
return PktInterrupt();
}
/**************************************************************************/
PUBLIC BOOL PktGetDriverInfo (void)
{
pktInfo.majVer = 0;
pktInfo.minVer = 0;
memset (&pktInfo.name, 0, sizeof(pktInfo.name));
reg.r_ax = 0x01FF;
reg.r_bx = 0;
if (!PktInterrupt())
return (FALSE);
pktInfo.number = reg.r_cx & 0xFF;
pktInfo.class = reg.r_cx >> 8;
#if 0
pktInfo.minVer = reg.r_bx % 10;
pktInfo.majVer = reg.r_bx / 10;
#else
pktInfo.majVer = reg.r_bx; // !!
#endif
pktInfo.funcs = reg.r_ax & 0xFF;
pktInfo.type = reg.r_dx & 0xFF;
#if (DOSX & PHARLAP)
ReadRealMem (&pktInfo.name, DOS_ADDR(reg.ds,reg.esi), sizeof(pktInfo.name));
#elif (DOSX & DJGPP)
dosmemget (DOS_ADDR(reg.x.ds,reg.x.si), sizeof(pktInfo.name), &pktInfo.name);
#elif (DOSX & DOS4GW)
memcpy (&pktInfo.name, (void*)DOS_ADDR(reg.r_ds,reg.r_si), sizeof(pktInfo.name));
#else
_fmemcpy (&pktInfo.name, MK_FP(reg.r_ds,reg.r_si), sizeof(pktInfo.name));
#endif
return (TRUE);
}
/**************************************************************************/
PUBLIC BOOL PktGetDriverParam (void)
{
reg.r_ax = 0x0A00;
if (!PktInterrupt())
return (FALSE);
#if (DOSX & PHARLAP)
ReadRealMem (&pktInfo.majVer, DOS_ADDR(reg.es,reg.edi), PKT_PARAM_SIZE);
#elif (DOSX & DJGPP)
dosmemget (DOS_ADDR(reg.x.es,reg.x.di), PKT_PARAM_SIZE, &pktInfo.majVer);
#elif (DOSX & DOS4GW)
memcpy (&pktInfo.majVer, (void*)DOS_ADDR(reg.r_es,reg.r_di), PKT_PARAM_SIZE);
#else
_fmemcpy (&pktInfo.majVer, MK_FP(reg.r_es,reg.r_di), PKT_PARAM_SIZE);
#endif
return (TRUE);
}
/**************************************************************************/
#if (DOSX & PHARLAP)
PUBLIC int PktReceive (BYTE *buf, int max)
{
WORD inOfs = *rxInOfsFp;
WORD outOfs = *rxOutOfsFp;
if (outOfs != inOfs)
{
RX_ELEMENT _far *head = (RX_ELEMENT _far*)(protBase+outOfs);
int size, len = max;
if (CheckElement(head))
{
size = min (head->firstCount, sizeof(RX_ELEMENT));
len = min (size, max);
_fmemcpy (buf, &head->destin, len);
}
else
size = -1;
outOfs += sizeof (RX_ELEMENT);
if (outOfs > LAST_RX_BUF)
outOfs = FIRST_RX_BUF;
*rxOutOfsFp = outOfs;
return (size);
}
return (0);
}
PUBLIC void PktQueueBusy (BOOL busy)
{
*rxOutOfsFp = busy ? (*rxInOfsFp + sizeof(RX_ELEMENT)) : *rxInOfsFp;
if (*rxOutOfsFp > LAST_RX_BUF)
*rxOutOfsFp = FIRST_RX_BUF;
*(DWORD _far*)(protBase + (WORD)&pktDrop) = 0;
}
PUBLIC WORD PktBuffersUsed (void)
{
WORD inOfs = *rxInOfsFp;
WORD outOfs = *rxOutOfsFp;
if (inOfs >= outOfs)
return (inOfs - outOfs) / sizeof(RX_ELEMENT);
return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT));
}
PUBLIC DWORD PktRxDropped (void)
{
return (*(DWORD _far*)(protBase + (WORD)&pktDrop));
}
#elif (DOSX & DJGPP)
PUBLIC int PktReceive (BYTE *buf, int max)
{
WORD ofs = _farpeekw (_dos_ds, realBase+rxOutOfs);
if (ofs != _farpeekw (_dos_ds, realBase+rxInOfs))
{
RX_ELEMENT head;
int size, len = max;
head.firstCount = _farpeekw (_dos_ds, realBase+ofs);
head.secondCount = _farpeekw (_dos_ds, realBase+ofs+2);
head.handle = _farpeekw (_dos_ds, realBase+ofs+4);
if (CheckElement(&head))
{
size = min (head.firstCount, sizeof(RX_ELEMENT));
len = min (size, max);
dosmemget (realBase+ofs+6, len, buf);
}
else
size = -1;
ofs += sizeof (RX_ELEMENT);
if (ofs > LAST_RX_BUF)
_farpokew (_dos_ds, realBase+rxOutOfs, FIRST_RX_BUF);
else _farpokew (_dos_ds, realBase+rxOutOfs, ofs);
return (size);
}
return (0);
}
PUBLIC void PktQueueBusy (BOOL busy)
{
WORD ofs;
disable();
ofs = _farpeekw (_dos_ds, realBase+rxInOfs);
if (busy)
ofs += sizeof (RX_ELEMENT);
if (ofs > LAST_RX_BUF)
_farpokew (_dos_ds, realBase+rxOutOfs, FIRST_RX_BUF);
else _farpokew (_dos_ds, realBase+rxOutOfs, ofs);
_farpokel (_dos_ds, realBase+pktDrop, 0UL);
enable();
}
PUBLIC WORD PktBuffersUsed (void)
{
WORD inOfs, outOfs;
disable();
inOfs = _farpeekw (_dos_ds, realBase+rxInOfs);
outOfs = _farpeekw (_dos_ds, realBase+rxOutOfs);
enable();
if (inOfs >= outOfs)
return (inOfs - outOfs) / sizeof(RX_ELEMENT);
return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT));
}
PUBLIC DWORD PktRxDropped (void)
{
return _farpeekl (_dos_ds, realBase+pktDrop);
}
#elif (DOSX & DOS4GW)
PUBLIC int PktReceive (BYTE *buf, int max)
{
WORD ofs = *(WORD*) (realBase+rxOutOfs);
if (ofs != *(WORD*) (realBase+rxInOfs))
{
RX_ELEMENT head;
int size, len = max;
head.firstCount = *(WORD*) (realBase+ofs);
head.secondCount = *(WORD*) (realBase+ofs+2);
head.handle = *(WORD*) (realBase+ofs+4);
if (CheckElement(&head))
{
size = min (head.firstCount, sizeof(RX_ELEMENT));
len = min (size, max);
memcpy (buf, (const void*)(realBase+ofs+6), len);
}
else
size = -1;
ofs += sizeof (RX_ELEMENT);
if (ofs > LAST_RX_BUF)
*(WORD*) (realBase+rxOutOfs) = FIRST_RX_BUF;
else *(WORD*) (realBase+rxOutOfs) = ofs;
return (size);
}
return (0);
}
PUBLIC void PktQueueBusy (BOOL busy)
{
WORD ofs;
_disable();
ofs = *(WORD*) (realBase+rxInOfs);
if (busy)
ofs += sizeof (RX_ELEMENT);
if (ofs > LAST_RX_BUF)
*(WORD*) (realBase+rxOutOfs) = FIRST_RX_BUF;
else *(WORD*) (realBase+rxOutOfs) = ofs;
*(DWORD*) (realBase+pktDrop) = 0UL;
_enable();
}
PUBLIC WORD PktBuffersUsed (void)
{
WORD inOfs, outOfs;
_disable();
inOfs = *(WORD*) (realBase+rxInOfs);
outOfs = *(WORD*) (realBase+rxOutOfs);
_enable();
if (inOfs >= outOfs)
return (inOfs - outOfs) / sizeof(RX_ELEMENT);
return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT));
}
PUBLIC DWORD PktRxDropped (void)
{
return *(DWORD*) (realBase+pktDrop);
}
#else /* real-mode small/large model */
PUBLIC int PktReceive (BYTE *buf, int max)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -