Beispiel #1
0
int fix_tcp_packet (in_Header *ip, tcp_Header *tcp, int ack_len, int data_len)
{
  static DWORD seq_num = 12345678;  /* starting sequence */
  tcp_PseudoHeader ph;
  WORD src_port;

  tcp->checksum = 0;
  src_port      = tcp->srcPort;
  tcp->srcPort  = tcp->dstPort;
  tcp->dstPort  = src_port;
  tcp->acknum   = intel (intel(tcp->seqnum) + ack_len);
  tcp->seqnum   = intel (seq_num);
  tcp->offset   = sizeof(*tcp) / 4;    /* in dwords */
  seq_num      += data_len;

  ph.src        = ip->source;
  ph.dst        = ip->destination;
  ph.mbz        = 0;
  ph.protocol   = TCP_PROTO;
  ph.length     = intel16 (sizeof(*tcp) + data_len);
  ph.checksum   = CHECKSUM (tcp, sizeof(*tcp) + data_len);

  ip->length    = intel16 (data_len + sizeof(*tcp) + sizeof(*ip));
  ip->checksum  = 0;
  ip->checksum  = ~CHECKSUM (ip, sizeof(*ip));
  tcp->checksum = ~CHECKSUM (&ph, sizeof(ph));
  return (sizeof(*ip) + sizeof(*tcp) + data_len);
}
Beispiel #2
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 #3
0
/**
 * Handle ICMP_REDIRECT messages.
 */
static void icmp_redirect (const union ICMP_PKT *icmp, const in_Header *ip,
                           const in_Header *orig_ip, int code)
{
  DWORD new_ip = intel (icmp->ip.ipaddr);
  DWORD old_ip = intel (orig_ip->destination);
  const char *msg;

  if (new_ip == old_ip)
  {
    /* Possibly because we and router use different netmasks
     */
  }
  else if ((new_ip ^ my_ip_addr) & sin_mask) /* new host not on subnet */
  {
    char buf[100];

    strcpy (buf, ", GW = ");
    strcat (buf, _inet_ntoa(NULL,new_ip));
    icmp_bogus (ip, ICMP_REDIRECT, buf);
    return;
  }

  msg = icmp_redirect_str[code];
  icmp_print (1, msg, 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, ICMP_REDIRECT, code, msg, &new_ip);
         break;
#endif
    case UDP_PROTO:
         if (do_redirect.udp)
            _udp_cancel (orig_ip, ICMP_REDIRECT, code, msg, &new_ip);
         break;

    case ICMP_PROTO:
         if (do_redirect.icmp)
         {
        /* _ip_recursion = TRUE; !! */
           _arp_register (new_ip, old_ip);
        /* _ip_recursion = FALSE; !! */
         }
         break;

    case IGMP_PROTO:
         if (do_redirect.igmp)
         {
        /* _ip_recursion = TRUE; !! */
           _arp_register (new_ip, old_ip);
        /* _ip_recursion = FALSE; !! */
         }
         break;
  }
}
Beispiel #4
0
//--------------------------------------------------------------
void ofShader::checkShaderInfoLog(GLuint shader, GLenum type, ofLogLevel logLevel) {
	GLsizei infoLength;
	glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLength);
	if (infoLength > 1) {
		GLchar* infoBuffer = new GLchar[infoLength];
		glGetShaderInfoLog(shader, infoLength, &infoLength, infoBuffer);
		ofLog(logLevel, "ofShader: %s shader reports:\n%s", nameForType(type).c_str(), infoBuffer);
		if (shaderSource.find(type) != shaderSource.end()) {
			// The following regexp should match shader compiler error messages by Nvidia and ATI.
			// Unfortunately, each vendor's driver formats error messages slightly different.
			std::regex nvidia_ati("^.*[(:]{1}(\\d+)[:)]{1}.*");
			std::regex intel("^[0-9]+:([0-9]+)\\([0-9]+\\):.*$");
			std::smatch matches;
			string infoString = (infoBuffer != nullptr) ? ofTrim(infoBuffer): "";
			if (std::regex_search(infoString, matches, intel) || std::regex_search(infoString, matches, nvidia_ati)){
				ofBuffer buf = shaderSource[type];
				ofBuffer::Line line = buf.getLines().begin();
				int  offendingLineNumber = ofToInt(matches[1]);
				ostringstream msg;
				msg << "ofShader: " + nameForType(type) + ", offending line " << offendingLineNumber << " :"<< endl;
				for(int i=0; line != buf.getLines().end(); line++, i++ ){
					string s = *line;
					if ( i >= offendingLineNumber -3 && i < offendingLineNumber + 2 ){
						msg << "\t" << setw(5) << (i+1) << "\t" << s << endl;
					}
				}
				ofLog(logLevel) << msg.str();
			}else{
				ofLog(logLevel) << shaderSource[type];
			}
		}
		delete [] infoBuffer;
	}
}
Beispiel #5
0
/*
 * igmp_report - send a IGMP Report packet
 *
 * int igmp_report (DWORD ip)
 * Where:
 *      ip is the IP address to report.
 *
 * Returns:
 *      0   if unable to send report
 *      1   report was sent successfully
 */
int igmp_report (DWORD ip)
{
    struct IGMP_PKT *pkt;
    IGMP_packet     *igmp;
    eth_address      ethaddr;

    /* get the ethernet addr of the destination
     */
    multi_to_eth ((DWORD)ALL_SYSTEMS, (BYTE*)&ethaddr);

    /* format the packet with the request's hardware address
     */
    pkt  = (struct IGMP_PKT*) _eth_formatpacket (ethaddr, IP_TYPE);
    igmp = &pkt->igmp;
    ip = intel (ip);

    /* fill in the igmp packet
     */
    igmp->type     = IGMP_REPORT;
    igmp->version  = IGMP_VERSION;
    igmp->mbz      = 0;
    igmp->address  = ip;
    igmp->checksum = 0;
    igmp->checksum = ~checksum (igmp,sizeof(*igmp));

    return IP_OUTPUT (&pkt->in, 0, ip, IGMP_PROTO,
                      0, 0, 0, (int)sizeof(*igmp), NULL);
}
Beispiel #6
0
/*
 * igmp_handler - handles the incoming IGMP packets
 *
 * void igmp_handler (in_Header *ip)
 * Where:
 *      ip    is the IP packet in question
 *
 * Returns: None
 *
 */
void igmp_handler (const in_Header *ip, BOOL broadcast)
{
    BYTE         i;
    DWORD        host;
    BOOL         found = 0;
    WORD         len   = in_GetHdrLen (ip);
    IGMP_packet *igmp  = (IGMP_packet*) ((BYTE*)ip + len);

    DEBUG_RX (NULL, ip);

    if (len < sizeof(*igmp))
    {
        STAT (igmpstats.igps_rcv_tooshort++);
        return;
    }

    if (checksum(igmp,sizeof(*igmp)) != 0xFFFF)
    {
        STAT (igmpstats.igps_rcv_badsum++);
        return;
    }

    host = intel (igmp->address);

    /* Determine whether this is a report or a query
     */
    switch (igmp->type)
    {
    case IGMP_QUERY:
        STAT (igmpstats.igps_rcv_queries++);
        for (i = 0; i < IPMULTI_SIZE; i++)
            if (_ipmulti[i].active             &&
                    _ipmulti[i].ina != ALL_SYSTEMS &&
                    _ipmulti[i].replytime == 0)
            {
                _ipmulti[i].replytime = set_timeout (Random(500,1000));
                found = 1;
            }
        if (!found && !broadcast)
            STAT (igmpstats.igps_rcv_badqueries++);
        break;

    case IGMP_REPORT:
        STAT (igmpstats.igps_rcv_reports++);
        for (i = 0; i < IPMULTI_SIZE; i++)
            if (_ipmulti[i].active      &&
                    _ipmulti[i].ina == host &&
                    host != ALL_SYSTEMS)
            {
                _ipmulti[i].replytime = 0;
                found = 1;
                STAT (igmpstats.igps_rcv_ourreports++);
                break;
            }
        if (!found && !broadcast)
            STAT (igmpstats.igps_rcv_badreports++);
        break;
    }
}
Beispiel #7
0
/*
 * resolve()
 * 	convert domain name -> address resolution.
 * 	returns 0 if name is unresolvable right now
 */
longword resolve_fn( char *name, sockfunct_t fn )	// S. Lawson
{
    longword ipaddr;
    // S. Lawson
#define DNSCACHESIZE 4			// cache up to 4 names
#define DNSCACHELENGTH 32		//   up to 32 characters
#define DNSCACHETIMEOUT 120             //     for up to 2 minutes
    static char DNScacheName[DNSCACHESIZE][DNSCACHELENGTH];
    static longword DNScacheIP[DNSCACHESIZE];
    static longword DNScacheTimeout[DNSCACHESIZE]={0,0,0,0};
    static char DNScacheNext=0;
    int DNScacheScan;

    if( !name ) return 0L;

    rip( name );			// S. Lawson - trim for cache scan
    if ( isaddr( name ))
	 return( aton( name ));

    // S. Lawson
    for (DNScacheScan=0 ; DNScacheScan<DNSCACHESIZE ; DNScacheScan++) {
       if (DNScacheTimeout[DNScacheScan]==0L) continue;
       if (chk_timeout(DNScacheTimeout[DNScacheScan])) {
	  DNScacheTimeout[DNScacheScan]=0L;
	  continue;
       }
       if(!strcmpi(DNScacheName[DNScacheScan],name))
	  return DNScacheIP[DNScacheScan];
    }

#ifdef NOTUSED	// S. Lawson
    if( do_ns_lookup(name, DTYPEA, typea_unpacker, &ipaddr) )
       return (intel(ipaddr));
    else return (0L);
#else	// S. Lawson
    if( do_ns_lookup(name, DTYPEA, typea_unpacker, &ipaddr, fn) ) {
       strncpy(DNScacheName[DNScacheNext], name, DNSCACHELENGTH);
       DNScacheName[DNScacheNext][DNSCACHELENGTH-1]='\0';
       DNScacheIP[DNScacheNext]=intel(ipaddr);
       DNScacheTimeout[DNScacheNext]=set_timeout(DNSCACHETIMEOUT);
       if (++DNScacheNext>=DNSCACHESIZE) DNScacheNext=0;
       return (intel(ipaddr));
    }
    return (0L);
#endif	// S. Lawson
}
Beispiel #8
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 #9
0
/**
 * Handle incoming RARP packets.
 */
BOOL _rarp_handler (const rarp_Header *rh, BOOL brdcast)
{
  SIO_TRACE (("_rarp_handler"));

  DEBUG_RX (NULL, rh);

  if (!brdcast && rh->opcode == RARP_REPLY && rh->protType == IP4_TYPE &&
      !memcmp(rh->dstEthAddr,_eth_addr,sizeof(mac_address)))
  {
    my_ip_addr = intel (rh->dstIPAddr);
    return (TRUE);
  }
  return (FALSE);
}
Beispiel #10
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 #11
0
void DccTransferRecv::sendAck()                   // slot
{
    //kdDebug() << "sendAck()" << endl;
    KIO::fileoffset_t pos = intel( m_transferringPosition );

    m_recvSocket->enableWrite( false );
    m_recvSocket->writeBlock( (char*)&pos, 4 );
    if ( m_transferringPosition == (KIO::fileoffset_t)m_fileSize )
    {
        kdDebug() << "DccTransferRecv::sendAck(): Sent final ACK." << endl;
        m_recvSocket->enableRead( false );
        disconnect( m_recvSocket, 0, 0, 0 );
        finishTransferLogger();
        m_writeCacheHandler->close();             // WriteCacheHandler will send the signal done()
    }
    else if ( m_transferringPosition > (KIO::fileoffset_t)m_fileSize )
    {
        kdDebug() << "DccTransferRecv::sendAck(): the remote host sent larger data than expected: " << QString::number( m_transferringPosition ) << endl;
        failed( i18n( "Transferring error" ) );
    }
}
Beispiel #12
0
static int ping_gateway (DWORD host, void *eth)
{
  struct ping_pkt  *pkt;
  struct icmp_echo *icmp;
  struct in_Header *ip;
  int    len;

  pkt  = (struct ping_pkt*) _eth_formatpacket (eth, IP4_TYPE);
  ip   = &pkt->in;
  icmp = &pkt->icmp;
  len  = sizeof (*icmp);
  icmp_id = (WORD) set_timeout (0);  /* "random" id */

  icmp->type       = ICMP_ECHO;
  icmp->code       = 0;
  icmp->index      = 1;
  icmp->identifier = icmp_id;
  icmp->sequence   = icmp_seq++;
  icmp->checksum   = 0;
  icmp->checksum   = ~CHECKSUM (icmp, len);

  return IP4_OUTPUT (ip, 0, intel(host), ICMP_PROTO, 1,
                     (BYTE)_default_tos, 0, len, NULL);
}
Beispiel #13
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 #14
0
/**
 * _eth_send() does the actual transmission once we are complete with
 * filling the buffer.  Do any last minute patches here, like fix the
 * size. Send to "loopback" device if it's IP and destination matches
 * loopback network (127.x.x.x.).
 *
 * Return length of network-layer packet (not length of link-layer
 * packet).
 */
int _eth_send (WORD len, const void *sock, const char *file, unsigned line)
{
#if defined(USE_DEBUG) || defined(USE_LOOPBACK)
  unsigned errline = 0;
#endif
  BOOL send_loopback_to_driver = FALSE;

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

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

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

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

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

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

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

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

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

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

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

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

debug_tx:

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

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

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

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

  /* Undo hack done in pppoe_mac_format()
   */
  if (proto == PPPOE_SESS_TYPE || _pktdevclass == PDCLASS_ETHER)
     _pkt_ip_ofs = sizeof(eth_Header);
  return (len);
}
Beispiel #15
0
DWORD ntohl (DWORD val) { return intel(val); }
Beispiel #16
0
DWORD htonl (DWORD val) { return intel(val); }
Beispiel #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;
  }
}
Beispiel #18
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);
}