2014-02-12 3 views
0

내 프로그램은 의 시작 IP와 끝 IP로 구분 된 범위의 IP 주소를 찾습니다. 다음은 로컬 무선 네트워크의 예는 다음과 같습니다in_addr_t, 하나의 IP에서 다음 IP로 점프

MyIP & Netmask = 192.168.1.0 
MyIP | ~Netmask = 192.168.1.255 

내 프로그램 192.168.1.254에 192.168.1.1에서 사용 가능한 모든 IP를 반복 할 수 있어야하지만, 내가 얻을 수있는 상수 또는 "적절한"방법을 찾을 수 없습니다 IP와 다른 IP 사이의 거리 여기에 내가 테스트를 위해 사용되는 샘플 프로그램입니다 :

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 

int main(int argc, char** argv) 
{ 
     struct sockaddr_in addr1, addr2, addr3, addr4, addr5; 

     addr1.sin_addr.s_addr = inet_addr("192.168.1.1"); 
     addr2.sin_addr.s_addr = inet_addr("192.168.1.2"); 
     addr3.sin_addr.s_addr = inet_addr("192.168.1.3"); 
     addr4.sin_addr.s_addr = inet_addr("192.168.1.255"); 
     addr5.sin_addr.s_addr = inet_addr("192.168.2.1"); 

     fprintf(stdout, "addr2 - addr1 = %u\n", addr2.sin_addr.s_addr - addr1.sin_addr.s_addr); 
     fprintf(stdout, "addr3 - addr2 = %u\n", addr3.sin_addr.s_addr - addr2.sin_addr.s_addr); 
     fprintf(stdout, "addr4 - addr3 = %u\n", addr4.sin_addr.s_addr - addr3.sin_addr.s_addr); 
     fprintf(stdout, "addr5 - addr4 = %u\n", addr5.sin_addr.s_addr - addr4.sin_addr.s_addr); 

     return EXIT_SUCCESS; 
} 

내가 얻을 다음과 같은 출력 :

addr2 - addr1 = 16777216 
addr3 - addr2 = 16777216 
addr4 - addr3 = 4227858432 
addr5 - addr4 = 33619968 

지금, 나는 192.168.1.1과 192.168.1.2 사이의 거리가 16777216 (2^24 인 이유를 이해). 자, 위의 값을 "적절하게"얻을 수있는 방법이 있습니까? 가능한 경우 사전 정의 된 상수를 사용하십시오 (도트 형식의 IP 문자열 조작은 실제로 솔루션이 아닙니다)?

  • 192.168.1.1에서 192.168.1.2로 점프하려면 in_addr_t 값에 무엇을 추가해야합니까?
  • 더 큰 서브넷에서 175.1.1.255에서 175.1.2.0으로 점프하려면 in_addr_t 값에 무엇을 추가해야합니까? 그러면 클래스 A IP는 어떻게됩니까?
  • 서브넷이 더 구체적인 경우에 대비하여 네트워크 정보를 사용하여 "갭"값을 결정할 수 있습니까?
  • 반복적 인 문제에 대해 더 쉽고/깨끗한 방법이 없습니까?
+1

아마 endian-ness 일 것입니다. 주소 값을 16 진수로 인쇄하고 패턴이 있는지 확인하십시오. –

답변

1

그것은 시스템의 엔디안 문제

의 IP 주소가이 방법으로 4 옥텟에서 제시 한 inet_addr("192.168.1.1") 반환 :

0x01 | 0x01 | 0xA8 | 0xC0 
// 1 . 1 . 168 . 192 

inet_addr("192.168.1.2") 반환

0x02 | 0x01 | 0xA8 | 0xC0 
// 2 . 1 . 168 . 192 

을 차이 inet_addr("192.168.1.2") - inet_addr("192.168.1.2")은 다음과 같습니다.

엔디안을 피하기 위해 각 inet_addr() 중위210
0x0201A8C0 - 0x0101A8C0 = 0x1000000 // in decimal is 16777216 

사용 htonl() 기능은 그래서 inet_addr("192.168.1.2")htonl()inet_addr("192.168.1.1") 반환

다음
0xC0 | 0xA8 | 0x01 | 0x01 
// 192 . 168 . 1 . 1 

와의

0xC0 | 0xA8 | 0x01 | 0x02 
// 192 . 168 . 1 . 2 

그리고 htonl()를 반환합니다

발행 차이점 1은 1과 같습니다.

 addr1.sin_addr.s_addr = htonl(inet_addr("192.168.1.1")); 
     addr2.sin_addr.s_addr = htonl(inet_addr("192.168.1.2")); 
     addr3.sin_addr.s_addr = htonl(inet_addr("192.168.1.3")); 
     addr4.sin_addr.s_addr = htonl(inet_addr("192.168.1.255")); 
     addr5.sin_addr.s_addr = htonl(inet_addr("192.168.2.1")); 
+2

만약 그가 네트워크 주문에서 호스트 주문으로 변환하는데'ntohl'을 사용해야한다고 생각한다면 ...'htonl'은 호스트 주문에서 네트워크 주문으로 변환합니다. –

+0

네트워크 바이트 순서 ... 내가 실제로 그것을 놓친 것은 무엇입니까?네트워크 주문 값을 반복하고 내 호스트의 상대적인 맥락에서 새로운'in_addr_t'를 설정하기 위해'ntohl'을 사용할 것입니다. 귀하의 상세한 답변을 보내 주셔서 감사합니다. –

+0

@JohnWHSmith u r Welcome – MOHAMED