Ejemplo n.º 1
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);
}
Ejemplo n.º 2
0
static int setup_rmode_receiver (void)
{
  WORD rx_seg, rx_ofs;
  WORD asmpkt_size_chk;
  int  head_size = RX_ELEMENT_HEAD_SIZE;

  WATT_ASSERT (rm_base);
  WATT_ASSERT ((head_size % 4) == 0);

  rx_seg = _pkt_inf->rm_seg;
  rx_ofs = PktReceiver;

#if 0  /* test */
  printf ("PktReceiver @ %04X:%04X, ", rx_seg, PktReceiver);
  printf ("_asmpkt_inf @ %04X:%04X\n", rx_seg, (int)sizeof(real_stub_array));
#endif

  *(WORD*)&real_stub_array[asmpkt_inf+0] = sizeof(real_stub_array);
  *(WORD*)&real_stub_array[asmpkt_inf+2] = rx_seg;

  asmpkt_size_chk = *(WORD*) (real_stub_array + size_chk);
  if (asmpkt_size_chk != sizeof(PKT_INFO))
  {
    TCP_CONSOLE_MSG (0, ("%s (%u): Development error:\n"
                     "  sizeof(pkt_info) = %ld in pcpkt.h\n"
                     "  sizeof(pkt_info) = %u in asmpkt.nas, (diff %ld)\n",
                     __FILE__, __LINE__,
                     (long)sizeof(PKT_INFO), asmpkt_size_chk,
                     (long)(sizeof(PKT_INFO) - asmpkt_size_chk)));
    return (-1);
  }

  if (*(WORD*)&real_stub_array[PktReceiver]   != 0xA80F ||  /* push gs */
      *(WORD*)&real_stub_array[PktReceiver+2] != 0xA00F)    /* push fs */
  {
    TCP_CONSOLE_MSG (0, ("%s (%u): Development error:\n"
                         "  PktReceiver misaligned\n", __FILE__, __LINE__));
    return (-1);
  }

  if (!has_rdtsc || !use_rdtsc)
  {
    DWORD patch_it = (*(WORD*) &real_stub_array[patch_nop]) +
                     (DWORD) &real_stub_array;

    TCP_CONSOLE_MSG (4, ("patch_it (%04X): %02X,%02X,%02X\n",
                     *(WORD*)&real_stub_array[patch_nop],
                     ((BYTE*)patch_it)[0],
                     ((BYTE*)patch_it)[1],
                     ((BYTE*)patch_it)[2]));

    ((BYTE*)patch_it) [0] = 0x90;  /* NOP */
    ((BYTE*)patch_it) [1] = 0x90;
    ((BYTE*)patch_it) [2] = 0x90;
  }

#if (DOSX & (PHARLAP|POWERPAK|X32VM))
  WriteRealMem (rm_base, &real_stub_array, sizeof(real_stub_array));
#elif (DOSX & DJGPP)
  dosmemput (&real_stub_array, sizeof(real_stub_array), rm_base);
#elif (DOSX & DOS4GW) || (DOSX == 0)
  memcpy ((void*)rm_base, &real_stub_array, sizeof(real_stub_array));
#else
  #error Help me!
#endif
  return (0);
}
Ejemplo n.º 3
0
/*
 * Append a transmit buffer at end of receive buffer.
 * Must not be called before checking if there is room.
 */
int pkt_append_recv (const void *tx, unsigned len)
{
  struct pkt_rx_element buf;
  struct pkt_ringbuf   *q = &_pkt_inf->pkt_queue;
  DWORD  addr;
  int    idx;

  DISABLE();
  idx = PEEKW (0, QUE_OFS(in_index));

  if (idx < 0 || idx >= q->num_buf)
  {
#if defined(USE_DEBUG)
    (*_printf) ("pkt_append_recv(): illegal index %d\n", idx);
 /* pkt_dump_real_mem(); */
#endif
    ENABLE();
    return (0);
  }

  buf.rx_length_1 = buf.rx_length_2 = len;
  buf.handle      = _pkt_inf->handle;
  buf.filler      = 0;
  get_tstamp (buf.tstamp_put);

  addr = ASMPKT_INF + offsetof (PKT_INFO, rx_buf[idx]);

#if (DOSX & (PHARLAP|POWERPAK|X32VM))
  WriteRealMem (addr, &buf, RX_ELEMENT_HEAD_SIZE);
#elif (DOSX & DOS4GW)
  memcpy ((void*)addr, &buf, RX_ELEMENT_HEAD_SIZE);
#elif (DOSX & DJGPP)
  DOSMEMPUTL (&buf, RX_ELEMENT_HEAD_SIZE/4, addr);
#elif (DOSX == 0)
  memcpy ((void*)addr, &buf, RX_ELEMENT_HEAD_SIZE);
#else
  #error Help me!
#endif

  addr += RX_ELEMENT_HEAD_SIZE;

#if (DOSX & (PHARLAP|POWERPAK|X32VM))
  WriteRealMem (addr, (void*)tx, len);
#elif (DOSX & DOS4GW)
  memcpy ((void*)addr, tx, len);
#elif (DOSX & DJGPP)
  DOSMEMPUTL (tx, (len+3)/4, addr);
#elif (DOSX == 0)
  memcpy ((void*)addr, tx, len);
#else
  #error Help me!
#endif

  if (++idx == q->num_buf)
     idx = 0;

  POKEW (0, QUE_OFS(in_index), idx);
  ENABLE();
/* pkt_dump_real_mem(); */
  return (len);
}
Ejemplo n.º 4
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);
}