赞
踩
如果在工程中静态使用winpcap库,会在工程使用npcap库时遇到不能抓取回环包的问题.
不能抓取回环包的锅,要由npcap开发者来背。
他们开发的npcap的输出为wpcap.dll, 既然dll同名,就要保持接口完全一致. 可是他们加了新接口,导致静态包含winpcap库时, 内存布局变了. 那提供新的.h和.lib吧?也没有提供,让使用WpdPack_4_1_2的lib, 这不崩溃就不错了。
为了兼容winpcap和npcap, 动态使用wpcap.dll是个不错的选择。
而必须动态使用wpcap.dll的原因,并不像npcap文档上说的那样(e.g. dll会延迟加载).
开始试验时,没注意动态加载wpcap.dll. 发现不能抓回环包.
同事注意到相同条件(正确装了npcap安装包)下,wireshark是可以抓回环包的。
花了2天, 研究了wireshark和抓回环包相关的代码,扒出一个可用的demo工程。
wireshark代码是在QT中用c写的,改了一点点,整理出来的工程可以在VS中编译运行。
新版的npcap-0.99-r6.exe, 安装后,在win10下正常。在win7,winserver2008下,使原有的网络都断掉了(ip没了,其他计算机无法访问此台计算机),只有卸载了npcap才正常。
旧版的npcap-0.80.exe, 安装后,可以在保证原有网络正常的情况下,使新装的回环网卡支持回环抓包。
指定回环网卡后,只要ping 127.0.0.1 就可以抓到包.
src_capture_packet_on_loop_back_adapter.7z
封装了wpcap_dll_ex.h和wpcap_dll_ex.cpp 用来实现动态使用winpcap.
dy_load_wpcap_dll.cpp 是测试程序,如果原来有工程的话,直接包上wpcap_dll_ex.h,调用fn_dy_load_wpcap()后, 就是可以抓回环包的版本。
wpcap.dll中的API不到120个,wpcap_dll_ex.cpp中只封装了一部分,如果工程中用到新的pcap的API, 在wpcap_dll_ex.cpp加入很方便。
// @file \wpcap_dll_ex.h
#ifndef __WPCAP_DLL_EX_H__2018_0622_1636__
#define __WPCAP_DLL_EX_H__2018_0622_1636__
#include "pcap.h"
#define PCAP_SRC_IF_STRING "rpcap://"
bool fn_dy_load_wpcap(void);
#endif // #ifndef __WPCAP_DLL_EX_H__2018_0622_1636__
// @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 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);
/* 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),
#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),
{ 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);
}
#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);
}
// 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
#define PCAP_FILE_DUMP_TO "c:\\test\\abc.pcap"
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);
int _tmain(int argc, _TCHAR* argv[])
{
bool rc = false;
pcap_if_t *alldevs = NULL;
pcap_if_t *d = NULL;
int inum = 0;
int i = 0;
pcap_t* adhandle = NULL;
char errbuf[PCAP_ERRBUF_SIZE] = {'\0'};
pcap_dumper_t* dumpfile = NULL;
do {
if (!fn_dy_load_wpcap()) {
break;
}
printf("our prog begin\n");
/* Retrieve the device list on the local machine */
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 WinPcap is installed.\n");
return -1;
}
printf("Enter the interface number (1-%d):", i);
scanf_s("%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++);
printf("our IMP\n");
// 走这里了
// argv[2] is netcard name
adhandle = pcap_create(d->name, errbuf);
if (NULL == adhandle) {
printf("5. watch\n");
return -1;
}
pcap_set_promisc(adhandle, 1); // interface_opts->promisc_mode is 1
pcap_set_timeout(adhandle, -1); // timeout is 250
pcap_set_buffer_size(adhandle, 10 * 1024 * 1024);
printf("6. watch\n");
int err = 0;
err = pcap_activate(adhandle);
if (0 != err) {
printf("7. watch\n");
return -1;
}
int old_datalink = pcap_datalink(adhandle);
printf("old_datalink = %d\n", old_datalink);
if (0 != old_datalink) {
err = pcap_set_datalink(adhandle, 0);
if (0 != err) {
printf("8. watch, err continue\n");
// return -1;
}
}
// capture_loop_init_filter
printf("9. watch\n");
int snaplen = pcap_snapshot(adhandle);
printf("snaplen = %d\n", snaplen);
/* Open the device */
//if ( (adhandle= pcap_open(d->name, // name of the device
// 65536, // portion of the packet to capture
// // 65536 guarantees that the whole packet will be captured on all the link layers
// PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
// 1000, // read timeout
// NULL, // authentication on the remote machine
// errbuf // error buffer
// ) ) == NULL)
//{
// fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
// /* Free the device list */
// pcap_freealldevs(alldevs);
// return -1;
//}
/* Open the dump file */
dumpfile = pcap_dump_open(adhandle, PCAP_FILE_DUMP_TO);
if (dumpfile == NULL)
{
fprintf(stderr, "\nError opening output file\n");
return -1;
}
printf("\nlistening on %s... Press Ctrl+C to stop...\n", d->description);
/* At this point, we no longer need the device list. Free it */
pcap_freealldevs(alldevs);
/* start the capture */
pcap_loop(adhandle, 0, packet_handler, (unsigned char *)dumpfile);
printf("task over\n");
rc = true;
} while (0);
if (!rc) {
printf("error happen\n");
}
system("pause");
return 0;
}
/* Callback function invoked by libpcap for every incoming packet */
void packet_handler(u_char *dumpfile, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
/* save the packet on the dump file */
static int cnt = 0;
cnt++;
printf("recv cnt = %d\n", cnt);
print_packet("recv", (const char*)pkt_data, header->caplen);
pcap_dump(dumpfile, header, pkt_data);
}
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;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。