0

I do small iPhone app and I need to get IP range and iterate through it with objective C. I can get local IP, netmask. Also I have found on SO solution how to get Broadcast address. But how can I get also Network address? By knowing Network address what is first in the local network and Broadcast address what is last in the local network I would like to iterate all IP from that range. Simply call it and see response. How can I do that?

Solution to get Broadcast from https://stackoverflow.com/a/21077257

#include <net/ethernet.h>
#include <arpa/inet.h>

NSString *localIPAddress = @"192.168.1.10";
NSString *netmaskAddress = @"255.255.192.0";

// Strings to in_addr:
struct in_addr localAddr;
struct in_addr netmaskAddr;
inet_aton([localIPAddress UTF8String], &localAddr);
inet_aton([netmaskAddress UTF8String], &netmaskAddr);

// The broadcast address calculation:
localAddr.s_addr |= ~(netmaskAddr.s_addr);

// in_addr to string:
NSString *broadCastAddress = [NSString stringWithUTF8String:inet_ntoa(localAddr)];

Update: from netmaskAddress I can get number of hosts in the network. I only need to work with IPs. The question now is how can I get next IP from the given? For example I have

NSString *ip = "192.168.1.5"

How can I get "192.168.1.6" with objective C?

Community
  • 1
  • 1
poul
  • 123
  • 2
  • 14
  • What do you want to iterate? Can you explain your use case? – Marius Waldal Feb 13 '14 at 12:48
  • I have to find another device in the network. So I have to call all IP from the local network. – poul Feb 13 '14 at 12:52
  • Have you looked into iOS multi peer connectivity? Perhaps it solves your usecase: http://nshipster.com/multipeer-connectivity/ https://developer.apple.com/library/ios/documentation/MultipeerConnectivity/Reference/MultipeerConnectivityFramework/Introduction/Introduction.html – rist Feb 13 '14 at 13:36

1 Answers1

1

I do not recommend do bit operations on this kind of IP's (in_addr) because if you will take a look inside the bytes are reverse ordered.

The code below is printing the device ip, network ip, netmask and broadcast address and all ip's in network range. It might be helpful. Enjoy!

NetworkInformation *network = [[NetworkInformation alloc] init];
NSLog(@"%@", network);
for(NSString *ip in network.ipsInRange){
    NSLog(@"ip: %@", ip);
}

NetworkInformation.h

#import <Foundation/Foundation.h>

@interface NetworkInformation : NSObject
@property (nonatomic, retain) NSString *deviceIP;
@property (nonatomic, retain) NSString *netmask;
@property (nonatomic, retain) NSString *address;
@property (nonatomic, retain) NSString *broadcast;
@property (nonatomic, retain) NSArray *ipsInRange;
- (void)updateData;
- (NSString *)description;
@end

NetworkInformation.m

#import "NetworkInformation.h"
#import <arpa/inet.h>
#import <ifaddrs.h>

@implementation NetworkInformation

- (id)init {
    self = [super init];
    if (self) {
        [self updateData];
    }
    return self;
}

-(void)updateData {
    [self updateDataFromWifiNetwork];
    self.address = [self getNetworkAddress];
    self.ipsInRange = [self getIPsInRange];
}

- (void)updateDataFromWifiNetwork {
    self.deviceIP = nil;
    self.netmask = nil;
    self.broadcast = nil;
    struct ifaddrs *interfaces = NULL;
    struct ifaddrs *temp_addr = NULL;
    int success = 0;
    success = getifaddrs(&interfaces);
    if (success == 0){
        temp_addr = interfaces;
        while(temp_addr != NULL){
            if(temp_addr->ifa_addr->sa_family == AF_INET){
                if([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]){
                    self.deviceIP = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
                    self.netmask = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_netmask)->sin_addr)];
                    self.broadcast = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_dstaddr)->sin_addr)];
                }
            }
            temp_addr = temp_addr->ifa_next;
        }
    }
    freeifaddrs(interfaces);
    if(!self.deviceIP || !self.netmask){
        NSLog(@"error in updateDataFromWifiNetwork, device ip: %@ netmask: %@", self.deviceIP, self.netmask);
    }
}

-(NSString*)getNetworkAddress {
    if(!self.deviceIP || !self.netmask){
        return nil;
    }
    unsigned int address = [self convertSymbolicIpToNumeric:self.deviceIP];
    address &= [self convertSymbolicIpToNumeric:self.netmask];
    return [self convertNumericIpToSymbolic:address];
}

-(NSArray*)getIPsInRange {
    unsigned int address = [self convertSymbolicIpToNumeric:self.address];
    unsigned int netmask = [self convertSymbolicIpToNumeric:self.netmask];
    NSMutableArray *result = [[NSMutableArray alloc] init];
    int numberOfBits;
    for (numberOfBits = 0; numberOfBits < 32; numberOfBits++) {
        if ((netmask << numberOfBits) == 0){
            break;
        }
    }
    int numberOfIPs = 0;
    for (int n = 0; n < (32 - numberOfBits); n++) {
        numberOfIPs = numberOfIPs << 1;
        numberOfIPs = numberOfIPs | 0x01;
    }
    for (int i = 1; i < (numberOfIPs) && i < numberOfIPs; i++) {
        unsigned int ourIP = address + i;
        NSString *ip = [self convertNumericIpToSymbolic:ourIP];
        [result addObject:ip];
    }
    return result;
}

-(NSString*)convertNumericIpToSymbolic:(unsigned int)numericIP {
    NSMutableString *sb = [NSMutableString string];
    for (int shift = 24; shift > 0; shift -= 8) {
        [sb appendString:[NSString stringWithFormat:@"%d", (numericIP >> shift) & 0xff]];
        [sb appendString:@"."];
    }
    [sb appendString:[NSString stringWithFormat:@"%d", (numericIP & 0xff)]];
    return sb;
}

-(unsigned int)convertSymbolicIpToNumeric:(NSString*)symbolicIP {
    NSArray *st = [symbolicIP componentsSeparatedByString: @"."];
    if (st.count != 4){
        NSLog(@"error in convertSymbolicIpToNumeric, splited string count: %lu", st.count);
        return 0;
    }
    int i = 24;
    int ipNumeric = 0;
    for (int n = 0; n < st.count; n++) {
        int value = [(NSString*)st[n] intValue];
        if (value != (value & 0xff)) {
            NSLog(@"error in convertSymbolicIpToNumeric, invalid IP address: %@", symbolicIP);
            return 0;
        }
        ipNumeric += value << i;
        i -= 8;
    }
    return ipNumeric;
}

-(NSString*)description {
    return [NSString stringWithFormat: @"\nip:%@\nnetmask:%@\nnetwork:%@\nbroadcast:%@", self.deviceIP, self.netmask, self.address, self.broadcast];
}

@end