My Drive

[winpcap] pkt_dump 본문

programming

[winpcap] pkt_dump

sunnyeo.park 2015. 7. 26. 14:39

//pkt_dump.c 


#include "pcap.h"


typedef struct mac_address {

u_char byte1;

u_char byte2;

u_char byte3;

u_char byte4;

u_char byte5;

u_char byte6;

}mac;


#define ETHER_ADDR_LEN 6

struct ether_header

{

u_char ether_dhost[ETHER_ADDR_LEN];

u_char ether_shost[ETHER_ADDR_LEN];

u_short ether_type;

}eth;


typedef struct ip_address

{

u_char byte1;

u_char byte2;

u_char byte3;

u_char byte4;

}ip_address;


typedef struct ip_header

{

u_char ver_ihl;

u_char tos;

u_short tlen;

u_short identification;

u_short flags_fo;

u_char ttl;

u_char proto;

u_short crc;

ip_address saddr;

ip_address daddr;

u_int op_pad;

}ip_header;


typedef struct tcp_header

{

u_short sport;

u_short dport;

u_int seqnum;

u_int acknum;

u_char th_off;

u_char flags;

u_short win;

u_short crc;

u_short urgptr;

}tcp_header;


typedef struct udp_header

{

u_short sport;

u_short dport;

u_short len;

u_short crc;

}udp_header;


void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);


main()

{

pcap_if_t *alldevs;

pcap_if_t *d;

int inum;

int i = 0;

pcap_t *adhandle;

char errbuf[PCAP_ERRBUF_SIZE];

u_int netmask;

char packet_filter[] = ""; // 원하는 필터 정보 설정 (ex. "tcp")

struct bpf_program fcode;


if(pcap_findalldevs(&alldevs, errbuf) == -1) // 랜카드 검색

{

fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);

exit(1);

}


for(d=alldevs; d; d=d->next) // 검색된 랜카드 정보 출력

{

printf("%d. %s", ++i, d->name);

if(d -> description)

printf(" (%s)\n", d->description);

else

printf(" (No description available)\n");

}


if(i==0)

{

printf("\nNo interfaces found! Make sure WinPcap is installed.\n");

return -1;

}


printf("nic 카드 선택하세요..(1-%d):", i);

scanf("%d", &inum); // 랜카드 선택


if(inum < 1 || inum > i)

{

printf("\nInterface number out of range.\n");

pcap_freealldevs(alldevs);

return -1;

}


for(d = alldevs, i=0; i<inum-1; d=d->next, i++);


if((adhandle=pcap_open_live(d->name, 65536, 1, 1000, errbuf)) == NULL) // 네트워크 패킷을 수집하기 위한 방법 설정

{

fprintf(stderr, "\n %s isn't supported by winpcap \n", d->name);

return -1;

}


if(pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) < 0) // 사용자가 정의한 필터링 룰을 bpf_program 구조체에 저장하여, 특정 프로토콜만을 선별적으로 수집

{

fprintf(stderr, "\nUnable to compile the packet filter. Check the syntax.\n");

pcap_freealldevs(alldevs);

return -1;

}


if(pcap_setfilter(adhandle, &fcode) < 0)

{

fprintf(stderr, "\nError setting the filter.\n");

pcap_freealldevs(alldevs);

return -1;

}


printf("\nlistening on %s...\n\n", d->description);

pcap_freealldevs(alldevs);

pcap_loop(adhandle, 0, packet_handler, NULL); // packet_handler() 함수 호출하여 패킷 수집

pcap_close(adhandle);

return 0;

}


void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)

{

struct tm *ltime;

char timestr[16];

ip_header *ih;

tcp_header *th;

udp_header *uh;

u_int ip_len, i;

time_t local_tv_sec;


local_tv_sec = header->ts.tv_sec;

ltime = localtime(&local_tv_sec);

strftime(timestr, sizeof timestr, "%H:%M:%S", ltime);


printf("====Ethernet Packet====\n\n");

printf("%s.%.6d \n\n", timestr, header->ts.tv_usec);


mac* srcmac;

mac* destmac;

destmac = (mac*)pkt_data;

srcmac = (mac*)(pkt_data+6);


printf("%02x.%02x.%02x.%02x.%02x.%02x -> %02x.%02x.%02x.%02x.%02x.%02x\n\n", srcmac->byte1, srcmac->byte2, srcmac->byte3, srcmac->byte4, srcmac->byte5, srcmac->byte6, destmac->byte1, destmac->byte2, destmac->byte3, destmac->byte4, destmac->byte5, destmac->byte6);


ih = (ip_header*)(pkt_data+14);

ip_len = (ih->ver_ihl & 0xf) * 4;

th = (tcp_header*)((u_char*)ih+ip_len);

uh = (udp_header*)((u_char*)ih+ip_len);

if(ih->proto == 6)

{

printf("%d.%d.%d.%d (%d) -> %d.%d.%d.%d (%d), flag: %04x\n\n", ih->saddr.byte1, ih->saddr.byte2, ih->saddr.byte3, ih->saddr.byte4, ntohs(th->sport), ih->daddr.byte1, ih->daddr.byte2, ih->daddr.byte3, ih->daddr.byte4, ntohs(th->dport), th->flags);

printf("TCP Protocol\n\n");


for(i=55; i<header->caplen + 1; i++)

printf("%02x", pkt_data[i-1]);

printf("\n\n");

for(i=55; i<header->caplen+1; i++)

{

if((pkt_data[i-1] >= 33) && (pkt_data[i-1] <= 126))

printf(" %c", pkt_data[i-1]);

else

printf(" ");

}


printf("\n\n");

printf("=============The End=============\n\n\n");

}

}



'programming' 카테고리의 다른 글

[winpcap] pkt_send  (1) 2015.07.26
[winpcap] udp_header  (0) 2015.07.26
[winpcap] tcp_header  (0) 2015.07.26
[winpcap] ip_header  (0) 2015.07.26
[winpcap] mac_address  (0) 2015.07.26
Comments