보안 / AI / 프로그래밍

[0x423] 네트워크 바이트 순서 // 엔디언 본문

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

[0x423] 네트워크 바이트 순서 // 엔디언

DevKTW 2021. 1. 23. 21:55

엔디언(Endianness)은 컴퓨터의 메모리와 같은 1차원의 공간에 여러 개의 연속된 대상을 배열하는 방법을 뜻하며, 바이트를 배열하는 방법을 특히 바이트 순서(Byte order)라 한다. (출처 : Wikipedia)

 

컴퓨터 아키텍쳐에 따라서 빅 엔디언, 리틀 엔디언, 미들 엔디언.. 등등으로 나뉜다.

주로 빅 엔디언과 리틀 엔디언이 주를 이룬다.

 

네트워크 바이트 순서와 호스트 바이트 순서란?

 

컴퓨터 아키텍쳐에 따라 호스트 바이트 순서가 다르기 때문에 서로 다른 바이트 순서를 사용하는 컴퓨터들이 데이터를 주고 받을 때 문제 발생하므로, 이 문제점을 해결하기 위해 네트워크를 통해 데이터를 전송할 때는 통일된 방식을 이용해 데이터를 전송하기로 약속을 했는데, 이것이 바로 네트워크 바이트 순서 이다. 네트워크 바이트 순서는 빅 엔디언을 따른다.

 

호스트 바이트 순서는 말 그대로 데이터를 받는 호스트의 바이트 순서 ( 데이터를 쓰는 방식 ) 이다.

 

빅 엔디언과 리틀 엔디언의 데이터를 쓰는 방식의 차이   ( 출처 : Wikipedia )


네트워크 바이트 순서 <-> 호스트 바이트 순서 변환 함수 ( AF_INET 소켓 구조체 )

C 언어에서 제공하는 바이트 순서 변환 기능의 함수는 netinet/in.h, arpa/inet.h 에 정의되어 있으며, 아래와 같다.

네트워크 바이트 순서와 호스트 바이트 순서 간의 변환 기능을 가진 함수들


위에서 배웠듯이, 무언가를 전송하려면 네트워크 바이트 순서 (빅 엔디언) 로 데이터를 입력하고 패킷에 담아 전송해야 한다.

 

그렇다면, 인터넷 주소 또한 네트워크 바이트 순서로 입력될텐데, 우리가 평소에 보는 EX) 192.168.0.xxx 같은 구조로 보려면 어떤 방법이 있을까?

 

이에 대한 해결책은 arpa/inet.h 에 정의되어 있는 아래의 유용한 함수를 이용하면 간편하다.

 

inet_aton(char *ascii_addr, struct in_addr *network_addr)

이 함수는 ASCII 문자열로 표현된 IP 주소를 in_addr 구조체로 바꾼다. in_addr 구조체는 네트워크 바이트 순서로 표현된 32Bit 정수이다.

 

이에 반대 기능을 하는 함수는 아래와 같다.

inet_ntoa(struct in_addr *network_addr)

이 함수는 in_addr 구조체의 포인터를 넘기면 함수는 숫자 사이에 점을 찍는 IP 주소 표시법으로 구성된 ASCII 문자열을 가리키는 문자 포인터를 리턴한다. 이 문자열은 함수상에 정적으로 할당된 메모리 버퍼에 있다.

Comments