pcap_open_offline

前言

为了重复实验,重现bug. 分析离线pcap文件, 是个不错的选择.
用pcap_open_offline可以打开离线文件. 剩下的步骤和直接抓包分析是一样的, 可能得去掉pcap_activate等只适合实际网卡的API.

在做实验的过程中,居然发现vs2017(15.8.28010.0)也可以对变量名进行重构, 方便很多啊.
在这里插入图片描述

实验

实验在https://blog.csdn.net/LostSpeed/article/details/81873620基础上做的。
要添加pcap_open_offline的动态载入函数.

// dy_load_wpcap_dll.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "wpcap_dll_ex.h"

// please declare _CRT_SECURE_NO_WARNING on project

#ifndef MYLOG_I
#define MYLOG_I printf
#endif // #ifndef MYLOG_I

#ifndef LINE_80
#define LINE_80 "--------------------------------------------------------------------------------"
#endif // #ifndef LINE_80

#include <stdint.h>

typedef uint32_t addr_t;
typedef uint16_t port_t;

// @ref https://stackoverflow.com/questions/16519846/parse-ip-and-tcp-header-especially-common-tcp-header-optionsof-packets-capture
#pragma pack(push, 1)
typedef struct {
	u_char  dst_addr[6];
	u_char  src_addr[6];
	u_short type;
} TAG_ETHER_HEADER;

typedef struct {
	uint8_t  ver_ihl;  // 4 bits version and 4 bits internet header length
	uint8_t  tos;
	uint16_t total_length;
	uint16_t id;
	uint16_t flags_fo; // 3 bits flags and 13 bits fragment-offset
	uint8_t  ttl;
	uint8_t  protocol;
	uint16_t checksum;
	addr_t   src_addr;
	addr_t   dst_addr;
} TAG_IP_HEADER;

typedef struct {
	uint16_t src_port;
	uint16_t dst_port;
	uint32_t seq;
	uint32_t ack;
	uint8_t  data_offset;  // high 4 bits * 4 is tcp-payload
	uint8_t  flags;
	uint16_t window_size;
	uint16_t checksum;
	uint16_t urgent_p;
} TAG_TCP_HEADER;

/*
TAG_TCP_HEADER.flags
Flags: 0x011 (FIN, ACK)
000. .... .... = Reserved: Not set
...0 .... .... = Nonce: Not set
.... 0... .... = Congestion Window Reduced (CWR): Not set
.... .0.. .... = ECN-Echo: Not set
.... ..0. .... = Urgent: Not set
.... ...1 .... = Acknowledgment: Set
.... .... 0... = Push: Not set
.... .... .0.. = Reset: Not set
.... .... ..0. = Syn: Not set
.... .... ...1 = Fin: Set
[TCP Flags: ·······A···F]
*/

#define FLAG_BIT_TCP_FIN 0x01
#define FLAG_BIT_TCP_SYN 0x02
#define FLAG_BIT_TCP_ACK 0x10

typedef struct {
	uint8_t kind;
	uint8_t size;
} TAG_TCP_OPTION;

typedef struct {
	port_t   src_port;
	port_t   dst_port;
	uint16_t length;
	uint16_t checksum;
} TAG_UDP_HEADER;
#pragma pack(pop)

#define WORK_ON_COMPANY
#ifdef WORK_ON_COMPANY
#define OFFLINE_PCAP_FILE_TO_PARSE "D:\\my_tmp\\doc\\ora308_host_192_168_16_41_port_1521.pcap"
#else // #ifdef WORK_ON_COMPANY
#define OFFLINE_PCAP_FILE_TO_PARSE "D:\\my_tmp\\doc\\ora308_host_192_168_16_41_port_1521.pcap"
#endif // #ifdef WORK_ON_COMPANY

#define MY_CAPTRUE_FILTER "host 192.168.16.41 and port 1521"

pcap_t* g_h_lib_pcap = NULL;

struct bpf_program g_my_bpf_program;
bool g_b_valid_bpf = false;

void packet_handler(u_char *dumpfile, const struct pcap_pkthdr *header, const u_char *pkt_data);
void print_packet(const char* psz_tip, const char* pdata, int iLen);
char get_hex_char_to_disp(u_char c);
bool is_char_can_print(char c);

BOOL WINAPI phandler_routine(DWORD CtrlType)
{
	BOOL rc = FALSE;
	switch (CtrlType) {
	case CTRL_C_EVENT:
		{
			if (NULL != g_h_lib_pcap) {
				pcap_breakloop(g_h_lib_pcap);
			}
		}
		rc = TRUE;
		break;
	default:
		break;
	}

	return rc;
}

int _tmain(int argc, _TCHAR* argv[])
{
	bool rc = false;
	int i = 0;
	int err = 0;
	char errbuf[PCAP_ERRBUF_SIZE] = {'\0'};

	do {
		if (!fn_dy_load_wpcap()) {
			break;
		}

		if (!SetConsoleCtrlHandler(phandler_routine, TRUE)) {
			break;
		}

		g_h_lib_pcap = pcap_open_offline(OFFLINE_PCAP_FILE_TO_PARSE, errbuf);
		if (NULL == g_h_lib_pcap) {
			return -1;
		}

		pcap_set_promisc(g_h_lib_pcap, 1); // interface_opts->promisc_mode is 1
		pcap_set_timeout(g_h_lib_pcap, -1); // timeout is 250

		pcap_set_buffer_size(g_h_lib_pcap, 10 * 1024 * 1024);

		// capture_loop_init_filter
		int snaplen = pcap_snapshot(g_h_lib_pcap);
		printf("snaplen = %d\n", snaplen);

		// compile BPF
		if (pcap_compile(g_h_lib_pcap, &g_my_bpf_program, MY_CAPTRUE_FILTER, 1, 0) == -1) {
			fprintf(stderr, "error\n");
			break;
		}

		g_b_valid_bpf = true;

		// set BPF filter
		if (pcap_setfilter(g_h_lib_pcap, &g_my_bpf_program) == -1) {
			fprintf(stderr, "error\n");
			break;
		}

		/* start the capture */
		pcap_loop(g_h_lib_pcap, 0, packet_handler, NULL);

		printf("task over\n");
		rc = true;
	} while (0);

	if (!rc) {
		printf("error happen\n");
	}

	if (g_b_valid_bpf) {
		g_b_valid_bpf = false;
		pcap_freecode(&g_my_bpf_program);
	}

	if (NULL != g_h_lib_pcap) {
		pcap_close(g_h_lib_pcap);
		g_h_lib_pcap = NULL;
	}

	system("pause");
	return 0;
}

/* Callback function invoked by libpcap for every incoming packet */
void packet_handler(u_char *ctx, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
	/* save the packet on the dump file */
	// 假设抓的都是tcp的包数据

	static int cnt = 0; // 收到的包计数
	static long int l_padding_packet_recv = 0; // 收到带padding的tcp包

	const u_char* pc_data_left = NULL; // 没处理的数据
	int len_data_left = 0; // 没处理的数据长度
	int len_padding_bytes = 0; // tcp-payload 之后的 padding字节数量

	TAG_ETHER_HEADER* p_ether_hdr = NULL;
	TAG_IP_HEADER* p_ip_hdr = NULL;
	TAG_TCP_HEADER* p_tcp_hdr = NULL;
	int ip_header_size = 0;
	bool is_process_ok = false;

	// ip. total_length	10240	unsigned short
	// ip头 + tcp头 + tcp-payload 的总长度
	unsigned short uw_tcp_ip_data_length_by_ip_header = 0; // ip头中声明的当前包-数据总长度

	// 说明tcp-option部分可能长度为0~40
	unsigned char uc_tcp_header_length = 0; // tcp头的长度, 由TAG_TCP_HEADER.data_offset高4位 * 4决定, 最终值为20~60

	printf(">>%s\n", LINE_80);
	do {
		cnt++;
		printf("recv cnt = %d\n", cnt);

		if ((NULL == header) || (NULL == pkt_data)) {
			printf("error\n");
			break;
		}

		len_data_left = header->caplen; // 最开始能确定的包数据总长度为包捕获长度
		pc_data_left = pkt_data;

		// remove ether header from data in
		if (len_data_left < (int)sizeof(TAG_ETHER_HEADER)) {
			printf("error\n");
			break;
		}

		p_ether_hdr = (TAG_ETHER_HEADER*)pc_data_left;
		pc_data_left += sizeof(TAG_ETHER_HEADER);
		len_data_left -= sizeof(TAG_ETHER_HEADER);

		// remove ip header from data in
		if (len_data_left < (int)sizeof(TAG_IP_HEADER)) {
			printf("error\n");
			break;
		}

		p_ip_hdr = (TAG_IP_HEADER*)pc_data_left;
		uw_tcp_ip_data_length_by_ip_header = ntohs(p_ip_hdr->total_length);
		ip_header_size = 4 * (p_ip_hdr->ver_ihl & 0x0F);

		if (len_data_left < (int)uw_tcp_ip_data_length_by_ip_header) {
			printf("error\n");
			break;
		} else if (len_data_left > (int)uw_tcp_ip_data_length_by_ip_header) {
			len_padding_bytes = len_data_left - (int)uw_tcp_ip_data_length_by_ip_header;
			printf("find packet have padding %dbytes\n", len_padding_bytes);
		} else {
			printf("this packet not padding bytes\n");
		}

		// 已经扒掉了网卡头, 现在, 剩下的数据长度就是ip头中指定的ip_hdr + tcp_hdr + tcp_payload的总长度
		len_data_left = uw_tcp_ip_data_length_by_ip_header;

		pc_data_left += ip_header_size;
		len_data_left -= ip_header_size;

		// remove tcp header from data in
		if (len_data_left < (int)sizeof(TAG_TCP_HEADER)) {
			printf("error\n");
			break;
		}

		p_tcp_hdr = (TAG_TCP_HEADER*)pc_data_left;
		uc_tcp_header_length = ((p_tcp_hdr->data_offset >> 4) & 0x0f) * 4;

		if (len_data_left < (int)uc_tcp_header_length) {
			printf("error\n");
			break;
		}

		pc_data_left += uc_tcp_header_length;
		len_data_left -= uc_tcp_header_length;

		// tcp pay_load
		// print_packet("tcp payload", (const char*)pc_data_left, len_data_left);

		// tcp padding
		// pc_data_left += len_data_left;
		// len_data_left = 0;
		// print_packet("find padding", (const char*)pc_data_left, len_padding_bytes);

		is_process_ok = true;
	} while (0);

	if (!is_process_ok) {
		printf("!is_process_ok\n");
		if (NULL != g_h_lib_pcap) {
			printf("pcap_breakloop\n");
			pcap_breakloop(g_h_lib_pcap);
		}
	}

	printf("<<%s\n", LINE_80);
}

void print_packet(const char* psz_tip, const char* pdata, int iLen)
{
	char szBuf[260] = { '\0' };
	const int iOneRowChars = 16;
	const unsigned char* pCur = NULL;
	int iPos = 0;

	do {
		if (NULL == pdata) {
			break;
		}

		MYLOG_I("%s : %d(bytes)\n", ((NULL != psz_tip) && ((int)strlen(psz_tip) > 0)) ? psz_tip : "print_packet", iLen);

		do {
			pCur = (unsigned char*)(pdata + iPos);
			if (iLen >= iOneRowChars) {
				sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X  |  %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
					*(pCur + 0),
					*(pCur + 1),
					*(pCur + 2),
					*(pCur + 3),
					*(pCur + 4),
					*(pCur + 5),
					*(pCur + 6),
					*(pCur + 7),
					*(pCur + 8),
					*(pCur + 9),
					*(pCur + 10),
					*(pCur + 11),
					*(pCur + 12),
					*(pCur + 13),
					*(pCur + 14),
					*(pCur + 15),
					get_hex_char_to_disp(*(pCur + 0)),
					get_hex_char_to_disp(*(pCur + 1)),
					get_hex_char_to_disp(*(pCur + 2)),
					get_hex_char_to_disp(*(pCur + 3)),
					get_hex_char_to_disp(*(pCur + 4)),
					get_hex_char_to_disp(*(pCur + 5)),
					get_hex_char_to_disp(*(pCur + 6)),
					get_hex_char_to_disp(*(pCur + 7)),
					get_hex_char_to_disp(*(pCur + 8)),
					get_hex_char_to_disp(*(pCur + 9)),
					get_hex_char_to_disp(*(pCur + 10)),
					get_hex_char_to_disp(*(pCur + 11)),
					get_hex_char_to_disp(*(pCur + 12)),
					get_hex_char_to_disp(*(pCur + 13)),
					get_hex_char_to_disp(*(pCur + 14)),
					get_hex_char_to_disp(*(pCur + 15)));

				MYLOG_I("%s\n", szBuf);
				iPos += iOneRowChars;
				iLen -= iOneRowChars;
			}
			else {
				switch (iLen) {
				case 15: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X     |  %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c ",
						*(pCur + 0),
						*(pCur + 1),
						*(pCur + 2),
						*(pCur + 3),
						*(pCur + 4),
						*(pCur + 5),
						*(pCur + 6),
						*(pCur + 7),
						*(pCur + 8),
						*(pCur + 9),
						*(pCur + 10),
						*(pCur + 11),
						*(pCur + 12),
						*(pCur + 13),
						*(pCur + 14),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)),
						get_hex_char_to_disp(*(pCur + 2)),
						get_hex_char_to_disp(*(pCur + 3)),
						get_hex_char_to_disp(*(pCur + 4)),
						get_hex_char_to_disp(*(pCur + 5)),
						get_hex_char_to_disp(*(pCur + 6)),
						get_hex_char_to_disp(*(pCur + 7)),
						get_hex_char_to_disp(*(pCur + 8)),
						get_hex_char_to_disp(*(pCur + 9)),
						get_hex_char_to_disp(*(pCur + 10)),
						get_hex_char_to_disp(*(pCur + 11)),
						get_hex_char_to_disp(*(pCur + 12)),
						get_hex_char_to_disp(*(pCur + 13)),
						get_hex_char_to_disp(*(pCur + 14)));

					MYLOG_I("%s\n", szBuf);
				}
						 break;
				case 14: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X        |  %c%c%c%c%c%c%c%c%c%c%c%c%c%c  ",
						*(pCur + 0),
						*(pCur + 1),
						*(pCur + 2),
						*(pCur + 3),
						*(pCur + 4),
						*(pCur + 5),
						*(pCur + 6),
						*(pCur + 7),
						*(pCur + 8),
						*(pCur + 9),
						*(pCur + 10),
						*(pCur + 11),
						*(pCur + 12),
						*(pCur + 13),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)),
						get_hex_char_to_disp(*(pCur + 2)),
						get_hex_char_to_disp(*(pCur + 3)),
						get_hex_char_to_disp(*(pCur + 4)),
						get_hex_char_to_disp(*(pCur + 5)),
						get_hex_char_to_disp(*(pCur + 6)),
						get_hex_char_to_disp(*(pCur + 7)),
						get_hex_char_to_disp(*(pCur + 8)),
						get_hex_char_to_disp(*(pCur + 9)),
						get_hex_char_to_disp(*(pCur + 10)),
						get_hex_char_to_disp(*(pCur + 11)),
						get_hex_char_to_disp(*(pCur + 12)),
						get_hex_char_to_disp(*(pCur + 13)));

					MYLOG_I("%s\n", szBuf);
				}
						 break;
				case 13: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X           |  %c%c%c%c%c%c%c%c%c%c%c%c%c   ",
						*(pCur + 0),
						*(pCur + 1),
						*(pCur + 2),
						*(pCur + 3),
						*(pCur + 4),
						*(pCur + 5),
						*(pCur + 6),
						*(pCur + 7),
						*(pCur + 8),
						*(pCur + 9),
						*(pCur + 10),
						*(pCur + 11),
						*(pCur + 12),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)),
						get_hex_char_to_disp(*(pCur + 2)),
						get_hex_char_to_disp(*(pCur + 3)),
						get_hex_char_to_disp(*(pCur + 4)),
						get_hex_char_to_disp(*(pCur + 5)),
						get_hex_char_to_disp(*(pCur + 6)),
						get_hex_char_to_disp(*(pCur + 7)),
						get_hex_char_to_disp(*(pCur + 8)),
						get_hex_char_to_disp(*(pCur + 9)),
						get_hex_char_to_disp(*(pCur + 10)),
						get_hex_char_to_disp(*(pCur + 11)),
						get_hex_char_to_disp(*(pCur + 12)));

					MYLOG_I("%s\n", szBuf);
				}
						 break;
				case 12: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X              |  %c%c%c%c%c%c%c%c%c%c%c%c    ",
						*(pCur + 0),
						*(pCur + 1),
						*(pCur + 2),
						*(pCur + 3),
						*(pCur + 4),
						*(pCur + 5),
						*(pCur + 6),
						*(pCur + 7),
						*(pCur + 8),
						*(pCur + 9),
						*(pCur + 10),
						*(pCur + 11),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)),
						get_hex_char_to_disp(*(pCur + 2)),
						get_hex_char_to_disp(*(pCur + 3)),
						get_hex_char_to_disp(*(pCur + 4)),
						get_hex_char_to_disp(*(pCur + 5)),
						get_hex_char_to_disp(*(pCur + 6)),
						get_hex_char_to_disp(*(pCur + 7)),
						get_hex_char_to_disp(*(pCur + 8)),
						get_hex_char_to_disp(*(pCur + 9)),
						get_hex_char_to_disp(*(pCur + 10)),
						get_hex_char_to_disp(*(pCur + 11)));

					MYLOG_I("%s\n", szBuf);
				}
						 break;
				case 11: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X                 |  %c%c%c%c%c%c%c%c%c%c%c     ",
						*(pCur + 0),
						*(pCur + 1),
						*(pCur + 2),
						*(pCur + 3),
						*(pCur + 4),
						*(pCur + 5),
						*(pCur + 6),
						*(pCur + 7),
						*(pCur + 8),
						*(pCur + 9),
						*(pCur + 10),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)),
						get_hex_char_to_disp(*(pCur + 2)),
						get_hex_char_to_disp(*(pCur + 3)),
						get_hex_char_to_disp(*(pCur + 4)),
						get_hex_char_to_disp(*(pCur + 5)),
						get_hex_char_to_disp(*(pCur + 6)),
						get_hex_char_to_disp(*(pCur + 7)),
						get_hex_char_to_disp(*(pCur + 8)),
						get_hex_char_to_disp(*(pCur + 9)),
						get_hex_char_to_disp(*(pCur + 10)));

					MYLOG_I("%s\n", szBuf);
				}
						 break;
				case 10: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X                    |  %c%c%c%c%c%c%c%c%c%c      ",
						*(pCur + 0),
						*(pCur + 1),
						*(pCur + 2),
						*(pCur + 3),
						*(pCur + 4),
						*(pCur + 5),
						*(pCur + 6),
						*(pCur + 7),
						*(pCur + 8),
						*(pCur + 9),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)),
						get_hex_char_to_disp(*(pCur + 2)),
						get_hex_char_to_disp(*(pCur + 3)),
						get_hex_char_to_disp(*(pCur + 4)),
						get_hex_char_to_disp(*(pCur + 5)),
						get_hex_char_to_disp(*(pCur + 6)),
						get_hex_char_to_disp(*(pCur + 7)),
						get_hex_char_to_disp(*(pCur + 8)),
						get_hex_char_to_disp(*(pCur + 9)));

					MYLOG_I("%s\n", szBuf);
				}
						 break;
				case 9: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X                       |  %c%c%c%c%c%c%c%c%c       ",
						*(pCur + 0),
						*(pCur + 1),
						*(pCur + 2),
						*(pCur + 3),
						*(pCur + 4),
						*(pCur + 5),
						*(pCur + 6),
						*(pCur + 7),
						*(pCur + 8),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)),
						get_hex_char_to_disp(*(pCur + 2)),
						get_hex_char_to_disp(*(pCur + 3)),
						get_hex_char_to_disp(*(pCur + 4)),
						get_hex_char_to_disp(*(pCur + 5)),
						get_hex_char_to_disp(*(pCur + 6)),
						get_hex_char_to_disp(*(pCur + 7)),
						get_hex_char_to_disp(*(pCur + 8)));

					MYLOG_I("%s\n", szBuf);
				}
						break;
				case 8: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X                          |  %c%c%c%c%c%c%c%c        ",
						*(pCur + 0),
						*(pCur + 1),
						*(pCur + 2),
						*(pCur + 3),
						*(pCur + 4),
						*(pCur + 5),
						*(pCur + 6),
						*(pCur + 7),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)),
						get_hex_char_to_disp(*(pCur + 2)),
						get_hex_char_to_disp(*(pCur + 3)),
						get_hex_char_to_disp(*(pCur + 4)),
						get_hex_char_to_disp(*(pCur + 5)),
						get_hex_char_to_disp(*(pCur + 6)),
						get_hex_char_to_disp(*(pCur + 7)));

					MYLOG_I("%s\n", szBuf);
				}
						break;
				case 7: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X                             |  %c%c%c%c%c%c%c         ",
						*(pCur + 0),
						*(pCur + 1),
						*(pCur + 2),
						*(pCur + 3),
						*(pCur + 4),
						*(pCur + 5),
						*(pCur + 6),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)),
						get_hex_char_to_disp(*(pCur + 2)),
						get_hex_char_to_disp(*(pCur + 3)),
						get_hex_char_to_disp(*(pCur + 4)),
						get_hex_char_to_disp(*(pCur + 5)),
						get_hex_char_to_disp(*(pCur + 6)));

					MYLOG_I("%s\n", szBuf);
				}
						break;
				case 6: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X                                |  %c%c%c%c%c%c          ",
						*(pCur + 0),
						*(pCur + 1),
						*(pCur + 2),
						*(pCur + 3),
						*(pCur + 4),
						*(pCur + 5),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)),
						get_hex_char_to_disp(*(pCur + 2)),
						get_hex_char_to_disp(*(pCur + 3)),
						get_hex_char_to_disp(*(pCur + 4)),
						get_hex_char_to_disp(*(pCur + 5)));

					MYLOG_I("%s\n", szBuf);
				}
						break;
				case 5: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X %2.2X %2.2X                                   |  %c%c%c%c%c           ",
						*(pCur + 0),
						*(pCur + 1),
						*(pCur + 2),
						*(pCur + 3),
						*(pCur + 4),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)),
						get_hex_char_to_disp(*(pCur + 2)),
						get_hex_char_to_disp(*(pCur + 3)),
						get_hex_char_to_disp(*(pCur + 4)));

					MYLOG_I("%s\n", szBuf);
				}
						break;
				case 4: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X %2.2X                                      |  %c%c%c%c            ",
						*(pCur + 0),
						*(pCur + 1),
						*(pCur + 2),
						*(pCur + 3),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)),
						get_hex_char_to_disp(*(pCur + 2)),
						get_hex_char_to_disp(*(pCur + 3)));

					MYLOG_I("%s\n", szBuf);
				}
						break;
				case 3: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X                                         |  %c%c%c             ",
						*(pCur + 0),
						*(pCur + 1),
						*(pCur + 2),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)),
						get_hex_char_to_disp(*(pCur + 2)));

					MYLOG_I("%s\n", szBuf);
				}
						break;
				case 2: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X                                            |  %c%c              ",
						*(pCur + 0),
						*(pCur + 1),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)));

					MYLOG_I("%s\n", szBuf);
				}
						break;
				case 1: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X                                               |  %c               ",
						*(pCur + 0),
						get_hex_char_to_disp(*(pCur + 0)));

					MYLOG_I("%s\n", szBuf);
				}
						break;
				default:
					break;
				}
				iPos += iLen;
				iLen -= iLen;
			}
		} while (iLen > 0);
	} while (0);
}

bool is_char_can_print(char c)
{
	return ((c >= 32) && (c < 127));
}

char get_hex_char_to_disp(u_char c)
{
	char c_rc = '.';

	if (is_char_can_print((char)c)) {
		c_rc = (char)c;
	}

	return c_rc;
}

// @file \wpcap_dll_ex.cpp

#include "stdafx.h"
#include "wpcap_dll_ex.h"

#define	G_STRINGIFY_ARG(contents)	#contents
#define G_STRINGIFY(macro_or_string)	G_STRINGIFY_ARG (macro_or_string)

/* CPP magic: Concatenate two strings or macros that resolve to strings.
* Use CONCAT(), not _CONCAT() */
#define _CONCAT(a,b)		a ## b
#define CONCAT(a,b)		_CONCAT(a,b)

#define SYM(x, y)	{ G_STRINGIFY(x) , (void**) &CONCAT(p_,x), y }

/* Define if pcap_breakloop is known */
#define HAVE_PCAP_BREAKLOOP 1

/* Define to 1 if you have the `pcap_create' function. */
#define HAVE_PCAP_CREATE 1

/* Define to 1 if the capture buffer size can be set. */
#define CAN_SET_CAPTURE_BUFFER_SIZE 1

/* Define to 1 if you have the `pcap_datalink_name_to_val' function. */
#define HAVE_PCAP_DATALINK_NAME_TO_VAL 1

/* Define to 1 if you have the `pcap_datalink_val_to_description' function. */
#define HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION 1

/* Define to 1 if you have the `pcap_datalink_val_to_name' function. */
#define HAVE_PCAP_DATALINK_VAL_TO_NAME 1

/* Define to 1 if you have the `pcap_findalldevs' function and a pcap.h that
declares pcap_if_t. */
#define HAVE_PCAP_FINDALLDEVS 1

/* Define to 1 if you have the `pcap_freecode' function. */
#define HAVE_PCAP_FREECODE 1

/* Define to 1 if you have the `pcap_free_datalinks' function. */
#define HAVE_PCAP_FREE_DATALINKS 1

/* Define to 1 if you have the `pcap_get_selectable_fd' function. */
/* #undef HAVE_PCAP_GET_SELECTABLE_FD */

/* Define to 1 if you have the `pcap_lib_version' function. */
#define HAVE_PCAP_LIB_VERSION 1

/* Define to 1 if you have the `pcap_list_datalinks' function. */
#define HAVE_PCAP_LIST_DATALINKS 1

/* Define to 1 if you have the `pcap_open' function. */
#define HAVE_PCAP_OPEN 1

/* Define to 1 if you have the `pcap_open_dead' function. */
#define HAVE_PCAP_OPEN_DEAD 1

/* Define to 1 if you have libpcap/WinPcap remote capturing support. */
#define HAVE_PCAP_REMOTE 1

/* Define to 1 if you have the `pcap_set_datalink' function. */
#define HAVE_PCAP_SET_DATALINK 1

/* Define to 1 if you have the `pcap_setsampling' function. */
#define HAVE_PCAP_SETSAMPLING 1

/* Define to 1 if you have the `bpf_image' function. */
#define HAVE_BPF_IMAGE 1

typedef struct _tag_symbol_table_t {
	const char*		name;
	void**			ptr;
	bool			optional;
} TAG_SYMBOL_TABLE_T;

/*
* XXX - should we require at least WinPcap 3.1 both for building an
* for using Wireshark?
*/

static char*   (*p_pcap_lookupdev) (char *);
static void(*p_pcap_close) (pcap_t *);
static int(*p_pcap_stats) (pcap_t *, struct pcap_stat *);
static int(*p_pcap_dispatch) (pcap_t *, int, pcap_handler, u_char *);
static int(*p_pcap_snapshot) (pcap_t *);
static int(*p_pcap_datalink) (pcap_t *);
static int(*p_pcap_setfilter) (pcap_t *, struct bpf_program *);
static char*   (*p_pcap_geterr) (pcap_t *);
static int(*p_pcap_compile) (pcap_t *, struct bpf_program *, const char *, int, bpf_u_int32);
static int(*p_pcap_compile_nopcap) (int, int, struct bpf_program *, const char *, int, bpf_u_int32);
static int(*p_pcap_lookupnet) (const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
static pcap_t* (*p_pcap_open_live) (const char *, int, int, int, char *);
static pcap_t* (*p_pcap_open_offline)(const char *fname, char *errbuf);
static int(*p_pcap_loop) (pcap_t *, int, pcap_handler, u_char *);
#ifdef HAVE_PCAP_OPEN_DEAD
static pcap_t* (*p_pcap_open_dead) (int, int);
#endif
static void(*p_pcap_freecode) (struct bpf_program *);
#ifdef HAVE_PCAP_FINDALLDEVS
static int(*p_pcap_findalldevs) (pcap_if_t **, char *);
static void(*p_pcap_freealldevs) (pcap_if_t *);
#endif
#ifdef HAVE_PCAP_DATALINK_NAME_TO_VAL
static int(*p_pcap_datalink_name_to_val) (const char *);
#endif
#ifdef HAVE_PCAP_DATALINK_VAL_TO_NAME
static const char *(*p_pcap_datalink_val_to_name) (int);
#endif
#ifdef HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION
static const char *(*p_pcap_datalink_val_to_description) (int);
#endif
#ifdef HAVE_PCAP_BREAKLOOP
static void(*p_pcap_breakloop) (pcap_t *);
#endif
static const char *(*p_pcap_lib_version) (void);
static int(*p_pcap_setbuff) (pcap_t *, int dim);
static int(*p_pcap_next_ex) (pcap_t *, struct pcap_pkthdr **pkt_header, const u_char **pkt_data);
#ifdef HAVE_PCAP_REMOTE
static pcap_t* (*p_pcap_open) (const char *, int, int, int, struct pcap_rmtauth *, char *);
static int(*p_pcap_findalldevs_ex) (char *, struct pcap_rmtauth *, pcap_if_t **, char *);
static int(*p_pcap_createsrcstr) (char *, int, const char *, const char *, const char *, char *);
#endif
#ifdef HAVE_PCAP_SETSAMPLING
static struct pcap_samp* (*p_pcap_setsampling)(pcap_t *);
#endif

#ifdef HAVE_PCAP_LIST_DATALINKS
static int(*p_pcap_list_datalinks)(pcap_t *, int **);
#endif

#ifdef HAVE_PCAP_SET_DATALINK
static int(*p_pcap_set_datalink)(pcap_t *, int);
#endif

#ifdef HAVE_PCAP_FREE_DATALINKS
static int(*p_pcap_free_datalinks)(int *);
#endif

#ifdef HAVE_BPF_IMAGE
static char	*(*p_bpf_image)(const struct bpf_insn *, int);
#endif

#ifdef HAVE_PCAP_CREATE
static pcap_t	*(*p_pcap_create)(const char *, char *);
static int(*p_pcap_set_snaplen)(pcap_t *, int);
static int(*p_pcap_set_promisc)(pcap_t *, int);
static int(*p_pcap_can_set_rfmon)(pcap_t *);
static int(*p_pcap_set_rfmon)(pcap_t *, int);
static int(*p_pcap_set_timeout)(pcap_t *, int);
static int(*p_pcap_set_buffer_size)(pcap_t *, int);
static int(*p_pcap_activate)(pcap_t *);
static const char *(*p_pcap_statustostr)(int);
#endif

static pcap_dumper_t *(*p_pcap_dump_open)(pcap_t *a, const char *b);
static void (*p_pcap_dump)(u_char* a, const struct pcap_pkthdr* b, const u_char* c);
static void	(*p_pcap_dump_close)(pcap_dumper_t *);

/* These are the symbols I need or want from Wpcap */
static TAG_SYMBOL_TABLE_T	symbols[] = {
	SYM(pcap_lookupdev, FALSE),
	SYM(pcap_close, FALSE),
	SYM(pcap_stats, FALSE),
	SYM(pcap_dispatch, FALSE),
	SYM(pcap_snapshot, FALSE),
	SYM(pcap_datalink, FALSE),
	SYM(pcap_setfilter, FALSE),
	SYM(pcap_geterr, FALSE),
	SYM(pcap_compile, FALSE),
	SYM(pcap_compile_nopcap, FALSE),
	SYM(pcap_lookupnet, FALSE),
#ifdef HAVE_PCAP_REMOTE
	SYM(pcap_open, FALSE),
	SYM(pcap_findalldevs_ex, FALSE),
	SYM(pcap_createsrcstr, FALSE),
#endif

#ifdef HAVE_PCAP_FINDALLDEVS
	SYM(pcap_findalldevs, FALSE),
	SYM(pcap_freealldevs, TRUE),
#endif

	SYM(pcap_open_live, FALSE),
	SYM(pcap_open_offline, FALSE),
#ifdef HAVE_PCAP_OPEN_DEAD
	SYM(pcap_open_dead, FALSE),
#endif
#ifdef HAVE_PCAP_SETSAMPLING
	SYM(pcap_setsampling, TRUE),
#endif
	SYM(pcap_loop, FALSE),
	SYM(pcap_freecode, TRUE),

#ifdef HAVE_PCAP_DATALINK_NAME_TO_VAL
	SYM(pcap_datalink_name_to_val, TRUE),
#endif
#ifdef HAVE_PCAP_DATALINK_VAL_TO_NAME
	SYM(pcap_datalink_val_to_name, TRUE),
#endif
#ifdef HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION
	SYM(pcap_datalink_val_to_description, TRUE),
#endif
#ifdef HAVE_PCAP_BREAKLOOP
	/*
	* We don't try to work around the lack of this at
	* run time; it's present in WinPcap 3.1, which is
	* the version we build with and ship with.
	*/
	SYM(pcap_breakloop, FALSE),
#endif
	SYM(pcap_lib_version, TRUE),
	SYM(pcap_setbuff, TRUE),
	SYM(pcap_next_ex, TRUE),
#ifdef HAVE_PCAP_LIST_DATALINKS
	SYM(pcap_list_datalinks, FALSE),
#endif
#ifdef HAVE_PCAP_SET_DATALINK
	SYM(pcap_set_datalink, FALSE),
#endif
#ifdef HAVE_PCAP_FREE_DATALINKS
	SYM(pcap_free_datalinks, TRUE),
#endif
#ifdef HAVE_BPF_IMAGE
	SYM(bpf_image, FALSE),
#endif
#ifdef HAVE_PCAP_CREATE
	SYM(pcap_create, TRUE),
	SYM(pcap_set_snaplen, TRUE),
	SYM(pcap_set_promisc, TRUE),
	SYM(pcap_can_set_rfmon, TRUE),
	SYM(pcap_set_rfmon, TRUE),
	SYM(pcap_set_timeout, FALSE),
	SYM(pcap_set_buffer_size, FALSE),
	SYM(pcap_activate, TRUE),
	SYM(pcap_statustostr, TRUE),
#endif

	SYM(pcap_dump_open, TRUE),
	SYM(pcap_dump, TRUE),
	SYM(pcap_dump_close, TRUE),

{ NULL, NULL, FALSE }
};

static char g_program_path[MAX_PATH] = {'\0'};
static char g_system_path[MAX_PATH] = { '\0' };
static char g_npcap_path[MAX_PATH] = { '\0' };

static bool g_b_ok_init_dll_search_path = false;
static bool g_b_ok_init_dll_load_paths = false;

static bool fn_init_dll_load_paths();
static bool fn_init_dll_search_path();
static HMODULE ws_module_open(char* module_name);
static char* module_build_path(char* dir, char* name);
static bool get_module_symbol(HMODULE wh, TAG_SYMBOL_TABLE_T * symbol);

static bool fn_init_dll_load_paths()
{
	char path_buf[MAX_PATH] = {'\0'};
	char* p_find = NULL;

	if (!g_b_ok_init_dll_load_paths) {
		if (!fn_init_dll_search_path()) {
			return false;
		}

		if (GetModuleFileNameA(NULL, path_buf, MAX_PATH) == 0 || GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
			return false;
		}

		p_find = strrchr(path_buf, '\\');
		if (NULL != p_find) {
			p_find[0] = '\0';
		}

		strcpy_s(g_program_path, sizeof(g_program_path), path_buf);
		strcat_s(g_program_path, sizeof(g_program_path), "\\");

		if (GetSystemDirectoryA(path_buf, MAX_PATH) == 0) {
			return false;
		}
		strcpy_s(g_system_path, sizeof(g_system_path), path_buf);
		strcat_s(g_system_path, sizeof(g_system_path), "\\");

		strcat_s(path_buf, sizeof(path_buf), "\\Npcap\\");
		strcpy_s(g_npcap_path, sizeof(g_npcap_path), path_buf);
		g_b_ok_init_dll_load_paths = true;
	}

	return g_b_ok_init_dll_load_paths;
}

static bool fn_init_dll_search_path()
{
	BOOL dll_dir_set = FALSE;
	wchar_t npcap_path_w[MAX_PATH];
	unsigned int retval;

	typedef BOOL(WINAPI *PFN_SetDllDirectoryW)(LPCWSTR);
	PFN_SetDllDirectoryW pfn_SetDllDirectoryW = NULL;

	if (!g_b_ok_init_dll_search_path) {
		pfn_SetDllDirectoryW = (PFN_SetDllDirectoryW)GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "SetDllDirectoryW");
		if (NULL != pfn_SetDllDirectoryW) {
			dll_dir_set = pfn_SetDllDirectoryW(L"");
			if (dll_dir_set) {
				retval = GetSystemDirectoryW(npcap_path_w, MAX_PATH);
				if (0 < retval && retval <= MAX_PATH) {
					wcscat_s(npcap_path_w, MAX_PATH, L"\\Npcap");
					dll_dir_set = pfn_SetDllDirectoryW(npcap_path_w);
				}
			}
		}

		g_b_ok_init_dll_search_path = (TRUE == dll_dir_set);
	}

	return g_b_ok_init_dll_search_path;
}

static bool get_module_symbol(HMODULE wh, TAG_SYMBOL_TABLE_T * symbol)
{
	if (NULL == symbol) {
		return false;
	}

	if (0 == strcmp("pcap_findalldevs", symbol->name)) {
		printf(" "); // for debug
	}

	*symbol->ptr = GetProcAddress(wh, symbol->name);
	return (NULL != symbol->ptr);
}

bool fn_dy_load_wpcap(void)
{
	HMODULE wh = NULL;
	TAG_SYMBOL_TABLE_T* sym = NULL;

	wh = ws_module_open("wpcap.dll");
	if (!wh) {
		return false;
	}

	sym = (TAG_SYMBOL_TABLE_T *)&symbols[0];
	while (sym->name) {
		if (!get_module_symbol(wh, sym)) {
			if (FALSE == sym->optional) {
				/*
				* We don't care if it's missing; we just
				* don't use it.
				*/
				*sym->ptr = (void*)NULL;
			}
			else {
				/*
				* We require this symbol.
				*/
				return false;
			}
		}
		sym++;
	}

	return true;
}

static char* module_build_path(char* dir, char* name)
{
	char* psz_path_name = NULL;
	size_t len_dir = 0;
	size_t len_name = 0;
	size_t len_path_name = 0;

	if ((NULL == dir) || (NULL == name)) {
		return NULL;
	}

	len_dir = strlen(dir);
	len_name = strlen(name);

	len_path_name = len_dir + len_name + 2; // append '\n' + '\\'
	psz_path_name = new char[len_path_name];
	if (NULL == psz_path_name) {
		return NULL;
	}
	memset(psz_path_name, 0, len_path_name);

	strcpy_s(psz_path_name, len_path_name, dir);
	if (dir[len_dir - 1] != '\\') {
		strcat_s(psz_path_name, len_path_name, "\\");
	}

	strcat_s(psz_path_name, len_path_name, name);

	return psz_path_name;
}

static HMODULE ws_module_open(char* module_name)
{
	char* full_path = NULL;
	HMODULE mod = NULL;

	if (!fn_init_dll_load_paths() || !module_name)
		return NULL;

	/* First try the program directory */
	full_path = module_build_path(g_program_path, module_name);

	if (NULL != full_path) {
		mod = LoadLibraryA(full_path);
		if (NULL != mod) {
			delete(full_path);
			return mod;
		}
	}

	/* Next try the system directory */
	full_path = module_build_path(g_system_path, module_name);

	if (NULL != full_path) {
		mod = LoadLibraryA(full_path);
		if (NULL != mod) {
			delete(full_path);
			return mod;
		}
	}

	/* At last try the Npcap directory */
	full_path = module_build_path(g_npcap_path, module_name);

	if (NULL != full_path) {
		mod = LoadLibraryA(full_path);
		if (NULL != mod) {
			delete(full_path);
			return mod;
		}
	}

	return NULL;
}

char* pcap_lookupdev(char *a)
{
	if (NULL == p_pcap_lookupdev) {
		return NULL;
	}

	return p_pcap_lookupdev(a);
}

void pcap_close(pcap_t *a)
{
	if (NULL == p_pcap_close) {
		return;
	}

	p_pcap_close(a);
}

int pcap_stats(pcap_t *a, struct pcap_stat *b)
{
	if (NULL == p_pcap_stats) {
		return -1;
	}

	return p_pcap_stats(a, b);
}

int pcap_dispatch(pcap_t *a, int b, pcap_handler c, u_char *d)
{
	if (NULL == p_pcap_dispatch) {
		return -1;
	}
	return p_pcap_dispatch(a, b, c, d);
}

int pcap_snapshot(pcap_t *a)
{
	if (NULL == p_pcap_snapshot) {
		return -1;
	}
	return p_pcap_snapshot(a);
}

int pcap_datalink(pcap_t *a)
{
	if (NULL == p_pcap_datalink) {
		return -1;
	}
	return p_pcap_datalink(a);
}

#ifdef HAVE_PCAP_SET_DATALINK
int pcap_set_datalink(pcap_t *p, int dlt)
{
	if (NULL == p_pcap_set_datalink) {
		return -1;
	}
	return p_pcap_set_datalink(p, dlt);
}
#endif

int pcap_setfilter(pcap_t *a, struct bpf_program *b)
{
	if (NULL == p_pcap_setfilter) {
		return -1;
	}
	return p_pcap_setfilter(a, b);
}

char* pcap_geterr(pcap_t *a)
{
	if (NULL == p_pcap_geterr) {
		return NULL;
	}
	return p_pcap_geterr(a);
}

int pcap_compile(pcap_t *a, struct bpf_program *b, const char *c, int d, bpf_u_int32 e)
{
	if (NULL == p_pcap_compile) {
		return -1;
	}
	return p_pcap_compile(a, b, c, d, e);
}

int pcap_compile_nopcap(int a, int b, struct bpf_program *c, const char *d, int e, bpf_u_int32 f)
{
	if (NULL == p_pcap_compile_nopcap) {
		return -1;
	}

	return p_pcap_compile_nopcap(a, b, c, d, e, f);
}

int pcap_lookupnet(const char *a, bpf_u_int32 *b, bpf_u_int32 *c, char *d)
{
	if (NULL == p_pcap_lookupnet) {
		return -1;
	}

	return p_pcap_lookupnet(a, b, c, d);
}

pcap_t* pcap_open_live(const char *a, int b, int c, int d, char *e)
{
	if (NULL == p_pcap_open_live) {
		return NULL;
	}

	return p_pcap_open_live(a, b, c, d, e);
}

pcap_t* pcap_open_offline(const char *a, char *b)
{
	if (NULL == p_pcap_open_offline) {
		return NULL;
	}

	return p_pcap_open_offline(a, b);
}

#ifdef HAVE_PCAP_OPEN_DEAD
pcap_t* pcap_open_dead(int a, int b)
{
	if (NULL == p_pcap_open_dead) {
		return NULL;
	}
	return p_pcap_open_dead(a, b);
}
#endif

#ifdef HAVE_BPF_IMAGE
char * bpf_image(const struct bpf_insn *a, int b)
{
	if (NULL == p_bpf_image) {
		return NULL;
	}
	return p_bpf_image(a, b);
}
#endif

#ifdef HAVE_PCAP_REMOTE
pcap_t* pcap_open(const char *a, int b, int c, int d, struct pcap_rmtauth *e, char *f)
{
	if (NULL == p_pcap_open) {
		return NULL;
	}
	return p_pcap_open(a, b, c, d, e, f);
}

int pcap_findalldevs_ex(char *a, struct pcap_rmtauth *b, pcap_if_t **c, char *d)
{
	if (NULL == p_pcap_findalldevs_ex) {
		return -1;
	}

	return p_pcap_findalldevs_ex(a, b, c, d);
}

int pcap_createsrcstr(char *a, int b, const char *c, const char *d, const char *e, char *f)
{
	if (NULL == p_pcap_createsrcstr) {
		return -1;
	}

	return p_pcap_createsrcstr(a, b, c, d, e, f);
}
#endif

#ifdef HAVE_PCAP_SETSAMPLING
struct pcap_samp * pcap_setsampling(pcap_t *a)
{
	if (p_pcap_setsampling != NULL) {
		return p_pcap_setsampling(a);
	}
	return NULL;
}
#endif

int pcap_loop(pcap_t *a, int b, pcap_handler c, u_char *d)
{
	if (NULL == p_pcap_loop) {
		return -1;
	}

	return p_pcap_loop(a, b, c, d);
}

void pcap_freecode(struct bpf_program *a)
{
	if (p_pcap_freecode) {
		p_pcap_freecode(a);
	}
}

#ifdef HAVE_PCAP_FINDALLDEVS
int pcap_findalldevs(pcap_if_t **a, char *b)
{
	if (NULL == p_pcap_findalldevs) {
		return -1;
	}

	return p_pcap_findalldevs(a, b);
}

void pcap_freealldevs(pcap_if_t *a)
{
	if (NULL != p_pcap_freealldevs) {
		p_pcap_freealldevs(a);
	}
}
#endif

#ifdef HAVE_PCAP_CREATE
pcap_t * pcap_create(const char *a, char *b)
{
	if (NULL == p_pcap_create) {
		return NULL;
	}

	return p_pcap_create(a, b);
}

int pcap_set_snaplen(pcap_t *a, int b)
{
	if (NULL == p_pcap_set_snaplen) {
		return -1;
	}

	return p_pcap_set_snaplen(a, b);
}

int pcap_set_promisc(pcap_t *a, int b)
{
	if (NULL == p_pcap_set_promisc) {
		return -1;
	}
	return p_pcap_set_promisc(a, b);
}

int pcap_can_set_rfmon(pcap_t *a)
{
	if (p_pcap_can_set_rfmon != NULL) {
		return p_pcap_can_set_rfmon(a);
	}

	return -1;
}

int pcap_set_rfmon(pcap_t *a, int b)
{
	if (NULL == p_pcap_set_rfmon) {
		return -1;
	}
	return p_pcap_set_rfmon(a, b);
}

int pcap_set_timeout(pcap_t *a, int b)
{
	if (NULL == p_pcap_set_timeout) {
		return -1;
	}
	
	return p_pcap_set_timeout(a, b);
}

int pcap_set_buffer_size(pcap_t *a, int b)
{
	if (NULL == p_pcap_set_buffer_size) {
		return -1;
	}
	return p_pcap_set_buffer_size(a, b);
}

int pcap_activate(pcap_t *a)
{
	if (NULL == p_pcap_activate) {
		return -1;
	}

	return p_pcap_activate(a);
}

const char* pcap_statustostr(int a)
{
	if (NULL == pcap_statustostr) {
		return NULL;
	}

	return pcap_statustostr(a);
}
#endif

#ifdef HAVE_PCAP_DATALINK_NAME_TO_VAL
int pcap_datalink_name_to_val(const char *name)
{
	if (NULL != p_pcap_datalink_name_to_val) {
		return -1;
	}

	return p_pcap_datalink_name_to_val(name);
}
#endif

#ifdef HAVE_PCAP_LIST_DATALINKS
int pcap_list_datalinks(pcap_t *p, int **ddlt)
{
	if (NULL != p_pcap_list_datalinks) {
		return -1;
	}

	return p_pcap_list_datalinks(p, ddlt);
}
#endif

#ifdef HAVE_PCAP_FREE_DATALINKS
void pcap_free_datalinks(int *ddlt)
{
	/*
	* If we don't have pcap_free_datalinks() in WinPcap,
	* we don't free the memory - we can't use free(), as
	* we might not have been built with the same version
	* of the C runtime library as WinPcap was, and, if we're
	* not, free() isn't guaranteed to work on something
	* allocated by WinPcap.
	*/
	if (p_pcap_free_datalinks != NULL)
		p_pcap_free_datalinks(ddlt);
}
#endif

#ifdef HAVE_PCAP_DATALINK_VAL_TO_NAME
const char * pcap_datalink_val_to_name(int dlt)
{
	if (NULL == p_pcap_datalink_val_to_name) {
		return NULL;
	}

	return p_pcap_datalink_val_to_name(dlt);
}
#endif

#ifdef HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION
const char * pcap_datalink_val_to_description(int dlt)
{
	if (NULL == p_pcap_datalink_val_to_description) {
		return NULL;
	}

	return p_pcap_datalink_val_to_description(dlt);
}
#endif

#ifdef HAVE_PCAP_BREAKLOOP
void pcap_breakloop(pcap_t *a)
{
	if (NULL != p_pcap_breakloop) {
		p_pcap_breakloop(a);
	}
}
#endif

/* setbuff is win32 specific! */
int pcap_setbuff(pcap_t *a, int b)
{
	if (NULL == p_pcap_setbuff) {
		return -1;
	}

	return p_pcap_setbuff(a, b);
}

/* pcap_next_ex is available since libpcap 0.8 / WinPcap 3.0! */
/* (if you get a declaration warning here, try to update to at least WinPcap 3.1b4 develpack) */
int pcap_next_ex(pcap_t *a, struct pcap_pkthdr **b, const u_char **c)
{
	if (NULL == p_pcap_next_ex) {
		return -1;
	}

	return p_pcap_next_ex(a, b, c);
}

pcap_dumper_t *pcap_dump_open(pcap_t *a, const char *b)
{
	if (NULL == p_pcap_dump_open) {
		return NULL;
	}

	return p_pcap_dump_open(a, b);
}

void pcap_dump(u_char* a, const struct pcap_pkthdr* b, const u_char* c)
{
	if (NULL == p_pcap_dump) {
		return;
	}

	return p_pcap_dump(a, b, c);
}

void pcap_dump_close(pcap_dumper_t* a)
{
	if (NULL == p_pcap_dump_close) {
		return;
	}

	return p_pcap_dump_close(a);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值