Overview
pcap에 대한 설명과 linux 환경에서 libpcap을 사용해 패킷 스니핑(Packet Sniffing)을 하는 예제를 기술한다.
pcap
- 네트워크 트래픽을 캡처하고 저장하기 위한 파일 형식 및 API를 의미한다.
- Packet Capture의 약자로 Wireshark, tcpdump 등을 통해서 패킷을 저장하게 되면 pcap 형식으로 파일이 저장되기 때문에 네트워크 오류 발생 혹은 네트워크 프로그램을 구현할 때 데이터 확인 및 분석을 위해 사용된다.
Packet
pcap을 확인하기 위해서는 Packet과 OSI 7계층에 대한 내용을 이해할 필요가 있는데 아래 링크를 통해 확인하자.
https://en.wikipedia.org/wiki/Network_packet
Network packet - Wikipedia
From Wikipedia, the free encyclopedia Formatted unit of data carried by a packet-switched network In telecommunications and computer networking, a network packet is a formatted unit of data carried by a packet-switched network. A packet consists of control
en.wikipedia.org
https://ko.wikipedia.org/wiki/OSI_%EB%AA%A8%ED%98%95
OSI 모형 - 위키백과, 우리 모두의 백과사전
위키백과, 우리 모두의 백과사전. OSI 모형의 통신 (3-5계층의 예) OSI 모형(Open Systems Interconnection Reference Model)은 국제표준화기구(ISO)에서 개발한 모델로, 컴퓨터 네트워크 프로토콜 디자인과 통신
ko.wikipedia.org
pcap Programming
libpcap을 통해 개발자는 패킷을 캡처하고, 원하는 방식으로 분석/필터링/처리/저장 등을 하기 위한 프로그램을 구현 가능하다.
C++을 통해 TCP 패킷만 출력 해 주는 프로그램 예제를 만들어보자.
libpcap 설치
sudo apt update
sudo apt install libpcap-dev
설치 후 C/C++ 에서 #include <pcap.h>를 통해 사용 가능하다.
소스코드 예제
#include <pcap.h>
#include <iostream>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
// 패킷을 캡처할 때 호출되는 콜백 함수
void packet_handler(u_char *userData, const struct pcap_pkthdr* pkthdr, const u_char* packet)
{
// Ethernet 헤더는 14바이트
const struct ip* ip_header = (struct ip*)(packet + 14); // IP 헤더 위치
int ip_header_length = ip_header->ip_hl * 4;
// IP 프로토콜이 TCP일 경우에만 처리(IP 프로토콜에서 TCP에 해당하는 값는 6)
if (ip_header->ip_p == IPPROTO_TCP)
{
const struct tcphdr* tcp_header = (struct tcphdr*)(packet + 14 + ip_header_length);
// 출력: IP 주소와 포트 정보
std::cout << "TCP Packet: "
<< inet_ntoa(ip_header->ip_src) << ":" << ntohs(tcp_header->th_sport)
<< " -> "
<< inet_ntoa(ip_header->ip_dst) << ":" << ntohs(tcp_header->th_dport)
<< std::endl;
}
}
int main()
{
// error 메시지 버퍼
char errbuf[PCAP_ERRBUF_SIZE];
// 사용할 네트워크 장치 이름
const char* device = "eth0";
// 장치를 열어 패킷을 캡처할 준비
pcap_t* handle = pcap_open_live(device, BUFSIZ, 1, 1000, errbuf);
if (handle == nullptr)
{
// 장치 열기에 실패한 경우 에러 메시지 출력(예:sudo 권한 없이 실행하면 해당 오류 출력)
std::cerr << "pcap_open_live() 실패: " << errbuf << std::endl;
return 1;
}
std::cout << "eth0 - TCP 패킷 수신 중..." << std::endl;
// 캡처 루프 시작: 패킷이 수신될 때마다 packet_handler 호출
pcap_loop(handle, 0, packet_handler, nullptr);
// 종료
pcap_close(handle);
return 0;
}
빌드 명령 예제
g++ -o test_program main.cc -lpcap
핵심
네트워크에서 내가 원하는 패킷만 확인하거나 처리를 하기 위해서는 OSI 7계층에서 어떤 계층의 헤더 값에서 데이터를 확인해야 할지는 많은 공부가 필요하기 때문에 이에대한 사전 학습이 필요할 것이다.
위 예제에서는 TCP 패킷만 출력하기 위해 네트워크 계층의 IP 헤더에서 protocol 값이 tcp인지를 확인하는 부분이 존재한다.
if (ip_header->ip_p == IPPROTO_TCP)
이를 통해서 원하는 패킷만을 사용자는 출력하여 확인이 가능하게 된다.
결론
네트워크에 대한 공부를 우선적으로 하자
'Network' 카테고리의 다른 글
| Raw Socket (2) | 2025.08.15 |
|---|---|
| Snort (5) | 2025.07.26 |
| Netfilter (7) | 2025.07.16 |
| VLAN (Virtual LAN) (0) | 2025.06.09 |
| CommonAPI(4) - Service / Client (0) | 2025.05.27 |