How to use NSHost to get the name behind a bunch of LAN ip addresses?
Question
I know how to get the name behind an ip address using the terminal and dig. I.e:
dig @224.0.0.251 -p5353 -x 192.168.0.195 +short
However, I don't want to use NSTask in my application. How can I use NSHost to get the name behind an ip address within a LAN? I tried this, but it always returns nil:
NSHost *myHost = [NSHost hostWithAddress:@"192.168.0.195"];
NSLog(@"name: %@", [myHost name]);
Thanks a lot!
Edit: These methods/functions... +[NSHost hostWithAddress:] gethostbyaddr(3) - A BSD function ...seem to be the same as:
dig -x 192.168.0.195
If I use that dig command in the terminal it says that no servers could be reached. (Yes I don't have a DNS server in my LAN), so no wonder I get back nil.
It would be great if I could implement dig @224.0.0.251 -p5353 -x 192.168.0.195 +short
(bonjour multicast lookup) in my app without having to use NSTask. :)
Solution
It does not use NSHost
, but uses the Bonjour-API and it seems to work as you want:
#import <Cocoa/Cocoa.h>
#import <dns_sd.h>
#import <resolv.h>
static void callback(DNSServiceRef serviceRef, DNSServiceFlags flags, uint32_t interfaceIndex,
DNSServiceErrorType errorCode, const char *fullname,
uint16_t rrtype, uint16_t rrclass,
uint16_t rdlen, const void *rdata,
uint32_t ttl, void *context) {
char result[1024] = {0};
dn_expand(rdata, rdata + rdlen, rdata, result, 1024);
NSLog(@"Found: %s", result);
}
int main(int argc, char const *argv[]) {
DNSServiceRef reverseLookupService = NULL;
DNSServiceErrorType error = kDNSServiceErr_NoError;
error = DNSServiceQueryRecord(&reverseLookupService, kDNSServiceFlagsForceMulticast,
kDNSServiceInterfaceIndexAny, "5.1.168.192.in-addr.arpa.",
kDNSServiceType_PTR, kDNSServiceClass_IN,
callback, NULL);
if (error != kDNSServiceErr_NoError) {
NSLog(@"Error: %d", error);
exit(1);
}
error = DNSServiceProcessResult(reverseLookupService);
DNSServiceRefDeallocate(reverseLookupService);
return 0;
}
The important part is using DNSServiceQueryRecord
with kDNSServiceFlagsForceMulticast
. Look at https://developer.apple.com/library/mac/#documentation/Networking/Reference/DNSServiceDiscovery_CRef/dns_sd_h/index.html#//apple_ref/c/func/DNSServiceQueryRecord for more info about this function.
You'll have to convert the IP address to in-addr.arpa.-format yourself, but that is not hard (the octets are backwards with "in-addr.arpa." at the end. IPv6 is probably similar, but I have not tested it).
It imports resolv.h
(and you need to link it to libresolv), but only for dn_expand
. The data passed to the callback is compressed, and dn_expand
creates a human-readable representation.