Use Windows' connection name as the port description
... instead of the PCAP returned description. This allows for a better UX since user can more easily identify which port is which. This will work only Windows Vista and higher since IPHLPAPI.DLL has published APIs only for these versions. Older windows versions such as XP will continue to use the PCAP returned description Fixes #222
This commit is contained in:
parent
f71e0929d9
commit
1cddfbf2ec
@ -26,26 +26,36 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#include "winpcapport.h"
|
||||
|
||||
#include <QStringList>
|
||||
#include <pcap.h>
|
||||
|
||||
PortManager *PortManager::instance_ = NULL;
|
||||
|
||||
#if defined(Q_OS_WIN32)
|
||||
#include <QUuid>
|
||||
#include <ipHlpApi.h>
|
||||
#define NETIO_STATUS NTSTATUS
|
||||
// Define the function prototypes since they are not defined in ipHlpApi.h
|
||||
NETIO_STATUS WINAPI ConvertInterfaceGuidToLuid(
|
||||
const GUID *InterfaceGuid, PNET_LUID InterfaceLuid);
|
||||
NETIO_STATUS WINAPI ConvertInterfaceLuidToAlias(
|
||||
const NET_LUID *InterfaceLuid, PWSTR InterfaceAlias, SIZE_T Length);
|
||||
|
||||
#define MyGetProcAddress(hDll, function) \
|
||||
hDll ? reinterpret_cast<decltype(&function)> (GetProcAddress(hDll, #function)) : NULL;
|
||||
#endif
|
||||
|
||||
PortManager::PortManager()
|
||||
{
|
||||
int i;
|
||||
pcap_if_t *deviceList;
|
||||
pcap_if_t *device;
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
AbstractPort::Accuracy txRateAccuracy;
|
||||
|
||||
qDebug("PCAP Lib: %s", pcap_lib_version());
|
||||
qDebug("Retrieving the device list from the local machine\n");
|
||||
|
||||
if (pcap_findalldevs(&deviceList, errbuf) == -1)
|
||||
qDebug("Error in pcap_findalldevs_ex: %s\n", errbuf);
|
||||
|
||||
txRateAccuracy = rateAccuracy();
|
||||
|
||||
pcap_if_t *deviceList = GetPortList();
|
||||
|
||||
for(device = deviceList, i = 0; device != NULL; device = device->next, i++)
|
||||
{
|
||||
AbstractPort *port;
|
||||
@ -67,7 +77,7 @@ PortManager::PortManager()
|
||||
}
|
||||
|
||||
#if defined(Q_OS_WIN32)
|
||||
port = new WinPcapPort(i, device->name);
|
||||
port = new WinPcapPort(i, device->name, device->description);
|
||||
#elif defined(Q_OS_LINUX)
|
||||
port = new LinuxPort(i, device->name);
|
||||
#elif defined(Q_OS_BSD4)
|
||||
@ -91,7 +101,7 @@ PortManager::PortManager()
|
||||
portList_.append(port);
|
||||
}
|
||||
|
||||
pcap_freealldevs(deviceList);
|
||||
FreePortList(deviceList);
|
||||
|
||||
foreach(AbstractPort *port, portList_)
|
||||
port->init();
|
||||
@ -113,6 +123,65 @@ PortManager* PortManager::instance()
|
||||
return instance_;
|
||||
}
|
||||
|
||||
pcap_if_t* PortManager::GetPortList()
|
||||
{
|
||||
pcap_if_t *deviceList = NULL;
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
|
||||
if (pcap_findalldevs(&deviceList, errbuf) == -1)
|
||||
qDebug("Error in pcap_findalldevs_ex: %s\n", errbuf);
|
||||
|
||||
#if defined(Q_OS_WIN32)
|
||||
// Use windows' connection name as the description for a better UX
|
||||
ipHlpApi_ = LoadLibrary(TEXT("ipHlpApi.dll"));
|
||||
auto guid2Luid = MyGetProcAddress(ipHlpApi_, ConvertInterfaceGuidToLuid);
|
||||
auto luid2Alias = MyGetProcAddress(ipHlpApi_, ConvertInterfaceLuidToAlias);
|
||||
|
||||
if (guid2Luid && luid2Alias) {
|
||||
pcap_if_t *device;
|
||||
for(device = deviceList; device != NULL; device = device->next) {
|
||||
GUID guid = static_cast<GUID>(QUuid(
|
||||
QString(device->name).remove("\\Device\\NPF_")));
|
||||
NET_LUID luid;
|
||||
|
||||
oldDescriptions_.append(device->description);
|
||||
newDescriptions_.append(new QByteArray());
|
||||
if (guid2Luid(&guid, &luid) == NO_ERROR) {
|
||||
WCHAR conn[256];
|
||||
if (luid2Alias(&luid, conn, 256) == NO_ERROR) {
|
||||
*(newDescriptions_.last()) = QString().fromWCharArray(conn)
|
||||
.toLocal8Bit();
|
||||
device->description = newDescriptions_.last()->data();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return deviceList;
|
||||
}
|
||||
|
||||
void PortManager::FreePortList(pcap_if_t *deviceList)
|
||||
{
|
||||
#if defined(Q_OS_WIN32)
|
||||
int i = 0;
|
||||
pcap_if_t *device;
|
||||
if (oldDescriptions_.size()) {
|
||||
for(device = deviceList; device != NULL; device = device->next)
|
||||
device->description = oldDescriptions_.at(i++);
|
||||
}
|
||||
oldDescriptions_.clear();
|
||||
|
||||
while (newDescriptions_.size())
|
||||
delete newDescriptions_.takeFirst();
|
||||
|
||||
if (ipHlpApi_)
|
||||
FreeLibrary(ipHlpApi_);
|
||||
#endif
|
||||
|
||||
pcap_freealldevs(deviceList);
|
||||
}
|
||||
|
||||
AbstractPort::Accuracy PortManager::rateAccuracy()
|
||||
{
|
||||
QString rateAccuracy = appSettings->value(kRateAccuracyKey,
|
||||
|
@ -20,9 +20,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#ifndef _SERVER_PORT_MANAGER_H
|
||||
#define _SERVER_PORT_MANAGER_H
|
||||
|
||||
#include <QList>
|
||||
#include "abstractport.h"
|
||||
|
||||
#include <pcap.h>
|
||||
#include <QByteArray>
|
||||
#include <QList>
|
||||
|
||||
class PortManager
|
||||
{
|
||||
public:
|
||||
@ -39,9 +42,17 @@ private:
|
||||
bool filterAcceptsPort(const char *name);
|
||||
|
||||
private:
|
||||
QList<AbstractPort*> portList_;
|
||||
pcap_if_t* GetPortList();
|
||||
void FreePortList(pcap_if_t *deviceList);
|
||||
|
||||
QList<AbstractPort*> portList_;
|
||||
static PortManager *instance_;
|
||||
#ifdef Q_OS_WIN32
|
||||
HMODULE ipHlpApi_;
|
||||
QList<char*> oldDescriptions_;
|
||||
QList<QByteArray*> newDescriptions_;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -26,8 +26,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
const uint OID_GEN_MEDIA_CONNECT_STATUS = 0x00010114;
|
||||
|
||||
WinPcapPort::WinPcapPort(int id, const char *device)
|
||||
: PcapPort(id, device)
|
||||
WinPcapPort::WinPcapPort(int id, const char *device, const char *description)
|
||||
: PcapPort(id, device)
|
||||
{
|
||||
monitorRx_->stop();
|
||||
monitorTx_->stop();
|
||||
@ -40,6 +40,8 @@ WinPcapPort::WinPcapPort(int id, const char *device)
|
||||
monitorRx_ = new PortMonitor(device, kDirectionRx, &stats_);
|
||||
monitorTx_ = new PortMonitor(device, kDirectionTx, &stats_);
|
||||
|
||||
data_.set_description(description);
|
||||
|
||||
adapter_ = PacketOpenAdapter((CHAR*)device);
|
||||
if (!adapter_)
|
||||
qFatal("Unable to open adapter %s", device);
|
||||
|
@ -31,7 +31,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
class WinPcapPort : public PcapPort
|
||||
{
|
||||
public:
|
||||
WinPcapPort(int id, const char *device);
|
||||
WinPcapPort(int id, const char *device, const char *description);
|
||||
~WinPcapPort();
|
||||
|
||||
virtual OstProto::LinkState linkState();
|
||||
|
Loading…
Reference in New Issue
Block a user