Ejemplo n.º 1
0
////////////////////////////////////////////////////
// handle a new packet on the stream
void EQPacketStream::handlePacket(EQUDPIPPacketFormat& packet)
{
  emit numPacket(++m_packetCount, (int)m_streamid);

  // Only accept packets if we've been initialized unless they are
  // initialization packets!
  if (packet.getNetOpCode() != OP_SessionRequest &&
      packet.getNetOpCode() != OP_SessionResponse &&
      ! m_sessionKey)
  {
#if (defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1)) || defined(PACKET_SESSION_DIAG)
    seqDebug("discarding packet %s:%d ==>%s:%d netopcode=%04x size=%d. Session not initialized. Need to zone to start picking up packets. Session tracking %s.",
      (const char*)packet.getIPv4SourceA(), packet.getSourcePort(),
      (const char*)packet.getIPv4DestA(), packet.getDestPort(),
      packet.getNetOpCode(), packet.payloadLength(),
        (m_session_tracking_enabled == 2 ? "locked on" : 
          (m_session_tracking_enabled == 1 ? "enabled" : "disabled")));
#endif
    return;
  }

  emit rawPacket(packet.payload(), packet.payloadLength(), m_dir,
    packet.getNetOpCode());

  processPacket(packet, false); // false = isn't subpacket

  // if the cache isn't empty, then process it.
  if (!m_cache.empty()) 
    processCache();
}
Ejemplo n.º 2
0
EQUDPIPPacketFormat::EQUDPIPPacketFormat(EQUDPIPPacketFormat& packet,
					 bool copy)
{
  // note whether or not this object ownw the memory
  m_ownCopy = copy;
  m_sessionKey = packet.getSessionKey();

  if (copy)
  {
    // allocate our own copy
    uint8_t* ipdata = new uint8_t[packet.m_dataLength];

    // copy the data into the copy
    memcpy((void*)ipdata, (void*)packet.m_ip, packet.m_dataLength);

    // initialize the object
    init(ipdata);
  }
  else
  {
    // just copy over the other objects data
    m_dataLength = packet.m_dataLength;
    m_ip = packet.m_ip;
    m_udp = packet.m_udp;
  }
}
Ejemplo n.º 3
0
////////////////////////////////////////////////////
// handle a new packet on the stream
void EQPacketStream::handlePacket(EQUDPIPPacketFormat& packet)
{
  emit numPacket(++m_packetCount, (int)m_streamid);

  // Packet is ours now. Logging needs to know this later on.
  packet.setSessionKey(getSessionKey());

  // Only accept packets if we've been initialized unless they are
  // initialization packets!
  if (packet.getNetOpCode() != OP_SessionRequest &&
      packet.getNetOpCode() != OP_SessionResponse &&
      ! m_sessionKey)
  {
#if (defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1)) || (defined(PACKET_SESSION_DIAG) && PACKET_SESSION_DIAG > 1)
    seqDebug("discarding packet %s:%d ==>%s:%d netopcode=%04x size=%d. Session not initialized. Need to zone to start picking up packets. Session tracking %s.",
      (const char*)packet.getIPv4SourceA(), packet.getSourcePort(),
      (const char*)packet.getIPv4DestA(), packet.getDestPort(),
      packet.getNetOpCode(), packet.payloadLength(),
        (m_session_tracking_enabled == 2 ? "locked on" : 
          (m_session_tracking_enabled == 1 ? "enabled" : "disabled")));
#endif
    return;
  }

  // Only accept packets that correspond to our latched client port, if
  // it is set. This helps filter out multiple sessions on the same physical
  // host when two eq clients zone at the same time. The first one will win.
  if (m_sessionClientPort != 0 &&
      ((dir() == DIR_Server && m_sessionClientPort != packet.getDestPort()) ||
       (dir() == DIR_Client && m_sessionClientPort != packet.getSourcePort())))
  {
#if (defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1)) || (defined(PACKET_SESSION_DIAG) && PACKET_SESSION_DIAG > 1)
    seqDebug("discarding packet %s:%d ==>%s:%d netopcode=%04x size=%d. Multiple sessions on the same box? Ignoring all but one of them. Latched client port %d. Session tracking %s.",
      (const char*)packet.getIPv4SourceA(), packet.getSourcePort(),
      (const char*)packet.getIPv4DestA(), packet.getDestPort(),
      packet.getNetOpCode(), packet.payloadLength(),
      m_sessionClientPort,
        (m_session_tracking_enabled == 2 ? "locked on" :
          (m_session_tracking_enabled == 1 ? "enabled" : "disabled")));
#endif
    return;
  }

  // Only accept packets that pass the EQ protocol-level CRC check. This helps
  // weed out non-EQ packets that we might see.
#ifdef APPLY_CRC_CHECK
  if (packet.hasCRC())
  {
    uint16_t calcedCRC = calculateCRC(packet);

    if (calcedCRC != packet.crc())
    {
      seqWarn("INVALID PACKET: Bad CRC [%s:%d -> %s:%d] netOp %04x seq %04x len %d crc (%04x != %04x)",
         (const char*)packet.getIPv4SourceA(), packet.getSourcePort(),
         (const char*)packet.getIPv4DestA(), packet.getDestPort(),
         packet.getNetOpCode(), packet.arqSeq(), packet.getUDPPayloadLength(),
         packet.crc(), calcedCRC);
      return;
    }
  }
#endif /* APPLY_CRC_CHECK */

  // Decode the packet first
  if (! packet.decode(m_maxLength))
  {
    seqWarn("Packet decode failed for stream %s (%d), op %04x, flags %02x packet dropped.",
      EQStreamStr[m_streamid], m_streamid, packet.getNetOpCode(),
      packet.getFlags());
    return;
  }
#ifdef PACKET_DECODE_DIAG
  else if (packet.hasFlags())
  {
    seqDebug("Successful decode for stream %s (%d), op %04x, flags %02x.",
        EQStreamStr[m_streamid], m_streamid, packet.getNetOpCode(),
        packet.getFlags());
  }
#endif

  // Raw packet
  emit rawPacket(packet.rawPayload(), packet.rawPayloadLength(), m_dir, 
    packet.getNetOpCode());

  processPacket(packet, false); // false = isn't subpacket

  // if the cache isn't empty, then process it.
  if (!m_cache.empty()) 
    processCache();
}
Ejemplo n.º 4
0
void EQPacket::dispatchPacket(EQUDPIPPacketFormat& packet)
{
  // Detect client by world server port traffic...
  if (m_detectingClient && packet.getSourcePort() == WorldServerGeneralPort)
  {
    m_ip = packet.getIPv4DestA();
    m_client_addr = packet.getIPv4DestN();
    m_detectingClient = false;
    emit clientChanged(m_client_addr);
    seqInfo("Client Detected: %s", (const char*)m_ip);
  }
  else if (m_detectingClient && packet.getDestPort() == WorldServerGeneralPort)
  {
    m_ip = packet.getIPv4SourceA();
    m_client_addr = packet.getIPv4SourceN();
    m_detectingClient = false;
    emit clientChanged(m_client_addr);
    seqInfo("Client Detected: %s", (const char*)m_ip);
  }

  // Dispatch based on known streams
  if ((packet.getDestPort() == ChatServerPort) ||
      (packet.getSourcePort() == ChatServerPort))
  {
    // Drop chat server traffic
    return;
  }
  else if ((packet.getDestPort() == WorldServerChatPort) ||
      (packet.getSourcePort() == WorldServerChatPort))
  {
    // Drop cross-server chat traffic
    return;
  }
  else if ((packet.getDestPort() == WorldServerChat2Port) ||
      (packet.getSourcePort() == WorldServerChat2Port))
  {
    // Drop email and cross-game chat traffic
    return;
  }
  else if (((packet.getDestPort() >= LoginServerMinPort) &&
      (packet.getDestPort() <= LoginServerMaxPort)) ||
      (packet.getSourcePort() >= LoginServerMinPort) &&
      (packet.getSourcePort() <= LoginServerMaxPort))
  {
    // Drop login server traffic
    return;
  }
  else if (packet.getDestPort() == WorldServerGeneralPort ||
      packet.getSourcePort() == WorldServerGeneralPort)
  {
    // World server traffic. Dispatch it.
    if (packet.getIPv4SourceN() == m_client_addr)
    {
      m_client2WorldStream->handlePacket(packet);
    }
    else
    {
      m_world2ClientStream->handlePacket(packet);
    }
  }
  else
  {
    // Anything else we assume is zone server traffic.
    if (packet.getIPv4SourceN() == m_client_addr)
    {
      m_client2ZoneStream->handlePacket(packet);
    }
    else
    {
      m_zone2ClientStream->handlePacket(packet);
    }
  }
} /* end dispatchPacket() */
Ejemplo n.º 5
0
////////////////////////////////////////////////////
// handle a new packet on the stream
void EQPacketStream::handlePacket(EQUDPIPPacketFormat& packet)
{
  emit numPacket(++m_packetCount, (int)m_streamid);

  if (!packet.isARQ()) // process packets that don't have an arq sequence
  { 
    // we only handle packets with opcodes
    if (packet.payloadLength() < 2)
      return;
    
    // process the packets payload immediately
    processPayload(packet.payload(), packet.payloadLength());
  }
  else if (packet.isARQ()) // process ARQ sequences
  {
     uint16_t arqSeq = packet.arq();
     emit seqReceive(arqSeq, (int)m_streamid);
      
     /* this conditions should only be met once per zone/world, New Sequence */
     if (packet.isSEQStart() && !packet.isClosingLo() && 
	 (m_session_tracking_enabled < 2))
     {
#ifdef PACKET_PROCESS_DIAG
       seqDebug("EQPacket: SEQStart found, setting arq seq, %04x  stream %s",
	      arqSeq, EQStreamStr[m_streamid]);
#endif

       initDecode();
       
       // hey, a SEQStart, use it's packet to set ARQ
       m_arqSeqExp = arqSeq;
       m_arqSeqFound = true;
       emit seqExpect(m_arqSeqExp, (int)m_streamid);
       
       if ((m_streamid == zone2client) && m_session_tracking_enabled)
       {
	 m_session_tracking_enabled = 2;
	 
	 emit lockOnClient(packet.getSourcePort(),
			   packet.getDestPort());
	 
	 // notify that the client port has been latched
	 emit sessionTrackingChanged(m_session_tracking_enabled);
       }
     }
     else if (!m_arqSeqFound && m_session_tracking_enabled == 0 &&
              !packet.isClosingHi() && !packet.isClosingLo() && 
	      (m_streamid == zone2client))
     {
#ifdef PACKET_PROCESS_DIAG
       seqDebug("SEQ: new sequence found, setting arq seq, %04x  stream %s",
	      arqSeq, EQStreamStr[m_streamid]);
#endif
       m_arqSeqExp = arqSeq;
       m_arqSeqFound = true;
       emit seqExpect(m_arqSeqExp, (int)m_streamid);
     }
     // is this the currently expected sequence, if so, do something with it.
     if (m_arqSeqExp == arqSeq)
     {
       m_arqSeqExp = arqSeq + 1;
       emit seqExpect(m_arqSeqExp, (int)m_streamid);
       
#ifdef PACKET_PROCESS_DIAG
       seqDebug("SEQ: Found next arq in data stream %s, incrementing arq seq, %04x", 
	      EQStreamStr[m_streamid], arqSeq);
#endif

       if (!packet.isASQ() && !packet.isFragment() && !packet.isClosingHi())
       {
	 // seems to be a sort of ping from client to server, has ARQ
	 // but no ASQ, Flags look like 0x0201 (network byte order)
#ifdef PACKET_PROCESS_DIAG
	 seqDebug("SEQ: ARQ without ASQ from stream %s arq 0x%04x",
		EQStreamStr[m_streamid], arqSeq);
#endif
       }
       // since the servers do not care about client closing sequences, we won't either
       // Hey clients have rights too, or not! 
       else if (packet.isClosingHi() && packet.isClosingLo() && 
		(m_streamid == zone2client))
       {
	 if (m_session_tracking_enabled)
	   m_session_tracking_enabled = 1; 
	 
	 emit closing();
	 
	 return;
       } // if the packet is a fragment do appropriate processing
       else if (packet.isFragment())
	 processFragment(packet);
       else if (packet.payloadLength() >= 2) // has to have an opcode
	 processPayload(packet.payload(), packet.payloadLength());
     } // it's a packet from the future, add it to the cache
     else if ( ( (arqSeq > m_arqSeqExp) && 
                 (arqSeq < (uint32_t(m_arqSeqExp + arqSeqWrapCutoff))) ) || 
               (arqSeq < (int32_t(m_arqSeqExp) - arqSeqWrapCutoff)) ) 
     {
#ifdef PACKET_PROCESS_DIAG
       seqDebug("SEQ: out of order arq %04x stream %s, sending to cache, %04d",
	      arqSeq, EQStreamStr[m_streamid], m_cache.size());
#endif
       
       setCache(arqSeq, packet);
     }
     
     // if the cache isn't empty, then check for the expected ARQ sequence
     if (!m_cache.empty()) 
       processCache();
  } /* end ARQ processing */
}
Ejemplo n.º 6
0
////////////////////////////////////////////////////
// handle a new packet on the stream
void EQPacketStream::handlePacket(EQUDPIPPacketFormat& packet)
{
  emit numPacket(++m_packetCount, (int)m_streamid);

  // Only accept packets if we've been initialized unless they are
  // initialization packets!
  if (packet.getNetOpCode() != OP_SessionRequest &&
      packet.getNetOpCode() != OP_SessionResponse &&
      ! m_sessionKey)
  {
#if (defined(PACKET_PROCESS_DIAG) && (PACKET_PROCESS_DIAG > 1)) || (defined(PACKET_SESSION_DIAG) && PACKET_SESSION_DIAG > 1)
    seqDebug("discarding packet %s:%d ==>%s:%d netopcode=%04x size=%d. Session not initialized. Need to zone to start picking up packets. Session tracking %s.",
      (const char*)packet.getIPv4SourceA(), packet.getSourcePort(),
      (const char*)packet.getIPv4DestA(), packet.getDestPort(),
      packet.getNetOpCode(), packet.payloadLength(),
        (m_session_tracking_enabled == 2 ? "locked on" : 
          (m_session_tracking_enabled == 1 ? "enabled" : "disabled")));
#endif
    return;
  }

  // Decode the packet first
  if (! packet.decode(m_maxLength))
  {
    seqWarn("Packet decode failed for stream %s (%d), op %04x, flags %02x packet dropped.",
      EQStreamStr[m_streamid], m_streamid, packet.getNetOpCode(),
      packet.getFlags());
    return;
  }
#ifdef PACKET_DECODE_DIAG
  else if (packet.hasFlags())
  {
    seqDebug("Successful decode for stream %s (%d), op %04x, flags %02x.",
        EQStreamStr[m_streamid], m_streamid, packet.getNetOpCode(),
        packet.getFlags());
  }
#endif

  // Raw packet
  emit rawPacket(packet.rawPayload(), packet.rawPayloadLength(), m_dir, 
    packet.getNetOpCode());

  processPacket(packet, false); // false = isn't subpacket

  // if the cache isn't empty, then process it.
  if (!m_cache.empty()) 
    processCache();
}