Beispiel #1
0
/**
 * Check if ip-source is a (directed) broadcast address.
 * Some hacker may try to create a broadcast storm.
 * Also check for null source address (0.0.0.0).
 * Broadcast destination is already filtered out by icmp_handler().
 */
static BOOL icmp_check (const in_Header *ip, int type)
{
  DWORD src, dst;
  BOOL  bcast;

  src   = intel (ip->source);
  dst   = intel (ip->destination);
  bcast = (~src & ~sin_mask) == 0;

  if (bcast)
  {
    icmp_bogus (ip, type, _LANG(" (broadcast)"));
    return (FALSE);
  }
  if (ip->source == 0UL)
  {
    icmp_bogus (ip, type, _LANG(" (network)"));
    return (FALSE);
  }
  if (IN_MULTICAST(dst))
  {
    icmp_bogus (ip, type, _LANG(" (multicast)"));
    return (FALSE);
  }
  if (IN_EXPERIMENTAL(dst))
  {
    icmp_bogus (ip, type, _LANG(" (experimental)"));
    return (FALSE);
  }
  return (TRUE);
}
Beispiel #2
0
static void do_dial (const char *value)
{
  int rc = slip_dial (value);

  if (rc == -1)
     outsnl (_LANG("Modem not responding\7"));
  if (rc == -2)
     outsnl (_LANG("Connect failed"));
}
Beispiel #3
0
/**
 * Print info about bogus and possibly dangerous ICMP messages.
 * e.g. "ICMP: (144.133.122.111) Bogus Redirect; GW = 111.110.109.108"
 */
static void icmp_bogus (const in_Header *ip, int type, const char *msg)
{
  char buf[100];

  strcpy (buf, _LANG("Bogus "));
  strcat (buf, _LANG(icmp_type_str[type]));
  if (msg)
     strcat (buf, msg);
  icmp_print (1, buf, ip->source);
}
Beispiel #4
0
/*
 * Check if ip-source is a (directed) broadcast address.
 * Some hacker may try to create a broadcast storm.
 * Also check for null source address (0.0.0.0).
 * Broadcast destination is already filtered out by icmp_handler().
 */
static int icmp_chk_src (const in_Header *ip, int type)
{
  BOOL bcast = (~intel(ip->source) & ~sin_mask) == 0;

  if (bcast)
  {
    icmp_bogus (ip, type, _LANG(" (broadcast)"));
    return (0);
  }
  if (ip->source == 0UL)
  {
    icmp_bogus (ip, type, _LANG(" (network)"));
    return (0);
  }
  return (1);
}
Beispiel #5
0
void ReadHostFile (const char *fname)
{
  if (!fname || !*fname)
     return;

  hostFname = strdup (fname);
  if (!hostFname)
     return;

  sethostent (1);
  if (!hostFile)
     return;

  while (1)
  {
    struct _hostent h;

    if (!_gethostent(&h))
       break;

    if (!tree_insert(&host_root, (void*)&h, sizeof(h), (CmpFunc)host_cmp_name))
    {
      outsnl (_LANG("Hostfile too big!\7"));
      break;
    }
  }
  atexit (endhostent);

}
Beispiel #6
0
static int icmp_echo_reply (const in_Header *ip, const union ICMP_PKT *req,
                            unsigned len)
{
  struct _pkt     *pkt;
  union  ICMP_PKT *icmp;

  if (!icmp_check(ip,ICMP_ECHO))
     return (0);

  icmp_print (2, _LANG("PING reply sent"), 0);

#if defined(USE_FRAGMENTS)
  if (len > _mtu - sizeof(*ip))
  {
    icmp = (union ICMP_PKT*) req;        /* reuse input for output */
    icmp->echo.type     = ICMP_ECHOREPLY;
    icmp->echo.checksum = 0;
    icmp->echo.checksum = ~CHECKSUM (icmp, len);
    return _IP4_SEND_FRAGMENTS (NULL, ICMP_PROTO, ip->source, icmp, len);
  }
#endif

  pkt  = (struct _pkt*) _eth_formatpacket (MAC_SRC(ip), IP4_TYPE);
  icmp = &pkt->icmp;

  len = min (len, _mtu - sizeof(*ip));
  memcpy (icmp, req, len);
  icmp->echo.type = ICMP_ECHOREPLY;
  icmp->echo.code = req->echo.code; /* Win uses 0, Unix !0 */

  /* Use supplied ip values in case we ever multi-home.
   * Note that ip values are still in network order.
   */
  return icmp_send (pkt, ip->destination, ip->source, len);
}
Beispiel #7
0
/**
 * Send an ICMP destination/protocol unreachable back to 'ip->source'.
 * Limit the rate of these to 20 per second. Ref. RFC-1812.
 */
int icmp_send_unreach (const in_Header *ip, int code)
{
  static DWORD next_time = 0UL;
  struct _pkt    *pkt;
  union ICMP_PKT *unr;
  unsigned        len;

  if (!icmp_check(ip,ICMP_UNREACH))
     return (0);

  if (next_time && !chk_timeout(next_time))
     return (0);

  next_time = set_timeout (50);

  pkt = (struct _pkt*) _eth_formatpacket (MAC_SRC(ip), IP4_TYPE);
  unr = &pkt->icmp;
  len = intel16 (ip->length) - in_GetHdrLen (ip);
  len = min (len, sizeof(*ip)+sizeof(unr->unused.spares));

  icmp_print (1, _LANG(icmp_unreach_str[code]), ip->destination);
  memcpy (&unr->unused.ip, ip, len);
  unr->unused.type = ICMP_UNREACH;
  unr->unused.code = (BYTE) code;

  return icmp_send (pkt, ip->destination, ip->source, sizeof(unr->unused));
}
Beispiel #8
0
/*
 * trace2com_init() - Public initialisation
 */
int trace2com_init (WORD portAddress, DWORD baudRate)
{
  BYTE  Lsb, Msb;
  WORD  base;
  DWORD div;

  /* Check/get UART address
   */
  if (portAddress < 1 || portAddress > 4)
     return (0);

  base = trace2com_stdPorts [portAddress-1];

  /* See if the chip is actually there and ready
   */
  if (_inportb (base+IER_REG) == 0xFF)    /* Nothing here */
     return (0);

  if ((_inportb (base+IER_REG) & 0x0F) != 0x00)
     return (0);    /* UART is already in use by another program */

  _outportb (base+IER_REG, 0);  /* disable all interrupts */
  if (_inportb (base+IER_REG) != 0)
     return (0);                /* Whatever is here is not an UART */

  /* Set up UARTs registers
   */
  div = 115200UL / baudRate;
  Msb = div >> 8;
  Lsb = (div << 8) >> 8;

  _outportb (base+LCR_REG, 0x80);       /* Turn address latch on */
  _outportb (base+BAUD_LSB_REG, Lsb);
  _outportb (base+BAUD_MSB_REG, Msb);
  _outportb (base+LCR_REG, 0x00);       /* Turn address latch off (again) */

  _outportb (base+IER_REG, 0x00);       /* No interrupts, we use polling */
  _outportb (base+FIFO_REG, 0x01|0x08); /* Activate FIFO @ MODE 2 */
  _outportb (base+LCR_REG , 0x03);      /* 8, N, 1 */
  _outportb (base+MCR_REG, 0x03);       /* DTR + DTS on */

  /* Check chip type, gives us the FIFO size
   */
  _outportb (base + FIFO_REG, 0x11);
  Lsb = _inportb (base + FIFO_REG);

  /* If we have a 16750 or 16550 the FIFO size is 16, otherwise we assume 1
   */
  trace2com_fifoSize_1 = ((Lsb & 0x20) != 0x20 ||
                          (Lsb & 0xC0) == 0xC0) ? 15 : 0;

  /* We are now officially open for business
   */
  trace2com_speed = baudRate;
  trace2com_base  = base;

  SIO_TRACE ((_LANG("Watt-32 COM%d trace started"), portAddress));
  return (1);
}
Beispiel #9
0
/**
 * Handle incoming PPPoE packets.
 */
int pppoe_handler (const pppoe_Packet *pkt)
{
  const BYTE *buf;
  const void *src;
  const void *dst;
  WORD  proto, len;
  BOOL  bcast, delivered = FALSE;

  if (pkt->type != 1 || pkt->ver != 1)
     return (0);

  src   = MAC_SRC (pkt);
  dst   = MAC_DST (pkt);
  proto = MAC_TYP (pkt);
  bcast = !memcmp (dst, _eth_brdcast, _eth_mac_len);

  if (proto == PPPOE_SESS_TYPE && state == StateSession)
  {
    if (pkt->code    == PPPOE_CODE_SESS &&
        pkt->session == session         && !bcast &&
        !memcmp(dst, _eth_addr, _eth_mac_len) &&  /* to us? */
        !memcmp(src, ac_macAddr, _eth_mac_len))
    {
      len = intel16 (pkt->length);
      buf = &pkt->data[0];
      ppp_input (buf, len);    /* assume ppp_input() traces it */
      delivered = TRUE;
    }
  }
  else if (!bcast && proto == PPPOE_DISC_TYPE && state == StateDiscovery)
  {
    if (pkt->code == PPPOE_CODE_PADO)          /* Offer (can this be bcast?) */
    {
      got_PADO = TRUE;
      memcpy (ac_macAddr, src, _eth_mac_len);
    }
    else if (pkt->code == PPPOE_CODE_PADT &&  /* Terminate */
             pkt->session == session)
    {
      if (cfg.trace)
         outsnl (_LANG("PPPoE: session terminated"));
      got_PADT = TRUE;
      session  = 0;
    }
    else if (pkt->code == PPPOE_CODE_PADS)    /* Session-confirmation */
    {
      got_PADS = TRUE;
      session  = pkt->session;
    }
    else if (pkt->code == PPPOE_CODE_PADM)    /* Message (what to do?) */
    {
      got_PADM = TRUE;
    }
  }
  if (!delivered)
     DEBUG_RX (NULL, pkt);
  return (1);
}
Beispiel #10
0
int sock_recv_from (udp_Socket *s, DWORD *hisip, WORD *hisport,
                    char *buffer, int len, int peek)
{
  tcp_Socket *t;
  recv_buf   *p;
  recv_data  *r = (recv_data*) s->rdata;
  int i;

  if (r->recv_sig != RECV_USED)
     return (-1);

  switch (s->ip_type)
  {
    case UDP_PROTO:
         p = (recv_buf*) r->recv_bufs;

         /* find a used buffer
          */
         for (i = 0; i < r->recv_bufnum; i++, p++)
         {
           switch (p->buf_sig)
           {
             case RECV_UNUSED:
                  break;
             case RECV_USED:
                  if (p->buf_len < 0)  /* a 0-byte probe packet */
                     len = -1;
                  else
                  {
                    len = min (p->buf_len, len);
                    memcpy (buffer, p->buf_data, len);
                  }
                  if (hisip)
                     *hisip = p->buf_hisip;
                  if (hisport)
                     *hisport = p->buf_hisport;
                  if (!peek)
                     p->buf_sig = RECV_UNUSED;
                  return (len);
             default:
                  outsnl (_LANG("ERROR: sock_recv_init data err"));
                  return (0);
           }
         }
         return (0);

#if !defined(USE_UDP_ONLY)
    case TCP_PROTO:
         t = (tcp_Socket*) s;
         if (len > t->rdatalen)
             len = t->rdatalen;
         if (len)
             memcpy (buffer, r->recv_bufs, len);
         return (len);
#endif
  }
  return (0);
}
Beispiel #11
0
int sock_recv (udp_Socket *s, char *buffer, int len)
{
  recv_buf   *p;
  recv_data  *r = (recv_data*) s->rdata;
  int i;

  if (r->recv_sig != RECV_USED)
     return (-1);

  switch (s->ip_type)
  {
    case UDP_PROTO:
         p = (recv_buf*) r->recv_bufs;

         /* find a used buffer
          */
         for (i = 0; i < r->recv_bufnum; i++, p++)
         {
           switch (p->buf_sig)
           {
             case RECV_UNUSED:
                  break;
             case RECV_USED:
                  if (len > p->buf_len)
                      len = p->buf_len;
                  if (len > 0)
                     memcpy (buffer, p->buf_data, len);
                  p->buf_sig = RECV_UNUSED;
                  return (len);
             default:
                  outsnl (_LANG("ERROR: sock_recv_init data err"));
                  return (0);
           }
         }
         return (0);

#if !defined(USE_UDP_ONLY)
    case TCP_PROTO :
         {
           tcp_Socket *t = (tcp_Socket*) s;

           if (len > t->rdatalen)
               len = t->rdatalen;
           if (len)
              memcpy (buffer, r->recv_bufs, len);
           return (len);
         }
#endif
  }
  return (0);
}
Beispiel #12
0
static void icmp_print (int dbg_lvl, const char *msg, DWORD src)
{
  if (debug_on < dbg_lvl)
     return;

  outs ("\nICMP: ");
  if (src)
  {
    outs ("(");
    outs (_inet_ntoa(NULL,intel(src)));
    outs ("): ");
  }
  outsnl (_LANG(msg));
}
Beispiel #13
0
/*
 * Do a reverse lookup on `my_ip_addr'. If successfull, replace
 * `hostname' and `def_domain' with returned result.
 */
int reverse_lookup_myip (void)
{
  char myname [MAX_HOSTLEN];

  if (!resolve_ip(htonl(my_ip_addr),myname))
     return (0);

  if (debug_on >= 1)
  {
    outs (_LANG("My FQDN: "));
    outsnl (myname);
  }
  if (sethostname(myname,sizeof(myname)) < 0)
     return (0);
  return (1);
}
Beispiel #14
0
/*
 * _dorarp - Checks global variable _rarptimeout
 *           returns 1 on success and sets ip address
 */
int _dorarp (void)
{
  DWORD rarptimeout    = set_timeout (1000 * _rarptimeout);
  WORD  magictimeout   = Random (7000, 14000);

  outs (_LANG("Configuring through RARP..."));

  while (1)
  {
    DWORD sendtimeout;

    if (!_rarp_request())
       break;

    sendtimeout   = set_timeout (magictimeout);
    magictimeout += Random (1000, 7000);

    while (!chk_timeout(sendtimeout))
    {
      const struct rarp_Header *rarp;
      WORD  eth_type;
      BOOL  bcast;

      if (chk_timeout(rarptimeout))
         return (0);

      WATT_YIELD();

      rarp = (rarp_Header*) _eth_arrived (&eth_type, &bcast);
      if (!rarp)
         continue;

      DEBUG_RX (NULL, rarp);

      if (eth_type == RARP_TYPE && !bcast &&
          rarp->opcode == RARP_REPLY && rarp->protType == IP4_TYPE &&
          !memcmp(rarp->dstEthAddr,_eth_addr,sizeof(mac_address)))
      {
        my_ip_addr = intel (rarp->dstIPAddr);
        _eth_free (rarp);
        return (1);
      }
      _eth_free (rarp);
    }
  }
  return (0);
}
Beispiel #15
0
static int slip_dial (const char *str)
{
  char dial_str[80];
  WORD mcr = slip_base_reg + 4;
  WORD lcr = slip_base_reg + 3;

  _outportb (lcr, _inportb(lcr) & 0x43);  /* 8N1 */
  _outportb (mcr, _inportb(mcr) | 1);     /* raise DTR */

  if (!modem_command("ATZ\r","OK",5))
     return (0);

  strcpy (dial_str, str);
  strcat (dial_str, "\r");
  outs (_LANG("SLIP dialing.."));

  if (!modem_command(dial_str,"OK",2))
     return (-1);

  if (!modem_command(NULL,"CONNECT",slip_timeout))
     return (-2);
  return (0);
}
Beispiel #16
0
 void backgroundon (void)
 {
   outsnl (_LANG("Use wintr_init() / wintr_enable() instead"));
   exit (3);
 }
Beispiel #17
0
/*
 * Unhook signal-handlers and optionally chain to previous handlers
 * if we caught signals.
 */
void _sock_sig_restore (void)
{
    if (signal_depth == 0)
        return;

    if (--signal_depth > 0)
        return;

    _sock_stop_timer();
    watcbroke   = 0;
    wathndlcbrk = wat_brkmode;

#if defined(SIGALRM) && TRAP_SIGALRM
    signal (SIGALRM, old_sigalrm);
    unblock_sigalrm();

#if 0
    /* don't do this since a socket function might be called from an
     * alarm handler. This could cause serious recursion and stack fault.
     */
    if (sigalrm_caught && old_sigalrm != SIG_IGN && old_sigalrm != SIG_DFL)
    {
        sigalrm_caught = 0;
        (*old_sigalrm) (SIGALRM);
    }
#endif
#endif

#if defined(SIGBREAK)
    signal (SIGBREAK, old_sigbrk);
    if (sigbrk_caught && old_sigbrk != SIG_IGN && old_sigbrk != SIG_DFL)
    {
        sigbrk_caught = 0;
        (*old_sigbrk) (SIGBREAK);
    }
#endif

#if defined(SIGPIPE)
    signal (SIGPIPE, old_sigpipe);
    if (sigpipe_caught)
    {
        if (old_sigpipe != SIG_IGN && old_sigpipe != SIG_DFL)
        {
            sigpipe_caught = 0;
            (*old_sigpipe) (SIGPIPE);
        }
        else
        {
            outsnl (_LANG("Terminating on SIGPIPE"));
            exit (-1);
        }
    }
#endif

#if defined(SIGQUIT)
    signal (SIGQUIT, old_sigquit);
    if (sigquit_caught)
    {
        if (old_sigquit != SIG_IGN && old_sigquit != SIG_DFL)
        {
            sigquit_caught = 0;
            (*old_sigquit) (SIGQUIT);
        }
        else
        {
            SOCK_DEBUGF ((NULL, "\nExiting stuck program"));
            exit (-1);
        }
    }
#endif

    signal (SIGINT, old_sigint);
    if (sigint_caught && old_sigint != SIG_IGN && old_sigint != SIG_DFL)
    {
        sigint_caught = 0;
        (*old_sigint) (SIGINT);
    }

    sigalrm_caught = sigbrk_caught  = 0;
    sigint_caught  = sigquit_caught = 0;
    sigpipe_caught = 0;
}
Beispiel #18
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 #19
0
/**
 * Handler for incoming ICMP packets.
 */
void icmp_handler (const in_Header *ip, BOOL broadcast)
{
  union ICMP_PKT  *icmp;
  const in_Header *orig_ip;
  int              type, code;
  unsigned         len;
  DWORD            delta_time;
  BOOL             for_me, i_orig;  /* is it for me, did I originate it */
  const char      *msg;

  DEBUG_RX (NULL, ip);

  if (block_icmp)   /* application is handling ICMP; not needed */
     return;

  len    = in_GetHdrLen (ip);
  icmp   = (union ICMP_PKT*) ((BYTE*)ip + len);
  len    = intel16 (ip->length) - len;
  for_me = _ip4_is_multihome_addr (intel(ip->destination));

  if (!for_me || broadcast)  /* drop broadcast pings.. */
     return;

  if (len < sizeof(icmp->info))
  {
    STAT (icmpstats.icps_tooshort++);
    return;
  }

  if (CHECKSUM(icmp,len) != 0xFFFF)
  {
    STAT (icmpstats.icps_checksum++);
    icmp_print (1, _LANG("bad checksum"), ip->source);
    return;
  }

  type    = icmp->unused.type;
  code    = icmp->unused.code;
  orig_ip = &icmp->ip.ip;
  i_orig  = _ip4_is_local_addr (intel(orig_ip->source));

  if (type == ICMP_MASKREPLY)
  {
    if (!_do_mask_req)
       return;
    i_orig = TRUE;
  }

  /* !! this needs work
   */
  if (!i_orig &&
      (type != ICMP_ECHOREPLY && type != ICMP_ECHO &&
       type != ICMP_IREQREPLY && type != ICMP_TSTAMP))
  {
    icmp_bogus (ip, type, NULL);
    return;
  }

  switch (type)
  {
    case ICMP_ECHOREPLY:  /* check if we were waiting for it */
         delta_time = set_timeout(0) - icmp->echo.identifier;
         add_ping (intel(ip->source), delta_time, icmp->echo.index);
         return;

    case ICMP_UNREACH:
         if (code < DIM(icmp_unreach_str))
         {
           UINT len_needed = 8 + in_GetHdrLen (orig_ip);
           WORD next_mtu   = 0;

           msg = _LANG (icmp_unreach_str[code]);
           icmp_print (1, msg, ip->source);

           if (orig_ip->proto == TCP_PROTO ||
               orig_ip->proto == UDP_PROTO)
              len_needed += 4;  /* Need the src/dest port numbers */

           if (len >= len_needed)
           {
             if (code == ICMP_UNREACH_NEEDFRAG)
                next_mtu = intel16 (icmp->needfrag.next_mtu);

#if !defined(USE_UDP_ONLY)
             if (orig_ip->proto == TCP_PROTO)
                _tcp_cancel (orig_ip, ICMP_UNREACH, code, msg, &next_mtu);
             else
#endif
             if (orig_ip->proto == UDP_PROTO)
                _udp_cancel (orig_ip, ICMP_UNREACH, code, msg, &next_mtu);

             /** \todo Handle cancelling raw sockets */
#if defined(USE_BSD_API) && 0  
             else
              _raw_cancel (orig_ip, ICMP_UNREACH, code, msg);
#endif
           }
           else
             STAT (icmpstats.icps_tooshort++);
         }
         else
           STAT (icmpstats.icps_badcode++);
         return;

    case ICMP_SOURCEQUENCH:
#if !defined(USE_UDP_ONLY)
         if (orig_ip->proto == TCP_PROTO)
         {
           msg = _LANG (icmp_type_str[type]);
           icmp_print (1, msg, ip->source);
           _tcp_cancel (orig_ip, ICMP_SOURCEQUENCH, code, msg, NULL);
         }
#endif
         return;

    case ICMP_REDIRECT:
         if (code < DIM(icmp_redirect_str))
              icmp_redirect (icmp, ip, orig_ip, code);
         else STAT (icmpstats.icps_badcode++);
         return;

    case ICMP_ECHO:
         icmp_print (2, _LANG("PING requested of us"), ip->source);
         icmp_echo_reply (ip, icmp, len);
         return;

    case ICMP_TIMXCEED:
         if (code >= DIM(icmp_exceed_str))
         {
           STAT (icmpstats.icps_badcode++);
           return;
         }
         if (code == 0)  /* "TTL exceeded in transit" */
            switch (orig_ip->proto)
            {
#if !defined(USE_UDP_ONLY)
              case TCP_PROTO:
                   msg = _LANG (icmp_exceed_str[0]);
                   icmp_print (1, msg, ip->source);
                   _tcp_cancel (orig_ip, ICMP_TIMXCEED, code, msg, NULL);
                   break;
#endif
              case UDP_PROTO:
                   msg = _LANG (icmp_exceed_str[0]);
                   icmp_print (1, msg, ip->source);
                   _udp_cancel (orig_ip, ICMP_TIMXCEED, code, msg, NULL);
                   break;
            }
         return;

    case ICMP_PARAMPROB:
         msg = _LANG (icmp_type_str[ICMP_PARAMPROB]);
         switch (orig_ip->proto)
         {
#if !defined(USE_UDP_ONLY)
           case TCP_PROTO:
                icmp_print (0, msg, ip->source);
                _tcp_cancel (orig_ip, ICMP_PARAMPROB, code, msg, NULL);
                break;
#endif
           case UDP_PROTO:
                icmp_print (0, msg, ip->source);
                _udp_cancel (orig_ip, ICMP_PARAMPROB, code, msg, NULL);
                break;
         }
         return;

    case ICMP_ROUTERADVERT:  /* todo !! */
         msg = _LANG (icmp_type_str[ICMP_ROUTERADVERT]);
         icmp_print (1, msg, ip->source);
         return;

    case ICMP_ROUTERSOLICIT: /* todo !! */
         msg = _LANG (icmp_type_str[ICMP_ROUTERSOLICIT]);
         icmp_print (1, msg, ip->source);
         return;

    case ICMP_TSTAMP:
         msg = _LANG (icmp_type_str[ICMP_TSTAMP]);
         icmp_print (1, msg, ip->source);
         /**< \todo send reply? */
         return;

    case ICMP_TSTAMPREPLY:
         msg = _LANG (icmp_type_str[ICMP_TSTAMPREPLY]);
         icmp_print (1, msg, ip->source);
         /**< \todo should store */
         return;

    case ICMP_IREQ:
         msg = _LANG (icmp_type_str[ICMP_IREQ]);
         icmp_print (1, msg, ip->source);
         /**< \todo send reply */
         return;

    case ICMP_IREQREPLY:
         msg = _LANG (icmp_type_str[ICMP_IREQREPLY]);
         icmp_print (1, msg, ip->source);
         /**< \todo send reply upwards */
         return;

    case ICMP_MASKREQ:
         /* might be sent by us, never answer */
         break;

    case ICMP_MASKREPLY:
         msg = _LANG (icmp_type_str[ICMP_MASKREPLY]);
         icmp_print (0, msg, ip->source);
         if ((icmp->mask.identifier == addr_mask_id)    &&
             (icmp->mask.sequence   == addr_mask_seq-1) &&
             sin_mask != intel(icmp->mask.mask))
            outsnl ("Conflicting net-mask from \"ICMP Addr Mask Reply\"\7");
         addr_mask_id = 0;
         return;
  }
}
Beispiel #20
0
/*
 * Open a TFTP connection on a random local port (our transaction ID).
 * Send the request, wait for first data block and send the first ACK.
 */
static int tftp_open (DWORD server, const char *fname)
{
  int  retry;
  WORD port = 69;

#if defined(USE_BSD_API)
  struct servent *sp = getservbyname ("tftp", "udp");

  if (sp)
     port = intel16 ((WORD)sp->s_port);
#endif

  currblock = 0UL;
  blocksize = 0;

  for (retry = 0; retry < tftp_retry; retry++)
  {
    WORD our_tid;  /* our transaction ID (local port) */

    if (tftp_lport && tftp_lport < TFTP_PORT_LOW)
       outsnl (_LANG("tftp: Illegal local port."));

    if (tftp_lport >= TFTP_PORT_LOW)
         our_tid = tftp_lport;
    else our_tid = Random (TFTP_PORT_LOW, TFTP_PORT_HIGH);

    /* Try to open a TFTP connection to the server
     */
    if (!udp_open(&sock->udp, our_tid, server, port, NULL))
    {
      TRACE (("tftp: %s\n", sockerr(sock)));
      return (0);
    }
    sock->udp.locflags |= LF_NOCLOSE;  /* don't close socket on timeout */

    /* Send the file request block, and then wait for the first data
     * block. If there is no response to the query, retry it with
     * another transaction ID (local port), so that all old packets get
     * discarded automatically.
     */
    send_req (RRQ, fname);

    /* This hack makes it work because the response is sent back on
     * a source-port different from port 69; i.e. the server TID
     * uses a random port. Force the response packet to match a passive
     * socket in udp_handler().
     */
    sock->udp.hisaddr = 0;

    ibuflen = recv_packet (1);
    if (ibuflen >= 0)
    {
      blocksize = ibuflen;
      isopen = TRUE;
      send_ack (1);
      return (1);
    }

    /* If an error (except timeout) occurred, retries are useless
     */
    if (tftp_errno == ERR_ERR || tftp_errno == ERR_UNKNOWN)
       break;
  }
  return (0);
}
Beispiel #21
0
/*
 * Load the BOOT-file from TFTP server
 */
int tftp_boot_load (void)
{
  int rc = 0;

  /* Allocate socket and buffers
   */
  sock   = (sock_type*) malloc (sizeof(sock->udp));
  inbuf  = (struct tftphdr*) malloc (TFTP_HEADSIZE+SEGSIZE);
  outbuf = (struct tftphdr*) malloc (TFTP_HEADSIZE+SEGSIZE);

  if (!sock || !inbuf || !outbuf)
  {
    outsnl (_LANG("No memory for TFTP boot."));
    return (0);
  }

  if (!tftp_boot_remote_file)
  {
    outsnl (_LANG("No remote TFTP boot filename defined."));
    return (0);
  }

  if (tftp_server_name[0] && !tftp_server)
     tftp_server = resolve (tftp_server_name);

  if (!tftp_server)
  {
    outsnl (_LANG("Cannot resolve TFTP-server "));
    return (0);
  }

  if (debug_on)
     outs (_LANG("Doing TFTP boot load..."));

  /* Open connection and request file
   */
  if (!tftp_open (tftp_server, tftp_boot_remote_file))
  {
    tftp_close();
    return (0);
  }

  while (1)
  {
    const char *buf;
    int   size = tftp_get_block (&buf);

    if (size < 0)  /* error in transfer */
    {
      rc = 0;
      break;
    }
    if (size > 0 && (*tftp_writer)(buf,size) < 0)
    {
      rc = -1;     /* writer failed, errno set */
      break;
    }
    if (size < blocksize)    /* got last block */
    {
      rc = 1;
      break;
    }
  }
  tftp_close();
  return (rc);
}
Beispiel #22
0
/*
 *  _recvdaemon - gets upcalled when data arrives
 */
static int _recvdaemon (udp_Socket *s, BYTE *data, int len,
                        tcp_PseudoHeader *ph, udp_Header *udp)
{
  recv_data *r;
  recv_buf  *p;
  int i;

  switch (s->ip_type)
  {
    case UDP_PROTO:
         r = (recv_data*)s->rdata;
         p = (recv_buf*) r->recv_bufs;
         if (r->recv_sig != RECV_USED)
         {
           outsnl (_LANG("ERROR: udp recv data conflict"));
           return (0);
         }
         /* find an unused buffer
          */
         for (i = 0; i < r->recv_bufnum; i++, p++)
             switch (p->buf_sig)
             {
               case RECV_USED:
                    break;
               case RECV_UNUSED:  /* take this one */
                    p->buf_sig     = RECV_USED;
                    p->buf_hisip   = ph->src;
                    p->buf_hisport = udp->srcPort;
                    len = min (len, sizeof(p->buf_data));
                    if (len > 0)
                    {
                      memcpy (p->buf_data, data, len);
                      p->buf_len = len;
                    }
                    else
                      p->buf_len = -1;  /* a 0-byte probe */
                    return (0);
               default:
                    outsnl (_LANG("ERROR: sock_recv_daemon data err"));
                    return (0);
             }
         return (0);

#if !defined(USE_UDP_ONLY)
    case TCP_PROTO:
         {
           tcp_Socket *t = (tcp_Socket*) s;

           r = (recv_data*) t->rdata;
           if (len > t->max_seg)
              return (0);

           if (r->recv_sig != RECV_USED)
           {
             outsnl (_LANG("ERROR: tcp recv data conflict"));
             return (0);
           }
           /* stick it on the end if you can
            */
           i = t->maxrdatalen - t->rdatalen;
           if (i > 1)
           {
             /* we can accept some of this */
             if (len > i)
                 len = i;
             if (len > 0)
                memcpy (&r->recv_bufs[s->rdatalen], data, len);
             s->rdatalen += len;
             return (len);
           }
           return (0);   /* didn't take none */
         }
#endif
  }
  return (0);
}
Beispiel #23
0
/**
 * Initialize the network driver interface.
 * \return 0 okay.
 * \return error-code otherwise.
 */
int _eth_init (void)
{
  int rc;

  SIO_TRACE (("_eth_init"));

  if (_eth_is_init)
     return (0);

  rc = pkt_eth_init (&_eth_addr);
  if (rc)
     return (rc);  /* error message already printed */

  /* Save our MAC-address incase we change it. Change back at exit.
   */
  memcpy (_eth_real_addr, _eth_addr, sizeof(_eth_real_addr));

  switch (_pktdevclass)
  {
    case PDCLASS_ETHER:
         mac_tx_format = eth_mac_format;
         mac_transmit  = eth_mac_xmit;
         break;
    case PDCLASS_TOKEN:
    case PDCLASS_TOKEN_RIF:
         mac_tx_format = tok_mac_format;
         mac_transmit  = tok_mac_xmit;
         break;
    case PDCLASS_FDDI:
         mac_tx_format = fddi_mac_format;
         mac_transmit  = fddi_mac_xmit;
         break;
    case PDCLASS_ARCNET:
         mac_tx_format = arcnet_mac_format;
         mac_transmit  = arcnet_mac_xmit;
         break;
    case PDCLASS_SLIP:
    case PDCLASS_PPP:
    case PDCLASS_AX25:  /* !! for now */
         mac_tx_format = null_mac_format;
         mac_transmit  = null_mac_xmit;
         break;
    default:
         outsnl (_LANG("No supported driver class found"));
         return (WERR_NO_DRIVER);
  }

  memset (TX_BUF(), 0, sizeof(union link_Packet));
  memset (&_eth_brdcast, 0xFF, sizeof(_eth_brdcast));
  _eth_loop_addr[0] = 0xCF;
  pkt_buf_wipe();

  if (!_eth_get_hwtype(NULL, &_eth_mac_len))
     _eth_mac_len = sizeof(eth_address);

  if (!strcmp(_pktdrvrname,"NDIS3PKT"))
     _eth_ndis3pkt = TRUE;

  else if (!strcmp(_pktdrvrname,"SwsVpkt"))
     _eth_SwsVpkt = TRUE;

  _eth_is_init = TRUE;
  RUNDOWN_ADD (_eth_release, 10);

  return (0);  /* everything okay */
}
Beispiel #24
0
void ReadNetworksFile (const char *fname)
{
  static BOOL been_here = FALSE;

  if (!fname || !*fname)
     return;

  if (been_here)  /* loading multiple network files */
  {
    free (networkFname);
    fclose (networkFile);
    networkFile = NULL;
  }

  networkFname = strdup (fname);
  if (!networkFname)
     return;

  setnetent (1);
  if (!networkFile)
     return;

  been_here = TRUE;

  while (1)
  {
    struct netent  *n = getnetent();
    struct _netent *n2;
    int    i;

    if (!n)
       break;

    n2 = (struct _netent*) calloc (sizeof(*n2), 1);
    if (!n2)
    {
      outs (networkFname);
      outsnl (_LANG(" too big!"));
      break;
    }

    for (i = 0; n->n_aliases[i]; i++)
        n2->n_aliases[i] = strdup (n->n_aliases[i]);
    n2->n_net      = n->n_net;
    n2->n_addrtype = n->n_addrtype;
    n2->n_name     = strdup (n->n_name);
    if (!n2->n_name)
       break;
    n2->n_next = network0;
    network0   = n2;
  }
  rewind (networkFile);
  RUNDOWN_ADD (endnetent, 251);

#if 0  /* test */
  {
    struct _netent *n;

    printf ("\n%s entries:\n", networkFname);

    for (n = network0; n; n = n->n_next)
    {
      int i;
      printf ("net %-15.15s name %-10.10s  Aliases:",
              inet_ntoa(inet_makeaddr(n->n_net,0)), n->n_name);
      for (i = 0; n->n_aliases[i]; i++)
          printf (" %s,", n->n_aliases[i]);
      puts ("");
    }
    fflush (stdout);
  }
#endif
}
Beispiel #25
0
/*
 *  Handler for incoming ICMP packets
 */
void icmp_handler (const in_Header *ip, BOOL broadcast)
{
  union icmp_pkt *icmp;
  in_Header      *orig_ip;
  int             len, type, code;
  BOOL            for_me, i_orig;  /* is it for me, did I originate it */
  const char     *msg;

  DEBUG_RX (NULL, ip);

  if (block_icmp)   /* application is handling ICMP; not needed */
     return;

  len    = in_GetHdrLen (ip);
  icmp   = (union icmp_pkt*) ((BYTE*)ip + len);
  len    = intel16 (ip->length) - len;
  for_me = (DWORD) (intel(ip->destination) - my_ip_addr) <= multihomes;

  if (!for_me || broadcast)  /* drop broadcast pings.. */
     return;

  if (len < sizeof(icmp->info))
  {
    STAT (icmpstats.icps_tooshort++);
    return;
  }

  if (checksum(icmp,len) != 0xFFFF)
  {
    STAT (icmpstats.icps_checksum++);
    icmp_print (1, _LANG("bad checksum"), ip->source);
    return;
  }

  type    = icmp->unused.type;
  code    = icmp->unused.code;
  orig_ip = &icmp->ip.ip;
  i_orig  = is_local_addr (intel(orig_ip->source));

  if (type == ICMP_MASKREPLY)
  {
    if (!_domask_req)
       return;
    i_orig = TRUE;
  }

  /* !! this needs work
   */
  if (!i_orig &&
      (type != ICMP_ECHOREPLY && type != ICMP_ECHO &&
       type != ICMP_IREQREPLY && type != ICMP_TSTAMP))
  {
    icmp_bogus (ip, type, NULL);
    return;
  }

  switch (type)
  {
    case ICMP_ECHOREPLY:  /* check if we were waiting for it */
         STAT (icmpstats.icps_inhist[ICMP_ECHOREPLY]++);
         ping_hcache = intel (ip->source);
         ping_tcache = set_timeout (1000) - *(DWORD*)&icmp->echo.identifier;
         if (ping_tcache > 0x7FFFFFFFL)
             ping_tcache += 0x1800B0L;
         ping_number = *(DWORD*)(((BYTE*)&icmp->echo.identifier) + 4);
         return;

    case ICMP_UNREACH:
         STAT (icmpstats.icps_inhist[ICMP_UNREACH]++);
         if (code < DIM(icmp_unreach_str))
         {
           icmp_print (1, msg = icmp_unreach_str[code], ip->source);
#if !defined(USE_UDP_ONLY)
           if (orig_ip->proto == TCP_PROTO)
              _tcp_cancel (orig_ip, type, msg, 0);
           else
#endif
           if (orig_ip->proto == UDP_PROTO)
              _udp_cancel (orig_ip, type, msg, 0);
         }
         else
           STAT (icmpstats.icps_badcode++);
         return;

    case ICMP_SOURCEQUENCH:
         STAT (icmpstats.icps_inhist[ICMP_SOURCEQUENCH]++);
#if !defined(USE_UDP_ONLY)
         if (orig_ip->proto == TCP_PROTO)
         {
           icmp_print (1, _LANG("Source Quench"), ip->source);
           _tcp_cancel (orig_ip, type, NULL, 0);
         }
#endif
         return;

    case ICMP_REDIRECT:
         STAT (icmpstats.icps_inhist[ICMP_REDIRECT]++);
         if (code < 4)
         {
           DWORD new_gw = intel (icmp->ip.ipaddr);

           /* Check if new gateway is on our subnet
            */
           if ((new_gw ^ my_ip_addr) & sin_mask)
           {
             char buf[100], adr[20];
             strcpy (buf, ", GW = ");
             strcat (buf, _inet_ntoa(adr,new_gw));
             icmp_bogus (ip, type, buf);
             return;
           }
           icmp_print (1, msg = icmp_redirect_str[code], ip->source);

           switch (orig_ip->proto)
           {
#if !defined(USE_UDP_ONLY)
             case TCP_PROTO:
                  if (do_redirect.tcp)  /* do it to some socket */
                     _tcp_cancel (orig_ip, type, msg, new_gw);
                  break;
#endif
             case UDP_PROTO:
                  if (do_redirect.udp)
                     _udp_cancel (orig_ip, type, msg, new_gw);
                  break;

             case ICMP_PROTO:
                  if (do_redirect.icmp)
                  {
                    _ip_recursion = 1;
                    _arp_register (new_gw, intel(orig_ip->destination), 0);
                    _ip_recursion = 0;
                  }
                  break;

             case IGMP_PROTO:
                  if (do_redirect.igmp)
                  {
                    _ip_recursion = 1;
                    _arp_register (new_gw, intel(orig_ip->destination), 0);
                    _ip_recursion = 0;
                  }
                  break;
           }
         }
         else
           STAT (icmpstats.icps_badcode++);
         return;

    case ICMP_ECHO:
         STAT (icmpstats.icps_inhist[ICMP_ECHO]++);
         icmp_print (2, _LANG("PING requested of us"), ip->source);
         {
           /* Extract eth-address and create Echo reply packet.
            */
           struct _pkt     *pkt;
           union  icmp_pkt *newicmp;

           if (!icmp_chk_src(ip,ICMP_ECHO))
              return;

           pkt     = (struct _pkt*) _eth_formatpacket (MAC_SRC(ip), IP_TYPE);
           newicmp = &pkt->icmp;

           /* Don't let a huge reassembled ICMP-packet kill us.
            */
           len = min (len, mtu - sizeof(*ip));
           memcpy (newicmp, icmp, len);
           newicmp->echo.type = ICMP_ECHOREPLY;
           newicmp->echo.code = code;

           /* Use supplied ip values in case we ever multi-home.
            * Note that ip values are still in network order.
            */
           icmp_send (pkt, ip->destination, ip->source, len);
           icmp_print (2, _LANG("PING reply sent"), 0);
         }
         return;

    case ICMP_TIMXCEED:
         if (code >= DIM(icmp_exceed_str))
         {
           STAT (icmpstats.icps_badcode++);
           return;
         }
         STAT (icmpstats.icps_inhist[ICMP_TIMXCEED]++);

         if (code != 1)
            switch (orig_ip->proto)
            {
#if !defined(USE_UDP_ONLY)
              case TCP_PROTO:
                   icmp_print (1, icmp_exceed_str[code], ip->source);
                   _tcp_cancel (orig_ip, ICMP_TIMXCEED, NULL, 0);
                   break;
#endif
              case UDP_PROTO:
                   icmp_print (1, icmp_exceed_str[code], ip->source);
                   _udp_cancel (orig_ip, ICMP_TIMXCEED, NULL, 0);
                   break;
            }
         return;

    case ICMP_PARAMPROB:
         STAT (icmpstats.icps_inhist[ICMP_PARAMPROB]++);
         switch (orig_ip->proto)
         {
#if !defined(USE_UDP_ONLY)
           case TCP_PROTO:
                icmp_print (0, _LANG(icmp_type_str[type]), ip->source);
                _tcp_cancel (orig_ip, type, NULL, 0);
                break;
#endif
           case UDP_PROTO:
                icmp_print (0, _LANG(icmp_type_str[type]), ip->source);
                _udp_cancel (orig_ip, type, NULL, 0);
                break;
         }
         return;

    case ICMP_ROUTERADVERT:  /* todo !! */
         STAT (icmpstats.icps_inhist[ICMP_ROUTERADVERT]++);
         icmp_print (1, _LANG(icmp_type_str[type]), ip->source);
         return;

    case ICMP_ROUTERSOLICIT: /* todo !! */
         STAT (icmpstats.icps_inhist[ICMP_ROUTERSOLICIT]++);
         icmp_print (1, _LANG(icmp_type_str[type]), ip->source);
         return;

    case ICMP_TSTAMP:
         STAT (icmpstats.icps_inhist[ICMP_TSTAMP]++);
         icmp_print (1, _LANG(icmp_type_str[type]), ip->source);
         /* todo!!, send reply? */
         return;

    case ICMP_TSTAMPREPLY:
         STAT (icmpstats.icps_inhist[ICMP_TSTAMPREPLY]++);
         icmp_print (1, _LANG(icmp_type_str[type]), ip->source);
         /* todo!!, should store */
         return;

    case ICMP_IREQ:
         STAT (icmpstats.icps_inhist[ICMP_IREQ]++);
         icmp_print (1, _LANG(icmp_type_str[type]), ip->source);
         /* todo!!, send reply */
         return;

    case ICMP_IREQREPLY:
         STAT (icmpstats.icps_inhist[ICMP_IREQREPLY]++);
         icmp_print (1, _LANG(icmp_type_str[type]), ip->source);
         /* todo!!, send reply upwards */
         return;

    case ICMP_MASKREQ:
         STAT (icmpstats.icps_inhist[ICMP_MASKREQ]++);
         break;

    case ICMP_MASKREPLY:
         STAT (icmpstats.icps_inhist[ICMP_MASKREPLY]++);
         icmp_print (0, _LANG(icmp_type_str[type]), ip->source);
         if ((icmp->mask.identifier == addr_mask_id)    &&
             (icmp->mask.sequence   == addr_mask_seq-1) &&
             sin_mask != intel(icmp->mask.mask))
            outsnl ("Conflicting net-mask from \"ICMP Addr Mask Reply\"\7");
         addr_mask_id = 0;
         return;
  }
}
Beispiel #26
0
/*
 * Gets upcalled when data arrives.
 * We MUST set 'p->buf_len = -1' to signal a 0-byte UDP packet
 * not 0
 */
static int sock_recvdaemon (sock_type *s, const void *data, unsigned len,
                            const tcp_PseudoHeader *ph, const udp_Header *udp)
{
  recv_data *r;
  recv_buf  *p;
  unsigned   i;

  switch (s->udp.ip_type)
  {
    case UDP_PROTO:
         r = (recv_data*) s->udp.rx_data;
         p = (recv_buf*) r->recv_bufs;
         if (r->recv_sig != RECV_USED)
         {
           outsnl (_LANG("ERROR: udp recv data conflict"));
           return (0);
         }
         /* find an unused buffer
          */
         for (i = 0; i < r->recv_bufnum; i++, p++)
             switch (p->buf_sig)
             {
               case RECV_USED:
                    break;
               case RECV_UNUSED:  /* take this one */
                    p->buf_sig     = RECV_USED;
                    p->buf_hisport = udp->srcPort;
                    p->buf_seqnum  = seq_num++;
#if defined(USE_IPV6)
                    if (s->udp.is_ip6)
                       memcpy (&p->buf_hisip6, &((tcp_PseudoHeader6*)ph)->src,
                               sizeof(p->buf_hisip6));

                    else
#endif
                       p->buf_hisip = ph->src;
                    len = min (len, sizeof(p->buf_data));
                    if (len > 0)
                    {
                      memcpy (p->buf_data, data, len);
                      p->buf_len = (short) len;
                    }
                    else
                      p->buf_len = -1;  /* a 0-byte probe */
#if 0
                    SOCK_DEBUGF (("\nsock_recvdaemon(): buffer %d, "
                                  "seq-num %ld, len %d",
                                  i, seq_num-1, p->buf_len));
#endif
                    return (0);
               default:
                    outsnl (_LANG("ERROR: sock_recv_daemon data err"));
                    return (0);
             }
         return (0);

#if !defined(USE_UDP_ONLY)
    case TCP_PROTO:
         {
           _tcp_Socket *t = &s->tcp;

           r = (recv_data*) t->rx_data;

           if (r->recv_sig != RECV_USED)
           {
             outsnl (_LANG("ERROR: tcp recv data conflict"));
             return (0);
           }
           /* stick it on the end if you can
            */
           i = t->max_rx_data - t->rx_datalen;
           if (i > 1)
           {
             /* we can accept some of this */
             if (len > i)
                 len = i;
             if (len > 0)
                memcpy (r->recv_bufs + t->rx_datalen, data, len);
             t->rx_datalen += len;
             return (len);
           }
           return (0);   /* didn't take none */
         }
#endif
  }
  return (0);
}
Beispiel #27
0
int sock_recv_from (sock_type *s, void *hisip, WORD *hisport,
                    void *buffer, unsigned len, int peek)
{
#if !defined(USE_UDP_ONLY)
  _tcp_Socket *t;
#endif
  recv_buf    *p, *oldest = NULL;
  recv_data   *r = (recv_data*) s->udp.rx_data;
  long seqnum = LONG_MAX;
  int  i;

  if (r->recv_sig != RECV_USED)
  {
    SOCK_ERRNO (EBADF);

    /* To differentiate an error from 0-byte probe (also -1) */
    return (-1);
  }

  switch (s->udp.ip_type)
  {
    case UDP_PROTO:
         p = (recv_buf*) r->recv_bufs;

         /* find the oldest used UDP buffer.
          */
         for (i = 0; i < r->recv_bufnum; i++, p++)
         {
           switch (p->buf_sig)
           {
             case RECV_UNUSED:
                  break;

             case RECV_USED:
                  /* Drop looped packets sent by us (running
                   * under Win32 DOS box using NDIS3PKT or SwsVpkt).
                   */
                  if ((_eth_ndis3pkt || _eth_SwsVpkt) &&
                      !s->tcp.is_ip6 && p->buf_hisip == intel(my_ip_addr))
                  {
                    p->buf_sig = RECV_UNUSED;
                    continue;
                  }
                  if (p->buf_seqnum < seqnum)  /* ignore wraps */
                  {
                    seqnum = p->buf_seqnum;
                    oldest = p;
#if 0
                    SOCK_DEBUGF (("\nsock_recv_from(): buffer %d, "
                                  "seq-num %ld, len %d",
                                  i, seqnum, p->buf_len));
#endif
                  }
                  break;

             default:
                  outsnl (_LANG("ERROR: sock_recv_init data err"));
                  return (0);
           }
         }
         break;

#if !defined(USE_UDP_ONLY)
    case TCP_PROTO:
         t = &s->tcp;
         len = min (len, (unsigned)t->rx_datalen);
         if (len)
             memcpy (buffer, r->recv_bufs, len);
         return (len);
#endif
  }

  if (!oldest)
     return (0);

  /* found the oldest UDP packet */

  p = oldest;
  if (p->buf_len < 0)  /* a 0-byte probe packet */
     len = -1;
  else
  {
    len = min ((unsigned)p->buf_len, len);
    memcpy (buffer, p->buf_data, len);
  }

#if defined(USE_IPV6)
  if (s->tcp.is_ip6)
  {
    if (hisip)
       memcpy (hisip, &p->buf_hisip6, sizeof(ip6_address));
  }
  else
#endif
  if (hisip)
     *(DWORD*)hisip = p->buf_hisip;

  if (hisport)
     *hisport = p->buf_hisport;

  if (!peek)
     p->buf_sig = RECV_UNUSED;
  return (len);
}
Beispiel #28
0
void ReadHostsFile (const char *fname)
{
  static BOOL been_here = FALSE;

  if (!fname || !*fname)
     return;

  if (been_here)  /* loading multiple hosts files */
  {
    free (hostFname);
    fclose (hostFile);
    hostFile = NULL;
  }

  hostFname = strdup (fname);
  if (!hostFname)
     return;

  sethostent (1);
  if (!hostFile)
     return;

  been_here = TRUE;

  while (1)
  {
    struct  hostent *h = gethostent();
    struct _hostent *h2;
    int     i;

    if (!h)
       break;

    h2 = (struct _hostent*) calloc (sizeof(*h2), 1);
    if (!h2)
    {
      outs (hostFname);
      outsnl (_LANG(" too big!"));
      break;
    }

    for (i = 0; h->h_aliases[i]; i++)
        h2->h_aliases[i] = strdup (h->h_aliases[i]);
    h2->h_name       = strdup (h->h_name);
    h2->h_address[0] = *(DWORD*) h->h_addr_list[0];
    h2->h_num_addr   = 1;
    if (!h2->h_name)
       break;
    h2->h_next = host0;
    host0      = h2;
  }

#if 0  /* test !! */
  {
    const struct _hostent *h;
    int   i;

    printf ("\n%s entries:\n", hostFname);
    for (h = host0; h; h = h->h_next)
    {
      printf ("address = %-17.17s name = %-30.30s  Aliases:",
               inet_ntoa(*(struct in_addr*)&h->h_address[0]), h->h_name);
      for (i = 0; h->h_aliases[i]; i++)
          printf (" %s,", h->h_aliases[i]);
      puts ("");
    }
    fflush (stdout);
  }
#endif
  rewind (hostFile);
  RUNDOWN_ADD (endhostent, 254);
}
Beispiel #29
0
/*
 * ___trace2com() - Strings passed here are dumped to the set-up serial
 * "com" port. If the string is < 16 chars long, it will fit into the
 * 16550 UARTs FIFO and will not cause any significant delay.
 * No interrupts are used, so this will not interfere with anything
 * else that might be happening.
 */
int MS_CDECL __trace2com (const char *fmt, ...)
{
  int     fifoLeft = 0; /* Assume TX FIFO is full on first round -> force check */
  char    buf [256];
  int     len, i;
  va_list args;

  if (trace2com_base <= 0)   /* Not yet initialized */
     return (0);

  va_start (args, fmt);

#if defined(VSNPRINTF)
  len = VSNPRINTF (buf, sizeof(buf)-1, fmt, args);
  if (len < 0 || len >= SIZEOF(buf)-1)
  {
    outsnl (_LANG("ERROR: __trace2com() overrun"));
    len = sizeof(buf)-1;
    buf [len] = '\0';
  }
#else
  len = vsprintf (buf, fmt, args);
  if (len > SIZEOF(buf))  /* harm already done, but better than no test */
  {
    outsnl (_LANG("ERROR: __trace2com() overrun"));
    return (0);
  }
#endif

  for (i = 0; i < len; i++)
  {
    DWORD to = set_timeout (400000/trace2com_speed); /* 10ms at 38kB/s */

    if (--fifoLeft < 0) /* Is the TX FIFO full? */
    {
      /* Wait until THRE or TX FIFO empty
       */
      while (!(_inportb (trace2com_base+LSR_REG) & LSR_THRE))
      {
        if (chk_timeout(to))
           return (i);
      }
      fifoLeft = trace2com_fifoSize_1; /* Now we can fill it up again */
    }
    _outportb (trace2com_base+TXRX_REG, buf[i]);
  }

  if (--fifoLeft < 0)
  {
    DWORD to = set_timeout (400000/trace2com_speed);

    /* Wait until THRE or TX FIFO empty
     */
    while (!(_inportb (trace2com_base+LSR_REG) & LSR_THRE))
    {
      if (chk_timeout(to))
         return (len);
    }
  }
  _outportb (trace2com_base+TXRX_REG, '\r');
  _outportb (trace2com_base+TXRX_REG, '\n');
  return (len+2);
}
Beispiel #30
0
int getopt (int argc, char **argv, const char *opt_str)
{
  char c, *q;
  int  i, j;

  if (optind == 0)
  {
    optind   = 1;
    done     = 0;
    next_opt = empty;
    if (optmode == GETOPT_ANY)
    {
      options     = malloc (argc * sizeof(char*));
      non_options = malloc (argc * sizeof(char*));
      if (!options || !non_options)
      {
        printf (_LANG("out of memory (getopt)\n"));
        exit (255);
      }
      options_count     = 0;
      non_options_count = 0;
    }
  }
  if (done)
     return (EOF);

restart:
  optarg = NULL;
  if (*next_opt == 0)
  {
    if (optind >= argc)
    {
      if (optmode == GETOPT_ANY)
      {
        j = 1;
        for (i = 0; i < options_count; ++i)
            argv[j++] = options[i];
        for (i = 0; i < non_options_count; ++i)
            argv[j++] = non_options[i];
        optind = options_count+1;
        free (options);
        free (non_options);
      }
      done = 1;
      return (EOF);
    }
    else if (!strchr (optswchar, argv[optind][0]) || argv[optind][1] == 0)
    {
      if (optmode == GETOPT_UNIX)
      {
        done = 1;
        return (EOF);
      }
      PUT (non_options);
      optarg = argv[optind++];
      if (optmode == GETOPT_ANY)
         goto restart;
      /* optmode==GETOPT_KEEP */
      return (0);
    }
    else if (argv[optind][0] == argv[optind][1] && argv[optind][2] == 0)
    {
      if (optmode == GETOPT_ANY)
      {
        j = 1;
        for (i = 0; i < options_count; ++i)
            argv[j++] = options[i];
        argv[j++] = argv[optind];
        for (i = 0; i < non_options_count; ++i)
            argv[j++] = non_options[i];
        for (i = optind+1; i < argc; ++i)
            argv[j++] = argv[i];
        optind = options_count+2;
        free (options);
        free (non_options);
      }
      ++optind;
      done = 1;
      return (EOF);
    }
    else
    {
      PUT (options);
      sw_char  = argv[optind][0];
      next_opt = argv[optind]+1;
    }
  }
  c = *next_opt++;
  if (*next_opt == 0)  /* Move to next argument if end of argument reached */
     optind++;
  if (c == ':' || (q = strchr (opt_str, c)) == NULL)
  {
    if (opterr)
    {
      if (c < ' ' || c >= 127)
           printf (_LANG("Invalid option; character code=0x%.2x\n"), c);
      else printf (_LANG("Invalid option `%c%c'\n"), sw_char, c);
    }
    optopt = '?';
    return ('?');
  }
  if (q[1] == ':')
  {
    if (*next_opt != 0)         /* Argument given */
    {
      optarg = next_opt;
      next_opt = empty;
      ++optind;
    }
    else if (q[2] == ':')
      optarg = NULL;            /* Optional argument missing */
    else if (optind >= argc)
    {                         /* Required argument missing */
      if (opterr)
         printf (_LANG("No argument for `%c%c' option\n"), sw_char, c);
      c = '?';
    }
    else
    {
      PUT (options);
      optarg = argv[optind++];
    }
  }
  optopt = c;
  return (c);
}