|
From: <cn...@us...> - 2024-06-28 00:12:03
|
Revision: 1477
http://sourceforge.net/p/seq/svn/1477
Author: cn187
Date: 2024-06-28 00:12:00 +0000 (Fri, 28 Jun 2024)
Log Message:
-----------
Rework capture filter and session detection logic
- reduce code duplication
- fix issues with session detection when an IP address isn't specified
- fix issues with session detection when specifying a MAC
- fix other related bugs
Modified Paths:
--------------
showeq/branches/cn187_devel/src/interface.cpp
showeq/branches/cn187_devel/src/packet.cpp
showeq/branches/cn187_devel/src/packet.h
showeq/branches/cn187_devel/src/packetcapture.cpp
showeq/branches/cn187_devel/src/packetstream.cpp
showeq/branches/cn187_devel/src/packetstream.h
Modified: showeq/branches/cn187_devel/src/interface.cpp
===================================================================
--- showeq/branches/cn187_devel/src/interface.cpp 2024-06-25 00:14:58 UTC (rev 1476)
+++ showeq/branches/cn187_devel/src/interface.cpp 2024-06-28 00:12:00 UTC (rev 1477)
@@ -5239,7 +5239,7 @@
maclst, 0, true, &ok);
if (ok)
{
- if (address.length() != 17)
+ if (address.length() != 17 && !address.isEmpty())
{
seqWarn("Invalid MAC Address (%s)! Ignoring!", address.toLatin1().data());
return;
Modified: showeq/branches/cn187_devel/src/packet.cpp
===================================================================
--- showeq/branches/cn187_devel/src/packet.cpp 2024-06-25 00:14:58 UTC (rev 1476)
+++ showeq/branches/cn187_devel/src/packet.cpp 2024-06-28 00:12:00 UTC (rev 1477)
@@ -181,54 +181,38 @@
// no client/server ports yet
m_clientPort = 0;
m_serverPort = 0;
-
- struct hostent *he;
- struct in_addr ia;
+
if (m_ip.isEmpty() && m_mac.isEmpty())
- seqFatal("No address specified");
-
- if (!m_ip.isEmpty())
{
- /* Substitute "special" IP which is interpreted
- to set up a different filter for picking up new sessions */
-
- if (m_ip == "auto")
- inet_aton (AUTOMATIC_CLIENT_IP, &ia);
- else if (inet_aton (m_ip.toLatin1().data(), &ia) == 0)
- {
- he = gethostbyname(m_ip.toLatin1().data());
- if (!he)
- seqFatal("Invalid address; %s", m_ip.toLatin1().data());
-
- memcpy (&ia, he->h_addr_list[0], he->h_length);
- }
- m_client_addr = ia.s_addr;
- m_ip = inet_ntoa(ia);
-
- if (m_ip == AUTOMATIC_CLIENT_IP)
- {
- m_detectingClient = true;
- seqInfo("Listening for first client seen.");
- }
- else
- {
- m_detectingClient = false;
- seqInfo("Listening for client: %s", m_ip.toLatin1().data());
- }
+ seqInfo("No address specified. Defaulting to client auto-detect");
+ m_ip = AUTOMATIC_CLIENT_IP;
}
+ validateIP();
+
if (m_playbackPackets == PLAYBACK_OFF)
{
// create the pcap object and initialize, either with MAC or IP
m_packetCapture = new PacketCaptureThread();
if (m_mac.length() == 17)
+ {
+ seqInfo("Listening for client MAC: %s", m_mac.toLatin1().data());
+
m_packetCapture->start(m_device.toLatin1().data(),
m_mac.toLatin1().data(),
m_realtime, MAC_ADDRESS_TYPE );
+ }
else
+ {
+ if (m_detectingClient)
+ seqInfo("Listening for next client seen. (you must zone for this to work!)");
+ else
+ seqInfo("Listening for client: %s", m_ip.toLatin1().data());
+
m_packetCapture->start(m_device.toLatin1().data(),
m_ip.toLatin1().data(),
m_realtime, IP_ADDRESS_TYPE );
+ }
emit filterChanged();
}
else if (m_playbackPackets == PLAYBACK_FORMAT_TCPDUMP)
@@ -303,6 +287,43 @@
}
}
+//helper function to verify specified IP is a valid IP or hostname, and/or
+//to set up auto detection.
+void EQPacket::validateIP()
+{
+ struct in_addr ia;
+ struct hostent *he;
+
+ if (m_ip.isEmpty() || m_ip == AUTOMATIC_CLIENT_IP)
+ {
+ /* Substitute "special" IP which is interpreted
+ to set up a different filter for picking up new sessions */
+ inet_aton (AUTOMATIC_CLIENT_IP, &ia);
+ }
+ else if (inet_aton (m_ip.toLatin1().data(), &ia) == 0)
+ {
+ he = gethostbyname(m_ip.toLatin1().data());
+ if (he)
+ {
+ memcpy (&ia, he->h_addr_list[0], he->h_length);
+ }
+ else
+ {
+ // If the IP or host is invalid, default to auto-detect, rather
+ // than immediately exiting (the previous behavior)
+ seqWarn("Invalid address or hostname: %s", m_ip.toLatin1().data());
+ seqWarn("Defaulting to client auto-detect");
+ m_ip = AUTOMATIC_CLIENT_IP;
+ inet_aton (AUTOMATIC_CLIENT_IP, &ia);
+ }
+ }
+ m_client_addr = ia.s_addr;
+ m_ip = inet_ntoa(ia);
+
+ m_detectingClient = (m_ip == AUTOMATIC_CLIENT_IP);
+
+}
+
////////////////////////////////////////////////////
// Destructor
EQPacket::~EQPacket()
@@ -557,9 +578,9 @@
this,
SIGNAL(sessionTrackingChanged(uint8_t)));
connect(stream,
- SIGNAL(lockOnClient(in_port_t, in_port_t)),
+ SIGNAL(lockOnClient(in_port_t, in_port_t, in_addr_t)),
this,
- SLOT(lockOnClient(in_port_t, in_port_t)));
+ SLOT(lockOnClient(in_port_t, in_port_t, in_addr_t)));
connect(stream,
SIGNAL(closing(uint32_t, EQStreamID)),
this,
@@ -697,23 +718,32 @@
// If we just closed the zone server session, unlatch the client port
if (streamId == zone2client || streamId == client2zone)
{
- m_clientPort = 0;
- m_serverPort = 0;
+ unlatchClientPort();
- emit clientPortLatched(m_clientPort);
-
seqInfo("EQPacket: SessionDisconnect detected, awaiting next zone session, pcap filter: EQ Client %s",
- m_ip.toLatin1().data());
+ (m_ip == AUTOMATIC_CLIENT_IP) ? "auto-detect" : m_ip.toLatin1().data());
}
}
+// Unlatch a locked-on client port, so the next client is detected correctly
+void EQPacket::unlatchClientPort()
+{
+ m_clientPort = 0;
+ m_serverPort = 0;
+ emit clientPortLatched(m_clientPort);
+}
+
+
////////////////////////////////////////////////////
// Locks onto a specific client port (for session tracking)
-void EQPacket::lockOnClient(in_port_t serverPort, in_port_t clientPort)
+void EQPacket::lockOnClient(in_port_t serverPort, in_port_t clientPort, in_addr_t clientAddr)
{
m_serverPort = serverPort;
m_clientPort = clientPort;
+ m_client_addr = clientAddr;
+ in_addr ia = inet_makeaddr(m_client_addr, m_client_addr);
+
if (m_playbackPackets == PLAYBACK_OFF ||
m_playbackPackets == PLAYBACK_FORMAT_TCPDUMP)
{
@@ -746,7 +776,7 @@
else
{
seqInfo("EQPacket: SessionRequest detected, pcap filter: EQ Client %s, Client port %d. Server port %d",
- m_ip.toLatin1().data(), m_clientPort, m_serverPort);
+ inet_ntoa(ia), m_clientPort, m_serverPort);
}
emit clientPortLatched(m_clientPort);
@@ -921,14 +951,14 @@
void EQPacket::monitorIPClient(const QString& ip)
{
m_ip = ip;
- struct in_addr ia;
- inet_aton (m_ip.toLatin1().data(), &ia);
- m_client_addr = ia.s_addr;
+
+ validateIP();
+
emit clientChanged(m_client_addr);
resetEQPacket();
- seqInfo("Listening for IP client: %s", m_ip.toLatin1().data());
+ seqInfo("Listening for IP client: %s", (m_ip == AUTOMATIC_CLIENT_IP) ? "auto-detect" : m_ip.toLatin1().data());
if (m_playbackPackets == PLAYBACK_OFF ||
m_playbackPackets == PLAYBACK_FORMAT_TCPDUMP)
{
@@ -945,24 +975,32 @@
void EQPacket::monitorMACClient(const QString& mac)
{
m_mac = mac;
- m_detectingClient = true;
struct in_addr ia;
inet_aton (AUTOMATIC_CLIENT_IP, &ia);
+ m_detectingClient = true;
m_client_addr = ia.s_addr;
emit clientChanged(m_client_addr);
resetEQPacket();
- seqInfo("Listening for MAC client: %s", m_mac.toLatin1().data());
+ if (!m_mac.isEmpty() && m_mac.length() == 17)
+ {
+ seqInfo("Listening for MAC client: %s", m_mac.toLatin1().data());
- if (m_playbackPackets == PLAYBACK_OFF ||
- m_playbackPackets == PLAYBACK_FORMAT_TCPDUMP)
+ if (m_playbackPackets == PLAYBACK_OFF ||
+ m_playbackPackets == PLAYBACK_FORMAT_TCPDUMP)
+ {
+ m_packetCapture->setFilter(m_device.toLatin1().data(),
+ m_mac.toLatin1().data(),
+ m_realtime,
+ MAC_ADDRESS_TYPE, 0, 0);
+ emit filterChanged();
+ }
+ }
+ else
{
- m_packetCapture->setFilter(m_device.toLatin1().data(),
- m_ip.toLatin1().data(),
- m_realtime,
- IP_ADDRESS_TYPE, 0, 0);
- emit filterChanged();
+ seqWarn("Invalid MAC specified. Defaulting to auto-detect of next client.");
+ monitorNextClient();
}
}
@@ -1005,50 +1043,31 @@
// stop the current packet capture
m_packetCapture->stop();
- // setup for capture on new device
- if (!m_ip.isEmpty())
- {
- struct hostent *he;
- struct in_addr ia;
+ validateIP();
- /* Substitute "special" IP which is interpreted
- to set up a different filter for picking up new sessions */
-
- if (m_ip == "auto")
- inet_aton (AUTOMATIC_CLIENT_IP, &ia);
- else if (inet_aton (m_ip.toLatin1().data(), &ia) == 0)
- {
- he = gethostbyname(m_ip.toLatin1().data());
- if (!he)
- seqFatal("Invalid address; %s", m_ip.toLatin1().data());
-
- memcpy (&ia, he->h_addr_list[0], he->h_length);
- }
- m_client_addr = ia.s_addr;
- m_ip = inet_ntoa(ia);
-
- if (m_ip == AUTOMATIC_CLIENT_IP)
- {
- m_detectingClient = true;
- seqInfo("Listening for first client seen.");
- }
- else
- {
- m_detectingClient = false;
- seqInfo("Listening for client: %s", m_ip.toLatin1().data());
- }
- }
-
resetEQPacket();
// restart packet capture
if (m_mac.length() == 17)
+ {
+ seqInfo("Listening for client MAC: %s", m_mac.toLatin1().data());
+
m_packetCapture->start(m_device.toLatin1().data(),
m_mac.toLatin1().data(),
m_realtime, MAC_ADDRESS_TYPE );
+ }
else
- m_packetCapture->start(m_device.toLatin1().data(), m_ip.toLatin1().data(),
- m_realtime, IP_ADDRESS_TYPE );
+ {
+ if (m_detectingClient)
+ seqInfo("Listening for next client seen. (you must zone for this to work!)");
+ else
+ seqInfo("Listening for client: %s", m_ip.toLatin1().data());
+
+ m_packetCapture->start(m_device.toLatin1().data(),
+ m_ip.toLatin1().data(),
+ m_realtime, IP_ADDRESS_TYPE );
+ }
+
emit filterChanged();
}
@@ -1127,10 +1146,7 @@
m_zone2ClientStream->reset();
m_zone2ClientStream->setSessionTracking(m_session_tracking);
- m_clientPort = 0;
- m_serverPort = 0;
-
- emit clientPortLatched(m_clientPort);
+ unlatchClientPort();
}
///////////////////////////////////////////
Modified: showeq/branches/cn187_devel/src/packet.h
===================================================================
--- showeq/branches/cn187_devel/src/packet.h 2024-06-25 00:14:58 UTC (rev 1476)
+++ showeq/branches/cn187_devel/src/packet.h 2024-06-28 00:12:00 UTC (rev 1477)
@@ -121,7 +121,8 @@
protected slots:
void closeStream(uint32_t sessionId, EQStreamID streamId);
- void lockOnClient(in_port_t serverPort, in_port_t clientPort);
+ void unlatchClientPort();
+ void lockOnClient(in_port_t serverPort, in_port_t clientPort, in_addr_t clientAddr);
signals:
// used for net_stats display
@@ -158,6 +159,7 @@
bool unknown);
private:
+ void validateIP();
PacketCaptureProviderThread* m_packetCapture;
VPacket* m_vPacket;
Modified: showeq/branches/cn187_devel/src/packetcapture.cpp
===================================================================
--- showeq/branches/cn187_devel/src/packetcapture.cpp 2024-06-25 00:14:58 UTC (rev 1476)
+++ showeq/branches/cn187_devel/src/packetcapture.cpp 2024-06-28 00:12:00 UTC (rev 1477)
@@ -376,13 +376,13 @@
if (address_type == IP_ADDRESS_TYPE)
{
- if (hostname && strcmp(hostname, AUTOMATIC_CLIENT_IP) != 0)
+ if (hostname && strlen(hostname) && strcmp(hostname, AUTOMATIC_CLIENT_IP) != 0)
// host was specified/detected
pfb += sprintf(pfb, " and host %s", hostname);
}
else if (address_type == MAC_ADDRESS_TYPE)
{
- if (hostname && strcmp(hostname, AUTOMATIC_CLIENT_IP) != 0)
+ if (hostname && strlen(hostname) && strcmp(hostname, AUTOMATIC_CLIENT_IP) != 0)
// mac was specified
pfb += sprintf(pfb, " and ether host %s", hostname);
}
Modified: showeq/branches/cn187_devel/src/packetstream.cpp
===================================================================
--- showeq/branches/cn187_devel/src/packetstream.cpp 2024-06-25 00:14:58 UTC (rev 1476)
+++ showeq/branches/cn187_devel/src/packetstream.cpp 2024-06-28 00:12:00 UTC (rev 1477)
@@ -92,6 +92,7 @@
m_sessionId(0),
m_sessionKey(0),
m_sessionClientPort(0),
+ m_sessionClientIP(0),
m_maxLength(0),
m_decodeKey(0),
m_validKey(true)
@@ -196,6 +197,7 @@
m_arqSeqExp = 0;
m_arqSeqFound = false;
m_sessionClientPort = 0;
+ m_sessionClientIP = 0;
m_sessionId = 0;
m_sessionKey = 0;
}
@@ -543,9 +545,11 @@
// 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 &&
+ if (m_sessionClientPort != 0 && m_sessionClientIP != 0 &&
((dir() == DIR_Server && m_sessionClientPort != packet.getDestPort()) ||
- (dir() == DIR_Client && m_sessionClientPort != packet.getSourcePort())))
+ (dir() == DIR_Client && m_sessionClientPort != packet.getSourcePort()) ||
+ (dir() == DIR_Server && m_sessionClientIP != packet.getIPv4DestN()) ||
+ (dir() == DIR_Client && m_sessionClientIP != packet.getIPv4SourceN())))
{
#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.",
@@ -1038,6 +1042,7 @@
// later. SessionRequest should always be an outer protocol packet
// so we can cast it to EQUDPIPPacketFormat to get the ip headers.
m_sessionClientPort = ((EQUDPIPPacketFormat&) packet).getSourcePort();
+ m_sessionClientIP = ((EQUDPIPPacketFormat&) packet).getIPv4SourceN();
}
}
break;
@@ -1132,6 +1137,7 @@
// later. SessionRequest should always be an outer protocol packet
// so we can cast it to EQUDPIPPacketFormat to get the ip headers.
m_sessionClientPort = ((EQUDPIPPacketFormat&) packet).getDestPort();
+ m_sessionClientIP = ((EQUDPIPPacketFormat&) packet).getIPv4DestN();
// If this is the world server talking to us, reset session tracking if
// it is on so we unlatch the client in case of getting kicked.
@@ -1149,8 +1155,9 @@
// headers!
m_session_tracking_enabled = 2;
- emit lockOnClient(((EQUDPIPPacketFormat&) packet).getSourcePort(),
- ((EQUDPIPPacketFormat&) packet).getDestPort());
+ emit lockOnClient(((EQUDPIPPacketFormat&) packet).getSourcePort(),
+ ((EQUDPIPPacketFormat&) packet).getDestPort(),
+ ((EQUDPIPPacketFormat&) packet).getIPv4DestN());
emit sessionTrackingChanged(m_session_tracking_enabled);
}
}
@@ -1200,6 +1207,7 @@
emit sessionTrackingChanged(m_session_tracking_enabled);
m_sessionClientPort = 0;
+ m_sessionClientIP = 0;
}
emit closing(m_sessionId, m_streamid);
Modified: showeq/branches/cn187_devel/src/packetstream.h
===================================================================
--- showeq/branches/cn187_devel/src/packetstream.h 2024-06-25 00:14:58 UTC (rev 1476)
+++ showeq/branches/cn187_devel/src/packetstream.h 2024-06-28 00:12:00 UTC (rev 1477)
@@ -112,7 +112,7 @@
// this signals a change in the session tracking state
void sessionTrackingChanged(uint8_t);
- void lockOnClient(in_port_t serverPort, in_port_t clientPort);
+ void lockOnClient(in_port_t serverPort, in_port_t clientPort, in_addr_t clientAddr);
// Signal a new session key being received
void sessionKey(uint32_t sessionId, EQStreamID streadid, uint32_t sessionKey);
@@ -155,6 +155,7 @@
uint32_t m_sessionId;
uint32_t m_sessionKey;
in_port_t m_sessionClientPort;
+ in_addr_t m_sessionClientIP;
uint32_t m_maxLength;
// encryption
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|