Пример #1
0
/*
 * Called from setup_pkt_inf() in pcpkt.c
 */
static DWORD setup_pkt_inf_fast (void)
{
  /* Allocate space for asmpkt_inf, temp area, pkt-stub and Tx buffer.
   */
  DWORD  rdata_size = PKT_TMP();
  size_t stub_size  = sizeof(real_stub_array);

#if (DOSX)
  rdata_size += PKT_TMP_SIZE + ETH_MAX + 10;
#endif

  if (rdata_size >= 64*1024UL)
  {
    TCP_CONSOLE_MSG (0, ("%s (%u): Development error:\nsize %u too large\n",
                         __FILE__, __LINE__, (unsigned int)rdata_size));
    return (0);
  }
  if (stub_size < 0xC0)
  {
    TCP_CONSOLE_MSG (0, ("%s (%u): Development error:\n\"pkt_stub.h\""
                         " seems truncated (%d bytes)\n",
                         __FILE__, __LINE__, SIZEOF(real_stub_array)));
    return (0);
  }

#if (DOSX & DJGPP)
  {
    int i, seg, sel;

    seg = __dpmi_allocate_dos_memory ((rdata_size+15)/16, &sel);
    if (seg < 0)
       return (0);

    _pkt_inf->rm_seg = seg;
    _pkt_inf->rm_sel = sel;
    rm_base = (_pkt_inf->rm_seg << 4);

    for (i = 0; i < (int)rdata_size; i += 4)  /* clear area */
        POKEL (_pkt_inf->rm_seg, i, 0);
  }

#elif (DOSX & DOS4GW)
  {
    WORD seg, sel;

    seg = dpmi_real_malloc (rdata_size, &sel);
    if (!seg)
       return (0);

    _pkt_inf->rm_seg = seg;
    _pkt_inf->rm_sel = sel;
    rm_base = (_pkt_inf->rm_seg) << 4;
    memset ((void*)rm_base, 0, rdata_size);
  }

#elif (DOSX & PHARLAP)
  {
    WORD largest, seg;
    int  i;

    if (_dx_real_alloc ((rdata_size+15)/16, &seg, &largest) != 0)
       return (0);

    _pkt_inf->rm_seg = seg;
    _pkt_inf->rm_sel = 0;
    RP_SET (rm_base, 0, _pkt_inf->rm_seg);
    for (i = 0; i < (int)rdata_size; i += 4)
        POKEL (_pkt_inf->rm_seg, i, 0);
  }

#elif (DOSX & X32VM)
  {
    int i;

    rm_base = _x32_real_alloc (rdata_size);
    if (!rm_base)
       return (0);

    _pkt_inf->rm_seg = _x32_real_segment (rm_base);
    _pkt_inf->rm_sel = 0;
    for (i = 0; i < (int)rdata_size; i += 4)
        POKEL (_pkt_inf->rm_seg, i, 0);
  }

#elif (DOSX & POWERPAK)
  {
    WORD seg, sel;
    int  i;

    seg = dpmi_real_malloc ((rdata_size+15)/16, &sel);
    if (!seg)
       return (0);

    _pkt_inf->rm_seg = seg;
    _pkt_inf->rm_sel = sel;
    RP_SET (rm_base, 0, _pkt_inf->rm_seg);
    for (i = 0; i < (int)rdata_size; i += 4)
        POKEL (_pkt_inf->rm_seg, i, 0);
  }

#elif (DOSX == 0)
  {
    char _far *buf = _fcalloc (rdata_size, 0);

    if (!buf)
       return (0);
    _pkt_inf->rm_seg = FP_SEG (buf);
    rm_base = (DWORD) buf;
  }

#else
  #error Help!
#endif

  pktq_far_init (sizeof(struct pkt_rx_element), RX_BUFS, ASMPKT_INF);
  _pkt_inf->pkt_queue.num_buf = RX_BUFS;
  return (rm_base);
}
Пример #2
0
int pkt_test_upcall (void)
{
#if !defined(NO_RMODE_CALL)
  int i, max = RX_BUFS + 3;

  for (i = 0; i < max; i++)
  {
    eth_Packet eth;
    IREGS      regs;
    DWORD      linear = 0;

    memset (&regs, 0, sizeof(regs));
    memset (&eth, 0, sizeof(eth));
    eth.head.type = IP4_TYPE;
    memset (&eth.head.destination, 0xFF, 6);
    memcpy (&eth.head.source, _eth_addr, 6);

#if (DOSX & (PHARLAP|X32VM))
    rmc.eax = 0;
    rmc.ebx = _pkt_inf->handle;
    rmc.ecx = ETH_MAX;
#endif
    regs.r_cx = ETH_MAX;
    regs.r_bx = _pkt_inf->handle;
    regs.r_ax = 0;
    regs.r_cs = _pkt_inf->rm_seg;
    regs.r_ip = PktReceiver;

    if (DPMI_REAL_CALL(&regs))
    {
      linear = SEG_OFS_ADDR (regs.r_es, regs.r_di);

      printf ("Upcall AX=0: ES:DI %04X:%04X\n",
              (WORD)regs.r_es, (WORD)regs.r_di);
#if (DOSX & DJGPP)
      if (linear)
         dosmemput (&eth, (WORD)regs.r_cx, linear);
#elif (DOSX & (DOS4GW|X32VM))
      if (linear)
         memcpy ((void*)linear, &eth, (WORD)regs.r_cx);
#elif (DOSX & (PHARLAP|POWERPAK))
      if (linear)
      {
        RP_SET (linear, regs.r_es, regs.r_di);
        WriteRealMem (linear, &eth, (WORD)regs.r_cx);
      }
#else
  #error Help me!
#endif
    }
    if (linear)
    {
      regs.r_ss = regs.r_sp = 0;
      regs.r_ax = 1;
      regs.r_cs = _pkt_inf->rm_seg;
      regs.r_ip = PktReceiver;
      regs.r_ds = regs.r_es;
      regs.r_si = regs.r_di;
      if (DPMI_REAL_CALL(&regs))
         printf ("Upcall AX=1\n");
    }
    printf ("buffers used %d, dropped %lu\n",
            pkt_buffers_used(), pkt_rx_dropped());
  }
#endif

  pkt_dump_real_mem();
  return (0);
}
Пример #3
0
static REALPTR _dx_alloc_rmode_wrapper (pmodeHook pmHook, 
                                        rmodeHook rmHook, 
                                        int  len, int stack_size,
                                        ReturnType returnType)
{
  #define DOFS  0x2C         /* offset of data section (tiny model)   */
  #define DSIZE 16           /* sizeof data section at wrapper end    */
  #define WOFS  (DOFS+DSIZE) /* offset of userWrapper code (optional) */
                             
  static unsigned char wrapper[] =
  {
    0x16,                     // 00       push ss
    0x06,                     // 01       push es
    0x1E,                     // 02       push ds
    0x0E,                     // 03       push cs
    0x1F,                     // 04       pop  ds           ;DS = CS
    0xF8,                     // 05       clc
    0xE8,0x33,0,              // 06       call userWrapper  ;33 relative (3A-8)
    0x72,0x1C,                // 09       jc short @exit
    0x66,0x60,                // 0B       pushad
    0x66,0xFF,0x36,DOFS+12,0, // 0D       push taskId       ;taskId to call
    0x66,0x6A,0,              // 12       push 0            ;use default selectors
    0xFF,0x36,DOFS+4,0,       // 15       push ourCS
    0x66,0xFF,0x36,DOFS,0,    // 19       push protGlue     ;(*protGlue)()
    0xFF,0x1E,DOFS+8,0,       // 1E       call rm2pmAddr
    0x83,0xC4,14,             // 22       add  sp,14        ;discard used stack
    0x66,0x61,                // 25       popad
    0x1F,                     // 27 @exit:pop  ds
    0x07,                     // 28       pop  es
    0x17,                     // 29       pop  ss
    0xCB,                     // 2A       retf
    0x90,                     // 2B       nop
    0,0,0,0,                  // +0  protGlue  dd ?
    0,0,0,0,                  // +4  ourCS     dw ?,?
    0,0,0,0,                  // +8  rm2pmAddr dd ?
    0,0,0,0                   // +12 taskId    dd ?
  };                          // +16 userWrapper: ..

  FARPTR  pmCbuf, fpWrapper;
  REALPTR rmCbuf, rm2pmAddr, dosReal;
  USHORT  para, paras, left;
  ULONG   cbufSize, i;
  UINT   *stack;

  assert (sizeof(wrapper) == (DOFS+DSIZE));

  if (!pmHook || numWrappers == MAX_WRAPPERS)
     return (0);

  _dx_rmlink_get (&rm2pmAddr,&rmCbuf,&cbufSize,&pmCbuf);
  len  += sizeof(wrapper);
  paras = (len + 15) / 16;
  para  = 0;

  if (_dx_real_above(paras,&para,&left))
  {
    ULONG temp;

    if (_dx_cmem_usage(0,0,&temp,&temp))
       return (0);
    if (_dx_real_above(paras,&para,&left))
       para = 0;
    if (_dx_cmem_usage(0,1,&temp,&temp))
    {
      if (para)
         _dx_real_free (para);
      return (0);
    }
    if (!para)
       return (0);
  }

  for (i = 0; i < MAX_WRAPPERS; i++)
      if (!_rmcb[i].dosReal)
         break;

  *(ULONG*) (wrapper+DOFS+0)  = (ULONG)&PmodeGlue;  /* pmode helper */
  *(ULONG*) (wrapper+DOFS+4)  = My_CS();            /* pmode CS     */
  *(ULONG*) (wrapper+DOFS+8)  = (ULONG)rm2pmAddr;   /* rm->pm addr  */
  *(ULONG*) (wrapper+DOFS+12) = i;                  /* task Id      */
  wrapper [0x2A] = returnType;                      /* RETF or IRET */

  /*
   * lock pages used by callback (for 386|VMM, allthough untested)
   */
  FP_SET (fpWrapper,para << 4, SS_DOSMEM);
  _dx_lock_pgs  (fpWrapper, len);
  _dx_lock_pgsn ((void*)&PmodeGlue, (UINT)&PmGlueEnd - (UINT)&PmodeGlue);

  RP_SET (dosReal,0,para);
  FillRealMem  (dosReal, 0, len);
  WriteRealMem (dosReal, &wrapper, sizeof(wrapper));

  if (rmHook)
       WriteRealMem(dosReal+WOFS,(void*)rmHook,len-sizeof(wrapper));
  else FillRealMem (dosReal+5,0x90,6);

  stack_size += sizeof(UINT) + 3;   /* add a DWORD for marker */
  stack_size &= ~3;                 /* make number of DWORDs  */
  stack = malloc (stack_size);
  if (!stack)
     return (0);

  _rmcb [i].dosReal     = dosReal;
  _rmcb [i].callback    = pmHook;
  _rmcb [i].stackStart  = stack;
  _rmcb [i].stackTop    = stack + stack_size/sizeof(UINT) - 2;
  _rmcb [i].stackTop[1] = MARKER;
  _rmcb [i].marker      = MARKER;
  _dx_lock_pgsn ((void*)stack, stack_size);

#if 0
  printf ("dosReal %08lX, rm2pmAddr %08lX, len %d, stack %08X\n",
          dosReal,rm2pmAddr,len,stack);
#endif
  numWrappers++;

  return (dosReal);
}