1b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek/* 277349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek * File.........: pktdrvr.c 377349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek * 477349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek * Responsible..: Gisle Vanem, giva@bgnett.no 577349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek * 677349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek * Created......: 26.Sept 1995 777349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek * 877349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek * Description..: Packet-driver interface for 16/32-bit C : 977349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek * Borland C/C++ 3.0+ small/large model 10b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek * Watcom C/C++ 11+, DOS4GW flat model 1141573ebf8fb971f40fa8a3e20648362c359b4916Ted Kremenek * Metaware HighC 3.1+ and PharLap 386|DosX 12b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek * GNU C/C++ 2.7+ and djgpp 2.x extender 1377349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek * 1477349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek * References...: PC/TCP Packet driver Specification. rev 1.09 1577349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek * FTP Software Inc. 16d065d6080f0620bb80b933f3f5d52d37bb2ea770Ted Kremenek * 17d065d6080f0620bb80b933f3f5d52d37bb2ea770Ted Kremenek */ 18d065d6080f0620bb80b933f3f5d52d37bb2ea770Ted Kremenek 19c77a55126fcad66fb086f8e100a494caa2496a2dZhongxing Xu#include <stdio.h> 201309f9a3b225ea846e5822691c39a77423125505Ted Kremenek#include <stdlib.h> 211309f9a3b225ea846e5822691c39a77423125505Ted Kremenek#include <string.h> 221309f9a3b225ea846e5822691c39a77423125505Ted Kremenek#include <dos.h> 231309f9a3b225ea846e5822691c39a77423125505Ted Kremenek 246b67630d5df195f4fe0e4273061c016901d69681Ted Kremenek#include "pcap-dos.h" 25c0c3f5dbc9e78aa53a86c7d5e3eeda23ddad93d6Ted Kremenek#include "pcap-int.h" 26f494b579b22f9950f5af021f0bf9879a91bb8b41Steve Naroff#include "msdos/pktdrvr.h" 27bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu 284beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek#if (DOSX) 2977349cb20bfd7069d081f84c91975bfa8ef60a32Ted Kremenek#define NUM_RX_BUF 32 /* # of buffers in Rx FIFO queue */ 301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#else 315e2d2c2ee3cf410643e0f9a5701708e51409d973Benjamin Kramer#define NUM_RX_BUF 10 325e2d2c2ee3cf410643e0f9a5701708e51409d973Benjamin Kramer#endif 335e2d2c2ee3cf410643e0f9a5701708e51409d973Benjamin Kramer 34f494b579b22f9950f5af021f0bf9879a91bb8b41Steve Naroff#define DIM(x) (sizeof((x)) / sizeof(x[0])) 351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#define PUTS(s) do { \ 3625e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu if (!pktInfo.quiet) \ 3725e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu pktInfo.error ? \ 380111f575b968e423dccae439e501225b8314b257Zhongxing Xu printf ("%s: %s\n", s, pktInfo.error) : \ 391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump printf ("%s\n", pktInfo.error = s); \ 40b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek } while (0) 41031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu 421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#if defined(__HIGHC__) 43b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek extern UINT _mwenv; 44b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 45031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu#elif defined(__DJGPP__) 461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump #include <stddef.h> 47b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek #include <dpmi.h> 484adc81e540b874bafa15715fd2c5cb662463debdTed Kremenek #include <go32.h> 49cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek #include <pc.h> 50b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek #include <sys/farptr.h> 51b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#elif defined(__WATCOMC__) 53846eabd187be4bfe992e8bca131166b734d86e0dTed Kremenek #include <i86.h> 54846eabd187be4bfe992e8bca131166b734d86e0dTed Kremenek #include <stddef.h> 551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump extern char _Extender; 56846d4e923bf11bcdc2816758aafa331795f29230Ted Kremenek 57031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu#else 58846d4e923bf11bcdc2816758aafa331795f29230Ted Kremenek extern void far PktReceiver (void); 59846d4e923bf11bcdc2816758aafa331795f29230Ted Kremenek#endif 600d093d3005dd583675a45a85bd688063572cc8afTed Kremenek 611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#if (DOSX & (DJGPP|DOS4GW)) 63b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek #include <sys/pack_on.h> 6403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu 651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump struct DPMI_regs { 66e448ab4f9dd162802f5d7cfea60f7830cc61c654Ted Kremenek DWORD r_di; 67e448ab4f9dd162802f5d7cfea60f7830cc61c654Ted Kremenek DWORD r_si; 681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump DWORD r_bp; 69e448ab4f9dd162802f5d7cfea60f7830cc61c654Ted Kremenek DWORD reserved; 70e448ab4f9dd162802f5d7cfea60f7830cc61c654Ted Kremenek DWORD r_bx; 71e448ab4f9dd162802f5d7cfea60f7830cc61c654Ted Kremenek DWORD r_dx; 721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump DWORD r_cx; 7372905cfa81cfd126f322c4173f56d332aac5539eJordy Rose DWORD r_ax; 7472905cfa81cfd126f322c4173f56d332aac5539eJordy Rose WORD r_flags; 7572905cfa81cfd126f322c4173f56d332aac5539eJordy Rose WORD r_es, r_ds, r_fs, r_gs; 76c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose WORD r_ip, r_cs, r_sp, r_ss; 77c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose }; 7872905cfa81cfd126f322c4173f56d332aac5539eJordy Rose 7972905cfa81cfd126f322c4173f56d332aac5539eJordy Rose /* Data located in a real-mode segment. This becomes far at runtime 8072905cfa81cfd126f322c4173f56d332aac5539eJordy Rose */ 8172905cfa81cfd126f322c4173f56d332aac5539eJordy Rose typedef struct { /* must match data/code in pkt_rx1.s */ 8272905cfa81cfd126f322c4173f56d332aac5539eJordy Rose WORD _rxOutOfs; 8372905cfa81cfd126f322c4173f56d332aac5539eJordy Rose WORD _rxInOfs; 8472905cfa81cfd126f322c4173f56d332aac5539eJordy Rose DWORD _pktDrop; 8572905cfa81cfd126f322c4173f56d332aac5539eJordy Rose BYTE _pktTemp [20]; 8672905cfa81cfd126f322c4173f56d332aac5539eJordy Rose TX_ELEMENT _pktTxBuf[1]; 8772905cfa81cfd126f322c4173f56d332aac5539eJordy Rose RX_ELEMENT _pktRxBuf[NUM_RX_BUF]; 8872905cfa81cfd126f322c4173f56d332aac5539eJordy Rose WORD _dummy[2]; /* screenSeg,newInOffset */ 8972905cfa81cfd126f322c4173f56d332aac5539eJordy Rose BYTE _fanChars[4]; 90094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek WORD _fanIndex; 91b94b81a9ab46c99b00c7ad28c5e1e212c63fc9acZhongxing Xu BYTE _PktReceiver[15]; /* starts on a paragraph (16byte) */ 9272905cfa81cfd126f322c4173f56d332aac5539eJordy Rose } PktRealStub; 939e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek #include <sys/pack_off.h> 949e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek 959e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek static BYTE real_stub_array [] = { 969e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek #include "pkt_stub.inc" /* generated opcode array */ 979e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek }; 989e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek 999e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek #define rxOutOfs offsetof (PktRealStub,_rxOutOfs) 100094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek #define rxInOfs offsetof (PktRealStub,_rxInOfs) 101ff944a8c481d6c0f1ad2633e4be9bf8b1dd2a09fZhongxing Xu #define PktReceiver offsetof (PktRealStub,_PktReceiver [para_skip]) 1029e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek #define pktDrop offsetof (PktRealStub,_pktDrop) 10372905cfa81cfd126f322c4173f56d332aac5539eJordy Rose #define pktTemp offsetof (PktRealStub,_pktTemp) 1049e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek #define pktTxBuf offsetof (PktRealStub,_pktTxBuf) 1059e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek #define FIRST_RX_BUF offsetof (PktRealStub,_pktRxBuf [0]) 1069e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek #define LAST_RX_BUF offsetof (PktRealStub,_pktRxBuf [NUM_RX_BUF-1]) 1079e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek 1089e9595b12e9b55586c4d50d370f429c7a3c92a90Ted Kremenek#else 109cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek extern WORD rxOutOfs; /* offsets into pktRxBuf FIFO queue */ 11032a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek extern WORD rxInOfs; 11132a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek extern DWORD pktDrop; /* # packets dropped in PktReceiver() */ 1121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump extern BYTE pktRxEnd; /* marks the end of r-mode code/data */ 113b22d589e2ccd09cada0bcea136f0966883a8bb11Ted Kremenek 11432a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek extern RX_ELEMENT pktRxBuf [NUM_RX_BUF]; /* PktDrvr Rx buffers */ 115cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek extern TX_ELEMENT pktTxBuf; /* PktDrvr Tx buffer */ 11650a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek extern char pktTemp[20]; /* PktDrvr temp area */ 1171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 11825e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu #define FIRST_RX_BUF (WORD) &pktRxBuf [0] 1192ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu #define LAST_RX_BUF (WORD) &pktRxBuf [NUM_RX_BUF-1] 1202ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu#endif 1212ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu 1222ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu 1232ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu#ifdef __BORLANDC__ /* Use Borland's inline functions */ 1242ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu #define memcpy __memcpy__ 1252ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu #define memcmp __memcmp__ 1262ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu #define memset __memset__ 1272ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu#endif 1282ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu 129b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 1301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#if (DOSX & PHARLAP) 131b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek extern void PktReceiver (void); /* in pkt_rx0.asm */ 132c77a55126fcad66fb086f8e100a494caa2496a2dZhongxing Xu static int RealCopy (ULONG, ULONG, REALPTR*, FARPTR*, USHORT*); 1335032ffe4259e7d436f2eb19e5a29fdae559e7c12Zhongxing Xu 1342ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu #undef FP_SEG 1351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump #undef FP_OFF 136846eabd187be4bfe992e8bca131166b734d86e0dTed Kremenek #define FP_OFF(x) ((WORD)(x)) 1371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump #define FP_SEG(x) ((WORD)(realBase >> 16)) 13832a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek #define DOS_ADDR(s,o) (((DWORD)(s) << 16) + (WORD)(o)) 1391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump #define r_ax eax 140cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek #define r_bx ebx 1411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump #define r_dx edx 142ec9227fea66c3439991fc84b0d33b0a8b4b8875eZhongxing Xu #define r_cx ecx 143ec9227fea66c3439991fc84b0d33b0a8b4b8875eZhongxing Xu #define r_si esi 14432a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek #define r_di edi 14532a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek #define r_ds ds 1461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump #define r_es es 147e01c98767dfd7153c3c84637c36659e3bbe16ff7Ted Kremenek LOCAL FARPTR protBase; 148e01c98767dfd7153c3c84637c36659e3bbe16ff7Ted Kremenek LOCAL REALPTR realBase; 149ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek LOCAL WORD realSeg; /* DOS para-address of allocated area */ 1501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump LOCAL SWI_REGS reg; 151031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu 1521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump static WORD _far *rxOutOfsFp, *rxInOfsFp; 153b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 154b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek#elif (DOSX & DJGPP) 15517fd8632dcda97022a51effc24060eacdad9dbe0Zhongxing Xu static _go32_dpmi_seginfo rm_mem; 1561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump static __dpmi_regs reg; 157031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu static DWORD realBase; 158031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu static int para_skip = 0; 15950a6d0ce344c02782e0207574005c3b2aaa5077cTed Kremenek 160ec9227fea66c3439991fc84b0d33b0a8b4b8875eZhongxing Xu #define DOS_ADDR(s,o) (((WORD)(s) << 4) + (o)) 161094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek #define r_ax x.ax 162094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek #define r_bx x.bx 163094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek #define r_dx x.dx 164094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek #define r_cx x.cx 165094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek #define r_si x.si 166ec9227fea66c3439991fc84b0d33b0a8b4b8875eZhongxing Xu #define r_di x.di 167094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek #define r_ds x.ds 168094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek #define r_es x.es 169ec9227fea66c3439991fc84b0d33b0a8b4b8875eZhongxing Xu 170ec9227fea66c3439991fc84b0d33b0a8b4b8875eZhongxing Xu#elif (DOSX & DOS4GW) 171094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek LOCAL struct DPMI_regs reg; 172094bef56a7900f13bb777f9a352704104b1458e7Ted Kremenek LOCAL WORD rm_base_seg, rm_base_sel; 1735a5d98bc6962dc2d1aaa5e0e522f1bf84273b9c1Ted Kremenek LOCAL DWORD realBase; 1741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump LOCAL int para_skip = 0; 1759c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu 1769c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu LOCAL DWORD dpmi_get_real_vector (int intr); 1779c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu LOCAL WORD dpmi_real_malloc (int size, WORD *selector); 1789c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu LOCAL void dpmi_real_free (WORD selector); 1799c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu #define DOS_ADDR(s,o) (((DWORD)(s) << 4) + (WORD)(o)) 1809c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu 1819c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu#else /* real-mode Borland etc. */ 1829c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu static struct { 1839c6cd67ea416bace666d614c84d5531124287653Zhongxing Xu WORD r_ax, r_bx, r_cx, r_dx, r_bp; 1841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump WORD r_si, r_di, r_ds, r_es, r_flags; 1854ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu } reg; 1864ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu#endif 1874ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu 1884ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu#ifdef __HIGHC__ 1894ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu #pragma Alias (pktDrop, "_pktDrop") 1904ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu #pragma Alias (pktRxBuf, "_pktRxBuf") 1914ffcb9974c6b7142c4a1483abfcb1f88b6371c45Zhongxing Xu #pragma Alias (pktTxBuf, "_pktTxBuf") 1926a6719a3a11087b48d9f1a4eb08b3bd43cb05a65Ted Kremenek #pragma Alias (pktTemp, "_pktTemp") 1936a6719a3a11087b48d9f1a4eb08b3bd43cb05a65Ted Kremenek #pragma Alias (rxOutOfs, "_rxOutOfs") 1946a6719a3a11087b48d9f1a4eb08b3bd43cb05a65Ted Kremenek #pragma Alias (rxInOfs, "_rxInOfs") 19503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu #pragma Alias (pktRxEnd, "_pktRxEnd") 1964323a57627e796dcfdfdb7d47672dc09ed308edaTed Kremenek #pragma Alias (PktReceiver,"_PktReceiver") 1971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#endif 198b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 199b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek 20003509aea098772644bf4662dc1c88634818ceeccZhongxing XuPUBLIC PKT_STAT pktStat; /* statistics for packets */ 20103509aea098772644bf4662dc1c88634818ceeccZhongxing XuPUBLIC PKT_INFO pktInfo; /* packet-driver information */ 2021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 203b387a3f23e423d62c053be86294b703da1d1a222Ted KremenekPUBLIC PKT_RX_MODE receiveMode = PDRX_DIRECT; 204b387a3f23e423d62c053be86294b703da1d1a222Ted KremenekPUBLIC ETHER myAddress = { 0, 0, 0, 0, 0, 0 }; 205031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing XuPUBLIC ETHER ethBroadcast = { 255,255,255,255,255,255 }; 2061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 207b387a3f23e423d62c053be86294b703da1d1a222Ted KremenekLOCAL struct { /* internal statistics */ 208b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek DWORD tooSmall; /* size < ETH_MIN */ 209031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu DWORD tooLarge; /* size > ETH_MAX */ 2101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump DWORD badSync; /* count_1 != count_2 */ 21111062b118476368fa5b294954713e5df97d8599fTed Kremenek DWORD wrongHandle; /* upcall to wrong handle */ 21211062b118476368fa5b294954713e5df97d8599fTed Kremenek } intStat; 21373099bfea9f5d4ec05265170bbefec3d76fb6b5eTed Kremenek 214102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor/***************************************************************************/ 215ccc263b44c62ce3a02f797a3ddb3d6017cf0e5e4Ted Kremenek 216102acd5369bbb17c0d6ab868af376671acff7a93Douglas GregorPUBLIC const char *PktGetErrorStr (int errNum) 217102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor{ 218ccc263b44c62ce3a02f797a3ddb3d6017cf0e5e4Ted Kremenek static const char *errStr[] = { 219102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor "", 220102acd5369bbb17c0d6ab868af376671acff7a93Douglas Gregor "Invalid handle number", 221ccc263b44c62ce3a02f797a3ddb3d6017cf0e5e4Ted Kremenek "No interfaces of specified class found", 222ccc263b44c62ce3a02f797a3ddb3d6017cf0e5e4Ted Kremenek "No interfaces of specified type found", 223ccc263b44c62ce3a02f797a3ddb3d6017cf0e5e4Ted Kremenek "No interfaces of specified number found", 2249c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek "Bad packet type specified", 22532a58084a4c53e6938dd81bfce224db25a5976d1Ted Kremenek "Interface does not support multicast", 22603509aea098772644bf4662dc1c88634818ceeccZhongxing Xu "Packet driver cannot terminate", 2271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump "Invalid receiver mode specified", 228c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose "Insufficient memory space", 229c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose "Type previously accessed, and not released", 230c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose "Command out of range, or not implemented", 231c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose "Cannot send packet (usually hardware error)", 232c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose "Cannot change hardware address ( > 1 handle open)", 233c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose "Hardware address has bad length or format", 234c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose "Cannot reset interface (more than 1 handle open)", 235c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose "Bad Check-sum", 236c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose "Bad size", 237c2b7dfaad674587cfd220ff447b3710d252130c3Jordy Rose "Bad sync" , 2382ce43c8f43254a9edea53a20dc0e69195bc82ae0Zhongxing Xu "Source hit" 23990e72e4106a0c3efa7575e9f9cba0c775bb54552Zhongxing Xu }; 24090e72e4106a0c3efa7575e9f9cba0c775bb54552Zhongxing Xu 2411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (errNum < 0 || errNum >= DIM(errStr)) 242a516ce16b472e61924f5dd10d181c3e8330979afTed Kremenek return ("Unknown driver error."); 243a516ce16b472e61924f5dd10d181c3e8330979afTed Kremenek return (errStr [errNum]); 244a516ce16b472e61924f5dd10d181c3e8330979afTed Kremenek} 2451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 246c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek/**************************************************************************/ 2476297a8ec313c722db50f686fd190842b7ea91118Ted Kremenek 2486297a8ec313c722db50f686fd190842b7ea91118Ted KremenekPUBLIC const char *PktGetClassName (WORD class) 2496297a8ec313c722db50f686fd190842b7ea91118Ted Kremenek{ 2506297a8ec313c722db50f686fd190842b7ea91118Ted Kremenek switch (class) 2516297a8ec313c722db50f686fd190842b7ea91118Ted Kremenek { 2526297a8ec313c722db50f686fd190842b7ea91118Ted Kremenek case PD_ETHER: 2531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return ("DIX-Ether"); 254044b6f0417cb98741f277602fabf5f07ec9a02c0Ted Kremenek case PD_PRONET10: 25500a3a5f024ac54088ab887712b292171188064f0Ted Kremenek return ("ProNET-10"); 25600a3a5f024ac54088ab887712b292171188064f0Ted Kremenek case PD_IEEE8025: 2571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return ("IEEE 802.5"); 258bc42c533e7d3d946704a49e242939dd232f33072Tom Care case PD_OMNINET: 259bc42c533e7d3d946704a49e242939dd232f33072Tom Care return ("OmniNet"); 26052d861ce41ce84d8389495ea78d97bcc962ac5baTom Care case PD_APPLETALK: 261bc42c533e7d3d946704a49e242939dd232f33072Tom Care return ("AppleTalk"); 262a7a8a450d908b34fa5f569f2e694ebd4b61aae2fTom Care case PD_SLIP: 263bc42c533e7d3d946704a49e242939dd232f33072Tom Care return ("SLIP"); 264bc42c533e7d3d946704a49e242939dd232f33072Tom Care case PD_STARTLAN: 265a7a8a450d908b34fa5f569f2e694ebd4b61aae2fTom Care return ("StartLAN"); 266bc42c533e7d3d946704a49e242939dd232f33072Tom Care case PD_ARCNET: 26705a2378c708688c8ef498a5cea40ed7f5db15fa5Ted Kremenek return ("ArcNet"); 268031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu case PD_AX25: 269846d4e923bf11bcdc2816758aafa331795f29230Ted Kremenek return ("AX.25"); 270512c913a6f93d225faacdb8e20308f5c4065c3ebTed Kremenek case PD_KISS: 2711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return ("KISS"); 2721670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek case PD_IEEE8023_2: 2733992a50eea030a2913f1d267554f55ecd00d694cZhongxing Xu return ("IEEE 802.3 w/802.2 hdr"); 2743992a50eea030a2913f1d267554f55ecd00d694cZhongxing Xu case PD_FDDI8022: 275bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu return ("FDDI w/802.2 hdr"); 276bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu case PD_X25: 2777b71c1977cccafa23f9ecb3b0b22199e61ae634cZhongxing Xu return ("X.25"); 2785a5d98bc6962dc2d1aaa5e0e522f1bf84273b9c1Ted Kremenek case PD_LANstar: 2795a5d98bc6962dc2d1aaa5e0e522f1bf84273b9c1Ted Kremenek return ("LANstar"); 28003509aea098772644bf4662dc1c88634818ceeccZhongxing Xu case PD_PPP: 28172905cfa81cfd126f322c4173f56d332aac5539eJordy Rose return ("PPP"); 282a46e4d91d8f3eb341f2387768db66dcfe8dd0afaZhongxing Xu default: 283935ef90f4b065c7c865ee5b2a99c5f9b1a115d72Zhongxing Xu return ("unknown"); 284935ef90f4b065c7c865ee5b2a99c5f9b1a115d72Zhongxing Xu } 285935ef90f4b065c7c865ee5b2a99c5f9b1a115d72Zhongxing Xu} 286935ef90f4b065c7c865ee5b2a99c5f9b1a115d72Zhongxing Xu 287a46e4d91d8f3eb341f2387768db66dcfe8dd0afaZhongxing Xu/**************************************************************************/ 288a46e4d91d8f3eb341f2387768db66dcfe8dd0afaZhongxing Xu 289a46e4d91d8f3eb341f2387768db66dcfe8dd0afaZhongxing XuPUBLIC char const *PktRXmodeStr (PKT_RX_MODE mode) 290a46e4d91d8f3eb341f2387768db66dcfe8dd0afaZhongxing Xu{ 291b107c4b7efb907d75620cd3c17f82fe27dc5b745Ted Kremenek static const char *modeStr [] = { 29279d73044b7d0adfbd18ee34285395e1d5135f662Ted Kremenek "Receiver turned off", 29379d73044b7d0adfbd18ee34285395e1d5135f662Ted Kremenek "Receive only directly addressed packets", 29479d73044b7d0adfbd18ee34285395e1d5135f662Ted Kremenek "Receive direct & broadcast packets", 295ec9227fea66c3439991fc84b0d33b0a8b4b8875eZhongxing Xu "Receive direct,broadcast and limited multicast packets", 296b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek "Receive direct,broadcast and all multicast packets", 297b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek "Receive all packets (promiscuouos mode)" 29803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu }; 2991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3009c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek if (mode > DIM(modeStr)) 3016d69b5d82281992e981caa9bc038e3f6cac6594aZhongxing Xu return ("??"); 3026d69b5d82281992e981caa9bc038e3f6cac6594aZhongxing Xu return (modeStr [mode-1]); 30303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu} 3041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 305c5b1bf10133a8ecbfe9e6b3ec92bae84e3d927e8Ted Kremenek/**************************************************************************/ 30603509aea098772644bf4662dc1c88634818ceeccZhongxing Xu 307031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing XuLOCAL __inline BOOL PktInterrupt (void) 3081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump{ 309ef44bfb9d0f15ba0391f8346c9f01355fb450a09Ted Kremenek BOOL okay; 31003509aea098772644bf4662dc1c88634818ceeccZhongxing Xu 3111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#if (DOSX & PHARLAP) 31203509aea098772644bf4662dc1c88634818ceeccZhongxing Xu _dx_real_int ((UINT)pktInfo.intr, ®); 31303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu okay = ((reg.flags & 1) == 0); /* OK if carry clear */ 31403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu 315031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu#elif (DOSX & DJGPP) 3161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump __dpmi_int ((int)pktInfo.intr, ®); 31703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu okay = ((reg.x.flags & 1) == 0); 31803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu 31903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu#elif (DOSX & DOS4GW) 320031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu union REGS r; 321c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek struct SREGS s; 322c95ad9ff6e574aecdd759542d5578bc65d586d93Ted Kremenek 32303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu memset (&r, 0, sizeof(r)); 32403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu segread (&s); 3251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump r.w.ax = 0x300; 326b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek r.x.ebx = pktInfo.intr; 32703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu r.w.cx = 0; 328662174ca204cb520f634bdcb34a3708f45389d14Zhongxing Xu s.es = FP_SEG (®); 329469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek r.x.edi = FP_OFF (®); 3301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump reg.r_flags = 0; 331de43424560f1a744de6214dab6bbee28ad8437f5Ted Kremenek reg.r_ss = reg.r_sp = 0; /* DPMI host provides stack */ 33203509aea098772644bf4662dc1c88634818ceeccZhongxing Xu 33303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu int386x (0x31, &r, &r, &s); 33403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu okay = (!r.w.cflag); 33553287518f69b8f06f82a6cdbd13e4e3a13b58186Ted Kremenek 3361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#else 337b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek reg.r_flags = 0; 33803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu intr (pktInfo.intr, (struct REGPACK*)®); 339b79b117d3b76da58b14ef835ccfcf2e988b7345fZhongxing Xu okay = ((reg.r_flags & 1) == 0); 340e1c2a675e0c089e1f53cbd55d2197a8beaa852aeTed Kremenek#endif 3414f09027385466f1f4c382c80ca77157e2aef97d9Ted Kremenek 34203509aea098772644bf4662dc1c88634818ceeccZhongxing Xu if (okay) 34303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu pktInfo.error = NULL; 34403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu else pktInfo.error = PktGetErrorStr (reg.r_dx >> 8); 3451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return (okay); 346b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek} 34703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu 348c05f23994720b3eb0a3b3494e7bfcec9e1536c89Ted Kremenek/**************************************************************************/ 3491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 35067d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek/* 35103509aea098772644bf4662dc1c88634818ceeccZhongxing Xu * Search for packet driver at interrupt 60h through 80h. If ASCIIZ 35267d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek * string "PKT DRVR" found at offset 3 in the interrupt handler, return 35367d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek * interrupt number, else return zero in pktInfo.intr 35403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu */ 35503509aea098772644bf4662dc1c88634818ceeccZhongxing XuPUBLIC BOOL PktSearchDriver (void) 35603509aea098772644bf4662dc1c88634818ceeccZhongxing Xu{ 35767d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek BYTE intr = 0x20; 358b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek BOOL found = FALSE; 35903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu 36003509aea098772644bf4662dc1c88634818ceeccZhongxing Xu while (!found && intr < 0xFF) 3611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump { 362b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek static char str[12]; /* 3 + strlen("PKT DRVR") */ 36303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu static char pktStr[9] = "PKT DRVR"; /* ASCIIZ string at ofs 3 */ 36403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu DWORD rp; /* in interrupt routine */ 365c4f8706b6539e06a5de153bd72850bb2e0a71456Zhongxing Xu 366fcfb503c280ed8c66d428fed911b2846c0f434fcTed Kremenek#if (DOSX & PHARLAP) 367fcfb503c280ed8c66d428fed911b2846c0f434fcTed Kremenek _dx_rmiv_get (intr, &rp); 36803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu ReadRealMem (&str, (REALPTR)rp, sizeof(str)); 369fcfb503c280ed8c66d428fed911b2846c0f434fcTed Kremenek 37061dfbecd8e6181b2ba42ffb5feede27a2bab3b8aTed Kremenek#elif (DOSX & DJGPP) 37103509aea098772644bf4662dc1c88634818ceeccZhongxing Xu __dpmi_raddr realAdr; 372c05f23994720b3eb0a3b3494e7bfcec9e1536c89Ted Kremenek __dpmi_get_real_mode_interrupt_vector (intr, &realAdr); 373c4f8706b6539e06a5de153bd72850bb2e0a71456Zhongxing Xu rp = (realAdr.segment << 4) + realAdr.offset16; 374b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek dosmemget (rp, sizeof(str), &str); 37503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu 376c05f23994720b3eb0a3b3494e7bfcec9e1536c89Ted Kremenek#elif (DOSX & DOS4GW) 3771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump rp = dpmi_get_real_vector (intr); 378469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek memcpy (&str, (void*)rp, sizeof(str)); 37903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu 38003509aea098772644bf4662dc1c88634818ceeccZhongxing Xu#else 3811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump _fmemcpy (&str, getvect(intr), sizeof(str)); 3824beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek#endif 3834beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek 3844beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek found = memcmp (&str[3],&pktStr,sizeof(pktStr)) == 0; 3854beaa9f51b2da57c64740cef2bd1c2fdb0c325d5Ted Kremenek intr++; 38697ed4f68f5dba3e21e7a490ef0f9ffd3bfead7f8Ted Kremenek } 38703509aea098772644bf4662dc1c88634818ceeccZhongxing Xu pktInfo.intr = (found ? intr-1 : 0); 388c05f23994720b3eb0a3b3494e7bfcec9e1536c89Ted Kremenek return (found); 389af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek} 390af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek 391af3374187c47acea45706eab6744be6b1c66a856Ted Kremenek 39203509aea098772644bf4662dc1c88634818ceeccZhongxing Xu/**************************************************************************/ 39303509aea098772644bf4662dc1c88634818ceeccZhongxing Xu 3941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpstatic BOOL PktSetAccess (void) 39503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu{ 396bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu reg.r_ax = 0x0200 + pktInfo.class; 397031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu reg.r_bx = 0xFFFF; 3981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump reg.r_dx = 0; 399469ecbded3616416ef938ed94a67f86149faf226Ted Kremenek reg.r_cx = 0; 40003509aea098772644bf4662dc1c88634818ceeccZhongxing Xu 40138ac4f504bf8ed514520b5a82be538bdb0860687Ted Kremenek#if (DOSX & PHARLAP) 4021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump reg.ds = 0; 40302737ed29d7fff2206f7c7ee958cdf0665e35542Ted Kremenek reg.esi = 0; 40403509aea098772644bf4662dc1c88634818ceeccZhongxing Xu reg.es = RP_SEG (realBase); 40503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu reg.edi = (WORD) &PktReceiver; 4068ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor 4078ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor#elif (DOSX & DJGPP) 40803509aea098772644bf4662dc1c88634818ceeccZhongxing Xu reg.x.ds = 0; 4098ecdb65716cd7914ffb2eeee993fa9039fcd31e8Douglas Gregor reg.x.si = 0; 4101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump reg.x.es = rm_mem.rm_segment; 4110518999d3adcc289997bd974dce90cc97f5c1c44Sebastian Redl reg.x.di = PktReceiver; 41203509aea098772644bf4662dc1c88634818ceeccZhongxing Xu 413031ccc0555a82afc2e8afe29e19dd57ff204e2deZhongxing Xu#elif (DOSX & DOS4GW) 4141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump reg.r_ds = 0; 415b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek reg.r_si = 0; 41603509aea098772644bf4662dc1c88634818ceeccZhongxing Xu reg.r_es = rm_base_seg; 417bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu reg.r_di = PktReceiver; 418bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu 41903509aea098772644bf4662dc1c88634818ceeccZhongxing Xu#else 420bb141217871e93767aa3f2de1b9946fa6d37066aZhongxing Xu reg.r_ds = 0; 421d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu reg.r_si = 0; 422d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu reg.r_es = FP_SEG (&PktReceiver); 423d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu reg.r_di = FP_OFF (&PktReceiver); 424d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu#endif 425d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu 426d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu if (!PktInterrupt()) 427d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu return (FALSE); 4287ce351db56fbce162a3b650518ce05b5c61ebf36Zhongxing Xu 429d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu pktInfo.handle = reg.r_ax; 430d706434b0231c76fd9acf30060646a7aa8f69aefZhongxing Xu return (TRUE); 431950db87e5efe2ff0c7234116929f8637aaf7ae7aZhongxing Xu} 432b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu 433b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu/**************************************************************************/ 434b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing Xu 435b13453bd8a91f331d0910ca95ad52aa41b52f648Zhongxing XuPUBLIC BOOL PktReleaseHandle (WORD handle) 436950db87e5efe2ff0c7234116929f8637aaf7ae7aZhongxing Xu{ 437950db87e5efe2ff0c7234116929f8637aaf7ae7aZhongxing Xu reg.r_ax = 0x0300; 438950db87e5efe2ff0c7234116929f8637aaf7ae7aZhongxing Xu reg.r_bx = handle; 4396a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski return PktInterrupt(); 4406a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski} 4416a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski 44203509aea098772644bf4662dc1c88634818ceeccZhongxing Xu/**************************************************************************/ 443856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu 444856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing XuPUBLIC BOOL PktTransmit (const void *eth, int len) 44503509aea098772644bf4662dc1c88634818ceeccZhongxing Xu{ 4466b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu if (len > ETH_MTU) 4476b8513829895e56a7b97e787ea74520bc626512eZhongxing Xu return (FALSE); 4487ce351db56fbce162a3b650518ce05b5c61ebf36Zhongxing Xu 4497b71c1977cccafa23f9ecb3b0b22199e61ae634cZhongxing Xu reg.r_ax = 0x0400; /* Function 4, send pkt */ 4507b71c1977cccafa23f9ecb3b0b22199e61ae634cZhongxing Xu reg.r_cx = len; /* total size of frame */ 451bc37b8dd9914e02580f531fa6e5e72be34d9675eZhongxing Xu 45203509aea098772644bf4662dc1c88634818ceeccZhongxing Xu#if (DOSX & DJGPP) 453bc37b8dd9914e02580f531fa6e5e72be34d9675eZhongxing Xu dosmemput (eth, len, realBase+pktTxBuf); 454bc37b8dd9914e02580f531fa6e5e72be34d9675eZhongxing Xu reg.x.ds = rm_mem.rm_segment; /* DOS data segment and */ 4558e18c1b840882d26039503629d7e4ad4822f3bdaZhongxing Xu reg.x.si = pktTxBuf; /* DOS offset to buffer */ 4569dc84c9455df2a77195147d0210c915dc1775a88Zhongxing Xu 4578e18c1b840882d26039503629d7e4ad4822f3bdaZhongxing Xu#elif (DOSX & DOS4GW) 4588e18c1b840882d26039503629d7e4ad4822f3bdaZhongxing Xu memcpy ((void*)(realBase+pktTxBuf), eth, len); 45932303020d0f1a21cbcab65ae0c69a4218dc8f0fbZhongxing Xu reg.r_ds = rm_base_seg; 46032303020d0f1a21cbcab65ae0c69a4218dc8f0fbZhongxing Xu reg.r_si = pktTxBuf; 46132303020d0f1a21cbcab65ae0c69a4218dc8f0fbZhongxing Xu 462b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu#elif (DOSX & PHARLAP) 4639c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek memcpy (&pktTxBuf, eth, len); 464b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu reg.r_ds = FP_SEG (&pktTxBuf); 46582c63bfa0c5130e0cf274c1974b6157ebefc04feMarcin Swiderski reg.r_si = FP_OFF (&pktTxBuf); 46682c63bfa0c5130e0cf274c1974b6157ebefc04feMarcin Swiderski 467b17b1b3cc2b0d4d3b263b9384571bbc7f3995771Zhongxing Xu#else 4686a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski reg.r_ds = FP_SEG (eth); 4696a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski reg.r_si = FP_OFF (eth); 4709c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek#endif 4716a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski 4726a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski return PktInterrupt(); 4736a02b609c2e23b28d24f9db4c8006137c6b55ae4Marcin Swiderski} 4749c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek 47548af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek/**************************************************************************/ 47648af2a9c1ed3259512f2d1431720add1fbe8fb5fTed Kremenek 4779c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek#if (DOSX & (DJGPP|DOS4GW)) 47803509aea098772644bf4662dc1c88634818ceeccZhongxing XuLOCAL __inline BOOL CheckElement (RX_ELEMENT *rx) 4791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#else 4809c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed KremenekLOCAL __inline BOOL CheckElement (RX_ELEMENT _far *rx) 4819c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek#endif 482b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek{ 4831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump WORD count_1, count_2; 4849c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek 4859c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek /* 48690e420321f60860f4c4e7a68ca9f7567824b46ecTed Kremenek * We got an upcall to the same RMCB with wrong handle. 487248072a8b9cd956c4ac63172fc2af09790f7c6a9Zhongxing Xu * This can happen if we failed to release handle at program exit 4881670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek */ 4891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (rx->handle != pktInfo.handle) 4909c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek { 491cd8f6ac9b613e1fe962ebf9c87d822ce765275e6Ted Kremenek pktInfo.error = "Wrong handle"; 4929c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek intStat.wrongHandle++; 4936297a8ec313c722db50f686fd190842b7ea91118Ted Kremenek PktReleaseHandle (rx->handle); 49410c16657eec144def180ee53d1e0249c9ed2b3b5Ted Kremenek return (FALSE); 4959c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek } 496cd8f6ac9b613e1fe962ebf9c87d822ce765275e6Ted Kremenek count_1 = rx->firstCount; 4979c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek count_2 = rx->secondCount; 498b640b3b5dfccaf259967cb2cb6755c9aa20d4423Ted Kremenek 4991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (count_1 != count_2) 5009c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek { 501ff4264dae31cf42807b64ecc114906b0b835690aTed Kremenek pktInfo.error = "Bad sync"; 5029c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek intStat.badSync++; 503ff4264dae31cf42807b64ecc114906b0b835690aTed Kremenek return (FALSE); 5045b9bd2137ebef350af803c634e3fdf5d74678100Ted Kremenek } 5051670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek if (count_1 > ETH_MAX) 5069c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek { 507a46e4d91d8f3eb341f2387768db66dcfe8dd0afaZhongxing Xu pktInfo.error = "Large esize"; 508e695e1cd7d8a579455e8969be36cbaf10a316a64Ted Kremenek intStat.tooLarge++; 5099c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek return (FALSE); 510de43424560f1a744de6214dab6bbee28ad8437f5Ted Kremenek } 5111670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek#if 0 51203509aea098772644bf4662dc1c88634818ceeccZhongxing Xu if (count_1 < ETH_MIN) 5131670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek { 5141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump pktInfo.error = "Small esize"; 5159c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek intStat.tooSmall++; 5169c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek return (FALSE); 5179c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek } 518f6f56d4fc8ebce17e7b83eb2c35f57a055c22283Ted Kremenek#endif 519f6f56d4fc8ebce17e7b83eb2c35f57a055c22283Ted Kremenek return (TRUE); 5201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 5211670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek 522b4b817d704287836b52b34369009e682f208aa2bTed Kremenek/**************************************************************************/ 523b4b817d704287836b52b34369009e682f208aa2bTed Kremenek 524834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong WanPUBLIC BOOL PktTerminHandle (WORD handle) 525834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan{ 526834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan reg.r_ax = 0x0500; 527834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan reg.r_bx = handle; 5289c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek return PktInterrupt(); 529652be346f74feba027bcbdeb6a3e3f4755a0e62cZhongxing Xu} 530652be346f74feba027bcbdeb6a3e3f4755a0e62cZhongxing Xu 5311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/**************************************************************************/ 532b4b817d704287836b52b34369009e682f208aa2bTed Kremenek 533b4b817d704287836b52b34369009e682f208aa2bTed KremenekPUBLIC BOOL PktResetInterface (WORD handle) 5349c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek{ 535b4b817d704287836b52b34369009e682f208aa2bTed Kremenek reg.r_ax = 0x0700; 5361670e403c48f3af4fceff3f6773a0e1cfc6c4eb3Ted Kremenek reg.r_bx = handle; 537834f9de3d3d76986d09f41725a70ba45a3e2aecdZhanyong Wan return PktInterrupt(); 5389c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek} 539852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek 540852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek/**************************************************************************/ 541852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek 542852274d4257134906995cb252fb3dfd2d71deae8Ted KremenekPUBLIC BOOL PktSetReceiverMode (PKT_RX_MODE mode) 543852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek{ 5449c14953d0c84f7cf5adfb4cd3c0f05a9b1723c1cTed Kremenek if (pktInfo.class == PD_SLIP || pktInfo.class == PD_PPP) 545852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek return (TRUE); 546852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek 5471c625f25055331bf76ab5479a8060d2b0f61e8b8Zhongxing Xu reg.r_ax = 0x1400; 5481c625f25055331bf76ab5479a8060d2b0f61e8b8Zhongxing Xu reg.r_bx = pktInfo.handle; 549b387a3f23e423d62c053be86294b703da1d1a222Ted Kremenek reg.r_cx = (WORD)mode; 5501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 551c0c3f5dbc9e78aa53a86c7d5e3eeda23ddad93d6Ted Kremenek if (!PktInterrupt()) 552c0c3f5dbc9e78aa53a86c7d5e3eeda23ddad93d6Ted Kremenek return (FALSE); 553d065d6080f0620bb80b933f3f5d52d37bb2ea770Ted Kremenek 554 receiveMode = mode; 555 return (TRUE); 556} 557 558/**************************************************************************/ 559 560PUBLIC BOOL PktGetReceiverMode (PKT_RX_MODE *mode) 561{ 562 reg.r_ax = 0x1500; 563 reg.r_bx = pktInfo.handle; 564 565 if (!PktInterrupt()) 566 return (FALSE); 567 568 *mode = reg.r_ax; 569 return (TRUE); 570} 571 572/**************************************************************************/ 573 574static PKT_STAT initialStat; /* statistics at startup */ 575static BOOL resetStat = FALSE; /* statistics reset ? */ 576 577PUBLIC BOOL PktGetStatistics (WORD handle) 578{ 579 reg.r_ax = 0x1800; 580 reg.r_bx = handle; 581 582 if (!PktInterrupt()) 583 return (FALSE); 584 585#if (DOSX & PHARLAP) 586 ReadRealMem (&pktStat, DOS_ADDR(reg.ds,reg.esi), sizeof(pktStat)); 587 588#elif (DOSX & DJGPP) 589 dosmemget (DOS_ADDR(reg.x.ds,reg.x.si), sizeof(pktStat), &pktStat); 590 591#elif (DOSX & DOS4GW) 592 memcpy (&pktStat, (void*)DOS_ADDR(reg.r_ds,reg.r_si), sizeof(pktStat)); 593 594#else 595 _fmemcpy (&pktStat, MK_FP(reg.r_ds,reg.r_si), sizeof(pktStat)); 596#endif 597 598 return (TRUE); 599} 600 601/**************************************************************************/ 602 603PUBLIC BOOL PktSessStatistics (WORD handle) 604{ 605 if (!PktGetStatistics(pktInfo.handle)) 606 return (FALSE); 607 608 if (resetStat) 609 { 610 pktStat.inPackets -= initialStat.inPackets; 611 pktStat.outPackets -= initialStat.outPackets; 612 pktStat.inBytes -= initialStat.inBytes; 613 pktStat.outBytes -= initialStat.outBytes; 614 pktStat.inErrors -= initialStat.inErrors; 615 pktStat.outErrors -= initialStat.outErrors; 616 pktStat.outErrors -= initialStat.outErrors; 617 pktStat.lost -= initialStat.lost; 618 } 619 return (TRUE); 620} 621 622/**************************************************************************/ 623 624PUBLIC BOOL PktResetStatistics (WORD handle) 625{ 626 if (!PktGetStatistics(pktInfo.handle)) 627 return (FALSE); 628 629 memcpy (&initialStat, &pktStat, sizeof(initialStat)); 630 resetStat = TRUE; 631 return (TRUE); 632} 633 634/**************************************************************************/ 635 636PUBLIC BOOL PktGetAddress (ETHER *addr) 637{ 638 reg.r_ax = 0x0600; 639 reg.r_bx = pktInfo.handle; 640 reg.r_cx = sizeof (*addr); 641 642#if (DOSX & DJGPP) 643 reg.x.es = rm_mem.rm_segment; 644 reg.x.di = pktTemp; 645#elif (DOSX & DOS4GW) 646 reg.r_es = rm_base_seg; 647 reg.r_di = pktTemp; 648#else 649 reg.r_es = FP_SEG (&pktTemp); 650 reg.r_di = FP_OFF (&pktTemp); /* ES:DI = address for result */ 651#endif 652 653 if (!PktInterrupt()) 654 return (FALSE); 655 656#if (DOSX & PHARLAP) 657 ReadRealMem (addr, realBase + (WORD)&pktTemp, sizeof(*addr)); 658 659#elif (DOSX & DJGPP) 660 dosmemget (realBase+pktTemp, sizeof(*addr), addr); 661 662#elif (DOSX & DOS4GW) 663 memcpy (addr, (void*)(realBase+pktTemp), sizeof(*addr)); 664 665#else 666 memcpy ((void*)addr, &pktTemp, sizeof(*addr)); 667#endif 668 669 return (TRUE); 670} 671 672/**************************************************************************/ 673 674PUBLIC BOOL PktSetAddress (const ETHER *addr) 675{ 676 /* copy addr to real-mode scrath area */ 677 678#if (DOSX & PHARLAP) 679 WriteRealMem (realBase + (WORD)&pktTemp, (void*)addr, sizeof(*addr)); 680 681#elif (DOSX & DJGPP) 682 dosmemput (addr, sizeof(*addr), realBase+pktTemp); 683 684#elif (DOSX & DOS4GW) 685 memcpy ((void*)(realBase+pktTemp), addr, sizeof(*addr)); 686 687#else 688 memcpy (&pktTemp, (void*)addr, sizeof(*addr)); 689#endif 690 691 reg.r_ax = 0x1900; 692 reg.r_cx = sizeof (*addr); /* address length */ 693 694#if (DOSX & DJGPP) 695 reg.x.es = rm_mem.rm_segment; /* DOS offset to param */ 696 reg.x.di = pktTemp; /* DOS segment to param */ 697#elif (DOSX & DOS4GW) 698 reg.r_es = rm_base_seg; 699 reg.r_di = pktTemp; 700#else 701 reg.r_es = FP_SEG (&pktTemp); 702 reg.r_di = FP_OFF (&pktTemp); 703#endif 704 705 return PktInterrupt(); 706} 707 708/**************************************************************************/ 709 710PUBLIC BOOL PktGetDriverInfo (void) 711{ 712 pktInfo.majVer = 0; 713 pktInfo.minVer = 0; 714 memset (&pktInfo.name, 0, sizeof(pktInfo.name)); 715 reg.r_ax = 0x01FF; 716 reg.r_bx = 0; 717 718 if (!PktInterrupt()) 719 return (FALSE); 720 721 pktInfo.number = reg.r_cx & 0xFF; 722 pktInfo.class = reg.r_cx >> 8; 723#if 0 724 pktInfo.minVer = reg.r_bx % 10; 725 pktInfo.majVer = reg.r_bx / 10; 726#else 727 pktInfo.majVer = reg.r_bx; // !! 728#endif 729 pktInfo.funcs = reg.r_ax & 0xFF; 730 pktInfo.type = reg.r_dx & 0xFF; 731 732#if (DOSX & PHARLAP) 733 ReadRealMem (&pktInfo.name, DOS_ADDR(reg.ds,reg.esi), sizeof(pktInfo.name)); 734 735#elif (DOSX & DJGPP) 736 dosmemget (DOS_ADDR(reg.x.ds,reg.x.si), sizeof(pktInfo.name), &pktInfo.name); 737 738#elif (DOSX & DOS4GW) 739 memcpy (&pktInfo.name, (void*)DOS_ADDR(reg.r_ds,reg.r_si), sizeof(pktInfo.name)); 740 741#else 742 _fmemcpy (&pktInfo.name, MK_FP(reg.r_ds,reg.r_si), sizeof(pktInfo.name)); 743#endif 744 return (TRUE); 745} 746 747/**************************************************************************/ 748 749PUBLIC BOOL PktGetDriverParam (void) 750{ 751 reg.r_ax = 0x0A00; 752 753 if (!PktInterrupt()) 754 return (FALSE); 755 756#if (DOSX & PHARLAP) 757 ReadRealMem (&pktInfo.majVer, DOS_ADDR(reg.es,reg.edi), PKT_PARAM_SIZE); 758 759#elif (DOSX & DJGPP) 760 dosmemget (DOS_ADDR(reg.x.es,reg.x.di), PKT_PARAM_SIZE, &pktInfo.majVer); 761 762#elif (DOSX & DOS4GW) 763 memcpy (&pktInfo.majVer, (void*)DOS_ADDR(reg.r_es,reg.r_di), PKT_PARAM_SIZE); 764 765#else 766 _fmemcpy (&pktInfo.majVer, MK_FP(reg.r_es,reg.r_di), PKT_PARAM_SIZE); 767#endif 768 return (TRUE); 769} 770 771/**************************************************************************/ 772 773#if (DOSX & PHARLAP) 774 PUBLIC int PktReceive (BYTE *buf, int max) 775 { 776 WORD inOfs = *rxInOfsFp; 777 WORD outOfs = *rxOutOfsFp; 778 779 if (outOfs != inOfs) 780 { 781 RX_ELEMENT _far *head = (RX_ELEMENT _far*)(protBase+outOfs); 782 int size, len = max; 783 784 if (CheckElement(head)) 785 { 786 size = min (head->firstCount, sizeof(RX_ELEMENT)); 787 len = min (size, max); 788 _fmemcpy (buf, &head->destin, len); 789 } 790 else 791 size = -1; 792 793 outOfs += sizeof (RX_ELEMENT); 794 if (outOfs > LAST_RX_BUF) 795 outOfs = FIRST_RX_BUF; 796 *rxOutOfsFp = outOfs; 797 return (size); 798 } 799 return (0); 800 } 801 802 PUBLIC void PktQueueBusy (BOOL busy) 803 { 804 *rxOutOfsFp = busy ? (*rxInOfsFp + sizeof(RX_ELEMENT)) : *rxInOfsFp; 805 if (*rxOutOfsFp > LAST_RX_BUF) 806 *rxOutOfsFp = FIRST_RX_BUF; 807 *(DWORD _far*)(protBase + (WORD)&pktDrop) = 0; 808 } 809 810 PUBLIC WORD PktBuffersUsed (void) 811 { 812 WORD inOfs = *rxInOfsFp; 813 WORD outOfs = *rxOutOfsFp; 814 815 if (inOfs >= outOfs) 816 return (inOfs - outOfs) / sizeof(RX_ELEMENT); 817 return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT)); 818 } 819 820 PUBLIC DWORD PktRxDropped (void) 821 { 822 return (*(DWORD _far*)(protBase + (WORD)&pktDrop)); 823 } 824 825#elif (DOSX & DJGPP) 826 PUBLIC int PktReceive (BYTE *buf, int max) 827 { 828 WORD ofs = _farpeekw (_dos_ds, realBase+rxOutOfs); 829 830 if (ofs != _farpeekw (_dos_ds, realBase+rxInOfs)) 831 { 832 RX_ELEMENT head; 833 int size, len = max; 834 835 head.firstCount = _farpeekw (_dos_ds, realBase+ofs); 836 head.secondCount = _farpeekw (_dos_ds, realBase+ofs+2); 837 head.handle = _farpeekw (_dos_ds, realBase+ofs+4); 838 839 if (CheckElement(&head)) 840 { 841 size = min (head.firstCount, sizeof(RX_ELEMENT)); 842 len = min (size, max); 843 dosmemget (realBase+ofs+6, len, buf); 844 } 845 else 846 size = -1; 847 848 ofs += sizeof (RX_ELEMENT); 849 if (ofs > LAST_RX_BUF) 850 _farpokew (_dos_ds, realBase+rxOutOfs, FIRST_RX_BUF); 851 else _farpokew (_dos_ds, realBase+rxOutOfs, ofs); 852 return (size); 853 } 854 return (0); 855 } 856 857 PUBLIC void PktQueueBusy (BOOL busy) 858 { 859 WORD ofs; 860 861 disable(); 862 ofs = _farpeekw (_dos_ds, realBase+rxInOfs); 863 if (busy) 864 ofs += sizeof (RX_ELEMENT); 865 866 if (ofs > LAST_RX_BUF) 867 _farpokew (_dos_ds, realBase+rxOutOfs, FIRST_RX_BUF); 868 else _farpokew (_dos_ds, realBase+rxOutOfs, ofs); 869 _farpokel (_dos_ds, realBase+pktDrop, 0UL); 870 enable(); 871 } 872 873 PUBLIC WORD PktBuffersUsed (void) 874 { 875 WORD inOfs, outOfs; 876 877 disable(); 878 inOfs = _farpeekw (_dos_ds, realBase+rxInOfs); 879 outOfs = _farpeekw (_dos_ds, realBase+rxOutOfs); 880 enable(); 881 if (inOfs >= outOfs) 882 return (inOfs - outOfs) / sizeof(RX_ELEMENT); 883 return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT)); 884 } 885 886 PUBLIC DWORD PktRxDropped (void) 887 { 888 return _farpeekl (_dos_ds, realBase+pktDrop); 889 } 890 891#elif (DOSX & DOS4GW) 892 PUBLIC int PktReceive (BYTE *buf, int max) 893 { 894 WORD ofs = *(WORD*) (realBase+rxOutOfs); 895 896 if (ofs != *(WORD*) (realBase+rxInOfs)) 897 { 898 RX_ELEMENT head; 899 int size, len = max; 900 901 head.firstCount = *(WORD*) (realBase+ofs); 902 head.secondCount = *(WORD*) (realBase+ofs+2); 903 head.handle = *(WORD*) (realBase+ofs+4); 904 905 if (CheckElement(&head)) 906 { 907 size = min (head.firstCount, sizeof(RX_ELEMENT)); 908 len = min (size, max); 909 memcpy (buf, (const void*)(realBase+ofs+6), len); 910 } 911 else 912 size = -1; 913 914 ofs += sizeof (RX_ELEMENT); 915 if (ofs > LAST_RX_BUF) 916 *(WORD*) (realBase+rxOutOfs) = FIRST_RX_BUF; 917 else *(WORD*) (realBase+rxOutOfs) = ofs; 918 return (size); 919 } 920 return (0); 921 } 922 923 PUBLIC void PktQueueBusy (BOOL busy) 924 { 925 WORD ofs; 926 927 _disable(); 928 ofs = *(WORD*) (realBase+rxInOfs); 929 if (busy) 930 ofs += sizeof (RX_ELEMENT); 931 932 if (ofs > LAST_RX_BUF) 933 *(WORD*) (realBase+rxOutOfs) = FIRST_RX_BUF; 934 else *(WORD*) (realBase+rxOutOfs) = ofs; 935 *(DWORD*) (realBase+pktDrop) = 0UL; 936 _enable(); 937 } 938 939 PUBLIC WORD PktBuffersUsed (void) 940 { 941 WORD inOfs, outOfs; 942 943 _disable(); 944 inOfs = *(WORD*) (realBase+rxInOfs); 945 outOfs = *(WORD*) (realBase+rxOutOfs); 946 _enable(); 947 if (inOfs >= outOfs) 948 return (inOfs - outOfs) / sizeof(RX_ELEMENT); 949 return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT)); 950 } 951 952 PUBLIC DWORD PktRxDropped (void) 953 { 954 return *(DWORD*) (realBase+pktDrop); 955 } 956 957#else /* real-mode small/large model */ 958 959 PUBLIC int PktReceive (BYTE *buf, int max) 960 { 961 if (rxOutOfs != rxInOfs) 962 { 963 RX_ELEMENT far *head = (RX_ELEMENT far*) MK_FP (_DS,rxOutOfs); 964 int size, len = max; 965 966 if (CheckElement(head)) 967 { 968 size = min (head->firstCount, sizeof(RX_ELEMENT)); 969 len = min (size, max); 970 _fmemcpy (buf, &head->destin, len); 971 } 972 else 973 size = -1; 974 975 rxOutOfs += sizeof (RX_ELEMENT); 976 if (rxOutOfs > LAST_RX_BUF) 977 rxOutOfs = FIRST_RX_BUF; 978 return (size); 979 } 980 return (0); 981 } 982 983 PUBLIC void PktQueueBusy (BOOL busy) 984 { 985 rxOutOfs = busy ? (rxInOfs + sizeof(RX_ELEMENT)) : rxInOfs; 986 if (rxOutOfs > LAST_RX_BUF) 987 rxOutOfs = FIRST_RX_BUF; 988 pktDrop = 0L; 989 } 990 991 PUBLIC WORD PktBuffersUsed (void) 992 { 993 WORD inOfs = rxInOfs; 994 WORD outOfs = rxOutOfs; 995 996 if (inOfs >= outOfs) 997 return ((inOfs - outOfs) / sizeof(RX_ELEMENT)); 998 return (NUM_RX_BUF - (outOfs - inOfs) / sizeof(RX_ELEMENT)); 999 } 1000 1001 PUBLIC DWORD PktRxDropped (void) 1002 { 1003 return (pktDrop); 1004 } 1005#endif 1006 1007/**************************************************************************/ 1008 1009LOCAL __inline void PktFreeMem (void) 1010{ 1011#if (DOSX & PHARLAP) 1012 if (realSeg) 1013 { 1014 _dx_real_free (realSeg); 1015 realSeg = 0; 1016 } 1017#elif (DOSX & DJGPP) 1018 if (rm_mem.rm_segment) 1019 { 1020 unsigned ofs; /* clear the DOS-mem to prevent further upcalls */ 1021 1022 for (ofs = 0; ofs < 16 * rm_mem.size / 4; ofs += 4) 1023 _farpokel (_dos_ds, realBase + ofs, 0); 1024 _go32_dpmi_free_dos_memory (&rm_mem); 1025 rm_mem.rm_segment = 0; 1026 } 1027#elif (DOSX & DOS4GW) 1028 if (rm_base_sel) 1029 { 1030 dpmi_real_free (rm_base_sel); 1031 rm_base_sel = 0; 1032 } 1033#endif 1034} 1035 1036/**************************************************************************/ 1037 1038PUBLIC BOOL PktExitDriver (void) 1039{ 1040 if (pktInfo.handle) 1041 { 1042 if (!PktSetReceiverMode(PDRX_BROADCAST)) 1043 PUTS ("Error restoring receiver mode."); 1044 1045 if (!PktReleaseHandle(pktInfo.handle)) 1046 PUTS ("Error releasing PKT-DRVR handle."); 1047 1048 PktFreeMem(); 1049 pktInfo.handle = 0; 1050 } 1051 1052 if (pcap_pkt_debug >= 1) 1053 printf ("Internal stats: too-small %lu, too-large %lu, bad-sync %lu, " 1054 "wrong-handle %lu\n", 1055 intStat.tooSmall, intStat.tooLarge, 1056 intStat.badSync, intStat.wrongHandle); 1057 return (TRUE); 1058} 1059 1060#if (DOSX & (DJGPP|DOS4GW)) 1061static void dump_pkt_stub (void) 1062{ 1063 int i; 1064 1065 fprintf (stderr, "PktReceiver %lu, pkt_stub[PktReceiver] =\n", 1066 PktReceiver); 1067 for (i = 0; i < 15; i++) 1068 fprintf (stderr, "%02X, ", real_stub_array[i+PktReceiver]); 1069 fputs ("\n", stderr); 1070} 1071#endif 1072 1073/* 1074 * Front end initialization routine 1075 */ 1076PUBLIC BOOL PktInitDriver (PKT_RX_MODE mode) 1077{ 1078 PKT_RX_MODE rxMode; 1079 BOOL writeInfo = (pcap_pkt_debug >= 3); 1080 1081 pktInfo.quiet = (pcap_pkt_debug < 3); 1082 1083#if (DOSX & PHARLAP) && defined(__HIGHC__) 1084 if (_mwenv != 2) 1085 { 1086 fprintf (stderr, "Only Pharlap DOS extender supported.\n"); 1087 return (FALSE); 1088 } 1089#endif 1090 1091#if (DOSX & PHARLAP) && defined(__WATCOMC__) 1092 if (_Extender != 1) 1093 { 1094 fprintf (stderr, "Only DOS4GW style extenders supported.\n"); 1095 return (FALSE); 1096 } 1097#endif 1098 1099 if (!PktSearchDriver()) 1100 { 1101 PUTS ("Packet driver not found."); 1102 PktFreeMem(); 1103 return (FALSE); 1104 } 1105 1106 if (!PktGetDriverInfo()) 1107 { 1108 PUTS ("Error getting pkt-drvr information."); 1109 PktFreeMem(); 1110 return (FALSE); 1111 } 1112 1113#if (DOSX & PHARLAP) 1114 if (RealCopy((ULONG)&rxOutOfs, (ULONG)&pktRxEnd, 1115 &realBase, &protBase, (USHORT*)&realSeg)) 1116 { 1117 rxOutOfsFp = (WORD _far *) (protBase + (WORD) &rxOutOfs); 1118 rxInOfsFp = (WORD _far *) (protBase + (WORD) &rxInOfs); 1119 *rxOutOfsFp = FIRST_RX_BUF; 1120 *rxInOfsFp = FIRST_RX_BUF; 1121 } 1122 else 1123 { 1124 PUTS ("Cannot allocate real-mode stub."); 1125 return (FALSE); 1126 } 1127 1128#elif (DOSX & (DJGPP|DOS4GW)) 1129 if (sizeof(real_stub_array) > 0xFFFF) 1130 { 1131 fprintf (stderr, "`real_stub_array[]' too big.\n"); 1132 return (FALSE); 1133 } 1134#if (DOSX & DJGPP) 1135 rm_mem.size = (sizeof(real_stub_array) + 15) / 16; 1136 1137 if (_go32_dpmi_allocate_dos_memory(&rm_mem) || rm_mem.rm_offset != 0) 1138 { 1139 PUTS ("real-mode init failed."); 1140 return (FALSE); 1141 } 1142 realBase = (rm_mem.rm_segment << 4); 1143 dosmemput (&real_stub_array, sizeof(real_stub_array), realBase); 1144 _farpokel (_dos_ds, realBase+rxOutOfs, FIRST_RX_BUF); 1145 _farpokel (_dos_ds, realBase+rxInOfs, FIRST_RX_BUF); 1146 1147#elif (DOSX & DOS4GW) 1148 rm_base_seg = dpmi_real_malloc (sizeof(real_stub_array), &rm_base_sel); 1149 if (!rm_base_seg) 1150 { 1151 PUTS ("real-mode init failed."); 1152 return (FALSE); 1153 } 1154 realBase = (rm_base_seg << 4); 1155 memcpy ((void*)realBase, &real_stub_array, sizeof(real_stub_array)); 1156 *(WORD*) (realBase+rxOutOfs) = FIRST_RX_BUF; 1157 *(WORD*) (realBase+rxInOfs) = FIRST_RX_BUF; 1158 1159#endif 1160 { 1161 int pushf = PktReceiver; 1162 1163 while (real_stub_array[pushf++] != 0x9C && /* pushf */ 1164 real_stub_array[pushf] != 0xFA) /* cli */ 1165 { 1166 if (++para_skip > 16) 1167 { 1168 fprintf (stderr, "Something wrong with `pkt_stub.inc'.\n"); 1169 para_skip = 0; 1170 dump_pkt_stub(); 1171 return (FALSE); 1172 } 1173 } 1174 if (*(WORD*)(real_stub_array + offsetof(PktRealStub,_dummy)) != 0xB800) 1175 { 1176 fprintf (stderr, "`real_stub_array[]' is misaligned.\n"); 1177 return (FALSE); 1178 } 1179 } 1180 1181 if (pcap_pkt_debug > 2) 1182 dump_pkt_stub(); 1183 1184#else 1185 rxOutOfs = FIRST_RX_BUF; 1186 rxInOfs = FIRST_RX_BUF; 1187#endif 1188 1189 if (!PktSetAccess()) 1190 { 1191 PUTS ("Error setting pkt-drvr access."); 1192 PktFreeMem(); 1193 return (FALSE); 1194 } 1195 1196 if (!PktGetAddress(&myAddress)) 1197 { 1198 PUTS ("Error fetching adapter address."); 1199 PktFreeMem(); 1200 return (FALSE); 1201 } 1202 1203 if (!PktSetReceiverMode(mode)) 1204 { 1205 PUTS ("Error setting receiver mode."); 1206 PktFreeMem(); 1207 return (FALSE); 1208 } 1209 1210 if (!PktGetReceiverMode(&rxMode)) 1211 { 1212 PUTS ("Error getting receiver mode."); 1213 PktFreeMem(); 1214 return (FALSE); 1215 } 1216 1217 if (writeInfo) 1218 printf ("Pkt-driver information:\n" 1219 " Version : %d.%d\n" 1220 " Name : %.15s\n" 1221 " Class : %u (%s)\n" 1222 " Type : %u\n" 1223 " Number : %u\n" 1224 " Funcs : %u\n" 1225 " Intr : %Xh\n" 1226 " Handle : %u\n" 1227 " Extended : %s\n" 1228 " Hi-perf : %s\n" 1229 " RX mode : %s\n" 1230 " Eth-addr : %02X:%02X:%02X:%02X:%02X:%02X\n", 1231 1232 pktInfo.majVer, pktInfo.minVer, pktInfo.name, 1233 pktInfo.class, PktGetClassName(pktInfo.class), 1234 pktInfo.type, pktInfo.number, 1235 pktInfo.funcs, pktInfo.intr, pktInfo.handle, 1236 pktInfo.funcs == 2 || pktInfo.funcs == 6 ? "Yes" : "No", 1237 pktInfo.funcs == 5 || pktInfo.funcs == 6 ? "Yes" : "No", 1238 PktRXmodeStr(rxMode), 1239 myAddress[0], myAddress[1], myAddress[2], 1240 myAddress[3], myAddress[4], myAddress[5]); 1241 1242#if defined(DEBUG) && (DOSX & PHARLAP) 1243 if (writeInfo) 1244 { 1245 DWORD rAdr = realBase + (WORD)&PktReceiver; 1246 unsigned sel, ofs; 1247 1248 printf ("\nReceiver at %04X:%04X\n", RP_SEG(rAdr), RP_OFF(rAdr)); 1249 printf ("Realbase = %04X:%04X\n", RP_SEG(realBase),RP_OFF(realBase)); 1250 1251 sel = _FP_SEG (protBase); 1252 ofs = _FP_OFF (protBase); 1253 printf ("Protbase = %04X:%08X\n", sel,ofs); 1254 printf ("RealSeg = %04X\n", realSeg); 1255 1256 sel = _FP_SEG (rxOutOfsFp); 1257 ofs = _FP_OFF (rxOutOfsFp); 1258 printf ("rxOutOfsFp = %04X:%08X\n", sel,ofs); 1259 1260 sel = _FP_SEG (rxInOfsFp); 1261 ofs = _FP_OFF (rxInOfsFp); 1262 printf ("rxInOfsFp = %04X:%08X\n", sel,ofs); 1263 1264 printf ("Ready: *rxOutOfsFp = %04X *rxInOfsFp = %04X\n", 1265 *rxOutOfsFp, *rxInOfsFp); 1266 1267 PktQueueBusy (TRUE); 1268 printf ("Busy: *rxOutOfsFp = %04X *rxInOfsFp = %04X\n", 1269 *rxOutOfsFp, *rxInOfsFp); 1270 } 1271#endif 1272 1273 memset (&pktStat, 0, sizeof(pktStat)); /* clear statistics */ 1274 PktQueueBusy (TRUE); 1275 return (TRUE); 1276} 1277 1278 1279/* 1280 * DPMI functions only for Watcom + DOS4GW extenders 1281 */ 1282#if (DOSX & DOS4GW) 1283LOCAL DWORD dpmi_get_real_vector (int intr) 1284{ 1285 union REGS r; 1286 1287 r.x.eax = 0x200; 1288 r.x.ebx = (DWORD) intr; 1289 int386 (0x31, &r, &r); 1290 return ((r.w.cx << 4) + r.w.dx); 1291} 1292 1293LOCAL WORD dpmi_real_malloc (int size, WORD *selector) 1294{ 1295 union REGS r; 1296 1297 r.x.eax = 0x0100; /* DPMI allocate DOS memory */ 1298 r.x.ebx = (size + 15) / 16; /* Number of paragraphs requested */ 1299 int386 (0x31, &r, &r); 1300 if (r.w.cflag & 1) 1301 return (0); 1302 1303 *selector = r.w.dx; 1304 return (r.w.ax); /* Return segment address */ 1305} 1306 1307LOCAL void dpmi_real_free (WORD selector) 1308{ 1309 union REGS r; 1310 1311 r.x.eax = 0x101; /* DPMI free DOS memory */ 1312 r.x.ebx = selector; /* Selector to free */ 1313 int386 (0x31, &r, &r); 1314} 1315#endif 1316 1317 1318#if defined(DOSX) && (DOSX & PHARLAP) 1319/* 1320 * Description: 1321 * This routine allocates conventional memory for the specified block 1322 * of code (which must be within the first 64K of the protected mode 1323 * program segment) and copies the code to it. 1324 * 1325 * The caller should free up the conventional memory block when it 1326 * is done with the conventional memory. 1327 * 1328 * NOTE THIS ROUTINE REQUIRES 386|DOS-EXTENDER 3.0 OR LATER. 1329 * 1330 * Calling arguments: 1331 * start_offs start of real mode code in program segment 1332 * end_offs 1 byte past end of real mode code in program segment 1333 * real_basep returned; real mode ptr to use as a base for the 1334 * real mode code (eg, to get the real mode FAR 1335 * addr of a function foo(), take 1336 * real_basep + (ULONG) foo). 1337 * This pointer is constructed such that 1338 * offsets within the real mode segment are 1339 * the same as the link-time offsets in the 1340 * protected mode program segment 1341 * prot_basep returned; prot mode ptr to use as a base for getting 1342 * to the conventional memory, also constructed 1343 * so that adding the prot mode offset of a 1344 * function or variable to the base gets you a 1345 * ptr to the function or variable in the 1346 * conventional memory block. 1347 * rmem_adrp returned; real mode para addr of allocated 1348 * conventional memory block, to be used to free 1349 * up the conventional memory when done. DO NOT 1350 * USE THIS TO CONSTRUCT A REAL MODE PTR, USE 1351 * REAL_BASEP INSTEAD SO THAT OFFSETS WORK OUT 1352 * CORRECTLY. 1353 * 1354 * Returned values: 1355 * 0 if error 1356 * 1 if success 1357 */ 1358int RealCopy (ULONG start_offs, 1359 ULONG end_offs, 1360 REALPTR *real_basep, 1361 FARPTR *prot_basep, 1362 USHORT *rmem_adrp) 1363{ 1364 ULONG rm_base; /* base real mode para addr for accessing */ 1365 /* allocated conventional memory */ 1366 UCHAR *source; /* source pointer for copy */ 1367 FARPTR destin; /* destination pointer for copy */ 1368 ULONG len; /* number of bytes to copy */ 1369 ULONG temp; 1370 USHORT stemp; 1371 1372 /* First check for valid inputs 1373 */ 1374 if (start_offs >= end_offs || end_offs > 0x10000) 1375 return (FALSE); 1376 1377 /* Round start_offs down to a paragraph (16-byte) boundary so we can set up 1378 * the real mode pointer easily. Round up end_offs to make sure we allocate 1379 * enough paragraphs 1380 */ 1381 start_offs &= ~15; 1382 end_offs = (15 + (end_offs << 4)) >> 4; 1383 1384 /* Allocate the conventional memory for our real mode code. Remember to 1385 * round byte count UP to 16-byte paragraph size. We alloc it 1386 * above the DOS data buffer so both the DOS data buffer and the appl 1387 * conventional mem block can still be resized. 1388 * 1389 * First just try to alloc it; if we can't get it, shrink the appl mem 1390 * block down to the minimum, try to alloc the memory again, then grow the 1391 * appl mem block back to the maximum. (Don't try to shrink the DOS data 1392 * buffer to free conventional memory; it wouldn't be good for this routine 1393 * to have the possible side effect of making file I/O run slower.) 1394 */ 1395 len = ((end_offs - start_offs) + 15) >> 4; 1396 if (_dx_real_above(len, rmem_adrp, &stemp) != _DOSE_NONE) 1397 { 1398 if (_dx_cmem_usage(0, 0, &temp, &temp) != _DOSE_NONE) 1399 return (FALSE); 1400 1401 if (_dx_real_above(len, rmem_adrp, &stemp) != _DOSE_NONE) 1402 *rmem_adrp = 0; 1403 1404 if (_dx_cmem_usage(0, 1, &temp, &temp) != _DOSE_NONE) 1405 { 1406 if (*rmem_adrp != 0) 1407 _dx_real_free (*rmem_adrp); 1408 return (FALSE); 1409 } 1410 1411 if (*rmem_adrp == 0) 1412 return (FALSE); 1413 } 1414 1415 /* Construct real mode & protected mode pointers to access the allocated 1416 * memory. Note we know start_offs is aligned on a paragraph (16-byte) 1417 * boundary, because we rounded it down. 1418 * 1419 * We make the offsets come out rights by backing off the real mode selector 1420 * by start_offs. 1421 */ 1422 rm_base = ((ULONG) *rmem_adrp) - (start_offs >> 4); 1423 RP_SET (*real_basep, 0, rm_base); 1424 FP_SET (*prot_basep, rm_base << 4, SS_DOSMEM); 1425 1426 /* Copy the real mode code/data to the allocated memory 1427 */ 1428 source = (UCHAR *) start_offs; 1429 destin = *prot_basep; 1430 FP_SET (destin, FP_OFF(*prot_basep) + start_offs, FP_SEL(*prot_basep)); 1431 len = end_offs - start_offs; 1432 WriteFarMem (destin, source, len); 1433 1434 return (TRUE); 1435} 1436#endif /* DOSX && (DOSX & PHARLAP) */ 1437