2013-06-03 3 views
1
CIDR 표기법을 제공하지만, 점점 서브넷 회원을 확인할 수 있습니다

우선, 내가 그것을해야하지만, 작은 서브넷 마스크는 항상 true를 반환하는 것처럼 보인다 내 코드를 찾고 :거의 예상치 못한 결과

[[email protected] test]# ./test "99.99.99.99/8" 25.25.25.25 

The given address is in the given cidr address 
[[email protected] test]# ./test "99.99.99.99/16" 25.25.25.25 

The given address is not in the given cidr address 
[[email protected] test]# ./test "99.99.99.99/24" 25.25.25.25 

The given address is not in the given cidr address 

을 물론, 마지막 두 가지 검사가 이상적입니다. 예기치 않은 네거티브를 얻지 않고 오탐 (false positives). 그것은 또한 내가 10 이하의 서브넷 마스크를 지정하는 경우에만 실패 할 것 같다

[[email protected] test]# ./test "99.99.99.99/9" 25.25.25.25 

The given address is in the given cidr address 
[[email protected] test]# ./test "99.99.99.99/10" 25.25.25.25 

The given address is not in the given cidr address 
[[email protected] test]# 

이 내가 일을하도록 정의한 기능입니다 (프로그램의 나머지 부분은 본질적으로/다른 리턴 코드에, 하나의 경우 " 주어진 IP)는 "주어진 IP 서브넷 밖에"에 제로 "서브넷에 있습니다

int inSubnet(const char *cidrNotation, const char *needleAddress){ 

     char subnetDesignation[25], strPad[25]; 
     unsigned short int maskSize; 
     unsigned int startOfCidr=strlen(cidrNotation)-3; 
     unsigned long int subnetMask=0, givenIP, subnetAddress; 
     unsigned short int iter=0; 

     /* BEGIN sanitization of arguments */ 
      // If they gave real CIDR clip it off the end and save it. 
     if (strstr(cidrNotation, "/")){ 

      strcpy(strPad, cidrNotation); 
      maskSize=atoi((strPad+startOfCidr+1)); 
      *(strPad+startOfCidr) = '\0'; 
      strcpy(subnetDesignation, strPad); 

      // Otherwise assume 32-bit mask (effectively equates two specific addys) 
     } else { 
      strcpy(subnetDesignation, cidrNotation); 
      maskSize=32; 
     } /* END SANITIZATION */ 

      // Generate subnet mask in network byte order 
     for (iter=1; iter<maskSize; iter++){ 
       subnetMask=subnetMask<<1; // move mask right by one, fill LSB with zero 
       subnetMask++; // flip the one bit on 
     } 

      // Get subnetDesignation into binary form and 
     inet_pton(AF_INET, subnetDesignation, &subnetAddress); 
     subnetAddress=subnetAddress & subnetMask; // Ensure it matches the subnet's prefix no matter how it was given 

     inet_pton(AF_INET, needleAddress, &givenIP); 

      // Since all non-subnet bits are flipped, the result of an AND should be identical to the subnet address. 
     if ((givenIP & subnetAddress) == subnetAddress) 
       return 1; 
     else 
       return 0; 

} 

내가 완성 프로젝트의이 부분을 얻기에 매우 가까이있어 것 같아, 난 그냥 일종의했습니다 어떻게 든 실종 됐습니다. 당신이 /8 마스크가있는 경우, 예를 들어, 당신은 단지 두 개의 문자를 사용

unsigned int startOfCidr=strlen(cidrNotation)-3; 

:

답변

2

난 당신이 안전하게 넷 마스크는 항상 문자열의 끝에 세 개의 문자를 차지한다고 가정 할 수 있다고 생각하지 않습니다 그것을 지정하십시오. (이것은 아마도 모든 것이 10보다 큰 경우 작동합니다.) 대신 / 문자를 검색하고 거기에서 시작하는 넷 마스크를 구문 분석하십시오.

+0

이런 젠장, 나는 그 사람이 나를 도망 갔는지 모르겠다. 시험 할 시간을주세요. 그러나 나는 당신이 옳을 것이라는 점에 거의 긍정적입니다. – Bratchley

+0

아직 내 코드를 업데이트하지 않았지만'/ 8' 대신'/ 08' 서브넷 마스크를 전달하면 예상대로 작동합니다. – Bratchley

+0

fwiw, 리터럴 포인터 수학을'strchr' 출력으로 대체하면 문제가 해결되었습니다. – Bratchley