📄 pktdrvr.c
字号:
{
if (rxOutOfs != rxInOfs)
{
RX_ELEMENT far *head = (RX_ELEMENT far*) MK_FP (_DS,rxOutOfs);
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;
rxOutOfs += sizeof (RX_ELEMENT);
if (rxOutOfs > LAST_RX_BUF)
rxOutOfs = FIRST_RX_BUF;
return (size);
}
return (0);
}
PUBLIC void PktQueueBusy (BOOL busy)
{
rxOutOfs = busy ? (rxInOfs + sizeof(RX_ELEMENT)) : rxInOfs;
if (rxOutOfs > LAST_RX_BUF)
rxOutOfs = FIRST_RX_BUF;
pktDrop = 0L;
}
PUBLIC WORD PktBuffersUsed (void)
{
WORD inOfs = rxInOfs;
WORD outOfs = rxOutOfs;
if (inOfs >= outOfs)
return ((inOfs - outOfs) / sizeof(RX_ELEMENT));
return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT));
}
PUBLIC DWORD PktRxDropped (void)
{
return (pktDrop);
}
#endif
/**************************************************************************/
LOCAL __inline void PktFreeMem (void)
{
#if (DOSX & PHARLAP)
if (realSeg)
{
_dx_real_free (realSeg);
realSeg = 0;
}
#elif (DOSX & DJGPP)
if (rm_mem.rm_segment)
{
unsigned ofs; /* clear the DOS-mem to prevent further upcalls */
for (ofs = 0; ofs < 16 * rm_mem.size / 4; ofs += 4)
_farpokel (_dos_ds, realBase + ofs, 0);
_go32_dpmi_free_dos_memory (&rm_mem);
rm_mem.rm_segment = 0;
}
#elif (DOSX & DOS4GW)
if (rm_base_sel)
{
dpmi_real_free (rm_base_sel);
rm_base_sel = 0;
}
#endif
}
/**************************************************************************/
PUBLIC BOOL PktExitDriver (void)
{
if (pktInfo.handle)
{
if (!PktSetReceiverMode(PDRX_BROADCAST))
PUTS ("Error restoring receiver mode.");
if (!PktReleaseHandle(pktInfo.handle))
PUTS ("Error releasing PKT-DRVR handle.");
PktFreeMem();
pktInfo.handle = 0;
}
if (pcap_pkt_debug >= 1)
printf ("Internal stats: too-small %lu, too-large %lu, bad-sync %lu, "
"wrong-handle %lu\n",
intStat.tooSmall, intStat.tooLarge,
intStat.badSync, intStat.wrongHandle);
return (TRUE);
}
#if (DOSX & (DJGPP|DOS4GW))
static void dump_pkt_stub (void)
{
int i;
fprintf (stderr, "PktReceiver %lu, pkt_stub[PktReceiver] =\n",
PktReceiver);
for (i = 0; i < 15; i++)
fprintf (stderr, "%02X, ", real_stub_array[i+PktReceiver]);
fputs ("\n", stderr);
}
#endif
/*
* Front end initialization routine
*/
PUBLIC BOOL PktInitDriver (PKT_RX_MODE mode)
{
PKT_RX_MODE rxMode;
BOOL writeInfo = (pcap_pkt_debug >= 3);
pktInfo.quiet = (pcap_pkt_debug < 3);
#if (DOSX & PHARLAP) && defined(__HIGHC__)
if (_mwenv != 2)
{
fprintf (stderr, "Only Pharlap DOS extender supported.\n");
return (FALSE);
}
#endif
#if (DOSX & PHARLAP) && defined(__WATCOMC__)
if (_Extender != 1)
{
fprintf (stderr, "Only DOS4GW style extenders supported.\n");
return (FALSE);
}
#endif
if (!PktSearchDriver())
{
PUTS ("Packet driver not found.");
PktFreeMem();
return (FALSE);
}
if (!PktGetDriverInfo())
{
PUTS ("Error getting pkt-drvr information.");
PktFreeMem();
return (FALSE);
}
#if (DOSX & PHARLAP)
if (RealCopy((ULONG)&rxOutOfs, (ULONG)&pktRxEnd,
&realBase, &protBase, (USHORT*)&realSeg))
{
rxOutOfsFp = (WORD _far *) (protBase + (WORD) &rxOutOfs);
rxInOfsFp = (WORD _far *) (protBase + (WORD) &rxInOfs);
*rxOutOfsFp = FIRST_RX_BUF;
*rxInOfsFp = FIRST_RX_BUF;
}
else
{
PUTS ("Cannot allocate real-mode stub.");
return (FALSE);
}
#elif (DOSX & (DJGPP|DOS4GW))
if (sizeof(real_stub_array) > 0xFFFF)
{
fprintf (stderr, "`real_stub_array[]' too big.\n");
return (FALSE);
}
#if (DOSX & DJGPP)
rm_mem.size = (sizeof(real_stub_array) + 15) / 16;
if (_go32_dpmi_allocate_dos_memory(&rm_mem) || rm_mem.rm_offset != 0)
{
PUTS ("real-mode init failed.");
return (FALSE);
}
realBase = (rm_mem.rm_segment << 4);
dosmemput (&real_stub_array, sizeof(real_stub_array), realBase);
_farpokel (_dos_ds, realBase+rxOutOfs, FIRST_RX_BUF);
_farpokel (_dos_ds, realBase+rxInOfs, FIRST_RX_BUF);
#elif (DOSX & DOS4GW)
rm_base_seg = dpmi_real_malloc (sizeof(real_stub_array), &rm_base_sel);
if (!rm_base_seg)
{
PUTS ("real-mode init failed.");
return (FALSE);
}
realBase = (rm_base_seg << 4);
memcpy ((void*)realBase, &real_stub_array, sizeof(real_stub_array));
*(WORD*) (realBase+rxOutOfs) = FIRST_RX_BUF;
*(WORD*) (realBase+rxInOfs) = FIRST_RX_BUF;
#endif
{
int pushf = PktReceiver;
while (real_stub_array[pushf++] != 0x9C && /* pushf */
real_stub_array[pushf] != 0xFA) /* cli */
{
if (++para_skip > 16)
{
fprintf (stderr, "Something wrong with `pkt_stub.inc'.\n");
para_skip = 0;
dump_pkt_stub();
return (FALSE);
}
}
if (*(WORD*)(real_stub_array + offsetof(PktRealStub,_dummy)) != 0xB800)
{
fprintf (stderr, "`real_stub_array[]' is misaligned.\n");
return (FALSE);
}
}
if (pcap_pkt_debug > 2)
dump_pkt_stub();
#else
rxOutOfs = FIRST_RX_BUF;
rxInOfs = FIRST_RX_BUF;
#endif
if (!PktSetAccess())
{
PUTS ("Error setting pkt-drvr access.");
PktFreeMem();
return (FALSE);
}
if (!PktGetAddress(&myAddress))
{
PUTS ("Error fetching adapter address.");
PktFreeMem();
return (FALSE);
}
if (!PktSetReceiverMode(mode))
{
PUTS ("Error setting receiver mode.");
PktFreeMem();
return (FALSE);
}
if (!PktGetReceiverMode(&rxMode))
{
PUTS ("Error getting receiver mode.");
PktFreeMem();
return (FALSE);
}
if (writeInfo)
printf ("Pkt-driver information:\n"
" Version : %d.%d\n"
" Name : %.15s\n"
" Class : %u (%s)\n"
" Type : %u\n"
" Number : %u\n"
" Funcs : %u\n"
" Intr : %Xh\n"
" Handle : %u\n"
" Extended : %s\n"
" Hi-perf : %s\n"
" RX mode : %s\n"
" Eth-addr : %02X:%02X:%02X:%02X:%02X:%02X\n",
pktInfo.majVer, pktInfo.minVer, pktInfo.name,
pktInfo.class, PktGetClassName(pktInfo.class),
pktInfo.type, pktInfo.number,
pktInfo.funcs, pktInfo.intr, pktInfo.handle,
pktInfo.funcs == 2 || pktInfo.funcs == 6 ? "Yes" : "No",
pktInfo.funcs == 5 || pktInfo.funcs == 6 ? "Yes" : "No",
PktRXmodeStr(rxMode),
myAddress[0], myAddress[1], myAddress[2],
myAddress[3], myAddress[4], myAddress[5]);
#if defined(DEBUG) && (DOSX & PHARLAP)
if (writeInfo)
{
DWORD rAdr = realBase + (WORD)&PktReceiver;
unsigned sel, ofs;
printf ("\nReceiver at %04X:%04X\n", RP_SEG(rAdr), RP_OFF(rAdr));
printf ("Realbase = %04X:%04X\n", RP_SEG(realBase),RP_OFF(realBase));
sel = _FP_SEG (protBase);
ofs = _FP_OFF (protBase);
printf ("Protbase = %04X:%08X\n", sel,ofs);
printf ("RealSeg = %04X\n", realSeg);
sel = _FP_SEG (rxOutOfsFp);
ofs = _FP_OFF (rxOutOfsFp);
printf ("rxOutOfsFp = %04X:%08X\n", sel,ofs);
sel = _FP_SEG (rxInOfsFp);
ofs = _FP_OFF (rxInOfsFp);
printf ("rxInOfsFp = %04X:%08X\n", sel,ofs);
printf ("Ready: *rxOutOfsFp = %04X *rxInOfsFp = %04X\n",
*rxOutOfsFp, *rxInOfsFp);
PktQueueBusy (TRUE);
printf ("Busy: *rxOutOfsFp = %04X *rxInOfsFp = %04X\n",
*rxOutOfsFp, *rxInOfsFp);
}
#endif
memset (&pktStat, 0, sizeof(pktStat)); /* clear statistics */
PktQueueBusy (TRUE);
return (TRUE);
}
/*
* DPMI functions only for Watcom + DOS4GW extenders
*/
#if (DOSX & DOS4GW)
LOCAL DWORD dpmi_get_real_vector (int intr)
{
union REGS r;
r.x.eax = 0x200;
r.x.ebx = (DWORD) intr;
int386 (0x31, &r, &r);
return ((r.w.cx << 4) + r.w.dx);
}
LOCAL WORD dpmi_real_malloc (int size, WORD *selector)
{
union REGS r;
r.x.eax = 0x0100; /* DPMI allocate DOS memory */
r.x.ebx = (size + 15) / 16; /* Number of paragraphs requested */
int386 (0x31, &r, &r);
if (r.w.cflag & 1)
return (0);
*selector = r.w.dx;
return (r.w.ax); /* Return segment address */
}
LOCAL void dpmi_real_free (WORD selector)
{
union REGS r;
r.x.eax = 0x101; /* DPMI free DOS memory */
r.x.ebx = selector; /* Selector to free */
int386 (0x31, &r, &r);
}
#endif
#if defined(DOSX) && (DOSX & PHARLAP)
/*
* Description:
* This routine allocates conventional memory for the specified block
* of code (which must be within the first 64K of the protected mode
* program segment) and copies the code to it.
*
* The caller should free up the conventional memory block when it
* is done with the conventional memory.
*
* NOTE THIS ROUTINE REQUIRES 386|DOS-EXTENDER 3.0 OR LATER.
*
* Calling arguments:
* start_offs start of real mode code in program segment
* end_offs 1 byte past end of real mode code in program segment
* real_basep returned; real mode ptr to use as a base for the
* real mode code (eg, to get the real mode FAR
* addr of a function foo(), take
* real_basep + (ULONG) foo).
* This pointer is constructed such that
* offsets within the real mode segment are
* the same as the link-time offsets in the
* protected mode program segment
* prot_basep returned; prot mode ptr to use as a base for getting
* to the conventional memory, also constructed
* so that adding the prot mode offset of a
* function or variable to the base gets you a
* ptr to the function or variable in the
* conventional memory block.
* rmem_adrp returned; real mode para addr of allocated
* conventional memory block, to be used to free
* up the conventional memory when done. DO NOT
* USE THIS TO CONSTRUCT A REAL MODE PTR, USE
* REAL_BASEP INSTEAD SO THAT OFFSETS WORK OUT
* CORRECTLY.
*
* Returned values:
* 0 if error
* 1 if success
*/
int RealCopy (ULONG start_offs,
ULONG end_offs,
REALPTR *real_basep,
FARPTR *prot_basep,
USHORT *rmem_adrp)
{
ULONG rm_base; /* base real mode para addr for accessing */
/* allocated conventional memory */
UCHAR *source; /* source pointer for copy */
FARPTR destin; /* destination pointer for copy */
ULONG len; /* number of bytes to copy */
ULONG temp;
USHORT stemp;
/* First check for valid inputs
*/
if (start_offs >= end_offs || end_offs > 0x10000)
return (FALSE);
/* Round start_offs down to a paragraph (16-byte) boundary so we can set up
* the real mode pointer easily. Round up end_offs to make sure we allocate
* enough paragraphs
*/
start_offs &= ~15;
end_offs = (15 + (end_offs << 4)) >> 4;
/* Allocate the conventional memory for our real mode code. Remember to
* round byte count UP to 16-byte paragraph size. We alloc it
* above the DOS data buffer so both the DOS data buffer and the appl
* conventional mem block can still be resized.
*
* First just try to alloc it; if we can't get it, shrink the appl mem
* block down to the minimum, try to alloc the memory again, then grow the
* appl mem block back to the maximum. (Don't try to shrink the DOS data
* buffer to free conventional memory; it wouldn't be good for this routine
* to have the possible side effect of making file I/O run slower.)
*/
len = ((end_offs - start_offs) + 15) >> 4;
if (_dx_real_above(len, rmem_adrp, &stemp) != _DOSE_NONE)
{
if (_dx_cmem_usage(0, 0, &temp, &temp) != _DOSE_NONE)
return (FALSE);
if (_dx_real_above(len, rmem_adrp, &stemp) != _DOSE_NONE)
*rmem_adrp = 0;
if (_dx_cmem_usage(0, 1, &temp, &temp) != _DOSE_NONE)
{
if (*rmem_adrp != 0)
_dx_real_free (*rmem_adrp);
return (FALSE);
}
if (*rmem_adrp == 0)
return (FALSE);
}
/* Construct real mode & protected mode pointers to access the allocated
* memory. Note we know start_offs is aligned on a paragraph (16-byte)
* boundary, because we rounded it down.
*
* We make the offsets come out rights by backing off the real mode selector
* by start_offs.
*/
rm_base = ((ULONG) *rmem_adrp) - (start_offs >> 4);
RP_SET (*real_basep, 0, rm_base);
FP_SET (*prot_basep, rm_base << 4, SS_DOSMEM);
/* Copy the real mode code/data to the allocated memory
*/
source = (UCHAR *) start_offs;
destin = *prot_basep;
FP_SET (destin, FP_OFF(*prot_basep) + start_offs, FP_SEL(*prot_basep));
len = end_offs - start_offs;
WriteFarMem (destin, source, len);
return (TRUE);
}
#endif /* DOSX && (DOSX & PHARLAP) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -