1

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:

  • First it returns 2 addresses, both the same, and are nonsense(not anywhere near 10.0.1.19, usually starts with 8)
  • after that, no results, and an error(err): err->domain = 12 and err->error = 8. Looks like some form of caching, not sure about that...

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

Oht
  • 409
  • 5
  • 19

1 Answers1

1

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)];
}
Lefteris
  • 14,550
  • 2
  • 56
  • 95
  • Thank you, this worked! i was casting the address the wrong way. edit: when i start the application a second time, no addresses are found :( – Oht Oct 22 '15 at 11:21
  • It seems to work if i put this code in a while until i find an ip, thank you for your help! – Oht Oct 22 '15 at 12:05