[pcap 라이브러리] 11. libpcap과 메모리 매핑 기술을 이용하여 지연 덤프 소스 코드
libpcap과 메모리 매핑 기술을 이용하여 지연 덤프
현재의 게시글은 앞으로 pcap 라이브러리를 이용하여 tshark 유틸과 같은 네트워크 트래픽을 수집하고 분석하는 도구를 만드는 과정을 게시하기 위해 어떠한 순서로 진행할 지 결정하기 위한 더미 코드입니다.
2016년 6월 이후부터 다양한 프로그래밍 언어와 기술에 관한 글과 무료 동영상 강의를 제작할 계획이며 그 중에 하나가 네트워크 보안에 관한 사항입니다. 네트워크 보안에 관한 주제는 네트워크 프로토콜, 소켓 프로그래밍, 리눅스에서 tshark 흉내내기, 윈도우즈에서 tshark 흉내내기와 C#언어로 와이어샤크 흉내내기 등을 다룰 예정입니다.
많은 관심과 조언 바랍니다.
아직 입문하기 위한 더미 코드들만 올린 상태입니다.
참고로 네트워크 프로토콜은 어느정도 정리한 상태입니다.
void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
int munmap(void *addr, size_t length);
//tiny_dump.c #include "td_core.h" #include <stdlib.h> #include <stdio.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/io.h> #include <memory.h> #define MEM_SIZE 0xfffff
void db_init(); void db_release(); 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); pcap_if_t *select_interface(pcap_if_t *alldevs); void dump_all(pcap_dumper_t *df,pcap_t *handle,char *path);
int main(int argc,char **argv){
char errbuf[PCAP_ERRBUF_SIZE]; pcap_if_t *alldevs; pcap_if_t *dev;
if(pcap_findalldevs(&alldevs,errbuf)==-1){ printf("fail findalldevs: %s\n", errbuf); return 1; }//if
dev = select_interface(alldevs); if(dev == 0){ printf("fail select_interface\n"); return 2; }//if printf("select <%s> inteface\n",dev->name);
pcap_t *handle; handle = pcap_open_live(dev->name, 4096, 1, 0, errbuf); if(handle == 0){ printf("fail pcap_open_live...%s\n",errbuf); return 3; }//if pcap_freealldevs(alldevs);
db_init();
pcap_dumper_t *df; df = pcap_dump_open(handle,argv[1]); if(df == 0){ printf("fail dump_open\n"); exit(4);}
pcap_loop(handle,3,catch_handler,(u_char *)df);
dump_all(df,handle,argv[1]);
pcap_close(handle);
return 0; }
pcap_if_t *select_interface(pcap_if_t *alldevs){ pcap_if_t *dev; pcap_if_t *base[100]; int i; printf("interface list...\n"); for(dev = alldevs, i=0; dev ; dev = dev->next,i++){ base[i] = dev; printf("<%d> : %s\n",i+1, dev->name); }//for
printf("select inteface:"); int num_dev; scanf("%d",&num_dev); fflush(stdin); if((num_dev<1) || (num_dev>i)){ printf("The number is not available...\n"); return 0; }//if return base[num_dev-1]; }
#define MAX_PACKET 0xffff typedef struct _hd_packet hd_packet; typedef struct _td_db td_db; struct _td_db{ void *db_base; u_char *ptr; int pcnt; hd_packet *base[MAX_PACKET]; };
struct _hd_packet{ p_pkthdr header; u_char packet[4096]; }; /////////////////////db/////////////////
td_db tdb; void db_store_packet(cp_pkthdr *pheader,cu_char *packet){ hd_packet *hp = (hd_packet *)tdb.ptr; hp->header = *pheader; memcpy(hp->packet,packet,pheader->len); tdb.ptr += sizeof(cp_pkthdr) + pheader->len; tdb.base[tdb.pcnt] = hp; tdb.pcnt++; } void db_init(){ tdb.db_base = mmap(0,MEM_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); //메모리 매핑 if(tdb.db_base == MAP_FAILED){ printf("error mmap\n"); exit(4);} tdb.ptr = tdb.db_base; tdb.pcnt = 0; memset(tdb.db_base, 0, MEM_SIZE); } void db_release(){ munmap(tdb.db_base,MEM_SIZE); //메모리 매핑 해제 }
///////////////////dump////////////////// void dump_all(pcap_dumper_t *df,pcap_t *handle,char *path){
int i = 0; hd_packet *hp; for(i=0; i<tdb.pcnt; ++i){ hp = tdb.base[i]; pcap_dump((u_char *)df,&(hp->header),hp->packet);
}//for pcap_dump_close(df); }
//////////////////capture handle//////// void catch_handler(u_char *args, cp_pkthdr *header,cu_char *packet){ printf("##### recved %d bytes #####\n",header->len); db_store_packet(header,packet); }
////////////////////decode///////////// 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; return header->hd_len; } int decode_tcp(cu_char *base){ printf("\n*****layer 4: tcp header *****\n"); tcp_hdr *header = (tcp_hdr *)base; 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"); } |
//td_core.h #ifndef __td_core_h #define __td_core_h
#define ETH_ADDR_LEN 6
#include <stdio.h> #include <pcap.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.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:13;//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:13;//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 |
관련 게시글
1. libpcap 패키지 전체 업데이트 및 설치, 테스트 코드
2. 자신의 Network IP와 Mask값 확인하기 소스
3. 패킷 스니핑 소스(pcap_lookupdev, pcap_open_live, pcap_next, pcap_close)
6. 자신의 Network에 필터를 적용하여 패킷 캡쳐 소스 코드
7. 캡쳐한 패킷 파일로 덤프하기 소스 코드(pcap_dump_open, pcap_dump)
8. 저장한 파일을 이용하기 소스 코드 (pcap_open_offline)
9. 필터식 BSF 문법 확인 (pcap_compile, pcap_compile_nopcap)
10. 기타 함수들 사용 예제 코드(pcap_is_swapped, pcap_freecode ,pcap_set_datalink)