Fix ping requestId and sequence number endiness from and to the network

This commit is contained in:
Simon Stürz 2022-06-29 12:25:09 +02:00
parent 0d20cf7816
commit c398f7ab2f
2 changed files with 27 additions and 26 deletions

View File

@ -180,11 +180,10 @@ void Ping::performPing(PingReply *reply)
memset(&requestPacket, 0, sizeof(requestPacket)); memset(&requestPacket, 0, sizeof(requestPacket));
requestPacket.icmpHeadr.type = ICMP_ECHO; requestPacket.icmpHeadr.type = ICMP_ECHO;
if (reply->requestId() == 0) { if (reply->requestId() == 0) {
requestPacket.icmpHeadr.un.echo.id = calculateRequestId(); reply->m_requestId = calculateRequestId();
} else {
requestPacket.icmpHeadr.un.echo.id = reply->requestId();
} }
requestPacket.icmpHeadr.un.echo.sequence = htons(reply->m_sequenceNumber++); requestPacket.icmpHeadr.un.echo.id = htons(reply->requestId());
requestPacket.icmpHeadr.un.echo.sequence = htons(reply->sequenceNumber());
// Write the ICMP payload // Write the ICMP payload
memset(&requestPacket.icmpPayload, ' ', sizeof(requestPacket.icmpPayload)); memset(&requestPacket.icmpPayload, ' ', sizeof(requestPacket.icmpPayload));
@ -199,13 +198,9 @@ void Ping::performPing(PingReply *reply)
qCWarning(dcPing()) << "Failed to get start time for ping measurement" << strerror(errno); qCWarning(dcPing()) << "Failed to get start time for ping measurement" << strerror(errno);
} }
reply->m_requestId = requestPacket.icmpHeadr.un.echo.id;
reply->m_targetHostAddress = targetHostAddress;
reply->m_sequenceNumber = requestPacket.icmpHeadr.un.echo.sequence;
qCDebug(dcPingTraffic()) << "Send ICMP echo request" << reply->targetHostAddress().toString() << ICMP_PACKET_SIZE << "[Bytes]" qCDebug(dcPingTraffic()) << "Send ICMP echo request" << reply->targetHostAddress().toString() << ICMP_PACKET_SIZE << "[Bytes]"
<< "ID:" << QString("0x%1").arg(requestPacket.icmpHeadr.un.echo.id, 4, 16, QChar('0')) << "ID:" << QString("0x%1").arg(reply->requestId(), 4, 16, QChar('0'))
<< "Sequence:" << htons(requestPacket.icmpHeadr.un.echo.sequence); << "Sequence:" << reply->sequenceNumber();
// Send packet to the target ip // Send packet to the target ip
int bytesSent = sendto(m_socketDescriptor, &requestPacket, sizeof(requestPacket), 0, (struct sockaddr *)&pingAddress, sizeof(pingAddress)); int bytesSent = sendto(m_socketDescriptor, &requestPacket, sizeof(requestPacket), 0, (struct sockaddr *)&pingAddress, sizeof(pingAddress));
@ -374,16 +369,19 @@ void Ping::onSocketReadyRead(int socketDescriptor)
<< "TTL" << ipHeader->ttl; << "TTL" << ipHeader->ttl;
struct icmp *responsePacket = reinterpret_cast<struct icmp *>(receiveBuffer + ipHeaderLength); struct icmp *responsePacket = reinterpret_cast<struct icmp *>(receiveBuffer + ipHeaderLength);
quint16 icmpId = htons(responsePacket->icmp_id);
quint16 icmpSequnceNumber = htons(responsePacket->icmp_seq);
qCDebug(dcPingTraffic()) << "ICMP packt (Size:" << icmpPacketSize << "Bytes):" qCDebug(dcPingTraffic()) << "ICMP packt (Size:" << icmpPacketSize << "Bytes):"
<< "Type" << responsePacket->icmp_type << "Type" << responsePacket->icmp_type
<< "Code:" << responsePacket->icmp_code << "Code:" << responsePacket->icmp_code
<< "ID:" << QString("0x%1").arg(responsePacket->icmp_id, 4, 16, QChar('0')) << "ID:" << QString("0x%1").arg(icmpId, 4, 16, QChar('0'))
<< "Sequence:" << responsePacket->icmp_seq; << "Sequence:" << icmpSequnceNumber;
if (responsePacket->icmp_type == ICMP_ECHOREPLY) { if (responsePacket->icmp_type == ICMP_ECHOREPLY) {
PingReply *reply = m_pendingReplies.take(responsePacket->icmp_id);
PingReply *reply = m_pendingReplies.take(icmpId);
if (!reply) { if (!reply) {
qCDebug(dcPing()) << "No pending reply for ping echo response with id" << QString("0x%1").arg(responsePacket->icmp_id, 4, 16, QChar('0')) << "Sequence:" << htons(responsePacket->icmp_seq) << "from" << senderAddress.toString(); qCDebug(dcPing()) << "No pending reply for ping echo response with id" << QString("0x%1").arg(icmpId, 4, 16, QChar('0')) << "Sequence:" << icmpSequnceNumber << "from" << senderAddress.toString();
return; return;
} }
@ -395,8 +393,8 @@ void Ping::onSocketReadyRead(int socketDescriptor)
} }
// Verify sequence number // Verify sequence number
if (responsePacket->icmp_seq != reply->sequenceNumber()) { if (icmpSequnceNumber != reply->sequenceNumber()) {
qCWarning(dcPing()) << "Received echo reply with different sequence number" << htons(responsePacket->icmp_seq); qCWarning(dcPing()) << "Received echo reply with different sequence number" << icmpSequnceNumber;
finishReply(reply, PingReply::ErrorInvalidResponse); finishReply(reply, PingReply::ErrorInvalidResponse);
return; return;
} }
@ -408,8 +406,8 @@ void Ping::onSocketReadyRead(int socketDescriptor)
reply->m_duration = qRound((receiveTimeValue.tv_sec * 1000 + (double)receiveTimeValue.tv_usec / 1000) * 100) / 100.0; reply->m_duration = qRound((receiveTimeValue.tv_sec * 1000 + (double)receiveTimeValue.tv_usec / 1000) * 100) / 100.0;
qCDebug(dcPing()) << "Received ICMP response" << reply->targetHostAddress().toString() << ICMP_PACKET_SIZE << "[Bytes]" qCDebug(dcPing()) << "Received ICMP response" << reply->targetHostAddress().toString() << ICMP_PACKET_SIZE << "[Bytes]"
<< "ID:" << QString("0x%1").arg(responsePacket->icmp_id, 4, 16, QChar('0')) << "ID:" << QString("0x%1").arg(icmpId, 4, 16, QChar('0'))
<< "Sequence:" << htons(responsePacket->icmp_seq) << "Sequence:" << icmpSequnceNumber
<< "Time:" << reply->duration() << "[ms]"; << "Time:" << reply->duration() << "[ms]";
if (reply->doHostLookup()) { if (reply->doHostLookup()) {
@ -439,22 +437,25 @@ void Ping::onSocketReadyRead(int socketDescriptor)
<< "TTL" << ipHeader->ttl; << "TTL" << ipHeader->ttl;
struct icmp *nestedResponsePacket = reinterpret_cast<struct icmp *>(receiveBuffer + messageOffset + nestedIpHeaderLength); struct icmp *nestedResponsePacket = reinterpret_cast<struct icmp *>(receiveBuffer + messageOffset + nestedIpHeaderLength);
icmpId = htons(nestedResponsePacket->icmp_id);
icmpSequnceNumber = htons(nestedResponsePacket->icmp_seq);
qCDebug(dcPingTraffic()) << "++ ICMP packt (Size:" << nestedIcmpPacketSize << "Bytes):" qCDebug(dcPingTraffic()) << "++ ICMP packt (Size:" << nestedIcmpPacketSize << "Bytes):"
<< "Type" << nestedResponsePacket->icmp_type << "Type" << nestedResponsePacket->icmp_type
<< "Code:" << nestedResponsePacket->icmp_code << "Code:" << nestedResponsePacket->icmp_code
<< "ID:" << QString("0x%1").arg(nestedResponsePacket->icmp_id, 4, 16, QChar('0')) << "ID:" << QString("0x%1").arg(icmpId, 4, 16, QChar('0'))
<< "Sequence:" << nestedResponsePacket->icmp_seq; << "Sequence:" << icmpSequnceNumber;
qCDebug(dcPing()) << "ICMP destination unreachable" << nestedDestinationAddress.toString() qCDebug(dcPing()) << "ICMP destination unreachable" << nestedDestinationAddress.toString()
<< "Code:" << nestedResponsePacket->icmp_code << "Code:" << nestedResponsePacket->icmp_code
<< "ID:" << QString("0x%1").arg(nestedResponsePacket->icmp_id, 4, 16, QChar('0')) << "ID:" << QString("0x%1").arg(icmpId, 4, 16, QChar('0'))
<< "Sequence:" << htons(nestedResponsePacket->icmp_seq); << "Sequence:" << icmpSequnceNumber;
PingReply *reply = m_pendingReplies.take(nestedResponsePacket->icmp_id); PingReply *reply = m_pendingReplies.take(icmpId);
if (!reply) { if (!reply) {
qCDebug(dcPingTraffic()) << "No pending reply for ping echo response unreachable with ID" qCDebug(dcPingTraffic()) << "No pending reply for ping echo response unreachable with ID"
<< QString("0x%1").arg(nestedResponsePacket->icmp_id, 4, 16, QChar('0')) << QString("0x%1").arg(icmpId, 4, 16, QChar('0'))
<< "Sequence:" << htons(nestedResponsePacket->icmp_seq) << "Sequence:" << icmpSequnceNumber
<< "from" << nestedSenderAddress.toString() << "to" << nestedDestinationAddress.toString(); << "from" << nestedSenderAddress.toString() << "to" << nestedDestinationAddress.toString();
return; return;
} }

View File

@ -92,7 +92,7 @@ signals:
private: private:
QTimer *m_timer = nullptr; QTimer *m_timer = nullptr;
QHostAddress m_targetHostAddress; QHostAddress m_targetHostAddress;
quint16 m_sequenceNumber = 0; quint16 m_sequenceNumber = 1;
quint16 m_requestId = 0; quint16 m_requestId = 0;
QString m_hostName; QString m_hostName;
QNetworkInterface m_networkInterface; QNetworkInterface m_networkInterface;