2013-12-13 9 views
4

У меня есть список ipaddress/mask, который нужно преобразовать в нотацию CIDR.Как преобразовать ipaddress/mask в CIDR с помощью C++?

, например. 12.174.36.240/24 необходимо преобразовать в 12.174.36.0/24 или что-то вроде того, что http://www.subnet-calculator.com/cidr.php делает

Как это может быть достигнуто?

PS: значение маски не всегда 24.

+0

http://stackoverflow.com/questions/6657475/netmask-conversion-to-cidr-format-in-c –

ответ

2

Просто, чтобы привести вас в правильном направлении, считают, что адрес IPv4 есть (32-разрядное целое число). Теперь рассмотрим, что такое маска (поле бит, используемое в побитовых операциях).

Возьмите адрес 127.0.0.1 в системе с большим энтузиазмом. В шестнадцатеричном виде это 0x7f000001. 24-битная маска - 0xffffff00 (24 бит из 1, 8 бит 0, всего 32 бита). Побитовый и адрес и маска 0x7f000001 & 0xffffff00 = 0x7f000000 - это формат CIDR.

Я оставляю это для вас, чтобы определить, как лучше всего разобрать адрес, преобразовать адрес IPv4 в его целочисленную форму (и обратно) и создать битовую маску из маски префикса маршрутизации, хотя я скажу вам, что есть стандартные функции, по крайней мере, для обработки адресов.

2

Таким образом, в основном IPV4-адрес и сетевая маска представляют собой 32-разрядное целое число без знака, отображаемое парами 8 бит с точкой между ними.

Так что если у вас есть «ABCD» вы можете получить целое значение, делая

(a<<24) + (b<<16) + (c<<8) + d 

Если вы не привыкли к < < это сдвигают биты числа к левому количеству раз как правильный аргумент. Таким образом, a<<b - это то же самое, что и a*2^b

Теперь в CIDR число после косой черты указывает, сколько бит (из 32) является сетевой частью числа перед косой чертой. например. 10.10.10.1/28 имеет 28-битную сеть и 32-28 = 4-разрядную часть хоста. Это означает, что если вы берете ip и переводите его на число (= 0x0A0A0A01) и делаете логическое & с 0xFFFFFFFF < < 4 (= 0xFFFFFFF0), вы получаете 0x0A0A0A00. Если вы переводите это на ip-адрес со следующим:

sprintf("%d.%d.%d.%d", (n>>24)&0xff, (n>>16)&0xff, (n>>8)&0xff, n&0xff) 

Вы получаете 10.10.10.0. Кроме того, если вы переводите 0xFFFFFFF0 в ip с тем же алгоритмом, вы получите 255.255.255.248, который является маской сети, которая соответствует длине маски 28.

IPv6 точно такой же, кроме 128 бит, разделенных на 8 16-разрядных кластеров, отображаемых в hex с запятыми между ними с некоторым причудливым ярлыком для нескольких прогонов 0 (: :) ..

например.

fe80::52e5:49ff:ffc9:1889/64 == 

;;convert the mask 
0xffffffffffffffffffffffffffffffff << (128-64) = 
0xffffffffffffffff0000000000000000 

;;convert the ip: 
fe80::52e5:49ff:ffc9:1889 == 
fe80:0000:0000:0000:52e5:49ff:ffc9:1889 == 
0xfe8000000000000052e549ffffc91889 

    0xfe8000000000000052e549ffffc91889 
& 0xffffffffffffffff0000000000000000 
= 0xfe800000000000000000000000000000 

;;convert first address in range back to string: 
fe80:0000:0000:0000:0000:0000:0000:0000 = 
fe80:: 

Я думаю, что на основе этого вы можете сделать функцию, которая делает то, что вы хотите.

+1

Спасибо. Я нашел аналогичный подход и в сети. Однако я искал некоторые стандартные библиотеки C++, которые выполняют аналогичную задачу? Наверное, нет, следовательно, для этого нужно будет использовать мою собственную функцию. Выведет код после его завершения. – chingupt