Пример #1
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"));
}
Пример #2
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);

}
Пример #3
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);
}
Пример #4
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);
}
Пример #5
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);
}
Пример #6
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));
}
Пример #7
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);
}
Пример #8
0
void ReadProtoFile (const char *fname)
{
  static int been_here = 0;

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

  if (been_here)  /* loading multiple protocol files */
  {
    free (protoFname);
    fclose (protoFile);
    protoFile = NULL;
  }
  been_here = 1;

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

  setprotoent (1);
  if (!protoFile)
     return;

  while (1)
  {
    struct _protoent *p, *p2 = (struct _protoent*) getprotoent();

    if (!p2)
       break;

    p = malloc (sizeof(*p));
    if (!p)
    {
      outsnl ("Protocol-file too big!\7");
      break;
    }
    *p = *p2;
    p->next = _proto0;
    _proto0 = p;
  }
  rewind (protoFile);
  atexit (endprotoent);
}
Пример #9
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);
}
Пример #10
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);
}
Пример #11
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;
  }
}
Пример #12
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);
}
Пример #13
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);
}
Пример #14
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);
}
Пример #15
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 */
}
Пример #16
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
}
Пример #17
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;
  }
}
Пример #18
0
 void backgroundon (void)
 {
   outsnl (_LANG("Use wintr_init() / wintr_enable() instead"));
   exit (3);
 }
Пример #19
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);
}
Пример #20
0
/*
 * Warn about calling 'getXbyY()' functions before calling
 * 'watt_sock_init()'. Many other functions will fail if we're not
 * initialised, but 'getXbyY()' are often used during application
 * startup.
 */
void uninit_warn (const char *func)
{
  outs ("Warning: function \"");
  outs (func);
  outsnl ("()\" called before \"sock_init()\".");
}
Пример #21
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;
}
Пример #22
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);
}