2015-02-05 2 views
2

CIDR 범위 목록을 반환하는 IPv4Range (startIPAddr, endIPAddr) 함수를 이해하려고합니다. 예를 들어주어진 IP 범위를 만드는 서브넷 목록을 계산하십시오.

:

10.0.0.0 - 10.0.0.3 -> 10.0.0.0/30 
    10.0.0.0 - 10.0.0.6 -> 10.0.0.0/30, 10.0.0.4/31, 10.0.0.6/32 

더욱 복잡한 경우.

이전에이 코드의 온라인 예제를 많이 보았지만 그 중 일부는 전혀 작동하지 않으며 나머지는 최소 공통 서브넷을 반환합니다 (예 : 10.0.0.0/29에 10.0.0.0 포함). - 10.0.0.4 그러나 그것들은 같지 않습니다. 그래서 나는 전체 범위보다는 오히려 기대 한 것이 아닙니다.)

답변

2

우선이 코드는 무언가를 직접 작성하지 않고 작동하는 코드를 가져 오는 사이트가 아닙니다. 그러나 나는이 문제에 어떻게 접근하고 필요한대로 쉽게 채택 할 수있는 코드를 제공하는지 설명 할 것입니다.

10.0.0.0 - 10.0.0.255과 같은 단일 범위를 정의하는 범위가 있으면이 문제는 쉽게 발생하므로 더 복잡한 것을 얻을 수 있습니다 (예 : 10.0.0.1 - 10.0.0.126). 이 범위는 실제로 10.0.0.0/25에 가깝지만 양쪽 끝에/32가 없기 때문에 범위를 채우기 위해 12 개의 범위가 필요합니다.

이 문제

은 다음과 같이 나타낼 수있다

   Start IP       End IP 
        v        v 
-------|----------+----------------+---------------+-----------|------ 
    ^  .        .   ^
    Subnet address .        . Broadcast address 
     .   .        .   . 
     .   \________________________________/   . 
     .      Provided Range     . 
     .              . 
     \_______________________________________________________/ 
           Scope Range 

당신은 나누기를 사용하여 쉽게 문제의 그런 종류를 해결하고 접근을 정복 할 수 있습니다. 이 경우 서브넷 마스크가 항상 2의 거듭 제곱임을 염두에두면 더 작은 두 개의 문제로이 문제 (범위 : 10.0.0.1 - 10.0.0.126/25 마스크)를 나눌 수 있습니다.

   Start IP       End IP 
        v        v 
-------|----------+---------------++---------------+-----------|------ 
    ^      ||       ^
    Subnet address     ||     Broadcast address 
     .       ||       . 
     \__________________________/\___________________________/ 
     .   /X+1      /X+1    . 
     .              . 
     \_______________________________________________________/ 
         Scope prefix length: /X 

접두어 길이를 늘리면 기본적으로 범위가 두 개로 분할됩니다. 따라서 10.0.0.0/25 대신에 10.0.0.0/2610.0.0.64/26이 있고 두 가지 새로운 범위는 10.0.0.1 - 10.0.0.63 및입니다.

  1. 귀하의 시작 IP 주소 끝 IP 당신의 범위는 당신이 그것을 더 분할 할 수 있도록 작은 주소를
  2. 을 방송하는 동일 서브넷과 같다 : 때까지 당신은 당신의 범위이 방법을 분할 계속 (/ 32).

이것은 내가 작성한 코드입니다. 모든 계산은 IP 주소 (하지 점 진수)의 진수 표현에 완료, 그래서 처음 두 기능은 long과 다른 방법으로 주위에 점으로 구분 된 십진수 표기법으로 IP와 string 변환 :

#include <sstream> 
long str_to_long(string ip){ 
    stringstream s(ip); 
    int o1, o2, o3, o4; 
    char ch; 
    s >> o1 >> ch >> o2 >> ch >> o3 >> ch >> o4; 
    long ip_long = 0; 
    ip_long = 0 | (o1 << 24) | (o2 << 16) | (o3 << 8) | o4; 
    return ip_long; 
} 

string long_to_str(long ip){ 
    stringstream tmp; 
    tmp << to_string((long long) ip >> 24 & 0xFF).c_str() << '.'; 
    tmp << to_string((long long) ip >> 16 & 0xFF).c_str() << '.'; 
    tmp << to_string((long long) ip >> 8 & 0xFF).c_str() << '.'; 
    tmp << to_string((long long) ip & 0xFF).c_str(); 
    return tmp.str(); 
} 

주를 함수는 두 개의 (long) 인수 - Start IP와 End IP -를 취하여 필요한 서브넷을 인쇄합니다. 대신이를 법원에 인쇄하는

void subnets(long start_ip, long end_ip){ 
    int host_bits = 0, host_mask = 0; 
    long tmp = start_ip^end_ip; 
    while(tmp != 0){ 
     tmp = tmp >> 1; 
     host_bits++; 
    } 
    host_mask = (unsigned long)-1 >> (32 - host_bits); 
    long network_addr = start_ip & (-1^host_mask); 
    long broadcast_addr = start_ip | host_mask; 
    if(host_bits > 1){ 
     long split_low = (network_addr | host_mask >> 1); 
     long split_high =(broadcast_addr & (-1^host_mask >> 1)); 
     if(start_ip != network_addr || end_ip != broadcast_addr){ 
      subnets(start_ip, split_low); 
      subnets(split_high, end_ip); 
     }else{ 
      cout << long_to_str(start_ip) << "/" << 32-host_bits << endl; 
     } 
    }else{ 
     cout << long_to_str(start_ip) << "/" << 32-host_bits << endl; 
    } 
} 

당신은 벡터 내부 서브넷을 넣어이를 채택 할 수있다 (또는 당신이 원하는 무엇이든). 따라서 처음에 언급 한 범위 인 subnets(str_to_long("10.0.0.1"), str_to_long("10.0.0.126"))을 사용하여이 범위를 실행하면 해당 범위를 만드는 12 개의 서브넷 목록을 얻게됩니다.

10.0.0.1/32 
10.0.0.2/31 
10.0.0.4/30 
10.0.0.8/29 
10.0.0.16/28 
10.0.0.32/27 
10.0.0.64/27 
10.0.0.96/28 
10.0.0.112/29 
10.0.0.120/30 
10.0.0.124/31 
10.0.0.126/32 
관련 문제