50#import <netinet6/in6.h> 
   55#import <CoreFoundation/CoreFoundation.h> 
   57#import "Reachability.h" 
   59#define kShouldPrintReachabilityFlags 1 
   61static void PrintReachabilityFlags(SCNetworkReachabilityFlags flags, 
const char *comment)
 
   63#if kShouldPrintReachabilityFlags 
   65  NSLog(
@"Reachability Flag Status: %c%c %c%c%c%c%c%c%c %s\n",
 
   66        (flags & kSCNetworkReachabilityFlagsIsWWAN) ? 
'W' : 
'-',
 
   67        (flags & kSCNetworkReachabilityFlagsReachable) ? 
'R' : 
'-',
 
   69        (flags & kSCNetworkReachabilityFlagsTransientConnection) ? 
't' : 
'-',
 
   70        (flags & kSCNetworkReachabilityFlagsConnectionRequired) ? 
'c' : 
'-',
 
   71        (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) ? 
'C' : 
'-',
 
   72        (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 
'i' : 
'-',
 
   73        (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ? 
'D' : 
'-',
 
   74        (flags & kSCNetworkReachabilityFlagsIsLocalAddress) ? 
'l' : 
'-',
 
   75        (flags & kSCNetworkReachabilityFlagsIsDirect) ? 
'd' : 
'-', comment);
 
   80static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags,
 
   83#pragma unused(target, flags) 
   84  NSCAssert(info != NULL, 
@"info was NULL in ReachabilityCallback");
 
   85  NSCAssert([(NSObject *)info isKindOfClass:[
Reachability class]],
 
   86            @"info was wrong class in ReachabilityCallback");
 
   90  NSAutoreleasePool *myPool = [[NSAutoreleasePool alloc] init];
 
   94  [[NSNotificationCenter defaultCenter] postNotificationName:kReachabilityChangedNotification
 
  103  SCNetworkReachabilityContext context = { 0, 
self, NULL, NULL, NULL };
 
  104  if (SCNetworkReachabilitySetCallback(reachabilityRef, ReachabilityCallback, &context))
 
  106    if (SCNetworkReachabilityScheduleWithRunLoop(reachabilityRef, CFRunLoopGetCurrent(),
 
  107                                                 kCFRunLoopDefaultMode))
 
  117  if (reachabilityRef != NULL)
 
  119    SCNetworkReachabilityUnscheduleFromRunLoop(reachabilityRef, CFRunLoopGetCurrent(),
 
  120                                               kCFRunLoopDefaultMode);
 
  127  if (reachabilityRef != NULL)
 
  129    CFRelease(reachabilityRef);
 
  134+ (
Reachability *)reachabilityWithHostName:(NSString *)hostName;
 
  137  SCNetworkReachabilityRef reachability =
 
  138      SCNetworkReachabilityCreateWithName(NULL, [hostName UTF8String]);
 
  139  if (reachability != NULL)
 
  141    retVal = [[[
self alloc] init] autorelease];
 
  144      retVal->reachabilityRef = reachability;
 
  145      retVal->localWiFiRef = NO;
 
  151+ (
Reachability *)reachabilityWithAddress:(const struct sockaddr_in *)hostAddress;
 
  153  SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(
 
  154      kCFAllocatorDefault, (
const struct sockaddr *)hostAddress);
 
  156  if (reachability != NULL)
 
  158    retVal = [[[
self alloc] init] autorelease];
 
  161      retVal->reachabilityRef = reachability;
 
  162      retVal->localWiFiRef = NO;
 
  170  struct sockaddr_in zeroAddress;
 
  171  bzero(&zeroAddress, 
sizeof(zeroAddress));
 
  172  zeroAddress.sin_len = 
sizeof(zeroAddress);
 
  173  zeroAddress.sin_family = AF_INET;
 
  174  return [
self reachabilityWithAddress:&zeroAddress];
 
  179  struct sockaddr_in localWifiAddress;
 
  180  bzero(&localWifiAddress, 
sizeof(localWifiAddress));
 
  181  localWifiAddress.sin_len = 
sizeof(localWifiAddress);
 
  182  localWifiAddress.sin_family = AF_INET;
 
  184  localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM);
 
  185  Reachability *retVal = [
self reachabilityWithAddress:&localWifiAddress];
 
  188    retVal->localWiFiRef = YES;
 
  193#pragma mark Network Flag Handling 
  195- (NetworkStatus)localWiFiStatusForFlags:(SCNetworkReachabilityFlags)flags
 
  197  PrintReachabilityFlags(flags, 
"localWiFiStatusForFlags");
 
  199  BOOL retVal = NotReachable;
 
  200  if ((flags & kSCNetworkReachabilityFlagsReachable) &&
 
  201      (flags & kSCNetworkReachabilityFlagsIsDirect))
 
  203    retVal = ReachableViaWiFi;
 
  208- (NetworkStatus)networkStatusForFlags:(SCNetworkReachabilityFlags)flags
 
  210  PrintReachabilityFlags(flags, 
"networkStatusForFlags");
 
  211  if ((flags & kSCNetworkReachabilityFlagsReachable) == 0)
 
  217  BOOL retVal = NotReachable;
 
  219  if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0)
 
  223    retVal = ReachableViaWiFi;
 
  226  if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand) != 0) ||
 
  227       (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))
 
  232    if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0)
 
  235      retVal = ReachableViaWiFi;
 
  239  if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)
 
  243    retVal = ReachableViaWWAN;
 
  248- (BOOL)connectionRequired;
 
  250  NSAssert(reachabilityRef != NULL, 
@"connectionRequired called with NULL reachabilityRef");
 
  251  SCNetworkReachabilityFlags flags;
 
  252  if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
 
  254    return (flags & kSCNetworkReachabilityFlagsConnectionRequired);
 
  259- (NetworkStatus)currentReachabilityStatus
 
  261  NSAssert(reachabilityRef != NULL, 
@"currentNetworkStatus called with NULL reachabilityRef");
 
  262  NetworkStatus retVal = NotReachable;
 
  263  SCNetworkReachabilityFlags flags;
 
  264  if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
 
  268      retVal = [
self localWiFiStatusForFlags:flags];
 
  272      retVal = [
self networkStatusForFlags:flags];