Beispiel #1
0
int pkt_release (void)
{
  ADAPTER *adapter;
  DWORD    status = 1;

  if (!_pkt_inf || _watt_fatal_error)
     return (0);

  adapter = (ADAPTER*) _pkt_inf->adapter;

  TCP_CONSOLE_MSG (2, ("pkt_release(): adapter %08lX\n", (DWORD)adapter));

  if (adapter && adapter != INVALID_HANDLE_VALUE)
  {
    /* Don't close the adapter before telling the thread about it.
     */
    if (_pkt_inf->recv_thread)
    {
      FILETIME ctime, etime, ktime, utime;
      DWORD    err = 0;

      _pkt_inf->stop_thread = TRUE;
      SetEvent (adapter->ReadEvent);
      Sleep (50);

      GetExitCodeThread (_pkt_inf->recv_thread, &status);
      if (status == STILL_ACTIVE)
           TCP_CONSOLE_MSG (2, ("pkt_release(): killing thread.\n"));
      else TCP_CONSOLE_MSG (2, ("pkt_release(): thread exit code %lu.\n",
                            status));

      if (!GetThreadTimes (_pkt_inf->recv_thread, &ctime, &etime, &ktime, &utime))
         err = GetLastError();
      TerminateThread (_pkt_inf->recv_thread, 1);
      CloseHandle (_pkt_inf->recv_thread);

      if (err)
         TCP_CONSOLE_MSG (2, ("  GetThreadTime() %s, ", win_strerror(err)));
      TCP_CONSOLE_MSG (2, ("  kernel time %.6fs, user time %.6fs\n",
                       filetime_sec(&ktime), filetime_sec(&utime)));
    }

    PacketCloseAdapter (adapter);

    _pkt_inf->adapter = NULL;
  }

  DO_FREE (_pkt_inf->npf_buf);
  DO_FREE (_pkt_inf);

  PacketInitModule (FALSE, dump_file);
  if (dump_file)
     fclose (dump_file);
  dump_file = NULL;
  return (int) status;
}
Beispiel #2
0
/*
 * Sets the receive mode of the interface.
 */
int pkt_set_rcv_mode (int mode)
{
  struct {
    PACKET_OID_DATA oidData;
    DWORD           filter;
  } oid;
  BOOL  rc;
  const ADAPTER *adapter;

  if (!_pkt_inf)
     return (0);

  adapter = (const ADAPTER*) _pkt_inf->adapter;

  memset (&oid, 0, sizeof(oid));
  oid.oidData.Oid    = OID_GEN_CURRENT_PACKET_FILTER;
  oid.oidData.Length = sizeof(oid.filter);
  *(DWORD*)oid.oidData.Data = mode;
  rc = PacketRequest (adapter, TRUE, &oid.oidData);
  if (rc)
       _pkt_rxmode = mode;
  else _pkt_errno = GetLastError();

  TCP_CONSOLE_MSG (2, ("pkt_set_rcv_mode(); mode 0x%02X, rc %d; %s\n",
                   mode, rc, !rc ? win_strerror(GetLastError()) : "okay"));
  return (rc);
}
Beispiel #3
0
/*
 * NDIS has the annoying feature (?) of looping packets we send in
 * NDIS_PACKET_TYPE_ALL_LOCAL mode (the default?). Disable it, but
 * doesn't seem to have any effect yet. Maybe need to use a BPF filter?
 *
 * No need when using RXMODE_DEFAULT (9).
 */
static BOOL ndis_set_loopback (BOOL enable)
{
  struct {
    PACKET_OID_DATA oidData;
    DWORD  options;
  } oid;
  const ADAPTER *adapter;
  BOOL  rc;
  DWORD options;
  DWORD gen_oid = OID_GEN_MAC_OPTIONS;
  DWORD opt_bit = NDIS_MAC_OPTION_NO_LOOPBACK;

  if (!_pkt_inf)
     return (FALSE);

  adapter = (const ADAPTER*) _pkt_inf->adapter;
  memset (&oid, 0, sizeof(oid));
  oid.oidData.Oid    = gen_oid;
  oid.oidData.Length = sizeof(oid.options);

  /* Get current MAC/protocol options
   */
  rc = PacketRequest (adapter, FALSE, &oid.oidData);
  options = *(DWORD*) &oid.oidData.Data;

 TCP_CONSOLE_MSG (2, ("ndis_set_loopback(); rc %d, options 0x%02lX; %s\n",
                  rc, options, !rc ? win_strerror(GetLastError()) : "okay"));
  if (enable)
       options &= ~opt_bit;
  else options |= opt_bit;

  /* Set it back
   */
  memset (&oid, 0, sizeof(oid));
  oid.oidData.Oid    = gen_oid;
  oid.oidData.Length = sizeof(oid.options);
  *(DWORD*) &oid.oidData.Data = options;
  rc = PacketRequest (adapter, TRUE, &oid.oidData);

 TCP_CONSOLE_MSG (2, ("ndis_set_loopback(); rc %d; %s\n",
                  rc, !rc ? win_strerror(GetLastError()) : "okay"));
  return (rc);
}
Beispiel #4
0
/*
 * Return the MAC address.
 */
int pkt_get_addr (mac_address *eth)
{
  mac_address mac;

  if (get_perm_mac_address(&mac))
  {
    memcpy (eth, &mac, sizeof(*eth));
    return (1);
  }
  TCP_CONSOLE_MSG (2, ("Failed to get our MAC address; %s\n",
                   win_strerror(GetLastError())));
  return (0);
}
Beispiel #5
0
struct pkt_rx_element *pkt_poll_recv (void)
{
  struct pkt_rx_element *rc;
  WORD   out_idx = PEEKW (0, QUE_OFS(out_index));
  WORD   in_idx  = PEEKW (0, QUE_OFS(in_index));

  if (out_idx != in_idx)
  {
    static struct pkt_rx_element rx_buf;
    struct pkt_ringbuf *q = &_pkt_inf->pkt_queue;
    DWORD  addr = ASMPKT_INF + offsetof(PKT_INFO,rx_buf[out_idx]);

    /* It might be faster to copy whole thing (head and rx-buffer)
     * in one operation ??
     */
    pullup_rx_element (&rx_buf, addr, RX_ELEMENT_HEAD_SIZE);

    if (check_rx_element(&rx_buf))
    {
      BYTE *pad;
      int   pad_len, size;

      get_tstamp (rx_buf.tstamp_get);
      size    = min (rx_buf.rx_length_1, q->buf_size - 4 - RX_ELEMENT_HEAD_SIZE);
      pad_len = q->buf_size - 4 - RX_ELEMENT_HEAD_SIZE - size;
      addr   += RX_ELEMENT_HEAD_SIZE;
      pullup_rx_element (&rx_buf.rx_buf, addr, ROUND_UP32(size));
      if (pad_len > 0)
      {
        pad = &rx_buf.rx_buf[0] + size;
        memset (pad, 0, pad_len);
      }
      rc = &rx_buf;
    }
    else
    {
      TCP_CONSOLE_MSG (1, ("pkt-error %s\n", pkt_error));
      rc = NULL;
    }

    if (++out_idx >= q->num_buf)
       out_idx = 0;
    POKEW (0, QUE_OFS(out_index), out_idx);
    return (rc);
  }
  return (NULL);
}
Beispiel #6
0
/*
 * Get hostname excluding domain-name
 */
int _get_machine_name (char *buf, int size)
{
  int     rc;
  DWORD   sz  = size;
  HMODULE mod = GetModuleHandle ("KERNEL32.DLL");
  BOOL (WINAPI *_GetComputerNameExA) (int, char*, DWORD*) = NULL;
  typedef BOOL (WINAPI *gcn_ex) (int, char*, DWORD*);

  if (mod)
     _GetComputerNameExA = (gcn_ex) GetProcAddress (mod, "GetComputerNameExA");

  if (!_GetComputerNameExA)
       rc = GetComputerNameA (buf, &sz);
  else rc = (*_GetComputerNameExA) (ComputerNameDnsHostname, buf, &sz);

  rc = rc ? 0 : -1;
  TCP_CONSOLE_MSG (2, ("_get_machine_name(): \"%s\", rc %d\n", buf, rc));
  return (rc);
}
Beispiel #7
0
/*
 * This functiom is called once each second.
 */
static void check_dead_gw (void)
{
  char   buf[20];
  static int i = 0;

  if (i >= gate_top)
      i = 0;

  for ( ; i < gate_top; i++)
  {
    struct gate_entry *gw = &gate_list [i];
    eth_address        eth;

    if (!is_on_LAN(gw->gate_ip))
       continue;

    if (!LAN_lookup(gw->gate_ip,&eth))
       continue;

    if (gw->chk_timer == 0UL || !chk_timeout(gw->chk_timer))
    {
      gw->chk_timer = set_timeout (DEAD_GW_TIMEOUT);
      continue;
    }

    if (gw->echo_pending &&
        _chk_ping(gw->gate_ip,NULL) == (DWORD)-1)
    {
      gw->is_dead      = TRUE;
      gw->echo_pending = FALSE;
      TCP_CONSOLE_MSG (1, ("Dead default GW %s (%d) detected\n",
                       _inet_ntoa(NULL,gw->gate_ip), i));
    }

    if (ping_gateway (gw->gate_ip, eth))
       gw->echo_pending = TRUE;

    gw->chk_timer = set_timeout (DEAD_GW_TIMEOUT);
    return;  /* only one ping per interval */
  }
}
Beispiel #8
0
void pkt_free_pkt (const void *pkt)
{
  struct pkt_ringbuf *q;
  const  char *q_tail;
  int    delta;

  if (!_pkt_inf || !pkt)
     return;

  q = &_pkt_inf->pkt_queue;
  pkt_drop_cnt = q->num_drop;

  q_tail = (const char*)pkt - _pkt_ip_ofs - RX_ELEMENT_HEAD_SIZE;
  delta  = q_tail - pktq_out_buf (q);
  if (delta)
  {
    TCP_CONSOLE_MSG (0, ("%s: freeing illegal packet 0x%p, delta %d.\n",
                     __FILE__, pkt, delta));
    pktq_clear (q);
  }
  else
    pktq_inc_out (q);
}
Beispiel #9
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);
}
Beispiel #10
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);
}
Beispiel #11
0
/**
 * Our low-level capture thread.
 *
 * Loop waiting for packet(s) in PacketReceivePacket(). In
 * _pkt_release() the receive event-handle (adapter->Readvent) is
 * set. This causes WaitForSingleObject() in PacketReceivePacket()
 * to return. It is vital that the ADAPTER object isn't deallocated
 * before PacketReceivePacket() returns.
 *
 * The return-value is > 0 if thread exited on it's own. Otherwise
 * it is 0  (from  GetExitCodeThread).
 */
DWORD __stdcall pkt_recv_thread (void *arg)
{
  int rc = 0;

  while (1)
  {
    const  ADAPTER *adapter;
    const  BYTE *pkt, *pkt_end;
    size_t cap_len, hdr_len;
    int    total_len, chunk;
    PACKET npf_pkt;

    if (!_pkt_inf || _pkt_inf->stop_thread)  /* signals closure */
    {
      rc = 1;
      break;
    }

    adapter  = (const ADAPTER*) _pkt_inf->adapter;
    npf_pkt.Length = _pkt_inf->npf_buf_size;
    npf_pkt.Buffer = _pkt_inf->npf_buf;

    if (!PacketReceivePacket(adapter, &npf_pkt, TRUE))
    {
      rc = 2;
      break;
    }
    total_len = npf_pkt.ulBytesReceived;

    ENTER_CRIT();

    for (pkt = npf_pkt.Buffer, pkt_end = (BYTE*)npf_pkt.Buffer + total_len, chunk = 1;
         pkt < pkt_end;
         pkt += Packet_WORDALIGN(cap_len+hdr_len), chunk++)
    {
      struct pkt_ringbuf    *q;
      struct pkt_rx_element *head;
      struct bpf_hdr        *bp;

      q  = &_pkt_inf->pkt_queue;
      bp = (struct bpf_hdr*) pkt;

      cap_len = bp->bh_caplen;
      hdr_len = bp->bh_hdrlen;

      num_rx_bytes += bp->bh_datalen;

      TCP_CONSOLE_MSG (2, ("pkt_recv_thread(): total_len %d, "
                           "chunk %d, cap_len %d, in-idx %d\n",
                       total_len, chunk, cap_len, q->in_index));

      if (cap_len > ETH_MAX)
      {
        _pkt_inf->error = "Large size";
        STAT (macstats.num_too_large++);
      }
      else
      if (pktq_in_index(q) == q->out_index)  /* queue is full, drop it */
         q->num_drop++;
      else
      {
        int pad_len, buf_max;

        head = (struct pkt_rx_element*) pktq_in_buf (q);
        memcpy (head->rx_buf, pkt + hdr_len, cap_len);
        head->tstamp_put = bp->bh_tstamp;
        head->rx_length  = cap_len;

        /* zero-pad up to ETH_MAX (don't destroy marker at end)
         */
        buf_max = q->buf_size - RX_ELEMENT_HEAD_SIZE - 4;
        pad_len = min (ETH_MAX, buf_max - cap_len);
        if (pad_len > 0)
           memset (&head->rx_buf[cap_len], 0, pad_len);
        pktq_inc_in (q);
      }
    }
    LEAVE_CRIT();
  }

  TCP_CONSOLE_MSG (2, ("pkt_recv_thread(): rc %d\n", rc));
  fflush (stdout);
  ARGSUSED (arg);
  thr_stopped = TRUE;
  return (rc);
}
Beispiel #12
0
/**
 * Initialise WinPcap and return our MAC address.
 */
int pkt_eth_init (mac_address *mac_addr)
{
  struct {
    PACKET_OID_DATA oidData;
    char            descr[512];
  } oid;
  const ADAPTER *adapter = NULL;
  DWORD thread_id;
  BOOL  is_up;

  if (_watt_is_win9x)  /**< \todo Support Win-9x too */
  {
    (*_printf) (_LANG("Win-NT or later reqired.\n"));
    _pkt_errno = PDERR_GEN_FAIL;
    return (WERR_ILL_DOSX);
  }

  if (!_watt_no_config || _watt_user_config_fn)
     parse_config_pass_1();

  _pkt_inf = calloc (sizeof(*_pkt_inf), 1);
  if (!_pkt_inf)
  {
    (*_printf) (_LANG("Failed to allocate WinPcap DRIVER data.\n"));
    _pkt_errno = PDERR_GEN_FAIL;
    return (WERR_NO_MEM);
  }

  if (debug_on >= 2 && dump_fname[0])
     dump_file = fopen_excl (ExpandVarStr(dump_fname), "w+t");

  if (!PacketInitModule(TRUE, dump_file))
  {
    (*_printf) (_LANG("Failed to initialise WinPcap.\n"));
    pkt_release();
    _pkt_errno = PDERR_NO_DRIVER;
    return (WERR_PKT_ERROR);
  }

  if (!_pktdrvrname[0] &&
      !find_adapter(_pktdrvrname,sizeof(_pktdrvrname)))
  {
    (*_printf) (_LANG("No WinPcap driver found.\n"));
    _pkt_errno = PDERR_NO_DRIVER;
    return (WERR_NO_DRIVER);
  }

  TCP_CONSOLE_MSG (2, ("device %s\n", _pktdrvrname));

  adapter = PacketOpenAdapter (_pktdrvrname);
  if (!adapter)
  {
    if (debug_on > 0)
       (*_printf) (_LANG("PacketOpenAdapter (\"%s\") failed; %s\n"),
                   _pktdrvrname, win_strerror(GetLastError()));
    pkt_release();
    return (WERR_NO_DRIVER);
  }

  _pkt_inf->adapter = adapter;
#if defined(USE_DYN_PACKET)
  _pkt_inf->adapter_info = NULL;
#else
  _pkt_inf->adapter_info = PacketFindAdInfo (_pktdrvrname);
#endif

  /* Query the NIC driver for the adapter description
   */
  memset (&oid, 0, sizeof(oid));
  oid.oidData.Oid    = OID_GEN_VENDOR_DESCRIPTION;
  oid.oidData.Length = sizeof(oid.descr);

  if (PacketRequest (adapter, FALSE, &oid.oidData))
     StrLcpy (_pktdrvr_descr, (char*)oid.oidData.Data, sizeof(_pktdrvr_descr));
  else
  {
    (*_printf) (_LANG("PacketRequest() failed; %s\n"),
                win_strerror(GetLastError()));
    pkt_release();
    return (WERR_PKT_ERROR);
  }

  if (!get_interface_type(&_pktdevclass))
  {
    pkt_release();
    return (WERR_PKT_ERROR);
  }

  if (get_connected_status(&is_up) && !is_up)
     (*_printf) (_LANG("Warning: the adapter %s is down\n"), _pktdrvrname);

  switch (_pktdevclass)
  {
    case PDCLASS_TOKEN:
         _pkt_ip_ofs = sizeof(tok_Header);
         break;
    case PDCLASS_ETHER:
         _pkt_ip_ofs = sizeof(eth_Header);
         break;
    case PDCLASS_FDDI:
         _pkt_ip_ofs = sizeof(fddi_Header);
         break;
    case PDCLASS_ARCNET:
         _pkt_ip_ofs = ARC_HDRLEN;
         break;
    default:
         pkt_release();
         (*_printf) (_LANG("WinPcap-ERROR: Unsupported driver class %dh\n"),
                     _pktdevclass);
         _pkt_errno = PDERR_NO_CLASS;
         return (WERR_PKT_ERROR);
  }

  if (!pkt_get_addr(mac_addr))  /* get our MAC address */
  {
    pkt_release();
    return (WERR_PKT_ERROR);
  }

  pktq_init (&_pkt_inf->pkt_queue,
             sizeof(_pkt_inf->rx_buf[0]),   /* RX_SIZE */
             DIM(_pkt_inf->rx_buf),         /* RX_BUFS */
             (char*)&_pkt_inf->rx_buf);

  _pkt_inf->npf_buf_size = RX_SIZE * pkt_num_rx_bufs;
  _pkt_inf->npf_buf = malloc (_pkt_inf->npf_buf_size);
  if (!_pkt_inf->npf_buf)
  {
    (*_printf) (_LANG("Failed to allocate %d byte Rx buffer.\n"),
                _pkt_inf->npf_buf_size);
    pkt_release();
    _pkt_errno = PDERR_GEN_FAIL;
    return (WERR_NO_MEM);
  }

  PacketSetMode (adapter, PACKET_MODE_CAPT);
  PacketSetBuff (adapter, _pkt_inf->npf_buf_size);
  PacketSetMinToCopy (adapter, ETH_MIN);

  /* PacketReceivePacket() blocks until something is received
   */
  PacketSetReadTimeout ((ADAPTER*)adapter, 0);

  /* Set Rx-mode forced via config.
   */
  if (_pkt_forced_rxmode != -1)
  {
    _pkt_forced_rxmode &= 0xFFFF;     /* clear bits not set via ARG_ATOX_W */
    if (_pkt_forced_rxmode == 0 ||    /* check illegal bit-values */
        (_pkt_forced_rxmode & 0x10) ||
        (_pkt_forced_rxmode & 0x40) ||
        (_pkt_forced_rxmode > 0x80))
     {
       TCP_CONSOLE_MSG (0, ("Illegal Rx-mode (0x%02X) specified\n",
                        _pkt_forced_rxmode));
       _pkt_forced_rxmode = -1;
     }
  }

  if (pkt_get_rcv_mode())
     _pkt_rxmode0 = _pkt_rxmode;

  if (_pkt_forced_rxmode != -1)
       pkt_set_rcv_mode (_pkt_forced_rxmode);
  else pkt_set_rcv_mode (RXMODE_DEFAULT);

#if 1
  _pkt_inf->recv_thread = CreateThread (NULL, 2048, pkt_recv_thread,
                                        NULL, 0, &thread_id);
#else
  _pkt_inf->recv_thread = _beginthreadex (NULL, 2048, pkt_recv_thread,
                                          NULL, 0, &thread_id);
#endif

  if (!_pkt_inf->recv_thread)
  {
    (*_printf) (_LANG("Failed to create receiver thread; %s\n"),
                win_strerror(GetLastError()));
    pkt_release();
    _pkt_errno = PDERR_GEN_FAIL;
    return (WERR_PKT_ERROR);
  }

  if (thr_realtime)
     SetThreadPriority (_pkt_inf->recv_thread,
                        THREAD_PRIORITY_TIME_CRITICAL);

  TCP_CONSOLE_MSG (2, ("capture thread-id %lu\n", thread_id));

#if defined(USE_DEBUG)
  if (debug_on >= 2)
  {
    (*_printf) ("link-details:\n");
    show_link_details();
  }
#endif
  return (0);
}
Beispiel #13
0
/**
 * _eth_send() does the actual transmission once we are complete with
 * filling the buffer.  Do any last minute patches here, like fix the
 * size. Send to "loopback" device if it's IP and destination matches
 * loopback network (127.x.x.x.).
 *
 * Return length of network-layer packet (not length of link-layer
 * packet).
 */
int _eth_send (WORD len, const void *sock, const char *file, unsigned line)
{
#if defined(USE_DEBUG) || defined(USE_LOOPBACK)
  unsigned errline = 0;
#endif
  BOOL send_loopback_to_driver = FALSE;

  SIO_TRACE (("_eth_send, len %d", len));

  if (!_eth_is_init)  /* GvB 2002-09, Lets us run without a working eth */
  {
    SOCK_ERRNO (ENETDOWN);
    return (0);
  }

#if defined(WIN32)
  /*
   * Just a test for now; send it to the driver and look what happens....
   * They go on the wire and not to the Winsock loopback provider.
   * No surprise here yet.
   */
  if (loopback_mode & LBACK_MODE_WINSOCK)
     send_loopback_to_driver = TRUE;
#endif

  if (proto == IP4_TYPE)
  {
    /* Sending to loopback device if IPv4.
     */
    const in_Header *ip = (const in_Header*) nw_pkt;

    if (!send_loopback_to_driver &&
        _ip4_is_loopback_addr(intel(ip->destination)))
    {
#if defined(USE_LOOPBACK)
      len = send_loopback (*TX_BUF(), FALSE, &errline);
#else
      STAT (ip4stats.ips_odropped++);    /* packet dropped (null-device) */
#endif
      goto debug_tx;
    }
  }

#if defined(USE_IPV6)
  else if (proto == IP6_TYPE)
  {
    const in6_Header *ip = (const in6_Header*) nw_pkt;

    if (!send_loopback_to_driver &&
        IN6_IS_ADDR_LOOPBACK(&ip->destination))
    {
#if defined(USE_LOOPBACK)
      len = send_loopback (*TX_BUF(), TRUE, &errline);
#else
      STAT (ip6stats.ip6s_odropped++);
#endif
      goto debug_tx;
    }
  }
#endif  /* USE_IPV6 */

#if defined(USE_PPPOE)
  else if (proto == PPPOE_SESS_TYPE)
  {
    pppoe_Packet *pppoe = (pppoe_Packet*) TX_BUF()->eth.data;

    pppoe->length = intel16 (len+2);
    len += PPPOE_HDR_SIZE + 2;      /* add 2 for protocol */
  }
#endif

  /* Store the last Tx CPU timestamp (for debugging).
   */
#if (DOSX) && !(DOSX & WINWATT)
  if (_dbugxmit && has_rdtsc)
     get_rdtsc2 (&_eth_last.tx.tstamp);
#endif

  /* Do the MAC-dependant transmit. `len' on return is total length
   * of link-layer packet sent. `len' is 0 on failure. The xmit-hook
   * is used by e.g. libpcap/libnet.
   */
  if (_eth_xmit_hook)
       len = (*_eth_xmit_hook) (TX_BUF(), len + _pkt_ip_ofs);
  else len = (*mac_transmit) (TX_BUF(), len + _pkt_ip_ofs);

  if (len > _pkt_ip_ofs)
  {
    _eth_last.tx.size = len;
    len -= _pkt_ip_ofs;
  }
  else
  {
    if (debug_on)
       outs ("Tx failed. ");
    len = 0;
    _eth_last.tx.size = 0;
  }

debug_tx:

#if defined(NEED_PKT_SPLIT)
  pkt_split_mac_out (TX_BUF());
#endif

#if defined(USE_STATISTICS)
  if (len > 0)
     update_out_stat();
#endif

#if defined(USE_DEBUG)
  if (_dbugxmit)
    (*_dbugxmit) (sock, (const in_Header*)nw_pkt, file, line);

  if (len == 0)
  {
    if (errline && !send_loopback_to_driver)
       dbug_printf ("** Error in loopback handler, line %u\n", errline);
    else
    {
      const char err[] = "** Transmit fault **\n";
      TCP_CONSOLE_MSG (0, ("%s", err));
      dbug_printf (err);
    }
  }
#else
  ARGSUSED (sock);
  ARGSUSED (file);
  ARGSUSED (line);
#endif

  /* Undo hack done in pppoe_mac_format()
   */
  if (proto == PPPOE_SESS_TYPE || _pktdevclass == PDCLASS_ETHER)
     _pkt_ip_ofs = sizeof(eth_Header);
  return (len);
}