ProjectExplorer: Fix parsing ports from netstat output on Windows

Handle IPv6, and do not try to interpret the result as hex.

Change-Id: I700c233d03cc706bc8712ab9fabee75d7f126df3
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
hjk
2017-08-23 09:36:47 +02:00
parent 94747ea2d0
commit 45caf84cc9
4 changed files with 107 additions and 59 deletions

View File

@@ -269,4 +269,71 @@ QTCREATOR_UTILS_EXPORT bool readMultiLineString(const QJsonValue &value, QString
return true;
}
QTCREATOR_UTILS_EXPORT int parseUsedPortFromNetstatOutput(const QByteArray &line)
{
const QByteArray trimmed = line.trimmed();
int base = 0;
QByteArray portString;
if (trimmed.startsWith("TCP") || trimmed.startsWith("UDP")) {
// Windows. Expected output is something like
//
// Active Connections
//
// Proto Local Address Foreign Address State
// TCP 0.0.0.0:80 0.0.0.0:0 LISTENING
// TCP 0.0.0.0:113 0.0.0.0:0 LISTENING
// [...]
// TCP 10.9.78.4:14714 0.0.0.0:0 LISTENING
// TCP 10.9.78.4:50233 12.13.135.180:993 ESTABLISHED
// [...]
// TCP [::]:445 [::]:0 LISTENING
// TCP 192.168.0.80:51905 169.55.74.50:443 ESTABLISHED
// UDP [fe80::880a:2932:8dff:a858%6]:1900 *:*
const int firstBracketPos = trimmed.indexOf('[');
int colonPos = -1;
if (firstBracketPos == -1) {
colonPos = trimmed.indexOf(':'); // IPv4
} else {
// jump over host part
const int secondBracketPos = trimmed.indexOf(']', firstBracketPos + 1);
colonPos = trimmed.indexOf(':', secondBracketPos);
}
const int firstDigitPos = colonPos + 1;
const int spacePos = trimmed.indexOf(' ', firstDigitPos);
if (spacePos < 0)
return -1;
const int len = spacePos - firstDigitPos;
base = 10;
portString = trimmed.mid(firstDigitPos, len);
} else {
// Expected output on Linux something like
//
// sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt ...
// 0: 00000000:2805 00000000:0000 0A 00000000:00000000 00:00000000 00000000 ...
//
const int firstColonPos = trimmed.indexOf(':');
if (firstColonPos < 0)
return -1;
const int secondColonPos = trimmed.indexOf(':', firstColonPos + 1);
if (secondColonPos < 0)
return -1;
const int spacePos = trimmed.indexOf(' ', secondColonPos + 1);
if (spacePos < 0)
return -1;
const int len = spacePos - secondColonPos - 1;
base = 16;
portString = trimmed.mid(secondColonPos + 1, len);
}
bool ok = true;
const int port = portString.toInt(&ok, base);
if (!ok) {
qWarning("%s: Unexpected string '%s' is not a port. Tried to read from '%s'",
Q_FUNC_INFO, line.data(), portString.data());
return -1;
}
return port;
}
} // namespace Utils