Пример #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();
}
Пример #2
0
void* PfRingDevice::captureThreadMain(void *ptr)
{
	PfRingDevice* device = (PfRingDevice*)ptr;
	int coreId = device->getCurrentCoreId().Id;
	pfring* ring = NULL;

	LOG_DEBUG("Starting capture thread %d", coreId);

	ring = device->m_CoreConfiguration[coreId].Channel;

	if (ring == NULL)
	{
		LOG_ERROR("Couldn't find ring for core %d. Exiting capture thread", coreId);
		return (void*)NULL;
	}

	while (!device->m_StopThread)
	{
		// if buffer is NULL PF_RING avoids copy of the data
		uint8_t* buffer = NULL;
		uint32_t bufferLen = 0;

		// in multi-threaded mode flag PF_RING_REENTRANT is set, and this flag doesn't work with zero copy
		// so I need to allocate a buffer and set buffer to point to it
		if (device->m_ReentrantMode)
		{
			uint8_t tempBuffer[MAX_PACKET_SIZE];
			buffer = tempBuffer;
			bufferLen = MAX_PACKET_SIZE;
		}

		struct pfring_pkthdr pktHdr;
		int recvRes = pfring_recv(ring, &buffer, bufferLen, &pktHdr, 0);
		if (recvRes > 0)
		{
			// if caplen < len it means we don't have the whole packet. Treat this case as packet drop
			// TODO: add this packet to dropped packet stats
//			if (pktHdr.caplen != pktHdr.len)
//			{
//				LOG_ERROR("Packet dropped due to len != caplen");
//				continue;
//			}

			RawPacket rawPacket(buffer, pktHdr.caplen, pktHdr.ts, false);
			device->m_OnPacketsArriveCallback(&rawPacket, 1, coreId, device, device->m_OnPacketsArriveUserCookie);
		}
		else if (recvRes < 0)
		{
			LOG_ERROR("pfring_recv returned an error: [Err=%d]", recvRes);
		}
	}

	LOG_DEBUG("Exiting capture thread %d", coreId);
	return (void*)NULL;
}
Пример #3
0
void PcapLiveDevice::onPacketArrives(uint8_t *user, const struct pcap_pkthdr *pkthdr, const uint8_t *packet)
{
	PcapLiveDevice* pThis = (PcapLiveDevice*)user;
	if (pThis == NULL)
	{
		LOG_ERROR("Unable to extract PcapLiveDevice instance");
		return;
	}

	RawPacket rawPacket(packet, pkthdr->caplen, pkthdr->ts, false);

	if (pThis->m_cbOnPacketArrives != NULL)
		pThis->m_cbOnPacketArrives(&rawPacket, pThis, pThis->m_cbOnPacketArrivesUserCookie);
}
Пример #4
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();
}
Пример #5
0
////////////////////////////////////////////////////
// process the packets payload, decoding if necessary
void EQPacketStream::processPayload(uint8_t* data, size_t len)
{
  uint16_t opCode = *(uint16_t*)data;
  
  data += 2;
  len -= 2;
  
  if (opCode & FLAG_DECODE)
    decodePacket(data, len, opCode);
  else
  {
    emit rawPacket(data, len, m_dir, opCode);

    dispatchPacket(data, len, opCode, m_opcodeDB.find(opCode));
  }
}
Пример #6
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();
}
Пример #7
0
////////////////////////////////////////////////////
// decode, decrypt, and unroll packet
void EQPacketStream::decodePacket(uint8_t *data, size_t len, uint16_t opCode)
{
  emit rawPacket(data, len, m_dir, opCode);

  if (opCode & FLAG_CRYPTO || opCode & FLAG_COMP) 
  {
    data = decodeOpCode (data, &len, opCode);
    if (data == NULL)
      return;

    emit rawPacket(data, len, m_dir, opCode);
  }
  
  const EQPacketOPCode* opcodeEntry = 0;

  // this works, but could really use a cleanup - mvern
  while (len > 2) 
  {
    if (opCode & FLAG_COMBINED) 
    {
      bool repeatop = false;
      uint8_t *dptr = data;
      size_t left = len;
      int32_t count = 1;
      
      if (opCode & FLAG_IMPLICIT) 
      {
	opCode = opCode & ~FLAG_IMPLICIT;
	repeatop = true;
      }

#ifdef PACKET_DECODE_DIAG
      seqDebug("unrolling on %s: 0x%04x", EQStreamStr[m_streamid], opCode);
#endif
      opCode = opCode & ~FLAG_COMBINED;
      
      while (count > 0) 
      {
	uint16_t size = 0;

	opcodeEntry = m_opcodeDB.find(opCode);

	if (opcodeEntry)
	{
	  size = opcodeEntry->implicitLen();
#ifdef PACKET_DECODE_DIAG // ZBTEMP
	  seqDebug("opcode %04x implicitlen %d",
		  opCode, size);
#endif
	}
#ifdef PACKET_DECODE_DIAG
	else 
	  seqDebug("No opcodeEntry for %04x", opCode);
#endif 
	
	if (size == 0) 
	{ // Not an implicit length opcode
	  if (dptr[0] == 0xff) 
	  { // > 255 length
	    left--;
	    dptr++;
	    size = ntohs(*((uint16_t *)dptr));
	    left -= 2;
	    dptr += 2;
	  } 
	  else 
	  { // single octet length
	    size = dptr[0];
	    left--;
	    dptr++;
	  }
	}
#ifdef PACKET_DECODE_DIAG
	seqDebug ("size on %s: %d", EQStreamStr[m_streamid], size);
#endif
		
	if (size > left) 
	{
	  seqWarn("error on %s: size > left (size=%d, left=%d, opcode=0x%04x)", 
		     EQStreamStr[m_streamid], size, left, opCode);
	  return;
	}
	
#ifdef PACKET_DECODE_DIAG
	seqDebug("sending from %s: 0x%04x, %d", 
	       EQStreamStr[m_streamid], opCode, size);
#endif
	dispatchPacket(dptr, size, opCode, opcodeEntry);
	
	// next
	dptr += size;
	left -= size;
	
	count--;
	if (repeatop) 
	{
	  count = dptr[0];
	  dptr++;
	  left--;
	  repeatop = false;
#ifdef PACKET_DECODE_DIAG
	  seqDebug ("repeating %d times on %s",
		  count, EQStreamStr[m_streamid]);
#endif
	}
      }
	    
      if (left > 2) 
      {
	opCode = *((unsigned short *)dptr);
	dptr += 2;
	left -= 2;

#ifdef PACKET_DECODE_DIAG
	seqDebug("doing leftover from %s: 0x%04x, %d", 
	       EQStreamStr[m_streamid], opCode, left);
#endif
	if (opCode & FLAG_COMBINED)
	{
	  data = dptr;
	  len = left;
	  continue;
	} 
	else 
	{
#ifdef PACKET_DECODE_DIAG
	  seqDebug("sending from %s: 0x%04x, %d", 
		 EQStreamStr[m_streamid], opCode, size);
#endif
	  dispatchPacket(dptr, left, opCode, m_opcodeDB.find(opCode));
	}
      }

      return;
    }
    else
      break;
  }
  
#ifdef PACKET_DECODE_DIAG
  seqDebug ("sending from %s: 0x%04x, %d",
	  EQStreamStr[m_streamid], opCode, size);
#endif
  dispatchPacket(data, len, opCode, m_opcodeDB.find(opCode));
}