pcap_findalldevs()
pcap_if_t *alldevs;
pcap_findalldevs(&alldevs, errbuf);
pcap_open_live()
pcap_t *handle = pcap_open_live(device_name, 65536, 1, 1000, errbuf);
pcap_loop()
pcap_loop(handle, 0, packet_handler, NULL);
...
pcap_close(handle);
handle : pcap_open_live() 를 통해 pcap 드라이버가 디바이스에 연결 성공 후 반환된 pcap_t 포인터 캡처 핸들러
cnt : 몇 개의 패킷을 캡쳐할지 지정(0 : infinite)
packet_handler : 수신된 패킷을 처리하는 handler 함수 포인터
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) {
// 도착 시각 및 크기 출력 등
}
user : 패킷 handler 로 넘길 유저 데이터 포인터
원본 예제 코드
#ifdef _MSC_VER
/*
* we do not want the warnings about the old deprecated and unsecure CRT functions
* since these examples can be compiled under *nix as well
*/
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <pcap.h>
#include <stdio.h>
#include <time.h>
#ifdef _WIN32
#include <tchar.h>
BOOL LoadNpcapDlls()
{
_TCHAR npcap_dir[512];
UINT len;
len = GetSystemDirectory(npcap_dir, 480);
if (!len) {
fprintf(stderr, "Error in GetSystemDirectory: %x", GetLastError());
return FALSE;
}
_tcscat_s(npcap_dir, 512, _T("\\\\Npcap"));
if (SetDllDirectory(npcap_dir) == 0) {
fprintf(stderr, "Error in SetDllDirectory: %x", GetLastError());
return FALSE;
}
return TRUE;
}
#endif
/* prototype of the packet handler */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
////////////////////////////////////////////////////////////////////////
int main()
{
pcap_if_t *alldevs;
pcap_if_t *d;
int inum;
int i=0;
pcap_t *adhandle;
char errbuf[PCAP_ERRBUF_SIZE];
#ifdef _WIN32
/* Load Npcap and its functions. */
if (!LoadNpcapDlls())
{
fprintf(stderr, "Couldn't load Npcap\\n");
exit(1);
}
#endif
/* Retrieve the device list */
// 1. 연결 가능한 NIC 네트워크 디바이스를 찾는다.
if(pcap_findalldevs(&alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\\n", errbuf);
exit(1);
}
/* Print the list */
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 Npcap is installed.\\n");
return -1;
}
printf("Enter the interface number (1-%d):",i);
scanf("%d", &inum);
if(inum < 1 || inum > i)
{
printf("\\nInterface number out of range.\\n");
/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}
/* Jump to the selected adapter */
for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
/* Open the device */
/* Open the adapter */
// 2. 연결 가능한 NIC 디바이스들 중 특정 네트워크 디바이스에
// pcap 드라이버를 연결한다.
if ((adhandle= pcap_open_live(d->name, // name of the device
65536, // portion of the packet to capture.
// 65536 grants that the whole packet will be captured on all the MACs.
1, // promiscuous mode (nonzero means promiscuous)
1000, // read timeout
errbuf // error buffer
)) == NULL)
{
fprintf(stderr,"\\nUnable to open the adapter. %s is not supported by Npcap\\n", d->name);
/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}
printf("\\nlistening on %s...\\n", d->description);
/* At this point, we don't need any more the device list. Free it */
pcap_freealldevs(alldevs);
/* start the capture */
// 3. pcap 드라이버와 연결되고 반환된 디바이스 어댑터 핸들러
// 를 통해 패킷을 지속적으로 수집하고, packet_handler 함수
// 를 콜백하여 처리한다.
pcap_loop(adhandle, 0, packet_handler, NULL);
// 4. 디바이스 어댑터 핸들러를 종료한다.
pcap_close(adhandle);
return 0;
}
////////////////////////////////////////////////////////////////////////////////
/* Callback function invoked by libpcap for every incoming packet */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
struct tm *ltime;
char timestr[16];
time_t local_tv_sec;
/*
* unused parameters
*/
(VOID)(param);
(VOID)(pkt_data);
/* convert the timestamp to readable format */
local_tv_sec = header->ts.tv_sec;
ltime=localtime(&local_tv_sec);
strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);
printf("%s,%.6d len:%d\\n", timestr, header->ts.tv_usec, header->len);
}