iosobjective-cbonjoursmbcfstream

Finding IP address of windows local hostname on iOS


I am trying to find the IP of a windows computer (named TEST) on a local wifi network on iOS for smb purposes. I have bonjour installed on this windows machine and if i type the following command in terminal on my mac(on the same wifi network):

ping TEST.local

I get a success ( '64 bytes from 10.0.1.19: icmp_seq=285 ttl=128 time=3.237 ms' ). Note the ip (10.0.1.19): It resolves the hostname correctly! No problem so far!

Now, I'm trying to do the same on iOS by using CFHostCreateWithName:

NSString *host = @"TEST.local";
CFHostRef hostref = CFHostCreateWithName(nil/*or kCFAllocatorDefault, same result...*/,(__bridge CFStringRef)host);

CFStreamError *err;
Boolean lookup = CFHostStartInfoResolution(hostref, kCFHostAddresses, err);
NSArray* addresses = (__bridge NSArray*)CFHostGetAddressing(hostref, &lookup);


id first = addresses.firstObject;

if(first!=nil) {

    struct in_addr *firstaddress = (__bridge struct in_addr *)first;
    NSString *strDNS = [NSString stringWithUTF8String:inet_ntoa(*(firstaddress))];
}

Results vary from:

So host resolving is fine on mac, but does not work on an iOS device connected to the same network... Did i miss something?


Solution

  • Basically, you can get the hostname using this:

    NSString* hostname = @"Mac-mini.local";
    
    CFHostRef hostRef = CFHostCreateWithName(kCFAllocatorDefault, (__bridge CFStringRef)hostname);
    Boolean lookup = CFHostStartInfoResolution(hostRef, kCFHostAddresses, NULL);
    
    if (lookup) {
        CFArrayRef addresses = CFHostGetAddressing(hostRef, &lookup);
    
        struct sockaddr_in *remoteAddr;
    
        for(int i = 0; i < CFArrayGetCount(addresses); i++) {
            CFDataRef saData = (CFDataRef)CFArrayGetValueAtIndex(addresses, i);
            remoteAddr = (struct sockaddr_in*)CFDataGetBytePtr(saData);
            if(remoteAddr != NULL){
                NSString *strDNS = [NSString stringWithUTF8String:inet_ntoa(remoteAddr->sin_addr)];
                NSLog(@"dns:%@",strDNS);
            }
        }
    
        CFRelease(addresses);
    }
    

    In your case you would have to modify it this way:

    NSString *host = @"TEST.local";
    CFHostRef hostref = CFHostCreateWithName(kCFAllocatorDefault,(__bridge CFStringRef)host);
    
    CFStreamError *err;
    Boolean lookup = CFHostStartInfoResolution(hostref, kCFHostAddresses, err);
    NSArray* addresses = (__bridge NSArray*)CFHostGetAddressing(hostref, &lookup);
    
    if(addresses.firstObject!=nil) {
        struct sockaddr_in *firstaddress = (struct sockaddr_in*)CFDataGetBytePtr((__bridge CFDataRef)addresses.firstObject);
        NSString *strDNS = [NSString stringWithUTF8String:inet_ntoa(firstaddress->sin_addr)];
    }