最初に、uint32_t
(<stdint.h>
で定義されています)にIPv4アドレスをパックし、ドット付き10進表記の最も左のオクテットを最も重要なビットに置きます。例えば、
uint32_t ipv4_pack(const uint8_t octet1,
const uint8_t octet2,
const uint8_t octet3,
const uint8_t octet4)
{
return (((uint32_t)octet1) << 24)
| (((uint32_t)octet2) << 16)
| (((uint32_t)octet3) << 8)
| ((uint32_t)octet4);
}
およびその逆は、128.64.32.16
等
unsigned char *ipv4_unpack(unsigned char *addr, const uint32_t packed)
{
addr[3] = (uint8_t)(packed);
addr[2] = (uint8_t)(packed >> 8);
addr[1] = (uint8_t)(packed >> 16);
addr[0] = (uint8_t)(packed >> 24);
return addr;
}
アドレス0x80402010
(128 == 80 、64 == 40 、32 == 20に充填されています,16 == 10 )。
あなたはまた、設定することを多くの最高ビットのバイナリマスクに(1〜32)
CIDRプレフィックスサイズを変換する必要が
:
uint32_t ipv4_mask(const int prefix_size)
{
if (prefix_size > 31)
return (uint32_t)0xFFFFFFFFU;
else
if (prefix_size > 0)
return ((uint32_t)0xFFFFFFFFU) << (32 - prefix_size);
else
return (uint32_t)0U;
}
プレフィックスバイナリで11111111111111111111111100000000のマスク24に相当します、 0xFFFFFF00は16進数です。
プレフィックス28は、11111111111111111111111111110000のバイナリマスクに対応し、0xFFFFFFF0は16進数のマスクに対応します。アドレスaddr1.addr2.addr3.addr4/prefix
について
、範囲(当該範囲について、典型的にゲートウェイアドレス)の最初のアドレスは
uint32_t first = ipv4_pack(addr1, addr2, addr3, addr4) & ipv4_mask(prefix);
及び最後のアドレス(前記範囲のため、典型的にはブロードキャストアドレス)
uint32_t last = ipv4_pack(addr1, addr2, addr3, addr4) | (~ipv4_mask(prefix));
あります
first <= last
すべての場合、first
からlast
までを反復し、ipv4_unpack()
を呼び出して値をドット付き10進表記に解凍すると、すべてのIPv4アドレスが生成されます。範囲。
IPv6でも同じことが働きますが、uint128_t
のようなタイプが必要です。 (これは、より小さい符号なし整数型でエミュレートすることができますが、命令はいくつかありますが、論理は同じです)。
現在のIPはIPv4とIPv6の2つだけです。IPアドレスではなく、IP(インターネットプロトコル)ではないと思います。 –
@Ron Maupinはいthats私が言ったこと。明快に編集 –