This is a short guide on how to check if an ip address is inside a certain ip / mask combination. An example would be to ensure that an ip address like "192.168.0.10" is inside "192.168.0.0/255.255.255.0"

One of the problems that you will face is that the standard functions for converting ip addresses to an unsigned int typically will also convert the address to network byte order which will not make. You could use the ntohl function to convert it back or a simple parsing functions like below to convert it to an unsigned long using sscanf.

uint32_t IPToUInt(const std::string ip) {
    int a, b, c, d;
    uint32_t addr = 0;

    if (sscanf(ip.c_str(), "%d.%d.%d.%d", &a, &b, &c, &d) != 4)
        return 0;

    addr = a << 24;
    addr |= b << 16;
    addr |= c << 8;
    addr |= d;
    return addr;
}

The rest is the very straight forward since an ip address is really just a 32bit number if you convert the ip address the subnet and the mask a straight check can be performed like this.

bool IsIPInRange(const std::string ip, const std::string network, const std::string mask) {
    uint32_t ip_addr = IPToUInt(ip);
    uint32_t network_addr = IPToUInt(network);
    uint32_t mask_addr = IPToUInt(mask);

    uint32_t net_lower = (network_addr & mask_addr);
    uint32_t net_upper = (net_lower | (~mask_addr));

    if (ip_addr >= net_lower &&
        ip_addr <= net_upper)
        return true;
    return false;
}

And just to make sure that it works here is some test code.

void test(const std::string ip, const std::string network, const std::string mask, bool expected) {
    if (IsIPInRange(ip, network, mask) != expected) {
        printf("Failed! %s %s %s %s\n", ip.c_str(), network.c_str(), mask.c_str(), expected ? "True" : "False");
    } else {
        printf("Success! %s %s %s %s\n", ip.c_str(), network.c_str(), mask.c_str(), expected ? "True" : "False");
    }
}

int main(int argc, char **argv) {
    std::string ip(argv[1]);

    test("192.168.1.1", "192.168.1.0", "255.255.255.0", true);
    test("192.168.1.1", "192.168.1.2", "255.255.255.255", false);
    test("192.168.1.3", "192.168.1.2", "255.255.255.255", false);

    test("220.1.1.22", "192.168.1.0", "255.255.255.0", false);
    test("220.1.1.22", "220.1.1.22", "255.255.255.255", true);
    test("220.1.1.22", "220.1.1.23", "255.255.255.255", false);
    test("220.1.1.22", "220.1.1.21", "255.255.255.255", false);

    test("0.0.0.1", "0.0.0.0", "0.0.0.0", true);
    test("192.168.1.2", "10.0.0.1", "255.255.255.255", false);

    return 0;
}


Did You find this page useful?

Yes No



Last Modified: 21 February 2017

Releated Posts


2017-04-25 - Linux Programming - Signals the easy way
2017-03-01 - Shooting yourself in the head with threads
2013-08-22 - CPP - Prevent an object by being copied with boost::noncopyable
2013-03-29 - CPP - Why you need a copy constructor
2013-03-27 - CPP -boost::optional
2013-02-16 - C - Some simple examples of using strcat
2012-11-06 - C++ - Stringstream example
2012-11-03 - C - How to override malloc / free
2012-09-22 - Linux Programming - Using inotify for detecting file modifications
2012-08-09 - C++ - Check an IP Address is in a IP Mask
2012-06-30 - CPP - Creating A basic python wrapper
2012-06-16 - CPP - Using gperf
2012-05-10 - CPP - Optional function arguments
2012-04-05 - Using gdb to debug a core file
2012-03-19 - CPP - Read / Write std::map to a file.
2012-03-15 - C - Is the stdin a tty
2012-03-13 - C - Converting from char / string to int using atoi
2012-03-08 - C - UDP Socket example
2012-02-20 - C - Get home dir location in linux
2012-02-17 - C - IP address validation
2012-02-15 - C - Get current ip address of an interface
2012-02-10 - Using asprintf instead of sprintf or snprintf
2012-01-31 - C - Example of how to overwrite argv
2012-01-30 - C - The string reverse
2012-01-27 - C - Palindrome
2012-01-26 - C - Example of using popen
2011-12-28 - C - gethostbyname example
2011-12-11 - C - Linux get mac address from interface
2011-02-10 - CSharp - Wake on Lan (WOL) Packet