M.Alatrash
M.Alatrash

Reputation: 1265

iOS iP Address comparing in range of iPs

I am developing an app which shows content based on country, so I get the IP Address of the user, the problem is how to check if this IP is between two IPs. Example:

if I have this IP : myIP = 127.0.0.1

how can I check if it's between this range: IP1 = 2.88.0.0; IP2 = 2.91.255.255;

Thanks.

Upvotes: 0

Views: 1190

Answers (2)

trojanfoe
trojanfoe

Reputation: 122391

127.0.0.1 is the address of the loopback device. You want the address of en0 or whatever, which is the device connected to the wifi/mobile network. (It's possible to enumerate all the device addresses using getifaddrs(); see this SO question).

For IPv4 address the value can be represented using an 32-bit unsigned int so the range change is as simple as:

BOOL inRange = ipAddress >= rangeStart && ipAddress <= endRange;

See this SO question.

EDIT The OP seems to be stuck on the conversion of an IP address represented using dot-notation within a string (i.e. "2.88.0.0") and the unsigned int that I refer to. For this I refer him to the inet_aton() function, which is used to perform that conversion. You will get many hits on the internet if you search for that function and how to use it.

EDIT 2 OK, I'll add a more complete answer as the OP is still having issues:

The key piece of information I think you are missing WRT using inet_aton() is byte order. There is a concept of network byte order, which is big-endian given the founders of the internet used Dec PDP 11's to develop on. Most computers these days are little endian. So you need to add htonl() into the mix, which is the function to convert from network to host byte order (where the l means long, which is in-fact 32-bit).

So:

#import <Foundation/Foundation.h>
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>

@interface NetworkStuff : NSObject
- (uint32_t)convertIpAddress:(NSString *)ipAddress;
- (BOOL)ipAddress:(NSString *)ipAddress isBetweenIpAddress:(NSString *)rangeStart
     andIpAddress:(NSString *)rangeEnd;
@end

@implementation NetworkStuff
- (uint32_t)convertIpAddress:(NSString *)ipAddress {
    struct sockaddr_in sin;
    inet_aton([ipAddress UTF8String], &sin.sin_addr);
    return ntohl(sin.sin_addr.s_addr);
}

- (BOOL)ipAddress:(NSString *)ipAddress isBetweenIpAddress:(NSString *)rangeStart
     andIpAddress:(NSString *)rangeEnd {
    uint32_t ip = [self convertIpAddress:ipAddress];
    uint32_t start = [self convertIpAddress:rangeStart];
    uint32_t end = [self convertIpAddress:rangeEnd];
    return ip >= start && ip <= end;
}

@end

#define BOOLSTR(b) (b ? @"YES" : @"NO")

int main()
{  
    @autoreleasepool{
        NetworkStuff *networkStuff = [NetworkStuff new];
        NSLog(@"%@", BOOLSTR([networkStuff ipAddress:@"2.90.1.2" isBetweenIpAddress:@"2.88.0.0" andIpAddress:@"2.91.255.255"]));
        NSLog(@"%@", BOOLSTR([networkStuff ipAddress:@"2.92.1.2" isBetweenIpAddress:@"2.88.0.0" andIpAddress:@"2.91.255.255"]));
    }
    return 0;
}

$ clang -DDEBUG=1 -g -fobjc-arc -o iprange iprange.m -framework Foundation
$ ./iprange
2014-02-10 09:42:29.530 iprange[14693:707] YES
2014-02-10 09:42:29.532 iprange[14693:707] NO

Upvotes: 2

M.Alatrash
M.Alatrash

Reputation: 1265

First i have convert the IP Address to number using the following method:

-(double)getIpAsNumberr:(NSString *)ip
{
    NSArray *ipParts = [ip componentsSeparatedByString:@"."];
    double result = 0;

    for (int i = 0; i < 4; i++)
    {
        result += [ipParts[i]doubleValue] * (pow(256, (3 - i)));
    }

    return result;
}

After Converting the IP Addresses I use the following method find if the IP Address is falling in some Range like being between 2.88.0.0 and 2.91.255.255 :

-(BOOL)isBetween:(NSString *)myIPAddress fromRange:(NSString *)from ToRange:(NSString *)to
{
    double myIpAsNumber = [self getIpAsNumberr:myIPAddress];
    double ipFromAsNumber = [self getIpAsNumberr:from];
    double ipToAsNumber = [self getIpAsNumberr:to];

    BOOL inRange = myIpAsNumber >= ipFromAsNumber && myIpAsNumber <= ipToAsNumber;

    return inRange;
}

That's it.

The following method I used to convert the IP Address to unsigned integer,(Didn't work for me, so I used the above one):

-(double)getIpAsUnSignedInteger:(NSString *)ip
{
    struct sockaddr_in antelope;
    char *some_addr;
    const char *ipUnsigned = [ip cStringUsingEncoding:NSStringEncodingConversionAllowLossy];

    inet_aton(ipUnsigned, &antelope.sin_addr); // store IP in antelope

    some_addr = inet_ntoa(antelope.sin_addr); // return the IP
    printf("%s\n", some_addr); // prints the IP Address

    // and this call is the same as the inet_aton() call, above:
    antelope.sin_addr.s_addr = inet_addr(ipUnsigned);

    NSString *ipAsNumber = [NSString stringWithFormat:@"%u",antelope.sin_addr.s_addr];
    NSLog(@"ssss == %@",ipAsNumber);

    return [ipAsNumber doubleValue];
}

Upvotes: 0

Related Questions