본문 바로가기

Java

네트워킹 - 서브넷 마스크 계산하기

참고==>네트워킹 - 서브넷 마스크 계산하기

하 나의 물리적 네트웍 의 모든 호스트는 같은 네트웍 주소를 가져야 한다. 만약 두 개 이상의 네트웍을 구성하길 원하면, 네트웍 주소를 서브넷으로 나누어야 한다. 이는 네트웍주소의 길이를 늘리면 (반대로 호스트의 길이를 줄이고)된다 - 보다 적은 호스트를 허용하는 여러개의 네트웍체계를 가지게 되며, 이 때, IP 주소들이결코 겹쳐져서는 안된다.

가장 정확한 방법은 한번에 한 bit 씩 네트웍의 길이를 늘리는 접근방식이다. 예를 들면, 하나의 /24 네트웍을 두개의 /25 네트웍으로. 하나의 /25 네트웍을 두개의 /26 네트웍으로,...

여기에 206.27.238.0 / 24 을 나눈 예를 들면,
206 . 27 . 238
11001000 00011011 11101110 xxxxxxxx 206.27.238.0/24 before
----------------------------------------------------------------
11001000 00011011 11101110 0xxxxxxx 206.27.238.0/25 after
11001000 00011011 11101110 1xxxxxxx 206.27.238.128/25
^
여기가 핵심으로 하나 들어난 네트웍 주소이다.

각 네트웍은 128개의 IP 주소를 가진다. (실제 126 개가 사용 가능 하다). 여기에 만족하면 좋은데, 더 원한다면, ..
11001000 00011011 11101110 0xxxxxxx 206.27.238.0/25
-------------------------------------------------------------
11001000 00011011 11101110 00xxxxxx 206.27.238.0/26
11001000 00011011 11101110 01xxxxxx 206.27.238.64/26
^
11001000 00011011 11101110 1xxxxxxx 206.27.238.128/25
-------------------------------------------------------------
11001000 00011011 11101110 10xxxxxx 206.27.238.128/26
11001000 00011011 11101110 11xxxxxx 206.27.238.192/26
^

이제. 하나의 /24 네트웍이 (256 개의 IP 주소), 각각 64개의 IP 주소가 가능한 4개의 /26 네트웍으로 나누어 졌다. 이렇게 하면, 0-63, 64-127, 128-191, 192-255가 되고, 이들은 겹치지 않는다. 각각의 네트웍의 첫 번째 와 마지막 숫자는 호스트 주소에 쓰이지 않으므로, 실제 사용가능한 주소는 1-62, 65-126, 129-190, 193-254 이다.

여기 잘못된 예를 들면:

First network: 206.27.238.0/25
Second network: 206.27.238.64/26
잘못된 곳은?
206.27.238.0/25 = 206 . 27 . 238 . 0xxxxxxx <-- range 0 to 127 206.27.238.64/26 = 206 . 27 . 238 . 01xxxxxx <-- range 64 to 127 OVERLAP! 이분법적인 네트웍 분리구성뿐아니라, 겹치지 않는다면, 다소 필요에 맞게 복잡한 구성도 가능하다. 아래에 한 예를 든다: 11001000 00011011 11101110 xxxxxxxx (original network)==>서브넷마스
-------------------------------------------------------------
11001000 00011011 11101110 000000xx 206.27.238.0/30 .0 to .3==>255.255.255.254
11001000 00011011 11101110 000001xx 206.27.238.4/30 .4 to .7==>255.255.255.254
11001000 00011011 11101110 000010xx 206.27.238.8/30 .8 to .11==>255.255.255.254
11001000 00011011 11101110 000011xx 206.27.238.12/30 .12 to .14==>255.255.255.254
11001000 00011011 11101110 0001xxxx 206.27.238.16/28 .16 to .31==>255.255.255.248
11001000 00011011 11101110 001xxxxx 206.27.238.32/27 .32 to .63==>255.255.255.240
11001000 00011011 11101110 01xxxxxx 206.27.238.64/26 .64 to .127==>255.255.255.224
11001000 00011011 11101110 1xxxxxxx 206.27.238.128/25 .128 to .255==>255.255.255.192

각 네트웍의 처음과 끝은 사용할 수 없고, 206.27.238.4/30 같은 네트웍은 단지 2개의 IP 주소 (.5, .6)만이 가능하다. 그러므로 /30 이 가장 작은 네트웍 이다. 이러한 주소는 주로 시리얼 연결된 라우터에 할당되는 주소로 많이 쓰인다. 양 라우터를 잇는 라인도 하나의 독립된 네트웍이며, 이를 위한 주소체계는 /30 이 적당하다. 단, 여러 라우터가 함께 연결되는 ISP의 경우는 다르다.


A class서브넷마스크별 구분

- 서브넷수 : 0개(0bit), subnet mask : 255.0.0.0, 호스트수 : 16,777,214개
- 서브넷수 : 2개(1bit), subnet mask : 255.128.0.0, 호스트수 : 8,388,606개
- 서브넷수 : 4개(2bit), subnet mask : 255.192.0.0, 호스트수 : 4,194,302개
- 서브넷수 : 8개(3bit), subnet mask : 255.224.0.0, 호스트수 : 2,097,150개
- 서브넷수 : 16개(4bit), subnet mask : 255.240.0.0, 호스트수 : 1,048,574개
- 서브넷수 : 32개(5bit), subnet mask : 255.248.0.0, 호스트수 : 524,286개
- 서브넷수 : 64개(6bit), subnet mask : 255.252.0.0, 호스트수 : 262,142개
- 서브넷수 : 128개(7bit), subnet mask : 255.254.0.0, 호스트수 : 131,070개
- 서브넷수 : 256개(8bit), subnet mask : 255.255.0.0, 호스트수 : 65,534개
- 서브넷수 : 5122개(9bit), subnet mask : 255.255.128.0, 호스트수 : 32,766개
- 서브넷수 : 1024개(10bit), subnet mask : 255.255.192.0, 호스트수 : 16,382개
- 서브넷수 : 2048개(11bit), subnet mask : 255.255.224.0, 호스트수 : 8190개
- 서브넷수 : 4096개(12bit), subnet mask : 255.255.240.0, 호스트수 : 4094개
- 서브넷수 : 8092개(13bit), subnet mask : 255.255.248.0, 호스트수 : 2046개
- 서브넷수 : 16382개(14bit), subnet mask : 255.255.252.0, 호스트수 : 1022개
- 서브넷수 : 32768개(15bit), subnet mask : 255.255.254.0, 호스트수 : 510개
- 서브넷수 : 65536개(16bit), subnet mask : 255.255.255.0, 호스트수 : 254개
- 서브넷수 : 131072개(17bit), subnet mask : 255.255.255.192, 호스트수 : 126개
- 서브넷수 : 262144개(18bit), subnet mask : 255.255.255.224, 호스트수 : 62개
- 서브넷수 : 524288개(19bit), subnet mask : 255.255.255.240, 호스트수 : 30개
- 서브넷수 : 1048576개(20bit), subnet mask : 255.255.255.248, 호스트수 : 14개
- 서브넷수 : 2097152개(21bit), subnet mask : 255.255.255.252, 호스트수 : 6개
- 서브넷수 : 4194304개(22bit), subnet mask : 255.255.255.254, 호스트수 : 2개
아이피 마스크를 이용해서 프로그램에서 계산하는 방법
참고==> D-H,appy :: IP 대역폭 계산

예를 들기 위한 ip는 '156.147.0.0/16' 이다
요 아이피는 마스크가 16이므로 네트워크 아이디부가 156.147 까지, 그리고 호스트가 0.0 ~ 255.255 이다
다시 설명하면 156.147.0.0을 2진수로 각각 표현하면
128+16+8+4 . 128+16+2+1 . 0. 0 이니까
비트로 표현하면
10011100 . 10010011 . 00000000 . 00000000 이다
그리고 마스크는 다음과 같다.
11111111 . 11111111 . 00000000 . 00000000 (/16 이니까 앞에서부터 16개만 1)

이렇게 되면 마스크가 1인 부분을 뺀 나머지 부분(= 마스크가 0인부분 = 하위 16비트)으로
호스트를 결정하는데

각각을 써보면
10011100 . 10010011 . 00000000 . 00000000 156.147.0.0 -> network id
10011100 . 10010011 . 00000000 . 00000001 156.147.0.1
10011100 . 10010011 . 00000000 . 00000010 156.147.0.2
10011100 . 10010011 . 00000000 . 00000011 156.147.0.3
10011100 . 10010011 . 00000000 . 00000100 156.147.0.4
10011100 . 10010011 . 11111111 . 11111111 156.147.255.255 -> broadcasting
등등등
으로 이루어진다

참고로 호스트 대역에서 0은 네트워크id, 255는 서브넷브로드캐스팅 주소로 할당되어있어서
실제 호스트로는 쓰지 않는다.

고로 마스크가 16이면
2^16 - 2 (65534개) 만큼의 호스트 갯수가 생긴다.
이 대역에서 서브네팅을 어떻게 하느냐에 따라 호스트 갯수는 달라진다...
그건 뭐...네트워크맹근 사람이 알아서 하고...

어쨋든 ip를 비트로 분리한다
string으로 ip를 입력받고 token함수로 . 과 / 을 분리하면
쉽게 156 147 0 0 16 을 분리할 수 있다
byte[]를 사용하여 분리하면
이차원 배열로 byte타입이 5개 생길것이다. a,b,c,d클래스+마스크
그러면 요 바이트 타입을 2진수로 나누는 함수로 비트화한다

함수는 알아서 작성하시길...
2로 나눠서 나머지쓰고 또 나누고 ...뭐 중학교때 배우는거...

그렇게 해서 각각을 나타내면

10011100 . 10010011 . 00000000 . 00000000 으로 되고
마스크는
string 타입 변수를 새로 생성해서 16만큼 루프 돌려서 앞에 1 쓰고 나머지 0으로 채워버리면
11111111 11111111 00000000 00000000으로 쉽게 나타낼 수 있다

그러면 이제 네트워크 아뒤는 바로 저 위에 ip를 쓰면 되고(156.147.0.0)
대역의 첫번째 호스트 주소는 저 아이피에 1만 더하면된다(156.147.0.1)
대역의 서브넷브로드캐스팅주소는 마스크에서 0인 부분만 ip에서 1로 바꾸면되고(156.147.255.255)
대역의 마지막 호스트 주소는 서브넷브로드캐스팅주소에서 1만 빼면된다(156.147.255.254)


PHP 를 이용하여 구하는 함수를 만들어 보았음

class lock_ip{

    function get_subnetmask($ip,$submask){//아이피와 서브네트워크192.168.0.5/255.255.255.0
        $subipbin = $this->ip2bin($submask);
        for($i=0;$i<32;$i++){
            if($subipbin[$i]=="0") break;
        }
        return $this->get_submask($ip,$i);
    }

    function get_submask($ip,$ipmask){//아이피와 마스크 네트워크 192.168.0.5/24
        //마스크 값까지만을 가지고 시작아이피와 끝아이피를 구한다.
        $binip = $this->ip2bin($ip);
        return array($this->bin2ip($this->bin2cut($binip,$ipmask,"0")),$this->bin2ip($this->bin2cut($binip,$ipmask,"1")));
    }

    function bin2ip($binip){
        return bindec(substr($binip,0,8)).".".bindec(substr($binip,8,8)).".".bindec(substr($binip,16,8)).".".bindec(substr($binip,24,8));
    }

    function ip2bin($ip){//아이피 값을 이진수0,1로 바꾼다.
        $ips = explode(".",$ip);
        $result="";
        for($i=0;$i<4;$i++) $result .= $this->decbin2string($ips[$i]);
        return $result;
    }

    function decbin2string($num){//2진수의 문자열을 앞단에 추가값을 주어 문자열로 만들어 반환
        $result="";
        $result = decbin($num);
        for($i=strlen($result);$i < 8;$i++) $result = "0".$result;
        return $result;
    }

    function bin2cut($bins,$cut,$mode="0"){//2진수의 문자열을 에서 원하는 $cut위치에서 부터$mode값을 마지막가지 채운다.
        $result="";
        for($i=0;$i < 32;$i++){
            if($i<$cut){$result .= $bins[$i];}else{$result .= $mode;}
        }
        return $result;
    }
}

//테스트를 해본다.
$lockip=new lock_ip("192.168.1.2");
print_r($lockip->get_subnetmask("192.168.0.3","255.255.240.0"));

print_r($lockip->get_subnetmask("192.168.0.3",16));

출처 : http://mylife.all.kr/2009/09/blog-post_23.html#comment-form