본문 바로가기

S-DEV/네트워크 보안

Basic header analysis

728x90

• 이더넷 프레임

이더넷 헤더의 규약

Destination MAC Address : 6byte

Source MAC Address : 6byte

Ether Type : 2byte 

 

Preamble : 프레임의 시작 

 

• IP 헤더

 

Version : 0100으로 들어간다 (IPv4)  -> 4 bite

IHL : IP헤더는 기본적으로 20byte가 들어가야 하는데 4 bite로는 표현을 할 수가 없기 때문에 IHL 에는 0101이 들어간다.

-> 5가 들어간다. -> 곱하기 4를 하면 실제 IP 헤더의 크기가 나온다.

즉, 45로 시작하면 IPv4의 시작위치라고 알 수 있음

 

* Protocol -> TCP는 0x06, ICMP는 0x01, UDP는 0x11이다.

 

• TCP 헤더

TCP 헤더의 크기를 알아내기 위해서는 Data offset * 4를 하면 구할 수 있다.

 

• Pcap Programming 실습

pcap_t 핸들을 이용하여 packet 수집 및 전송 

libpacp 설치 : sudo apt install libpcap-dev

 

- 스켈레톤 코드 

void usage() {
	printf("syntax: pcap-test <interface>\n");
	printf("sample: pcap-test wlan0\n");
}

typedef struct {
	char* dev_;
} Param;

Param param = {
	.dev_ = NULL
};


bool parse(Param* param, int argc, char* argv[]) {
	if (argc != 2) {
		usage();
		return false;
	}
	param->dev_ = argv[1];
	return true;
}

argc : 입력되는 인자의 개수가 2개가 아닌 경우  usage() 함수로 리턴하고 2개인 경우 param 구초체의 dev_ 변수에 인자값으로 설정을 해준다.

 

int main(int argc, char* argv[]) {
	if (!parse(&param, argc, argv))
		return -1;
// parse함수의 호출 결과를 확인하고, 그 결과가 false인 경우 return 값인 -1를 반환한다.
// -> 파싱 함수에서 잘못된 인수나 인수부족등의 문제가 발생했을 경우 프로그램을 종료하도록하는 방식이다.

	char errbuf[PCAP_ERRBUF_SIZE];
    // PCAP_ERRBUF_SIZE는 pcap.h 파일에서 256바이트로 정의되어 있음
    
	pcap_t* pcap = pcap_open_live(param.dev_, BUFSIZ, 1, 1000, errbuf);
    // pcap_open_live 함수를 호출하여 패킷 캡처를 위한 세션을 열고, 해당 세션을 나타내는 pcap_t 포인터를 반환한다.
    // param.dev_ 는 패킷을 캡처할 네트워크 인터페이스의 이름을 나타낸다.
    // 1은 Promiscuous모드를 활성화하는 값이다.
    // 1000은 패킷을 캡처할 때까지의 타임아웃을 지정한것이다.
    // errbuf는 오류메시지를 저장하기 위한 버퍼이다.
    
	if (pcap == NULL) {
		fprintf(stderr, "pcap_open_live(%s) return null - %s\n", param.dev_, errbuf);
		return -1;
	}
    // pcap_open_live 함수 호출 후 반환된 pcap_t 포인터가 NULL인지 확안하는 부분이다.
    

	while (true) {
		struct pcap_pkthdr* header;
		const u_char* packet;
		int res = pcap_next_ex(pcap, &header, &packet);
        // pcap_next_ex 함수를 호출하여 다음 패킷을 읽어온다.
        
		if (res == 0) continue;
		if (res == PCAP_ERROR || res == PCAP_ERROR_BREAK) {
			printf("pcap_next_ex return %d(%s)\n", res, pcap_geterr(pcap));
			break;
		}
        // 오류가 발생한 경우 PCAP_ERROR 또는 PCAP_ERROP_BREAK를 반환한다.
     
		printf("%u bytes captured\n", header->caplen);
        // header 구조체의 caplen을 통해 패킷의 크기를 출력합니다.
	}
    //pcap_next_ex 함수를 사용하여 캡처한 패킷을 계속해서 읽어오는 루프이다.
    

	pcap_close(pcap);
}

 

실습 결과

 

'S-DEV > 네트워크 보안' 카테고리의 다른 글

Report pcap test  (0) 2023.07.18
OSI model and TCP/IP Layer  (0) 2023.07.15
Byte order  (0) 2023.07.10
Git (sum 실습)  (0) 2023.07.02