Linux Socket Programming - 도메인과 주소체계 - NETWORK Labs. 김 도 형 한남대학교 컴퓨터공학과 컴퓨터 네트워크 실험실
목 차 주소 체계의 이해 소켓 주소의 형태 Big-endian, Little-endian byte Ordering 의 차이 가상 지역 주소와 형태 소켓 주소가 필요하지 않을 때
이름없는 소켓 개 요 No dial U.S present’s office Soviet Union’s
이름없는 소켓(계속) 익명 호출 socketpair(2)에 의해 생성 주소를 갖지 않는 소켓을 생성 직접 연결되고 주소 불필요 예) 긴급전화와 같이 전화번호가 없어도 직접연결 원격소켓이 연결되기 위해 실제 주소가 필요 연결된 소켓 중 하나는 주소가 없다. 호출한 위치의 로컬 소켓은 알 수 없다.
이름없는 소켓(계속) 주소 생성 지역 주소 통신에 필요 서비스에 접속하기 위한 프로그램 필요 지역주소는 접속유지에 필요 고정주소가 배정되면 망 관리자의 작업증가
도메인 이해 socket(2) 함수 TCP/IP를 대신하여 사용 #include <sys/types.h> #include <sys/socket.h> int socketpair(int domain, int type, int protocol, int sv[2]);
도메인 이해(계속) protocol 구문 일반적으로 0 으로 지정 주소 그룹 함수 운영체제에서 domain에 기본 프로토콜로 사용 주소 그룹 함수 AF_접두어로 표시 domain 구문은 주소 계층을 사용하기 위해 선택
도메인 이해(계속) 소켓 주소 형성 통신 프로토콜의 조건 도메인 형태 AF_접두사는 주소 체계 표시 자신의 네트워킹 주소 형태 주소계층은 사용되는 주소의 형태를 표시 도메인 형태 AF_LOCAL AF_UNIX AF_INET AF_접두사는 주소 체계 표시 도메인 구분은 주소 체계로 선택
소켓 주소 형태 소켓 주소 생성 BSD소켓 인터페이스 주소구조를 받아들일 포인터 타입( void *)이 없다. ANSI-C표준 미적용 주소구조를 받아들일 포인터 타입( void *)이 없다. C언어에 의해서 일반적인 주소 구조로 정의 # include <sys/socket.h>
소켓 주소 형태(계속) 소켓 주소생성 struct sockaddr { Sa_family_t sa_family; /* 주소 계층*/ Char sa_data[14] /* 주소 데이터*/ }; sa_family_t 는 리눅스 기반의 2바이트 정수 주소 데이터 sa_data[14]는 나머지 14바이트를 표시 전체 구조는 16바이트
소켓 주소 형태(계속) 소켓 주소 생성 (계속) 소켓 주소생성 개요 묘사 sa_data[14] sa_family
소켓 주소 형태(계속) 다른 주소 구문과 일치 모든 주소가 sa_family 멤버 같은 로케이션내에서 선언 레퍼런스 모델을 제공 모든 주소가 sa_family 멤버 같은 로케이션내에서 선언 원소들이 주소에서 남아 있는 바이트의 크기가를 판단하는데 필요
지역주소 형태 개 요 Linux가 실행되는 HOST 소켓에 사용 프린터로 출력되는 lpr(1) 명령에서 사용됨. PC의 지역 소켓이 통신 지역 통신을 위한 TCP/IP 사용도 가능.
지역 주소 형태(계속) 개 요(계속) 지역 주소 계층은 AF_UNIX도메인을 참조 Linux 커널 2.2.0이후로 추상 소켓이름을 지원함 구문의 명칭 – sockaddr_un AF_LOCAL또는 AF_UNIX주소 이름
지역 주소 형태(계속) 개 요(계속) struct sockaddr_un { Sa_family sun_family; /* 주소 계층*/ Char sun_path[108]; /* 경로명 */ }; sun_family 는 AF_LOCAL또는 AF_UNIX를 선언 scokaddr_un 규칙에 따라 값을 표현 sun_path[108]는 UNIX 경로명을 포함 문자 배열의 끝에 null byte가 필요치 않음
지역 주소 형태(계속) 일반적인 지역 주소의 형태 이름공간의 주소는 파일시스템의 경로명 경로명의 의한 소켓의 프로세서이름 경로명의 구성요소로 접근 디렉토리명에서 마지막 소켓 오브젝트 생성 권한을 갖음
지역 주소 형태(계속) 일반적인 지역 주소의 형태 /dev/printer의 AF_LOCAL/AF_UNIX 주소 / d e v Sun_family=AF_LOCAL Sun_path[108]
지역 주소 형태(계속) 일반적인 지역 주소의 형태 첫째 2바이트는 AF_LOCAL의 주소타입을 표시 null문자가 아닌 나머지 바이트는 /dev/printer 문자 C 코드는 주소를 초기화 프로그램은 자료 입력 전 모두 0으로 초기화 memset(3) 함수를 사용해서 종료. struct sockaddr_un unaddr; memset (&uaddr, 0, sizeof uaddr); 위 함수 호출은 주소 계층을 모두 0으로 바꿈
지역 주소 형태(계속) af_unix.c Sck_unix 선언 경로명 /tmp/my_sock 복사 adr_unix - 지역주소구조 정의 주소길이 계산 Socket(2)에 의해 소켓 생성 소켓 생성 Unlink(2) 호출 Netstat(1) invoke Adr_unix를 0으로 변환 소켓 종료 UNIX경로명 생성 AF_UNIX 초기화
지역 주소 형태(계속) 가상 지역 주소 AF_UNIX소켓은 항상 파일 시스템 객체가 포함 bind(2)호출에 의해 원래 파일 시스템 객체가 제거되지 않고 같은 이름이 사용되면 할당되지 않음 리눅스 커널 2.2는 지역 주소에 대한 가상 명칭가능 경로명의 첫번째 바이트를 null로 만듦
지역 주소 형태(계속) af_unix2.c
지역 주소 형태(계속) 주 의 AF_LOCAL, AF_UNIX를 리눅스의 SUN_LEN()매크로를 이용하면 첫번째 바이트는 null이 아님
인터넷(IPv4) 소켓 주소 형태 개 요 일반적으로 사용하는 리눅스 기반 주소계층은 AF_INET 계열 TCP/IP네트워크 이외의 다른 호스트와 통신하기 위해 IPv4를 제공 socketaddr_in 구문을 정의하는 include파일은 C언어에 의해 정의 #include <netient/in.n>
인터넷(IPv4) 소켓 주소 형태(계속) 개 요 struct sockaddr_in { sa_family_t sin_family; /* 주소계층 */ uinet16_t sin_port; /* 포트 번호*/ struct in_addr sin_addr; /* 인터넷 주소*/ unsigned char sin_zero[8] /* pad bytes */ }; Struct in_addr { unit32_t s_addr; /* 인터넷 주소*/
인터넷(IPv4) 소켓 주소 형태(계속) 개 요(계속) sin_family멤버는 sa_ family와 같은 저장공간을 공유 sin_family의 값은 AF_INET값을 초기화 sin_port멤버는 소켓 주소의 TCP/IP포트를 정의 network byte order에 값이 존재 in _addr는 32비트의 부호가 없는 정수로 이루어져 있음 나머지 8바이트는 sin_zero[8]에 의한 16바이트로 삽입
인터넷(IPv4) 소켓 주소 형태(계속) 개 요 Sin_zero[8] Sin_family=AF_INET sin_port sin_addr Network Byte Order sin_addr멤버가 4byte를 사용하므로 sin_prot멤버가 2바이트로 사용됨. sin_port, sin_addr값은 network byte order에 있으므로 태그를 표시
인터넷(IPv4) 소켓 주소 형태(계속) Network Byte Order 이해 종류가 다른 CPU구조들은 16또는 32비트이상의 정수 생성을 위해 데이터의 다중바이트 분류에 많은 다른 방법을 사용 대표적인 방법 big-endian little -endian
인터넷(IPv4) 소켓 주소 형태(계속) Network Byte Order이해 (계속) 0x1234의 표현 Big Endian Little Endian 0x12 0x34 Big Endian Order 0x34 0x12 Little Endian Order
인터넷(IPv4) 소켓 주소 형태(계속) Network Byte Order이해 (계속) 중요한 바이트를 어느쪽으로 두느냐에 따라서 Big-Endian , Little-Endian으로 구별 Intel CPU는 하위 바이트를 처음 두는 Little-Endian 사용. Motolora 68000시리즈는 Big-Endian 사용 만약 Big-Endian와 Little-Endian사용 시 사전에 확인 사전 확인 없이 사용하면 0x3412의 값은 4660대신 13330으로 표현됨
인터넷(IPv4) 소켓 주소 형태(계속) Network Byte Order이해 (계속) 네트워크전송시 Big-endian을 사용, 문제 해결 이 규칙을 따르면 모든 소프트웨어는 통신이 가능 AF_INET번지로 통신 TCP/IP포트 번호(in_port), IP번호(sin_addr)는 네트워크 바이트 오더에 존재
인터넷(IPv4) 소켓 주소 형태(계속) Endian 변환 Intel CPU용 little-endian 바이트 16bit 변환 #include < netinet/in.h > unsigned long htonlunsigned long hostlong ) ; unsigned short htons ( unsigned short hostshort ) ; unsigned long ntohl ( unsigned long netlong ) ; unsigned short ntohs ( unsigned short netshort ) ;
인터넷(IPv4) 소켓 주소 형태(계속) Endian 변환(계속) 네트워크 오더를 위해서 아래와 같은 함수를 사용 short host_short = 0x1234; short netw_short; netw_short = htons(host_shrt); netw_short는 네크워크 오더를 위해 적당한 값을 갖는다. netw_short를 호스트에서 사용하기 위한 변환 host_short = ntohs(netw_short);
인터넷(IPv4) 소켓 주소 형태(계속) 인터넷 주소 초기화 원격서비스에 연결할 때 호스트가 2개 이상의 각각 IP를 갖고 있는 NIC를 갖고 있을 때. 커널이 로컬포트 번호를 할당할 때 sin_prot 는 0으로 초기화
인터넷(IPv4) 소켓 주소 형태(계속) 인터넷 주소 초기화 예제 2.8 struct socketaddr_in adr_inet; int adr_len; memset(&adr_inet,0,sizeof adr_inet); adr_inet.sin_family = AF_INET; adr_inet.sin+port = ntohs(0); adr_inet.sin_addr.s_addr = ntohl(INADDR_ANY); adr_len = sizeof adr_inet;
인터넷(IPv4) 소켓 주소 형태(계속) 인터넷 주소 초기화(계속) adr_inet는 sockaddr_in 구문을 이용해서 정의 adr_inet는 memset(3)에 의해 0 입력 AF_INET이 adr_inet.sin_family로 의한 주소 계층 성립 ntohs(3) 함수로 endian변환 htohl(3) 함수로 endian 변환 adr_inet구문으로 주소크기 단순화
인터넷(IPv4) 소켓 주소 형태(계속) 인터넷 주소 초기화(계속) 일반적으로 사용되는 루프 백 IP 동일 호스트에서 다른 프로세스간의 통신 설정 adr_inet.sin_addr.s_addr = ntohl(INADDR_LOOPBACK);
인터넷(IPv4) 소켓 주소 형태(계속) 특정 인터넷 주소 초기화 인터넷 주소는 고정된 길이 AF_LOCAL주소의 길이는 유동적 AF_INET주소는 C언어에서 소켓의 크기를 선언 sizeof(struct sockaddr_in)
X.25주소 설명 X.25 주소 지정 소켓 인터페이스는 리눅스에서 거의 사용되지 않는 다른 프로토콜을 사용가능하게 함. sockaddr_x25구문으로 x.25프로토콜을 규정 sruct sockaddr_x25 { sa_family_t sx25_family; /* AF_X25 */ x25_address sx25_addr; /* X.121 Address */ }; typedef struct { char x25_addr[16]: } x25_address;
X.25주소 설명 sx25_family는 일반적인 소켓 구조의 처음 2바이트를 점유하고 AF_X25값을 갖고 있어야 함 X.25 네트워크 주소는 연속된 10진 숫자로 이루어져야 함 (X.121표준)
X.25주소 설명(계속) listing 2.11
X.25주소 설명(계속) 프로그램이 수행시 netstat(1)을 호출 하지 않음 netstat(1)이 AF_X25소켓에 전달하지 않음 /proc/net/x25의 내용을 표시하기 위해 cat(1)사용 커널을 컴파일 하여 proc파일 시스템을 컴파일 하여야 함
다른 주소 계층 설명 다른 주소계층의 지정 리눅스에서 지원하는 주소계층 각각 프로토콜은 시스템에 커널에 직접 컴파일 주의 AF_INET6 – 개발되고 있는 IPv6 AF_AX25 – X.25 아마추어 무선(HAM) 프로토콜 AF_APPLETALK – 리눅스용 AppleTalk 프로토콜 각각 프로토콜은 시스템에 커널에 직접 컴파일 주의 불완전하거나 시험적인 프로토콜은 시스템에 악영향을 미침
AF_UNSPEC 주소 계층 개 요 AF_UNSPEC은 지정하지 않은 주소 계층을 표현함 다른 프로토콜과 주소계층을 갖고 프로그램 작성하려면 지정되지 않은 주소계층을 표시할 방법 필요
다른 주소 계층 설명(계속) union { sockaddr sa; sockaddr_un un; sockaddr_in in; sockaddr_x25 x25; full_sockaddr_ax25 ax25; sockaddr_atalk at; } u;
AF_UNSPEC 주소 계층(계속) 어떤 변수가 입력 전에 union을 초기화 프로그램 종료 후, AF_INET주소로 이동 u.sa.sa_family = AF_UNSPEC; 프로그램 종료 후, AF_INET주소로 이동 u.in.sin_family = AF_INET; 주소계층을 알지 못할 때 AF_UNSPEC는 안전장치처럼 작용한다.