So I have tried looking at a couple of different answers for this. One that I thought may have promise was this one:
How to check network interface type is Ethernet or Wireless on Windows using Qt?
However, I don't really know too much about Networking or even about Windows. Personally, I cannot understand most of the Microsoft documentation on their websites. I have tried things like INetworkConnection
, NativeWiFi
, etc. But either they do not do what I want, or I just cannot figure out how to do it from the available documentation.
With that being said, I would like to use C++ to check if the device this program is being run on is connected to the internet via Ethernet cable. Basically, I want to do the following:
However, the problem is that I don't know how to check if the device has Ethernet connected. Is there a way to do this? I am NOT using QT. Thank you!
EDIT: I should also include what I have tried so far.
I tried using GetAdaptersInfo
and getting the Type
trait from the PIP_ADAPTER_INFO
variable type, but that always gives me Unknown type 71
whether I am on Ethernet or not.
The documentation for that GetAdaptersInfo
is here:
https://msdn.microsoft.com/en-us/library/aa365917%28VS.85%29.aspx
Thanks
EDIT 2: Here is the code I was using for 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;
}
Your problem is somewhat difficult as it can be really complicated to get the "current" network adapter --- windows routes packets depending on network adapter configuration and destination reachability so your "current" adapter may change at any time ... but since you already know how to retrieve IPs and MACs ("hardware address") of available adapters you could simply use your hack to retrieve a MAC for your current IP and filter/search inside of my second function for it! The field "PhysicalAddress" is what you're looking for, thats the MAC adress
I have made the experience that the only, somewhat reliable way of doing that is via GetIfTable and GetIfTable2, the former returns somewhat superficial adpater info and the latter provides great detail. Heres a sample implementation, as it uses the detailed function you can also query for WLAN adapters :
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;
}
Now all you need to do is iterate over the list and filter out disabled adapters and whatnot :
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!
}
}
Now its quite easy to generate lists of WLAN adapters and non-WLAN adapters (see comment in second function), search for your current MAC and conclude that it is wired or wireless - but be aware that these lists may overlap since 802.11 basically is an extended version of 802.3 but 802.3 does not include 802.11 (since its an extension) - so you will need a tiny bit of if/else logic going on in order to seperate WLAN from non-WLAN adapters.
You could also use WlanEnumInterfaces to get all of the WLAN adapters but thats basically the same as using the above function with NdisPhysicalMediumNative802_11
as parameter ...