libpcap으로 패킷 해석
1 단계: 프로토콜 헤더를 정의한다.
2 단계: 스니핑 코드 작성
pcap_loop을 이용
3 단계: 패킷 캡쳐 핸들러를 작성
각 계층별로 패킷 해석 정보를 출력하는 함수 호출
1 단계: 프로토콜 헤더 작성
//core_ehp.h #ifndef __core_ehp_h #define __core_ehp_h
#define ETH_ADDR_LEN 6
#include <pcap.h> #include <netinet/ip.h> typedef const struct pcap_pkthdr cp_pkthdr; typedef const u_char cu_char; typedef struct pcap_pkthdr p_pkthr;
typedef struct _eth_hdr eth_hdr; struct _eth_hdr{ u_char src[ETH_ADDR_LEN]; u_char dst[ETH_ADDR_LEN]; u_short type; }; #define SIZE_ETH (sizeof(eth_hdr)) typedef struct _ip_hdr ip_hdr; struct _ip_hdr{ #if __BYTE_ORDER == __LITTLE_ENDIAN u_char hd_len:4; u_char version:4; #elif __BYTE__ORDER == __BIG_ENDIAN u_char version:4; u_char hd_len:4; #endif u_char tos; u_short tot_len;
u_short id; #if __BYTE_ORDER == __LITTLE_ENDIAN u_short offset:15;//per 8byte u_short m_flag:1;//more fragment u_short d_flag:1;//don't fragment u_short r_flag:1;//reserved #endif #if __BYTE_ORDER == __BIG_ENDIAN u_short r_flag:1;//reserved u_short d_flag:1;//don't fragment u_short m_flag:1;//more fragment u_short offset:15;//per 8byte #endif
u_char ttl; u_char type; u_short check; u_int src_addr; u_int dst_addr; }; #define SIZE_IP (sizeof(ip_hdr))
typedef struct _tcp_hdr tcp_hdr; struct _tcp_hdr{ u_short sport; u_short dport; u_int seq; u_int ack; #if __BYTE_ORDER == __LITTLE_ENDIAN u_short reserved:4; u_short doff:4;//data offset per 4byte; #endif #if __BYTE_ORDER == __BIG_ENDIAN u_short doff:4; u_short reserved:4; #endif u_char flags; #define TCP_FIN 0x01 #define TCP_SYN 0x02 #define TCP_RST 0x04 #define TCP_PUSH 0x08 #define TCP_ACK 0x10 #define TCP_URG 0x20 u_short window; u_short check; u_short urgent; }; //to do - define udp header //to do - define icmp header //to do - define ip6 header //to do - define icmp6 header //to do - define igmp header
#endif |
2 단계: 스니핑
반복해서 패킷을 캡쳐하고 캡쳐하면 패킷 캡쳐 핸들러를 호출함
pcap_loop(pcap_handle,3,catch_handler,0);
int pcap_loop(pcap_t *pcap_handle, int cnt, pcap_handler cb_handler, u_char *user);
int pcap_dispath(pcap_t *pcap_handle, int cnt, pcap_handler cb_handler, u_char *user);
/*pcap_loop 대신 pcap_dispatch를 사용할 수도 있다. */
콜백 핸들러는 다음과 같은 시그니쳐를 갖는 함수 포인터(함수 이름)
void catch_handler(u_char *args,cp_pkthdr *handle,cu_char *packet);
//pc_dec.c #include "core_ehp.h"
void catch_handler(u_char *args,cp_pkthdr *handle,cu_char *packet); void decode_eth(cu_char *base); int decode_ip(cu_char *base); int decode_tcp(cu_char *base); void decode_data(cu_char *packet,u_int len); void view_ether_addr(const char *pre,cu_char *base);
int main(){ cu_char *packet; char errbuf[PCAP_ERRBUF_SIZE]; char *device; pcap_t *pcap_handle;
device = pcap_lookupdev(errbuf); if(device == 0){ printf("fail lookupdev...%s\n",errbuf); } printf("find device: %s sniffing\n",device);
pcap_handle = pcap_open_live(device, 4096, 1, 0, errbuf); if(pcap_handle == 0){ printf("fail pcap_open_live...%s\n",errbuf); }
pcap_loop(pcap_handle,3,catch_handler,0); pcap_close(pcap_handle); return 0; } |
3 단계: 프로토콜 해석하여 출력
void decode_eth(cu_char *base){ eth_hdr *ethhd = (eth_hdr *)base; printf("======layer 2: ehternet header =====\n"); view_ether_addr("src:",ethhd->src); view_ether_addr("\tdst:",ethhd->dst); printf("\ntype:%u\n",ethhd->type); } void view_ether_addr(const char *pre,cu_char *base){ printf("%s: %2x",pre,base); int i = 0; for(i=1;i<ETH_ADDR_LEN; ++i){ printf(":%02x",base[i]); }//for } int decode_ip(cu_char *base){ printf("\n*****layer 3: ip header *****\n"); ip_hdr *header = (ip_hdr *)base; //to do return header->type; } int decode_tcp(cu_char *base){ printf("\n*****layer 4: tcp header *****\n"); tcp_hdr *header = (tcp_hdr *)base; //to do return header->doff*4; } void decode_data(cu_char *packet,u_int len){ u_int i = 0; printf("--- body %d byte---\n",len); for(i=0; i<len; ++i){ printf("%x ",*packet); packet++; if(i%25 == 24){ printf("\n"); } }//for printf("\n-----------------\n\n"); } |
'네트워크 및 보안 > pcap 라이브러리' 카테고리의 다른 글
[pcap 라이브러리] 11. libpcap과 메모리 매핑 기술을 이용하여 지연 덤프 소스 코드 (0) | 2016.04.29 |
---|---|
[pcap 라이브러리] 10. 기타 함수들 사용 예제 코드(pcap_is_swapped, pcap_freecode ,pcap_set_datalink) (0) | 2016.04.29 |
[pcap 라이브러리] 9. 필터식 BSF 문법 확인 (pcap_compile, pcap_compile_nopcap) (0) | 2016.04.29 |
[pcap 라이브러리] 8. 저장한 파일을 이용하기 소스 코드 (pcap_open_offline) (0) | 2016.04.29 |
[pcap 라이브러리] 7. 캡쳐한 패킷 파일로 덤프하기 소스 코드(pcap_dump_open, pcap_dump) (0) | 2016.04.29 |
[pcap 라이브러리] 6. 자신의 Network에 필터를 적용하여 패킷 캡쳐 소스 코드 (0) | 2016.04.29 |
[pcap 라이브러리] 5. 필터 적용하여 패킷 캡쳐하기(소스 포함) (0) | 2016.04.29 |
[pcap 라이브러리] 3. 패킷 스니핑 소스(pcap_lookupdev, pcap_open_live, pcap_next, pcap_close) (0) | 2016.04.29 |
[pcap 라이브러리] 2. 자신의 Network IP와 Mask값 확인하기 소스 (0) | 2016.04.29 |
[pcap 라이브러리] 1. libpcap 패키지 전체 업데이트 및 설치, 테스트 코드 (0) | 2016.04.29 |