520 likes | 707 Views
주소 변환 함수. Network Lab. 김 성 준. 목 차. 인터넷 IP 주소 인터넷 주소 클래스 Netmask 의 이해 IP 주소 할당 사설 IP 주소 예약된 IP 주소 IP 주소 처리. 인터넷 IP 주소. 보통 점으로 구분된 네 개의 10 진수로 구성 4 바이트로 구성 10 진 표기법. 인터넷 주소 클래스. 인터넷 주소의 구성 네트워크 주소 (Netid) 호스트가 연결되어 있는 네트워크 확인 호스트 주소 (Hostid)
E N D
주소 변환 함수 Network Lab. 김 성 준 한남대학교 컴퓨터공학과 컴퓨터 네트워크 실험실
목 차 • 인터넷 IP 주소 • 인터넷 주소 클래스 • Netmask의 이해 • IP 주소 할당 • 사설 IP 주소 • 예약된 IP 주소 • IP 주소 처리
인터넷 IP 주소 • 보통 점으로 구분된 네 개의 10진수로 구성 • 4바이트로 구성 • 10진 표기법
인터넷 주소 클래스 • 인터넷 주소의 구성 • 네트워크 주소(Netid) • 호스트가 연결되어 있는 네트워크 확인 • 호스트 주소(Hostid) • 네트워크의 호스트 중에 하나의 특정 호스트 확인 Netid Hostid Class type
인터넷 주소 클래스 • 인터넷 주소 클래스
인터넷 주소 클래스(계속) • 인터넷 주소 클래스
인터넷 주소 클래스(계속) • 10진 표기법을 이용한 클래스
Netmask의 이해 • Netmask (Mask) Mask 255.255.0.0 141.14.0.0 141.14.2.21 IP 주소 IP 주소
Netmask의 이해 (계속) • netmask를 적용하여 네트워크 주소 산출
Netmask의 이해 (계속) • A, B, C 클래스 주소를 위한 Netmask
Netmask의 이해 (계속) • 예제 3.1 (netmask.c) 예제 IP 초기화 address[] adr_inet 초기화 최상위 바이트 검사 결과 출력
Netmask의 이해 (계속) • 참고 사항 • sockaddr_in 구조체 struct sockaddr_in { short sin_family; u_short sin_port; struct in_addr sin_addr; } • in_addr 구조체 struct in_addr { u_long s_addr; } • Address Family #define AF_UNSPEC PF_UNSPEC #define AF_LOCAL PF_LOCAL #define AF_UNIX PF_UNIX #define AF_INET PF_INET • Protocol Family #define PF_UNSPEC 0 /* Unspecified. */ #define PF_LOCAL 1 /* Local to host */ #define PF_UNIX PF_LOCAL /* Old BSD name for PF_LOCAL. */ #define PF_INET 2 /* IP protocol family. */
Netmask의 이해 (계속) • 초기화 • 각종 변수 및 초기값 설정 int x; /* Index variable */ struct sockaddr_in adr_inet; /* AF_INET */ int len_inet; /* length */ unsigned msb; /* Most significant byte */ char class; char *netmask; static struct { unsigned char ip[4]; } addresses[] = { { { 44,135,86,12 } }, { { 127,0,0,1 } }, { { 172,16,23,95 } }, { { 192,168,9,1 } } };
Netmask의 이해 (계속) • adr_inet 초기화 memset(&adr_inet,0,sizeof adr_inet); // 메모리 초기화 adr_inet.sin_family = AF_INET; // 도메인 설정 adr_inet.sin_port = htons(9000); // 포트 번호 설정 memcpy(&adr_inet.sin_addr.s_addr, addresses[x].ip,4); // addresses[x] -> adr_inet.sin_addr.s_addr 로 복사 len_inet = sizeof adr_inet;// 길이 정보 저장 ※ htonl 함수 : 호스트 순서 주소를 네트워크 순서 주소로 변환
Netmask의 이해 (계속) 0x80 = 1000 0xC0 = 1100 0xE0 = 1110 0xF0 = 1111 • 최상위 바이트 검사 msb = *(unsigned char *) adr_inet.sin_addr.s_addr; // 주소 추출 // 최상위 바이트 검사 if ( (msb & 0x80) == 0x00 ) { // 1비트만 검사 class = 'A'; netmask = "255.0.0.0"; // 0000 A 클래스 } else if ( (msb & 0xC0) == 0x80 ) { // 2비트만 검사 class = 'B'; netmask = "255.255.0.0"; // 1000 B 클래스 } else if ( (msb & 0xE0) == 0xC0 ) { // 3비트만 검사 class = 'C';netmask = "255.255.255.0"; // 1100 C 클래스 } else if ( (msb & 0xF0) == 0xE0 ) { // 4비트만 검사 class = 'D';netmask = "255.255.255.255"; // 1110 D 클래스 } else { class = 'E';netmask = "255.255.255.255"; // 1111 E 클래스 }
Netmask의 이해 (계속) • 결과 출력 printf("Address %u.%u.%u.%u is class %c netmask %s\n", addresses[x].ip[0], addresses[x].ip[1], addresses[x].ip[2], addresses[x].ip[3], class, netmask); • 실행 결과 [sjkim@alzza Chap03]$ ./netmask Address 44.135.86.12 is class A netmask 255.0.0.0 Address 127.0.0.1 is class A netmask 255.0.0.0 Address 172.16.23.95 is class B netmask 255.255.0.0 Address 192.168.9.1 is class C netmask 255.255.255.0
IP 주소 할당 • 3개의 클래스 (A, B, C) 클래스 신청 가능 • Netid를 부여 받아 Hostid 발급 • interNIC • www.nic.org • 한국(www.krnic.or.kr)
사설 IP 주소 • 보통 IP 주소는 InterNIC에 등록 • 인터넷에 연결되지 않으면 유일한 IP 를 가질 필요 없음. • RFC 1597 -> 사설 IP 할당 방법 기술 사설 IP 주소 범위
예약된 IP 주소 • 특정 목적을 위해 미리 예약된 IP 주소 • RFC 1166 – INTERNET NUMBERS • 예약된 IP 주소들을 나열 • AMPRNET(The Amateur Radio Internet)
IP 주소 처리 • 문자열 <-> 숫자 변환 함수 제공 • 프로그램 작성이 용이 • 제공되는 함수들 • inet_addr 함수 • inet_aton 함수 • inet_ntoa 함수 • inet_network 함수 • inet_lnaof함수 • inet_netof 함수 • inet_makeaddr 함수
IP 주소 처리 - inet_addr(3) 함수 • 문자열을 32비트 IP 주소로 변환 • unsigned long inet_addr(const char *string); • string-> 32비트 IP 주소로 변환할 문자열 • 변환이 성공하면 올바른 IP 주소 반환 • 만약 실패 하면 INADDR_NONE 반환 • errno에 어떠한 에러 코드도 설정하지 않음
IP 주소 처리 - inet_addr(3) 함수 (계속) • 예제 3.3 inetaddr.c 초기화 소켓 생성 / 주소 설정 주소 바인드 소켓 주소 출력
IP 주소 처리 - inet_addr(3) 함수(계속) • 초기화 int z; struct sockaddr_in adr_inet; /* AF_INET */ int len_inet; /* length */ int sck_inet; /* Socket */ • 소켓 생성 sck_inet = socket(AF_INET,SOCK_STREAM,0);
IP 주소 처리 - inet_addr(3) 함수(계속) • 주소 설정 memset(&adr_inet,0,sizeof adr_inet); // 초기화 adr_inet.sin_family = AF_INET; // 도메인 설정 adr_inet.sin_port = htons(9000); // 포트 설정 adr_inet.sin_addr.s_addr = inet_addr("127.0.0.95"); // 주소 설정 • 주소 바인드 z = bind(sck_inet, (struct ockaddr*)&adr_inet, len_inet); • 소켓 주소 출력 system("netstat -pa --tcp 2>/dev/null| grep inetaddr");
IP 주소 처리 - inet_addr(3) 함수(계속) • 실행 결과 tcp 0 0 127.0.0.95:9000 *:* CLOSE 5381/inetaddr • 에러 검출 함수 static void bail(const char *on_what) { fputs(on_what,stderr); // 문자열을 표준 에러로 출력 fputc('\n',stderr); // 표준 에러에 개행문자 출력 exit(1); // 프로그램 종료 }
IP 주소 처리 - inet_aton(3) 함수 • IP 주소 문자열을 32비트 IP 주소로 변환 • int inet_aton(const char *string, struct in_addr *addr); • string-> IP주소의 문자열 • addr -> 변환된 IP 주소로 갱신된 구조체 • 실패하면 0이 반환 • errno에 에러 코드 설정 하지 않음. • 성공하면 addr에 올바른 IP 주소 설정
IP 주소 처리 - inet_aton(3) 함수 (계속) • 예제 3.4 inetaton.c 초기화 소켓 생성 / 주소 설정 주소 바인드 소켓 주소 출력
IP 주소 처리 - inet_aton(3) 함수 (계속) • 초기화 int z; struct sockaddr_in adr_inet; /* AF_INET */ int len_inet; /* length */ int sck_inet; /* Socket */ • 소켓 생성 sck_inet = socket(AF_INET,SOCK_STREAM,0);
IP 주소 처리 - inet_aton(3) 함수 (계속) • 주소 설정 memset(&adr_inet,0,sizeof adr_inet); // 초기화 adr_inet.sin_family = AF_INET; // 도메인 설정 adr_inet.sin_port = htons(9000); // 포트 설정 // 주소 변환 실패하면 bail 함수 호출 if ( !inet_aton("127.0.0.23", &adr_inet.sin_addr) ) bail("bad address."); len_inet = sizeof adr_inet; // 길이 설정
IP 주소 처리 - inet_aton(3) 함수 (계속) • 주소 바인드 z = bind(sck_inet, (struct sockaddr *)&adr_inet, len_inet); • 소켓 주소 출력 system("netstat -pa --tcp 2>/dev/null| grep inetaton"); • 실행결과 tcp 0 0 127.0.0.23:9000 *:* CLOSE 5949/inetaton
IP 주소 처리 - inet_ntoa(3) 함수 • 32비트 IP 주소를 문자열로 변환 • char *inet_ntoa(struct in_addr addr); • addr -> 변환할 IP 주소를 저장하고 있는 구조체 • 성공하면 문자열 IP 주소의 포인터가 반환 • 내부 변수에 결과를 저장하기 때문에 다음에 호출 되기 전까지만 유효한 결과를 가진다.
IP 주소 처리 - inet_ntoa(3) 함수(계속) • 예제 3.5 inetntoa.c 초기화 주소 설정 함수 호출 후 결과 출력
IP 주소 처리 - inet_ntoa(3) 함수(계속) • 초기화 struct sockaddr_in adr_inet; /* AF_INET */ int len_inet; /* length */ • 주소 설정 memset(&adr_inet,0,sizeof adr_inet); // 구조체 초기화 adr_inet.sin_family = AF_INET; // Domain 설정 adr_inet.sin_port = htons(9000); // 포트번호 설정 // 주소 설정 “127.0.0.23” -> adr_inet.sin_addr if ( !inet_aton("127.0.0.23",&adr_inet.sin_addr)) puts("bad address.");
IP 주소 처리 - inet_ntoa(3) 함수(계속) • 함수 호출 및 결과 출력 printf("The IP Address is %s\n",inet_ntoa(adr_inet.sin_addr)) • 실행 결과 The IP Address is 127.0.0.23
IP 주소 처리 - inet_network(3) 함수 • IP 주소를 32비트 호스트 순서 값으로 변환 • 마스크 값을 호스트 비트 혹은 네트워크 비트에 적용 할 때 사용 • unsigned long inet_network(const char *addr); • addr -> 10진 IP주소를 포함하는 문자열 • 반환값은 호스트 순서 32비트 IP 주소 • 실패시 0xFFFFFFFF(모두 1)
IP 주소 처리 - inet_network(3) 함수(계속) • net_addr = inet_network("192.168.9.1") & 0xFFFFFF00; • 결과 => 0xC0A80900 (10진수 192.168.9.0) • 192.168.9.1을 16진수로 변환 -> C0 A8 09 01 • C0 A8 09 01 & FF FF FF 00 = C0 A8 09 00
IP 주소 처리 - inet_network(3) 함수(계속) • 예제 3.6 network.c 초기화 함수 호출 후 결과 출력
IP 주소 처리 - inet_network(3) 함수(계속) • 초기화 int x; const char *addr[] = {"44.135.86.12", "127.0.0.1", "172.16.23.95", “192.168.9.1"}; unsigned long net_addr; • 함수 호출 후 결과 출력 net_addr = inet_network(addr[x]); printf("%14s = 0x%08lX net 0x%08lX\n", addr[x],net_addr, (unsigned long)htonl(net_addr)) ※ htonl 함수 : 호스트 순서 주소를 네트워크 순서 주소로 변환
IP 주소 처리 - inet_network(3) 함수(계속) • 실행 결과 44.135.86.12 = 0x2C87560C net 0x0C56872C 127.0.0.1 = 0x7F000001 net 0x0100007F 172.16.23.95 = 0xAC10175F net 0x5F1710AC 192.168.9.1 = 0xC0A80901 net 0x0109A8C0 C0 09 192.168.9.1 = 0x C0 A8 09 01 net 0x 01 09 A8 C0 01 A8
IP 주소 처리 - inet_lnaof(3) 함수 • IP 주소에서 네트워크 ID 부분을 제외한 호스트 ID 부분만을 반환 • unsigned long inet_lnaof(struct in_addr addr); • addr -> 네트워크 바이트 순서의 IP 주소 • 반환값 -> addr의 호스트 ID 부분
IP 주소 처리 - inet_lnaof(3) 함수 (계속) • inet_lnaof(3) 함수의 처리 예제 44.135.86.12 (10진수) 2C.87.56.0C (16진수)
IP 주소 처리 - inet_netof(3) 함수 • Inet_lnaof(3) 함수와 유사 • Host ID 대신 네트워크 ID 반환 • unsigned long inet_netof(struct in_addr addr); • addr -> 네트워크 바이트 순서의 IP 주소 • 반환값 -> addr의 네트워크 ID 부분
IP 주소 처리 - inet_netof(3) 함수 (계속) • inet_netof(3) 함수의 처리 예제 44.135.86.12 (10진수) 2C.87.56.0C (16진수)
IP 주소 처리 - inet_makeaddr(3) 함수 • inet_lnaof(3) 함수와 inet_netof(3)함수가 에서 분리한 네트워크 iD와 호스트 ID를 다시 결합하여 원래의 IP 주소를 생성 • struct in_addr inet_makeaddr(int net,int host); • net -> inet_netof 함수에서 추출한 네트워크 ID • host -> inet_lnaof 함수에서 추출한 호스트 ID • 반환값 -> 원래의 IP 주소를 저장한 in_addr구조체
IP 주소 처리 - inet_makeaddr(3)함수(계속) • 예제 3.7 makeaddr.c 초기화 소켓 생성 / 주소 설정 주소 분리(호스트 ID와 네트워크 ID) 및 출력 구조체 재초기화 재결합 및 출력
IP 주소 처리 - inet_makeaddr(3)함수(계속) • 초기화 int x; // for문의 첨자 struct sockaddr_in adr_inet; /* AF_INET */ // 예제 IP 주소들 const char *addr[] = { "44.135.86.12", "127.0.0.1", "172.16.23.95", "192.168.9.1" }; // 네트워크 ID와 호스트 ID를 위한 변수 unsigned long net, hst;
IP 주소 처리 - inet_makeaddr(3)함수(계속) • 소켓 생성 및 주소 생성 memset(&adr_inet,0,sizeof adr_inet); // 메모리 초기화 adr_inet.sin_family = AF_INET; // 도메인 설정 adr_inet.sin_port = htons(9000); // 포트번호 설정 if ( !inet_aton(addr[x],&adr_inet.sin_addr) ) // 주소 생성 puts("bad address."); ※ htonl 함수 : 호스트 순서 주소를 네트워크 순서 주소로 변환
IP 주소 처리 - inet_makeaddr(3)함수(계속) • 주소 분리 및 출력 // 호스트 ID 추출 hst = inet_lnaof(adr_inet.sin_addr); // 네트워크 ID 추출 net = inet_netof(adr_inet.sin_addr); // 추출 내용 출력 (기존의 IP, 네트워크 ID, 호스트 ID) printf("%14s : net=0x%08lX host=0x%08lX\n", inet_ntoa(adr_inet.sin_addr), net, hst);
IP 주소 처리 - inet_makeaddr(3)함수(계속) • 구조체 재 초기화 • 재구성할 IP 주소를 보다 명확히 보여주기 위해서 memset(&adr_inet,0,sizeof adr_inet); // 메모리 초기화 adr_inet.sin_family = AF_INET; // 도메인 설정 adr_inet.sin_port = htons(9000); // 포트번호 설정
IP 주소 처리 - inet_makeaddr(3)함수(계속) • 주소의 재결합 및 출력 • 재결합 adr_inet.sin_addr = inet_makeaddr(net,hst); • 출력 printf("%14s : %s\n\n", "inet_makeaddr", inet_ntoa(adr_inet.sin_addr));