Search code examples
c++objective-cmacoslocal-network

How to get the names and ips of all devices on my local network?


My goal is to list the names and ips of all the devices on the local network.

list all the computer names on a local network on iPhone similar to this post, but it wasn't answered.

I've looked into Apples Bonjour and don't think that's what I need. It doesn't show all the devices on network.

I've also tried the code below, but I get weird output (below).

int sock;
struct ifconf ifconf;
struct ifreq ifreq[30];
int interfaces;
int i;

// Create a socket or return an error.
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
    diep("socket");

// Point ifconf's ifc_buf to our array of interface ifreqs.
ifconf.ifc_buf = (char *) ifreq;

// Set ifconf's ifc_len to the length of our array of interface ifreqs.
ifconf.ifc_len = sizeof ifreq;

//  Populate ifconf.ifc_buf (ifreq) with a list of interface names and addresses.
if (ioctl(sock, SIOCGIFCONF, &ifconf) == -1)
    diep("ioctl");

// Divide the length of the interface list by the size of each entry.
// This gives us the number of interfaces on the system.
interfaces = ifconf.ifc_len / sizeof(ifreq[0]);

// Print a heading that includes the total # of interfaces.
printf("IF(%d)\tIP\n", interfaces);

// Loop through the array of interfaces, printing each one's name and IP.
for (i = 0; i < interfaces; i++) {
    char ip[INET_ADDRSTRLEN];
    struct sockaddr_in *address = (struct sockaddr_in *) &ifreq[i].ifr_addr;

    // Convert the binary IP address into a readable string.
    if (!inet_ntop(AF_INET, &address->sin_addr, ip, sizeof(ip)))
        diep("inet_ntop");

    printf("FOUND: %s\t%s\n", ifreq[i].ifr_name, ip);
}

close(sock);

This is the output, which I can't really make sense of.

FOUND: lo0  24.3.0.0
FOUND:  28.30.0.0
FOUND:  0.0.0.0
FOUND:  0.0.0.0
FOUND:  0.0.0.1
FOUND: ip0  112.100.112.95
FOUND: pdp_ip1  255.7.0.0
FOUND:  20.18.4.0
FOUND: ip2  0.0.0.0
FOUND: ap1\256\372\272J\221\253 0.0.0.0
FOUND:  105.112.50.0
FOUND:  254.74.145.171
FOUND: ip2  0.0.0.0
FOUND: ip2  101.110.49.142
FOUND: awdl0    6.5.6.0
FOUND: \273Y\311    28.30.0.0

I'd like to see output something like this:

My-Mac    192.168.0.21
My-iPad   192.168.0.22
Mum's iPhone 192.168.0.23

A solution in either Objective-C or C++ would be useful. Thanks.


Solution

  • Just dug up this project again...and this is my attempt at sharing the code as @PRSingh requested...hope it helps.

    Defined in my .h

     NSNetServiceBrowser *serviceBrowser;
     NSNetService *service;
     NSMutableArray* snames;
     NSMutableArray* sips;
     UIActivityIndicatorView* spinner;
    

    In my .m

    #pragma mark - NSNetServiceDelegate Methods
    
    - (void)netServiceWillResolve:(NSNetService *)sender {
        NSLog(@"netServiceWillResolve");
    
        serviceBrowser = [[NSNetServiceBrowser alloc] init];
        if(!serviceBrowser) {
            NSLog(@"The NSNetServiceBrowser couldn't be allocated and initialized.");
        }
        serviceBrowser.delegate = self;
        [serviceBrowser searchForServicesOfType:@"_type._tcp." inDomain:@"local."];
    }
    
    - (void)netServiceWillPublish:(NSNetService *)netService
    {
        NSLog(@"netServiceWillPublish");
    }
    
    - (void)netServiceDidPublish:(NSNetService *)sender {
        NSLog(@"netServiceDidPublish");
    }
    
    - (void)netService:(NSNetService *)sender didNotPublish:(NSDictionary *)errorDict {
        NSLog(@"didNotPublish");
    }
    
    - (void)netServiceDidResolveAddress:(NSNetService *)netService {
        NSLog(@"netServiceDidResolveAddress");
        for (NSData* data in [netService addresses]) {
    
            char addressBuffer[100];
    
            struct sockaddr_in* socketAddress = (struct sockaddr_in*) [data bytes];
    
            int sockFamily = socketAddress->sin_family;
    
            if (sockFamily == AF_INET /*|| sockFamily == AF_INET6*/) {
    
                const char* addressStr = inet_ntop(sockFamily,
                                                   &(socketAddress->sin_addr), addressBuffer,
                                                   sizeof(addressBuffer));
    
               // int port = ntohs(socketAddress->sin_port);
    
                if (addressStr){
                    if(![sips containsObject:[NSString stringWithFormat:@"%s",addressStr]]){
                        [snames addObject:netService.name];
                        [sips addObject:[NSString stringWithFormat:@"%s",addressStr]];
                        [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
                    }
                }
    
            }
    
        }
    }
    
    - (void)netService:(NSNetService *)sender didNotResolve:(NSDictionary *)errorDict {
        NSLog(@"didNotResolve: %@",errorDict);
    }
    
    - (void)netService:(NSNetService *)sender didUpdateTXTRecordData:(NSData *)data {
        NSLog(@"didUpdateTXTRecordData");
    }
    
    - (void)netServiceDidStop:(NSNetService *)netService {
        NSLog(@"netServiceDidStop");
    }
    
    #pragma mark - NSNetServiceBrowserDelegate Methods
    
    - (void)netServiceBrowser:(NSNetServiceBrowser *)netServiceBrowser didFindService:(NSNetService *)netService moreComing:(BOOL)moreServicesComing {
        NSLog(@"didFindService: %@  lenght:%d",netService.name,[netService.name length]);
        [services addObject:netService];
    }
    
    
    - (void)netServiceBrowser:(NSNetServiceBrowser *)netServiceBrowser didRemoveService:(NSNetService *)netService moreComing:(BOOL)moreServicesComing {
        [services removeObject:netService];
        [netService stop];
        int index = [snames indexOfObject:netService.name];
        [snames removeObjectAtIndex:index];
        [sips removeObjectAtIndex:index];
        [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
    
        NSLog(@"didRemoveService");
    }
    

    For this to work I believe that all devices on the network need to be running bonjour with a 'type' of '_type_.tcp' (or what ever name you give it). You can play around with the type just to see what devices on your local network are already on certain service types (https://developer.apple.com/library/mac/qa/qa1312/_index.html).