⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcpkt.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    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(&regs))
  {
    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(&regs))
  {
    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(&regs))
  {
    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(&regs))
  {
    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 + -