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)
'네트워크 및 보안 > pcap 라이브러리' 카테고리의 다른 글
[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 라이브러리] 4. libpcap으로 패킷 해석하기 뼈대 만들기 (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 |