Проверьте, не включен ли компьютер с операционной системой Windows через Ethernet через стек

Поэтому я попытался найти несколько разных ответов для этого. Тот, который, как я думал, мог обещать, был этим:

Как проверить тип сетевого интерфейса Ethernet или Wireless в Windows, используя Qt?

Тем не менее, я не знаю слишком много о сети или даже о Windows. Лично я не могу понять большую часть документации Microsoft на их сайтах. Я пробовал такие вещи, как INetworkConnection, NativeWiFiи т. д. Но либо они не делают то, что я хочу, либо я просто не могу понять, как это сделать из имеющейся документации.

При этом я хотел бы использовать C ++, чтобы проверить, подключено ли устройство, на котором запускается эта программа, к Интернету через кабель Ethernet. По сути, я хочу сделать следующее:

  • Если компьютер подключен только к беспроводной сети, запустите программу
  • Если компьютер подключен только к проводной, не запускайте программу
  • Если компьютер подключен к проводной и беспроводной сети, не запускайте программу

Однако проблема в том, что я не знаю, как проверить, подключено ли устройство к Ethernet. Есть ли способ сделать это? Я НЕ пользуюсь QT. Спасибо!


РЕДАКТИРОВАТЬ: я должен также включить то, что я пытался до сих пор.

Я пытался с помощью GetAdaptersInfo и получить Type черта от PIP_ADAPTER_INFO тип переменной, но это всегда дает мне Unknown type 71 нахожусь ли я на Ethernet или нет.

Документация для этого GetAdaptersInfo это здесь:
https://msdn.microsoft.com/en-us/library/aa365917%28VS.85%29.aspx

Спасибо


РЕДАКТИРОВАТЬ 2: Вот код, который я использовал для GetAdaptersInfo

bool is_on_ethernet{
PIP_ADAPTER_INFO pAdapterInfo;
PIP_ADAPTER_INFO pAdapter = NULL;
DWORD dwRetVal = 0;
UINT i;

struct tm newtime;
char buffer[32];
errno_t error;

ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO));

if(pAdapterInfo == NULL)
printf("Error allocating memory need to call GetAdaptersInfo");

if(GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW){
free(pAdapterInfo);
pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen);
}

if((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR){
pAdapter = pAdapterInfo;

switch(pAdapter->Type){
case MIB_IF_TYPE_OTHER:
printf("Other\n");
return false;
break;
case MIB_IF_TYPE_ETHERNET:
printf("Ethernet\h");
return true;
break;
case MIB_IF_TYPE_TOKENRING:
printf("Token Ring\n");
return false;
break;
case MIB_IF_TYPE_FDDI
printf("FDDI\n");
return false;
break;
case MIB_IF_TYPE_PPP
printf("PPP\n");
return false;
break;
case MIB_IF_TYPE_LOOPBACK
printf("Lookback\n");
return false;
break;
case MIB_IF_TYPE_SLIP
printf("Slip\n");
return false;
break;
default
printf("Unknown type %ld\n\n", pAdapter->Type);
return false;
break;
}
}

if(pAdapterInfo)
free(pAdapterInfo);

return false;
}

3

Решение

Ваша проблема несколько сложна, поскольку может быть очень сложно получить «текущий» сетевой адаптер — Windows маршрутизирует пакеты в зависимости от конфигурации сетевого адаптера и достижимости назначения, поэтому ваш «текущий» адаптер может измениться в любое время … но так как вы вы уже знаете, как получить IP-адреса и MAC-адреса («аппаратный адрес») доступных адаптеров, вы можете просто использовать свой хак для получения MAC-адреса для вашего текущего IP-адреса и фильтрации / поиска в моей второй функции для него! Поле «PhysicalAddress» — это то, что вы ищете, это MAC-адрес

Я понял, что единственный надежный способ сделать это через GetIfTable а также GetIfTable2, бывший несколько возвращается поверхностная информация об adpater и последний обеспечивает отличный подробно.
Вот пример реализации, поскольку он использует подробную функцию, которую вы также можете запросить для адаптеров WLAN:

vector<MIB_IF_ROW2>* getDevices(NDIS_PHYSICAL_MEDIUM type)
{
vector<MIB_IF_ROW2> *v = new vector<MIB_IF_ROW2>();
PMIB_IF_TABLE2 table = NULL;
if(GetIfTable2Ex(MibIfTableRaw, &table) == NOERROR && table)
{
UINT32 i = 0;
for(; i < table->NumEntries; i++)
{
MIB_IF_ROW2 row;

ZeroMemory(&row, sizeof(MIB_IF_ROW2));
row.InterfaceIndex = i;
if(GetIfEntry2(&row) == NOERROR)
{
if(row.PhysicalMediumType == type)
{
v->push_back(row);
}
}
}
FreeMibTable(table);
}
return v;
}

Теперь все, что вам нужно сделать, это перебрать список и отфильтровать отключенные адаптеры и еще много чего:

vector<MIB_IF_ROW2>* wlan = getDevices(NdisPhysicalMediumNative802_11); //WLAN adapters
//see https://msdn.microsoft.com/en-us/library/windows/desktop/aa814491(v=vs.85).aspx, "PhysicalMediumType" for a full list
for(auto &row : *v)
{
//do some additional filtering, this needs to be changed for non-WLAN
if( row.TunnelType == TUNNEL_TYPE_NONE &&
row.AccessType != NET_IF_ACCESS_LOOPBACK &&
row.Type == IF_TYPE_IEEE80211 &&
row.InterfaceAndOperStatusFlags.HardwareInterface == TRUE)
{
//HERE BE DRAGONS!
}
}

Теперь довольно просто генерировать списки адаптеров WLAN и адаптеров не-WLAN (см. комментарий во второй функции), найдите свой текущий MAC-адрес и определите, является ли он проводным или беспроводным, но имейте в виду, что эти списки может перекрытие с 802,11 в основном это расширенная версия 802,3 но 802.3 делает не включить 802.11 (так как его расширение) — поэтому вам понадобится немного логики if / else, чтобы отделить WLAN от адаптеров, отличных от WLAN.

Вы также можете использовать WlanEnumInterfaces чтобы получить все адаптеры WLAN, но это в основном так же, как с помощью вышеуказанной функции с NdisPhysicalMediumNative802_11 как параметр …

1

Другие решения

Итак, во-первых, большое спасибо пользователю @ Nighthawk441 за то, что он указал мне правильное направление для этого. Без этого пользователя я бы наверняка не придумал решение.

При этом, решение, которое у меня есть сейчас, в лучшем случае, взломать. Кажется, это работает, но я не думаю, что это даже близко к лучшему варианту. Таким образом, я оставлю это как ответ, но я не приму это на некоторое время, если будет найден лучший ответ. Я также очень открыт для любых комментариев, которые кто-либо может иметь, поскольку это имеет отношение к этому ответу.

Короче говоря, я перебрал все адаптеры из GetAdaptersInfo, Чтобы увидеть, был ли адаптер подключен, я сравнил IP-адрес адаптера со строкой "0.0.0.0"Как будто это было что-то другое, я чувствовал, что можно с уверенностью сказать, что адаптер был подключен. Итак, без лишних слов, вот код, который я реализовал.

bool is_on_ethernet(){
PIP_ADAPTER_INFO pAdapterInfo;
PIP_ADAPTER_INFO pAdapter = NULL;
DWORD dwRetVal = 0;
UINT i;

struct tm newtime;
char buffer[32];
errno_t error;

ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO));

if(pAdapterInfo == NULL)
printf("Error allocating memory needed to call GetAdaptersInfo");

if(GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW){
free(pAdapterInfo);
pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen);
}

if((dwRetValue = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR){
do{
pAdapter = pAdapterInfo;

string ip_string = pAdapter->IpAddressList.IpAddress.String;

switch(pAdapter->Type){
case MIB_IF_TYPE_OTHER:
printf("Other\n");
break;
...
case MIB_IF_TYPE_ETHERNET:
printf("Ethernet\n");

//new code
if(ip_string.compare("0.0.0.0") != 0){
free(pAdapterInfo);
return true;
}

break;
default:
printf("Unknown type %ld\n", pAdapter->Type);
break;
}
}while(pAdapterInfo = pAdapterInfo->Next);
}

if(pAdapterInfo)
free(pAdapterInfo);

return false;
}

Просмотр этой ссылки действительно помог мне:

https://msdn.microsoft.com/en-us/library/windows/desktop/aa365819%28v=vs.85%29.aspx

Так что спасибо Nighthawk за предоставленную мне информацию. Надеюсь, это поможет кому-то еще! Если у кого-то есть комментарии или другие ответы, не стесняйтесь их публиковать! Спасибо!

0

По вопросам рекламы [email protected]