I am using Reachability framework to detect interface type. Its works fine when single interface used. But when multiple network interface is being used it works abnormally. It fails in the following case -
Suppose you have two network interfaces, one is WiFi and other one cellular(3G, 2G, EDGE etc). When I try to detect interface type for each of the interfaces it returns WiFi for each cases. But works fine when only WiFi or 3G interfaces are connected. I have used the following code to detect interface type -
static struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;
SCNetworkReachabilityFlags flags;
AFNetworkInterfaceType interfaceType = AF_NIC_TYPE_UNKNOWN;
bool reachable = true;
UserInfo info;
static SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)&zeroAddress);
SCNetworkReachabilityContext context = {0, &info, NULL, NULL, NULL};
if (SCNetworkReachabilityGetFlags(reachability, &flags))
{
if ((flags & kSCNetworkReachabilityFlagsReachable) == 0)
{
// The target host is not reachable.
reachable = false;
if ((flags & kSCNetworkReachabilityFlagsReachable) && (flags & kSCNetworkReachabilityFlagsIsDirect))
{
interfaceType = AF_NIC_TYPE_WIFI;
}
}
if ( true == reachable && (flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0)
{
/*
If the target host is reachable and no connection is required then we'll assume (for now) that you're on Wi-Fi...
*/
interfaceType = AF_NIC_TYPE_WIFI;
}
if ( true == reachable && (((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||
(flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))
{
/*
... and the connection is on-demand (or on-traffic) if the calling application is using the CFSocketStream or higher APIs...
*/
if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0)
{
/*
... and no [user] intervention is needed...
*/
interfaceType = AF_NIC_TYPE_WIFI;
}
}
if ( true == reachable && (flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)
{
/*
... but WWAN connections are OK if the calling application is using the CFNetwork APIs.
*/
interfaceType = AF_NIC_TYPE_CELLULAR;
}
}
And after debugging I have seen that it enters in the second block and detects interface type WiFi. Can some one show me the way how can I determine all the network interface's type correctly.
N.B: I am using the above code in a C++ library solution, which is a cross platform library.
This issue has been fixed. Posting it so that user's can get help. The main problem was that I was passing NULL in zeroAddress structure. After assigning my network interface address in the structure it passed all the cases and determined network interface type correctly.