Determining if a Network Connection is Present

Windows Mobile 6.5
A version of this page is also available for
4/8/2010

Using Winsock, you can determine programmatically whether the local device is connected to a network.

  1. Call WSAStartup to initialize Winsock.

  2. Call gethostname to obtain the name of the local host.

  3. Call getaddrinfo to resolve the name of the local host for all protocol families to obtain a list of network addresses.

  4. Search the list of network addresses to check if it contains the loopback address. For IPv6 networks, you must also check if the list contains the IPv6 loopback address. If any of the addresses match the loopback address, no network connection is present.

  5. Call freeaddrinfo to free the address information allocated by getaddrinfo.

  6. Call WSACleanup to free any resources for the application.

The following code sample shows how to determine if a network connection is present.

#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>

struct in_addr BIN_IPV4_ADDR_LOOPBACK = {127, 0, 0, 1};
struct in6_addr BIN_IPV6_ADDR_LOOPBACK =   {   0x0, 0x0,
                                             0x0, 0x0,
                                             0x0, 0x0,
                                             0x0, 0x0,
                                             0x0, 0x0,
                                             0x0, 0x0,
                                             0x0, 0x0,
                                             0x0, 0x1 };
#define   MAX_LOCAL_NAME_LEN               64

//Function Prototypes
BOOL IsNetPresent();
void Print(TCHAR *pFormat, ...);

int _tmain (int argc, TCHAR* argv[])
{
   WSADATA WSAData;

   WSAStartup(MAKEWORD(2,2), &WSAData);
   Print(TEXT("Network Connection %s present"), IsNetPresent() ? (TEXT("IS")) : (TEXT("is NOT")) );
   WSACleanup();

   return 0;
}

//
// Determine if you have a IPv4 or IPv6 network address.
//
BOOL IsNetPresent()
{
   BOOL bFoundLocalAddr = FALSE;
   char szAddrASCII[MAX_LOCAL_NAME_LEN];
   ADDRINFO AddrHints, *pAI, *pAddrInfo;

   //
   // Get the local host's name in ASCII text.
   //
   if(gethostname(szAddrASCII, MAX_LOCAL_NAME_LEN - 1))
   {
      Print(TEXT("Error getting local host name, error = %d"), WSAGetLastError());
      return FALSE;
   }

   //
   // To obtain a list of all the local
   // addresses, resolve the local name with getaddrinfo for all
   // protocol families.
   //

   memset(&AddrHints, 0, sizeof(AddrHints));
   AddrHints.ai_family = PF_UNSPEC;
   AddrHints.ai_flags = AI_PASSIVE;

   if(getaddrinfo(szAddrASCII, "10", &AddrHints, &pAddrInfo))
   {
      Print(TEXT("getaddrinfo(%hs) error %d"), szAddrASCII, WSAGetLastError());
      return FALSE;
   }

   //
   // Search the addresses returned.
   // If any of them match the loopback address, then
   // are not connected to an outside network.
   //
   // Note: This will not tell you how many networks you
   // are connected to.  If one or more networks are present,
   // then the loopback addresses will not be included in the
   // list returned from getaddrinfo.
   //

   bFoundLocalAddr = TRUE;
   for(pAI = pAddrInfo; pAI != NULL && bFoundLocalAddr; pAI = pAI->ai_next)
   {
      if(pAI->ai_family == PF_INET)
      {
         if(memcmp(&(((SOCKADDR_IN *)(pAI->ai_addr))->sin_addr), &BIN_IPV4_ADDR_LOOPBACK, sizeof(BIN_IPV4_ADDR_LOOPBACK)) == 0)
            bFoundLocalAddr = FALSE;
      }
      else if(pAI->ai_family == PF_INET6)
      {
         if(memcmp(&(((SOCKADDR_IN6 *)(pAI->ai_addr))->sin6_addr), &BIN_IPV6_ADDR_LOOPBACK, sizeof(BIN_IPV6_ADDR_LOOPBACK)) == 0)
            bFoundLocalAddr = FALSE;  
      }
   }

   freeaddrinfo(pAddrInfo);

   return bFoundLocalAddr;
}

void
Print(
   TCHAR *pFormat, 
   ...)
{
   va_list ArgList;
   TCHAR   Buffer[256];

   va_start (ArgList, pFormat);

   (void)StringCchPrintf(Buffer, 256, pFormat, ArgList);

#ifndef UNDER_CE
   _putts(Buffer);
#else
   OutputDebugString(Buffer);
#endif

   va_end(ArgList);
}

Community Additions

Show: