📄 pcpkt.c
字号:
DWORD size = (DWORD)&_pkt_end - (DWORD)&pkt_enqueue;
if (_go32_dpmi_lock_code(&pkt_enqueue, size) ||
_go32_dpmi_lock_code(&dosmemget, 100) ||
_go32_dpmi_lock_data(_pkt_inf, sizeof(*_pkt_inf)))
return (-1);
/* rm_reg is already locked */
return (0);
}
static int unlock_code_and_data (void)
{
__dpmi_meminfo mem;
DWORD base = 0;
__dpmi_get_segment_base_address (_my_ds(), &base);
mem.address = base + (DWORD)&pkt_enqueue;
mem.size = (DWORD)&_pkt_end - (DWORD)&pkt_enqueue;
__dpmi_unlock_linear_region (&mem);
mem.address = base + (DWORD)&dosmemget;
mem.size = 100;
__dpmi_unlock_linear_region (&mem);
mem.address = base + (DWORD)_pkt_inf;
mem.size = sizeof(*_pkt_inf);
__dpmi_unlock_linear_region (&mem);
return (0);
}
#elif (DOSX & WDOSX)
static int setup_rmode_callback (void)
{
WORD size = RDATA_SIZE;
BYTE entry = *(BYTE*) pkt_receiver_pm;
if (entry != 0xC8 && entry != 0x55) /* "enter x,y" or "push (e)bp" */
{
outsnl (_LANG("pkt_receiver_pm() has wrong entry. Use "
"\"normal\" stack-frame."));
return (-3);
}
rm_base_sel = 0;
rm_base_seg = dpmi_real_malloc (size, &rm_base_sel);
if (!rm_base_seg || !rm_base_sel)
return (-1);
if (!dpmi_alloc_callback(pkt_receiver_pm, &rm_cb))
return (-2);
rm_base = (BYTE*) (rm_base_seg << 4);
memset (rm_base, 0, size);
#if 1 /* test */
(*_printf) ("rm_mem = %04X:0000 rmode call-back %04X:%04X\r\n",
rm_base_seg, rm_cb.cb_segment, rm_cb.cb_offset);
#endif
return (0);
}
static int lock_code_and_data (void)
{
if (!dpmi_lock_region (&rm_cb, sizeof(rm_cb)))
return (-1);
return (0);
}
static int unlock_code_and_data (void)
{
if (!dpmi_unlock_region (&rm_cb, sizeof(rm_cb)))
return (-1);
return (0);
}
#elif (DOSX & DOS4GW) /* pkt_receiver4_rm() isn't a r->pmode callback,
* but what the heck...
*/
static int setup_rmode_callback (void)
{
int length;
/* test for asmpkt4.asm/pcpkt.h mismatch
*/
if (asmpkt_size_chk != sizeof(*_pkt_inf))
{
#ifdef USE_DEBUG
fprintf (stderr,
"sizeof(pkt_info) = %d pcpkt.h\n"
"sizeof(pkt_info) = %d asmpkt4.asm, (diff %d)\r\n",
sizeof(*_pkt_inf), asmpkt_size_chk,
sizeof(*_pkt_inf) - asmpkt_size_chk);
#endif
return (-3);
}
/* Allocate DOS-memory for pkt_receiver4_rm() and temp/Tx buffers.
*/
length = TX_BUF() + IP_SIZE;
rm_base_seg = dpmi_real_malloc (length, &pkt_rcv_sel);
if (!rm_base_seg)
return (-2);
rm_base = (BYTE*) (((DWORD)rm_base_seg) << 4);
/* Clear DOS area and copy code down into it.
*/
memset (rm_base, 0, length);
length = PKT_TMP() - 1;
memcpy (rm_base, (void*)&pkt_receiver4_start, length);
return (0);
}
static int lock_code_and_data (void)
{
return (0);
}
static int unlock_code_and_data (void)
{
return (0);
}
#elif (DOSX & POWERPAK)
static int setup_rmode_callback (void) { UNFINISHED(); return (-1); }
static int lock_code_and_data (void) { UNFINISHED(); return (-1); }
static int unlock_code_and_data (void) { UNFINISHED(); return (-1); }
#endif
/*
* For DOS4GW targets, allocate the '_pkt_inf' structure
* from DOS memory. All others allocate from heap.
*/
static int setup_pkt_inf (void)
{
#if (DOSX & DOS4GW)
DWORD seg = dpmi_real_malloc (sizeof(*_pkt_inf), &pkt_inf_sel);
asmpkt_inf = (struct pkt_info*) (seg << 16); /* run-time location */
_pkt_inf = (struct pkt_info*) (seg << 4);
#else
_pkt_inf = malloc (sizeof(*_pkt_inf));
#endif
if (!_pkt_inf) /* Allocation failed */
return (0);
/* Clear area
*/
memset (_pkt_inf, 0, sizeof(*_pkt_inf));
#if !defined(OLD_TURBOC)
assert (ARP_SIZE >= (ARP_MAX - PKT_MARGIN));
#endif
pktq_init (&_pkt_inf->ip_queue, sizeof(_pkt_inf->ip_buf[0]),
DIM(_pkt_inf->ip_buf), (char*)&_pkt_inf->ip_buf[0][0]);
pktq_init (&_pkt_inf->arp_queue, sizeof(_pkt_inf->arp_buf[0]),
DIM(_pkt_inf->arp_buf), (char*)&_pkt_inf->arp_buf[0][0]);
#if (DOSX & DOS4GW)
_pkt_inf->ip_queue.dos_ofs = offsetof (struct pkt_info, ip_buf[0][0]);
_pkt_inf->arp_queue.dos_ofs = offsetof (struct pkt_info, arp_buf[0][0]);
#endif
return (1);
}
/*
* Microsoft Quick-C doesn't have 'intr()' so we make our own.
*/
#if defined(_MSC_VER) && (DOSX == 0)
static void intr (int intno, IREGS *reg)
{
union REGS r;
struct SREGS s;
r.x.ax = reg->r_ax;
r.x.bx = reg->r_bx;
r.x.cx = reg->r_cx;
r.x.dx = reg->r_dx;
r.x.si = reg->r_si;
r.x.di = reg->r_di;
s.ds = reg->r_ds;
s.es = reg->r_es;
int86x (intno, &r, &r, &s);
reg->r_flags = r.x.cflag;
reg->r_ax = r.x.ax;
reg->r_bx = r.x.bx;
reg->r_cx = r.x.cx;
reg->r_dx = r.x.dx;
reg->r_si = r.x.si;
reg->r_di = r.x.di;
reg->r_ds = s.ds;
reg->r_es = s.es;
}
#endif
/*
* The API entry to the network link-driver. Either use protected mode
* interface via a (far) call (dynamic loaded module) or issue an
* interrupt for the real mode PKTDRVR.
*
* Return TRUE if CARRRY is clear, else FALSE.
*/
static int pkt_api_entry (IREGS *reg, unsigned line)
{
#if (DOSX)
/* Use 32-bit API; accessing card via pmode driver (to-do!!)
*/
if (_pkt32_drvr)
{
reg->r_flags = 0;
if (!(*_pkt32_drvr)(reg)) /* call the pmode interface */
{
reg->r_flags |= CARRY_BIT;
return (0);
}
return (1);
}
#endif
if (!pkt_interrupt)
{
#if defined(USE_DEBUG)
fprintf (stderr, "%s (%d): API called after deinit.\n", __FILE__, line);
#endif
reg->r_flags |= CARRY_BIT;
ARGSUSED (line);
return (0);
}
/* Use the (slower) 16-bit real-mode PKTDRVR API.
*/
#if (DOSX & PHARLAP)
_dx_real_int ((UINT)pkt_interrupt, reg);
#elif (DOSX & DJGPP)
__dpmi_int ((int)pkt_interrupt, reg);
#elif (DOSX & DOS4GW) && defined(__WATCOMC__)
dpmi_real_interrupt ((int)pkt_interrupt, reg);
#elif (DOSX & WDOSX)
dpmi_real_interrupt2 ((int)pkt_interrupt, reg);
#elif (DOSX & POWERPAK)
UNFINISHED();
#elif (DOSX == 0) && defined(_MSC_VER)
intr ((int)pkt_interrupt, reg);
#elif (DOSX == 0) && defined(__WATCOMC__)
intr ((int)pkt_interrupt, (union REGPACK*)reg);
#elif (DOSX == 0)
intr ((int)pkt_interrupt, (struct REGPACK*)reg);
#else
#error Unknown method in pkt_api_entry
#endif
return ((reg->r_flags & CARRY_BIT) == 0);
}
#if defined(USE_MULTICAST)
/*
* _pkt_set_rcv_mode - sets the receive mode of the interface
*
* int _pkt_set_rcv_mode (int handle, int mode)
* Where:
* handle is the handle returned by access_type
* mode is one of the following modes:
* 1 turn off receiver
* 2 receive only packets sent to this interface
* 3 mode 2 plus broadcast packets <default>
* 4 mode 3 plus limited multicast packets
* 5 mode 3 plus all multicast packets
* 6 all packets (AKA promiscuous mode )
* Returns:
* -1 upon error - _pkterror is set
* 0 if the mode was set successfully
*/
int _pkt_set_rcv_mode (int handle, int mode)
{
IREGS regs;
if (!_multicast_on) /* normal unicast/broadcast don't need to set mode */
{
_pkterror = CANT_SET;
return (-1);
}
/* This needs an Extended driver. SLIP/PPP is point-to-point.
*/
if (_pktdevlevel < 2 || _pktserial)
{
_pkterror = CANT_SET;
return (-1);
}
regs.r_ax = PD_SET_RCV;
regs.r_bx = handle;
regs.r_cx = mode;
if (!PKT_API(®s))
{
PKT_ERR ("Error setting receiver mode: ", regs.r_dx);
return (-1);
}
return (0);
}
/*
* _pkt_get_rcv_mode - gets the receive mode of the interface
*
* int _pkt_get_rcv_mode (int handle)
* Where:
* handle is the handle returned by access_type
*
* Returns:
* -1 upon error - _pkterror is set
* mode is one of the following modes: (upon return)
* 1 turn off receiver
* 2 receive only packets sent to this interface
* 3 mode 2 plus broadcast packets <default>
* 4 mode 3 plus limited multicast packets
* 5 mode 3 plus all multicast packets
* 6 all packets (AKA promiscuous mode )
*/
int _pkt_get_rcv_mode (int handle)
{
IREGS regs;
/* This needs an Extended driver (not SLIP/PPP)
*/
if (_pktdevlevel < 2 || _pktserial)
{
_pkterror = BAD_COMMAND;
return (-1);
}
regs.r_ax = PD_GET_RCV;
regs.r_bx = handle;
if (!PKT_API(®s))
{
PKT_ERR ("Error getting receiver mode: ", regs.r_dx);
return (-1);
}
return (regs.r_ax);
}
/*
* _pkt_get_multicast_list - gets the current list of multicast addresses
* from the packet driver
*
* int _pkt_get_multicast_list (int len, eth_address *listbuf)
* Where:
* len is the length of listbuf
* listbuf is the buffer into which the list is placed
* Returns:
* -1 upon error - _pkterror is set
* len if retrieval was successful
*
*/
int _pkt_get_multicast_list (int len, eth_address *listbuf)
{
IREGS regs;
/* Basic drivers don't support multicast
*/
if (_pktdevlevel < 2 || _pktserial)
{
_pkterror = NO_MULTICAST;
return (-1);
}
regs.r_ax = PD_GET_MULTI;
if (!PKT_API(®s))
{
PKT_ERR ("Error getting multicast list: ", regs.r_dx);
return (-1);
}
/* move it into the caller's buffer and return happily
*/
len = min (len, (WORD)regs.r_cx);
#if (DOSX & PHARLAP)
{
REALPTR rp;
RP_SET (rp, (WORD)regs.r_di, regs.r_es);
ReadRealMem ((void*)listbuf, rp, len);
}
#elif (DOSX & DJGPP)
dosmemget (regs.r_di + (regs.r_es << 4), len, (void*)listbuf);
#elif (DOSX & (DOS4GW|WDOSX))
memcpy (listbuf, SEG_OFS_TO_LIN(regs.r_es,regs.r_di), len);
#elif (DOSX & POWERPAK)
UNFINISHED();
#else
_fmemcpy (listbuf, MK_FP(regs.r_es,regs.r_di), len);
#endif
return (len);
}
/*
* _pkt_set_multicast_list - sets the list of multicast addresses for which
* the PD is responsible.
*
* int _pkt_set_multicast_list (int len, eth_address *listbuf)
* Where:
* len is the length of listbuf
* listbuf is the buffer containing the list
* Returns:
* -1 upon error - _pkterror is set
* 0 if set was successful
*/
int _pkt_set_multicast_list (int len, eth_address *listbuf)
{
IREGS regs;
WORD seg, ofs;
ASSERT_PKT_INF (0);
/* Basic drivers don't support multicast
*/
if (_pktdevlevel < 2 || _pktserial)
{
_pkterror = NO_MULTICAST;
return (-1);
}
#if (DOSX & PHARLAP)
seg = RP_SEG (rm_base);
ofs = PKT_TMP();
WriteRealMem (rm_base + PKT_TMP(), (void*)listbuf, len);
#elif (DOSX & DJGPP)
seg = RP_SEG();
ofs = PKT_TMP();
dosmemput ((void*)listbuf, len, rm_base + PKT_TMP());
#elif (DOSX & (DOS4GW|WDOSX))
seg = RP_SEG();
ofs = PKT_TMP();
memcpy (rm_base + PKT_TMP(), (void*)listbuf, len);
#elif (DOSX & POWERPAK)
UNFINISHED();
#else
seg = FP_SEG (listbuf);
ofs = FP_OFF (listbuf);
#endif
regs.r_ax = PD_SET_MULTI;
regs.r_cx = len;
regs.r_es = seg;
regs.r_di = ofs;
if (!PKT_API(®s))
{
PKT_ERR ("Error setting multicast list: ", regs.r_dx);
return (-1);
}
return (0);
}
/*
* _pkt_get_ip_rcv_mode - gets the receive mode of the interface for
* the IP handle
*
* int _pkt_get_ip_rcv_mode(void)
* Returns:
* -1 if the request failed - _pkterror is set
* mode is one of the following modes: (upon return)
* 1 turn off receiver
* 2 receive only packets sent to this interface
* 3 mode 2 plus broadcast packets <default>
* 4 mode 3 plus limited multicast packets
* 5 mode 3 plus all multicast packets
* 6 all packets (AKA promiscuous mode )
*/
int _pkt_get_ip_rcv_mode (void)
{
return _pkt_get_rcv_mode (_pkt_inf->ip_handle);
}
/*
* _pkt_set_ip_rcv_mode - sets the receive mode of the interface for
* the IP handle
*
* int _pkt_set_ip_rcv_mode(int mode)
* Where:
* mode is one of the following modes: (upon return)
* 1 turn off receiver
* 2 receive only packets sent to this interface
* 3 mode 2 plus broadcast packets <default>
* 4 mode 3 plus limited multicast packets
* 5 mode 3 plus all multicast packets
* 6 all packets (AKA promiscuous mode )
* Returns:
* -1 if the request failed - _pkterror is set
* 0 mode set was successful
*/
int _pkt_set_ip_rcv_mode (int mode)
{
return _pkt_set_rcv_mode (_pkt_inf->ip_handle, mode);
}
#endif /* USE_MULTICAST */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -