0

I have an IP address in unsigned long format, coding in C++ I have a CIDR notation IP address range such as "10.2.3.98/24"

How do i check if my IP address overlaps with the mentioned range?

FatalError
  • 52,695
  • 14
  • 99
  • 116
reza
  • 5,972
  • 15
  • 84
  • 126
  • 2
    Do you need help with parsing the strings as given, or have you already done that and need help with the bit masking? – Greg Hewgill Nov 19 '12 at 23:39
  • my problem is to go from IP address which i have as unsigned long to the representation of IP range notation start and end in unsigned long so I can do my range checking. In other words, how does one go from "10.2.3.98/24" to low and high range in unsigned long – reza Nov 20 '12 at 00:04

4 Answers4

1

To be as simple as possible, the part after the slash are the bits to keep, basically. So for example /24 means the most significant 3 bytes (24 bits) are preserved. Hence you can see if an address fits by masking it and checking for equality. The adress AND mask itself would be the min; If you are looking for max you can OR with the inverse of the mask.

adzm
  • 4,148
  • 1
  • 27
  • 21
0

This should work if you already know ip addresses as unsigned long and numbers:

bool cidr_overlap(uint32_t ip1, int n1,
                  uint32_t ip2, int n2)
{
    return (ip1 <= (ip2 | ((1ul << (32-n2))-1)))
        || (ip2 <= (ip1 | ((1ul << (32-n1))-1)));
}
mvp
  • 111,019
  • 13
  • 122
  • 148
0

Let's Assume Your IP addresses and Masks as Follows and IP addresses are in integer form.

Example 3232235896/30 ==> (actual IP 192.168.1.120/30)

Lets say You need to find out overlap of (ip_one , mask_one) and (ip_two , mask_two)

uint32_t mask_one_max = ((1ul << (32 - mask_one)) - 1);
uint32_t mask_one_min = ~mask_one_max;

uint32_t mask_two_max = ((1ul << (32 - mask_two)) - 1);
uint32_t mask_two_min = ~mask_two_max;

return (((ip_one & mask_one_min) <= (ip_two | mask_two_max)) && ((ip_two & mask_two_min) <= (ip_one | mask_one_max)));

This will return true if overlapping occurs.

The Solution is Proposed based on the Generic way of finding two integer ranges overlap. As you can see in the solution I first convert the CIDR ranges to range of Integers and use them to find the overlap.

Udenaka
  • 21
  • 2
0

This function checks if two networks overlap.

#include <arpa/inet.h>
#include <netinet/in.h>

static inline bool cidr_overlap(struct in_addr ip1, int n1, 
                                struct in_addr ip2, int n2)
{
    uint32_t mask1 = ~(((uint32_t)1 << (32 - n1)) - 1);
    uint32_t mask2 = ~(((uint32_t)1 << (32 - n2)) - 1);

    return (htonl(ip1.s_addr) & mask1 & mask2) == 
           (htonl(ip2.s_addr) & mask1 & mask2);
}