보안 / AI / 프로그래밍

[0x420] 프로토콜 ( Protocol ) // 소켓 ( Socket ) // 소켓 관련 C 함수 본문

Hacking :: The Art Of Exploitation/0x400 :: 네트워킹

[0x420] 프로토콜 ( Protocol ) // 소켓 ( Socket ) // 소켓 관련 C 함수

DevKTW 2021. 1. 12. 20:56

◇ 프로토콜 ( Protocol ) 이란?

    - 공통의 데이터 교환 방법 및 순서에 대해 정의한 의사소통 약속, 규악 혹은 규칙 체계를 말한다 ( 출처 : WIKIPEDIA )

 

프로토콜 종류 ( 출처 : Wikipeda )

◇ 소켓 ( Socket ) 이란?

    - 소켓은 운영체제를 통해 네트워크 통신을 하는 표준 방법이다.

    - 소켓은 전화 교환대의 소켓처럼 연결의 종점 ( End Point ) 으로 생각할 수 있다.

 

소켓의 가장 보편적인 타입인 스트림 소켓과 데이터그램 소켓이다.

 

 


C 소켓 관련 함수

int sockfd = socket(int domain, int type, int protocol)

    - socket() : 소켓 생성 함수이다.

 

    - sockfd : 소켓 파일 서술자이다. 파일 서술자 처럼 다뤄진다.

 

    - domain : 소켓의 프로토콜 패밀리 ( Protocol Family ) 를 지정한다. 프로토콜 패밀리는 bits/socket.h 에서 정의된다.

                   ( 인터넷을 통해 통신할 지, 같은 시스템 내에서 프로세스 끼리 통신할 지의 여부를 결정한다는 의미이다. )

                   ( 개인적으로 프로토콜의 집합 영역이라고 생각하는 것이 좋다고 생각한다. 어느 영역에서 사용될 것인가... )

 

    - type : 어떤 타입의 프로토콜을 사용할 것인지에 대해 지정한다.

                   ( SOCK_STREAM (TCP), SOCK_DGRAM(UDP), SOCK_RAW(사용자 정의) )

 

    - protocol : 통신에 있어 특정 프로토콜을 사용을 지정하기 위한 변수이며, 보통 0 값을 사용한다. 프로토콜 인자를 명시하여,

                       패밀리의 프로토콜 중 '하나'를 선택하는 데 사용된다.
                       하지만 실제로는 대부분의 프로토콜 패밀리가 '하나의 프로토콜 만을 가지고 있다.
                       그래서 프로토콜 인자는 첫 번째이자 유일한 프로토콜을 나타내기 위해 0이 된다.

 

( Kali Linux 에서 촬영됨 ) bits/socket.h 내부에 정의된 프로토콜 패밀리들이다.

int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen)

    - setsockopt() : 소켓을 설정하는 함수이다. 성공시 '0'을, 실패시 '-1'을 Return 한다.

 

    - optname :  설정할 옵션을 지정한다. 옵션의 종류는 아래와 같다.

출처 : 소켓 옵션 설정하기(setsockopt) · snowdeer's Code Holic

    - (void *) optval : 설정할 옵션의 값을 포인터를 넘기는 형태로 전달하여 지정한다.

 

    - optlen : 해당 변수를 전달하여, optval 버퍼의 크기를 제시한다.

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)

    - bind() : 들어오는 연결을 듣기 위해 소켓을 Local Host와 결합하는 함수이다. 성공시 '0'을, 실패시 '-1'을 Return 한다.

 

    - (struct sockaddr *) addr : socketaddr 구조체의 포인터를 지정한다. 즉, 호스트에 대한 인터넷 정보를 입력하는 것이다.

                                                 socketaddr 구조체는 bits/socket.h 에 정의된다. 구조체는 아래와 같다. ( 간단한 구조이다. )

좌측은 socketaddr 구조체가 정의된 헤더파일 위치이고, 우측은 sockaddr 구조체의 모습이다. ( struct sockaddr{...} 부분 )

    - addrlen : 해당 변수를 전달하여, socketaddr 구조체의 크기를 제시한다.

 

int listen(int sockfd, int backlog_queue_size)

    - listen() : 들어오는 연결을 듣고, 들어오는 연결 요청을 최대 backlog_queue_size만큼 큐에 넣는다.

                          성공시 '0'을, 실패시 '-1'을 Return 한다.

 

    - backlog_queue_size : 큐의 최대 크기를 지정한다. 즉 들어오는 연결 요청을 최대로 수용할 수 있는 크기를 지정한다.

참고 ) The backlog_queue_size, defines the maximum length to which the queue of pending connections for sockfd may grow. If a connection request arrives when the queue is full, the client may receive an error with an indication of ECONNREFUSED. - 큐가 최대치를 넘어갈 경우, 클라이언트는 ECONNREFUSED 오류를 받는다.
출처 : Socket Programming in C/C++ - GeeksforGeeks

 

int new_socket =  accept(int sockfd, struct sockaddr *remote_host, socklen_t *addr_length)

    - accpet() : 바인드 (Bind) 에 성공한 소켓의 들어오는 연결을 받아들인다. 원격 호스트의 주소 정보는 remote_host 에 쓰고,

                      주소 구조체의 길이는 addr_length에 쓴다.
                      이 함수는 성공시 연결된 소켓을 식별할 수 있게 새 소켓 파일 서술자를, 실패시 '-1'을 Return 한다.

 

int send(int sockfd, void *buffer, size_t len, int flags)
int recv(int sockfd, void *buffer, size_t len, int flags)

    - send() : *buffer의 [len] 바이트를 소켓 sockfd로 보낸다. 성공시 보낸 바이트 수를, 실패시 '-1'을 Return 한다.

    - recv() : 소켓 sockfd 에서부터 [len] 바이트를 읽어 *buffer에 넣는다. 성공시 받은 바이트수를, 실패시 '-1'을 Return 한다.

 

    - (void *) buffer : 전송할 데이터의 포인터

 

    - len : 전송할 데이터의 길이

 

    - flags : 전송할 데이터 또는 읽는 방법에 대한 옵션. 0 또는 bit or 연산으로 설정 가능하다.

                 (그래서 flag's' 였구나..)

 


참조자료

ko.wikipedia.org/wiki/%EC%9D%B8%ED%84%B0%EB%84%B7_%EC%A0%9C%EC%96%B4_%EB%A9%94%EC%8B%9C%EC%A7%80_%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C

Comments