符号なしの長い形式のIPアドレスを持っており、C++でコーディングしています。「10.2.3.98/24」などのCIDR表記のIPアドレス範囲があります。
IPアドレスが上記の範囲と重複しているかどうかを確認するにはどうすればよいですか?
符号なしの長い形式のIPアドレスを持っており、C++でコーディングしています。「10.2.3.98/24」などのCIDR表記のIPアドレス範囲があります。
IPアドレスが上記の範囲と重複しているかどうかを確認するにはどうすればよいですか?
できるだけ簡単にするために、スラッシュの後の部分は基本的に保持するビットです。したがって、たとえば/ 24は、最上位3バイト(24ビット)が保持されることを意味します。したがって、アドレスをマスクして等しいかどうかを確認することで、アドレスが適合するかどうかを確認できます。アドレスとマスク自体が最小になります。最大値を探している場合は、マスクの逆とORすることができます。
これは、IPアドレスがunsignedlongおよび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)));
}
次のようにIPアドレスとマスクを想定してみましょう。IPアドレスは整数形式です。
例3232235896/30==>(実際のIP 192.168.1.120 / 30)
(ip_one、mask_one)と(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)));
オーバーラップが発生した場合、これはtrueを返します。
このソリューションは、2つの整数範囲の重複を見つける一般的な方法に基づいて提案されています。ソリューションでわかるように、最初にCIDR範囲を整数の範囲に変換し、それらを使用して重複を見つけます。
この関数は、2つのネットワークが重複しているかどうかをチェックします。
#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);
}