前言
为了重复实验,重现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);
}