soobook
NETWORK

CIDR and Subnet Calculation

CIDR(Classless Inter-Domain Routing)는 IP 주소를 network 부분과 host 부분으로 나누는 경계를 비트 단위로 정하는 방식이다. 192.168.10.0/24에서 /24는 앞의 24비트가 network를 가리킨다는 뜻이고, 나머지 8비트로 그 network 안의 host를 구분한다.

IP Address Structure

IP 주소를 계산하려면 비트와 byte부터 알아야 한다.

비트(bit)는 컴퓨터가 다루는 정보의 가장 작은 단위이고, 0과 1 중 하나의 값을 가진다.

비트를 여러 개 이어 붙이면 표현할 수 있는 값이 늘어나며, 비트가 하나 늘 때마다 값의 개수는 두 배가 된다. 비트 1개로는 0과 1 두 가지를, 비트 2개로는 00, 01, 10, 11 네 가지를 표현할 수 있으므로, 비트 n개로는 2n2^n가지 값을 표현할 수 있다.

byte는 비트 8개를 묶은 단위다. 비트 8개로는 28=2562^8 = 256가지 값을 표현할 수 있으므로, byte 하나는 00000000(0)부터 11111111(255)까지의 값을 가진다. network 표준 문서는 byte 대신 octet이라는 용어를 쓴다.

예전에는 컴퓨터마다 byte를 이루는 비트 수가 달랐기 때문에, 정확히 8비트라는 뜻을 분명히 하려고 octet이라는 이름을 따로 쓴다.

IPv4 주소는 32비트, 즉 4byte 숫자이므로 주소를 2322^{32}개, 약 43억 개까지 만들 수 있다. 0과 1이 32개 이어진 값은 사람이 읽기 어려우므로, 32비트를 octet 네 개로 나누고 각 octet을 10진수로 바꿔 점으로 이어 쓴다.

그래서 IP 주소를 이루는 네 숫자는 각각 0부터 255까지의 값만 가진다.

decimal   192      .168      .10       .77
binary    11000000 .10101000 .00001010 .01001101

주소 하나는 다시 두 부분으로 나뉜다. 앞쪽의 network 부분은 이 주소가 어느 network에 속하는지를 나타내고, 뒤쪽의 host 부분은 그 network 안에서 어느 machine인지를 나타낸다. network 부분이 같은 주소끼리는 router를 거치지 않고 직접 통신하고, network 부분이 다른 주소로 가는 packet은 router가 전달한다.

router는 packet의 목적지 주소에서 network 부분만 보고 어디로 보낼지 정한다. 그래서 routing table에는 host마다 항목을 두지 않고, network마다 항목을 하나씩 둔다. 그러려면 router가 32비트 중 어디까지가 network 부분인지 알아야 한다. 이 경계를 처음에는 class로 정했고, 지금은 CIDR로 정한다.

Classful Addressing

IPv4 초기에는 주소의 첫 몇 비트를 보고 경계를 정했다. 첫 비트가 0이면 Class A, 앞 두 비트가 10이면 Class B, 앞 세 비트가 110이면 Class C이고, class가 정해지면 network 부분의 길이도 함께 정해진다. 이렇게 class로 경계를 정하는 방식을 classful addressing이라고 부른다.

Class첫 octet 범위앞 비트network 부분network 하나의 주소 수
A0 ~ 12708비트 (/8)16,777,216
B128 ~ 1911016비트 (/16)65,536
C192 ~ 22311024비트 (/24)256

첫 octet만 보면 class를 알 수 있으므로, router는 packet의 목적지 주소만 보고도 network 부분의 길이를 알 수 있었다.

착각하면 안 되는 것은, 앞 비트(0, 10, 110)가 network 길이를 계산해 내는 구조가 아니라 그냥 이렇게 약속한 것이라는 점이다. network 크기를 세 가지로 먼저 정해 두고, 주소가 그중 어느 형식인지를 맨 앞 비트로 표시하기로 정했다.

앞 비트는 network 부분 안에 포함된다. 이 약속을 비트로 그려 보면 다음과 같다. n은 network 번호를 적는 비트이고, h는 host 비트다.

Class A  0nnnnnnn.hhhhhhhh.hhhhhhhh.hhhhhhhh   0   + 7 bits  | 24 bits
Class B  10nnnnnn.nnnnnnnn.hhhhhhhh.hhhhhhhh   10  + 14 bits | 16 bits
Class C  110nnnnn.nnnnnnnn.nnnnnnnn.hhhhhhhh   110 + 21 bits | 8 bits

표에서 network 부분이 8, 16, 24비트인 것은 앞 비트와 network 번호 비트를 합친 길이이기 때문이다. 앞 비트는 값이 고정되어 있으므로, 실제로 만들 수 있는 network는 Class A가 27=1282^7 = 128개, Class B가 214=16,3842^{14} = 16{,}384개, Class C가 221=2,097,1522^{21} = 2{,}097{,}152개다.

표의 첫 octet 범위도 앞 비트에서 나온다. 첫 octet이 0xxxxxxx인 값은 0부터 127까지, 10xxxxxx인 값은 128부터 191까지, 110xxxxx인 값은 192부터 223까지다. 앞 비트가 하나 늘 때마다 범위는 절반으로 줄어들므로, 전체 주소 공간에서 Class A가 1/2, Class B가 1/4, Class C가 1/8을 차지한다.

첫 octet이 224부터 239까지인 Class D는 multicast용이고 240부터 255까지인 Class E는 예약 대역이어서, 두 class는 일반 host에 쓰지 않는다.

이 방식의 문제는 network 크기가 세 가지뿐이라는 점이다.

host 2,000대를 쓰는 조직을 생각해 보자. Class C network 하나에는 host를 254대까지만 둘 수 있으므로 부족하다.

그렇다고 Class B를 받으면 host를 65,534대까지 둘 수 있으므로, 2,000대를 쓰고도 6만 개가 넘는 주소가 쓰이지 않은 채 남는다.

이 주소들은 이미 그 조직에 할당된 network에 속하므로, 다른 조직에 나눠 줄 수도 없다.

CIDR에서는 이 조직에 /21 block 하나를 주면 된다. /21에는 주소가 2,048개 있으므로 host 2,000대를 수용하고도 남는 host 주소는 46개뿐이고, routing table에서도 항목 하나만 차지한다.

이렇게 class 대신 필요한 크기만큼 주소를 나눠 주기 위해, 1993년 9월에 RFC 1518과 RFC 1519가 CIDR를 정의했다. 이후 2006년에 RFC 4632가 RFC 1519를 대체했고, 지금 CIDR의 기준 문서는 RFC 4632다.

CIDR Notation

CIDR 표기는 주소 뒤에 /와 숫자를 붙인다. /n은 32비트 중 앞의 n비트가 network를 식별한다는 뜻이고, 이 n을 prefix 길이라고 부른다. 남은 32 − n비트는 host 부분이다. 192.168.10.0/24라면 앞 24비트인 192.168.10이 network를 가리키고, 마지막 8비트로 host를 구분한다.

host 부분이 32 − n비트이므로, network 하나에 들어가는 주소 수는 다음과 같다.

주소 수=232−n\text{주소 수} = 2^{32-n}

이 가운데 두 주소는 host에게 줄 수 없다. host 비트가 모두 0인 주소는 network 자체를 가리키는 network address이고, host 비트가 모두 1인 주소는 network 안의 모든 host에게 packet을 한 번에 보낼 때 쓰는 broadcast address다. 그래서 host에게 실제로 할당할 수 있는 주소 수는 다음과 같다.

host 수=232−n−2\text{host 수} = 2^{32-n} - 2

prefix 길이는 subnet mask라는 형식으로도 쓴다. subnet mask는 network 부분을 1로, host 부분을 0으로 채운 32비트 값을 IP 주소처럼 octet 네 개로 적은 것이다. /24는 1이 24개, 0이 8개이므로 255.255.255.0이 된다. 두 형식은 같은 정보를 담고 있어서 서로 바꿔 쓸 수 있다.

prefixsubnet mask주소 수host 수
/8255.0.0.016,777,21616,777,214
/16255.255.0.065,53665,534
/20255.255.240.04,0964,094
/21255.255.248.02,0482,046
/24255.255.255.0256254
/26255.255.255.1926462
/28255.255.255.2401614
/30255.255.255.25242
/32255.255.255.2551-

prefix 길이가 1 늘어날 때마다 주소 수는 절반으로 줄어든다. /32는 주소 하나를 그대로 가리키는 표기여서 network address와 broadcast address를 따로 두지 않는다. 또 RFC 3021은 장비 두 대만 연결하는 point-to-point link에서는 /31의 두 주소를 network address와 broadcast address로 남기지 않고 모두 host에 할당하도록 허용했다.

/20과 /21처럼 경계가 octet 중간에 걸리면, subnet mask의 해당 octet은 255나 0이 아닌 240, 248 같은 값이 된다. 이 값은 다음 절에서 직접 계산한다.

How to Calculate

IP 주소와 prefix 길이를 알면 network address와 broadcast address, host 범위를 구할 수 있다. 172.16.45.200/21을 예로 들어보자.

network address는 네트워크의 첫 주소이고, 네트워크 자체를 가리키는 번호로 쓴다. routing table에 172.16.40.0/21처럼 들어가는 값이 이 주소다. broadcast address는 네트워크의 마지막 주소다. 이 주소로 packet을 보내면 같은 network의 모든 host가 그 packet을 받는다.

위에서 “host 비트가 모두 0인 주소는 network 자체를 가리키는 network address”라고 설명했는데, “network 부분을 제외한 host 부분이” 0을 말하는 것이니 헷갈리면 안된다.

Step 1: Decimal to Binary

10진수 octet을 2진수로 바꾸려면, 8비트의 각 자리가 나타내는 값을 먼저 적어 둔다. 왼쪽부터 128, 64, 32, 16, 8, 4, 2, 1이다. 그다음 바꿀 숫자에서 큰 자리값부터 빼 나가면서, 뺄 수 있으면 그 자리에 1을 적고 뺄 수 없으면 0을 적는다.

bit value  128  64  32  16   8   4   2   1
200          1   1   0   0   1   0   0   0   = 128 + 64 + 8
45           0   0   1   0   1   1   0   1   = 32 + 8 + 4 + 1

200에서 128을 빼면 72가 남고, 72에서 64를 빼면 8이 남는다. 8은 32와 16보다 작으므로 그 두 자리는 0이고, 8의 자리에서 8을 빼면 0이 되므로 나머지 자리도 모두 0이다. 그래서 200은 11001000이다. 같은 방법으로 계산하면 172는 10101100, 16은 00010000, 45는 00101101이다.

Step 2: Prefix to Mask

/n의 mask는 왼쪽부터 1을 n개 채우고 나머지를 0으로 채운 값이다. /21은 1이 21개이므로 octet 단위로 나누면 8 + 8 + 5가 된다. 첫 번째와 두 번째 octet은 1이 8개여서 11111111이고, 세 번째 octet은 1이 5개, 0이 3개이므로 11111000이며, 네 번째 octet은 모두 0이다.

11111000을 10진수로 바꾸면 128 + 64 + 32 + 16 + 8 = 248이므로, /21의 subnet mask는 255.255.248.0이다. 경계가 걸린 octet의 값은 그 octet에 들어간 1의 개수에 따라 다음 아홉 가지 중 하나가 된다.

ones    0    1    2    3    4    5    6    7    8
value   0  128  192  224  240  248  252  254  255

Step 3: AND with the Mask

network address는 IP 주소와 mask를 비트마다 AND 연산해서 얻는다. AND는 두 비트가 모두 1일 때만 1이 되는 연산이다. 그래서 mask가 1인 자리에서는 IP의 원래 비트가 그대로 남고, mask가 0인 자리에서는 IP 비트가 무엇이든 0으로 지워진다. 결과는 network 부분을 그대로 두고 host 부분만 0으로 바꾼 값이 된다.

IP    172.16.45.200 = 10101100.00010000.00101101.11001000
Mask  /21           = 11111111.11111111.11111000.00000000   (255.255.248.0)
AND                 = 10101100.00010000.00101000.00000000   = 172.16.40.0

세 번째 octet을 보면, IP의 00101101에서 mask가 1인 앞 5비트 00101은 그대로 남고, mask가 0인 뒤 3비트 101은 000으로 바뀐다. 그래서 결과는 00101000이다.

Step 4: Binary to Decimal

마지막으로 결과를 octet마다 10진수로 되돌린다. 1이 있는 자리의 자리값을 모두 더하면 된다. 위 결과에서 세 번째 octet 00101000은 32 + 8 = 40이므로, network address는 172.16.40.0이다.

Broadcast Address and Host Count

broadcast address는 network address에서 host 비트를 모두 1로 채운 값이다. /21에서 host 비트는 뒤 11비트이고, 세 번째 octet의 뒤 3비트와 네 번째 octet 전체가 여기에 해당한다.

Network    = 10101100.00010000.00101000.00000000   = 172.16.40.0
Broadcast  = 10101100.00010000.00101111.11111111   = 172.16.47.255

세 번째 octet 00101111은 32 + 8 + 4 + 2 + 1 = 47이고, 네 번째 octet은 255다. host에게 줄 수 있는 주소는 network address 바로 다음인 172.16.40.1부터 broadcast address 바로 앞인 172.16.47.254까지이며, 개수는 211−2=2,0462^{11} - 2 = 2{,}046개다.

Private Ranges

RFC 1918(1996년)은 internet에서 routing되지 않는 주소 대역 세 개를 사설 대역으로 정했다. internet의 router는 사설 대역을 목적지로 하는 packet을 전달하지 않는다. 그래서 어느 조직이든 IANA나 registry와 조율하지 않고 이 대역을 내부 network에 쓸 수 있고, 여러 조직이 같은 주소를 겹쳐 써도 된다. 사설 대역의 host가 internet과 통신할 때는 내부 network와 internet 사이에 있는 NAT(Network Address Translation) 장비가 사설 주소를 공인 IP로 바꿔 준다.

CIDR범위주소 수classful 기준
10.0.0.0/810.0.0.0 ~ 10.255.255.25516,777,216Class A network 1개
172.16.0.0/12172.16.0.0 ~ 172.31.255.2551,048,576Class B network 16개
192.168.0.0/16192.168.0.0 ~ 192.168.255.25565,536Class C network 256개

즉 10.0.0.0/8은 Class A network 하나와 같은 범위이고, 172.16.0.0/12는 172.16부터 172.31까지 이어진 Class B network 16개, 192.168.0.0/16은 192.168.0부터 192.168.255까지 이어진 Class C network 256개와 같은 범위다.

Class Terms in Practice

classful 체계는 폐기되었지만, 실무에서는 “A class”, “C class”라는 말을 지금도 쓴다. 문제는 같은 class 이름이 두 가지 뜻으로 섞여 쓰인다는 점이다.

첫 번째 뜻은 대역의 위치다. “A class 대역”이라고 하면 보통 10.x.x.x를, “B class 대역”은 172.16.x.x부터 172.31.x.x까지를, “C class 대역”은 192.168.x.x를 가리킨다. 사설 대역 세 개가 각각 Class A, B, C 범위 안에 있어서 이런 이름이 붙었다.

두 번째 뜻은 network의 크기다. “C class 하나 할당해 줘”라는 말은 /24 network 하나, 즉 주소 256개를 달라는 뜻이다. Class C network 하나의 크기가 /24였기 때문에, 지금도 /24 network 하나를 “C class 하나”라고 부른다.

두 뜻은 한 주소 안에서 충돌하기도 한다. 10.1.2.0/24는 10.x.x.x에 있으므로 위치로는 “A class 대역”이지만, 크기가 /24이므로 크기로는 “C class 하나”다. classful 체계가 폐기되어 class 이름에는 공식적인 정의가 남아 있지 않으므로, 두 말 모두 틀렸다고 할 수 없다. 그래서 상대가 위치를 말하는지 크기를 말하는지는 맥락으로 구분해야 하고, 헷갈릴 때는 10.1.2.0/24처럼 CIDR 표기로 다시 확인하는 편이 정확하다.

Summary

CIDR는 IP 주소를 network 부분과 host 부분으로 나누는 경계를 /n으로 직접 적는 방식이다. 핵심은 다음과 같다.

  • /n은 32비트 중 앞 n비트가 network 부분이라는 뜻이다. network 하나의 주소 수는 232−n2^{32-n}이고, network address와 broadcast address를 뺀 232−n−22^{32-n} - 2개를 host에 할당한다.
  • network address는 IP와 mask를 AND 연산해서 구하고, broadcast address는 host 비트를 모두 1로 채워서 구한다.
  • class 체계는 1993년 CIDR로 대체되었다. 실무에서 쓰는 “A class”, “C class”는 대역의 위치를 가리키기도 하고 /8, /24 같은 크기를 가리키기도 하므로 맥락으로 구분한다.
  • 사설 대역은 RFC 1918이 정한 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16이고, 172.16.0.0/12는 172.16부터 172.31까지다.

References