223 lines
7.6 KiB
C
223 lines
7.6 KiB
C
|
/*
|
||
|
Dynamically load libpcap at runtime
|
||
|
|
||
|
This library optionally loads the 'libpcap' library at runtime, rather
|
||
|
than statically linked at compile time. The advantage of this is that
|
||
|
the user can build this project with no dependencies -- although they
|
||
|
may require this dependency in order to run the program.
|
||
|
|
||
|
As of 2017, libpcap shared libraries are standard on major Linux
|
||
|
distributions (Debian, Readhat), FreeBSD, OpenBSD, and macOS. On
|
||
|
Windows, "winpcap" must be downloaded.
|
||
|
*/
|
||
|
#ifndef STUB_PCAP_H
|
||
|
#define STUB_PCAP_H
|
||
|
#include <stdio.h>
|
||
|
|
||
|
|
||
|
|
||
|
/* Including the right ".h" file to define "timeval" is difficult, so instead
|
||
|
* so instead we are simply going to define our own structure. This should
|
||
|
* match the binary definition within the operating system
|
||
|
*/
|
||
|
#if __NetBSD__
|
||
|
#include <sys/time.h>
|
||
|
#define pcap_timeval timeval
|
||
|
#elif __OpenBSD__
|
||
|
#include <net/bpf.h>
|
||
|
#define pcap_timeval bpf_timeval
|
||
|
#else
|
||
|
struct pcap_timeval {
|
||
|
long tv_sec; /* seconds */
|
||
|
long tv_usec; /* and microseconds */
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
/* Forward reference of opaque 'pcap_t' structure */
|
||
|
struct pcap;
|
||
|
typedef struct pcap pcap_t;
|
||
|
|
||
|
/* Forward reference of opaque 'pcap_if_t' structure */
|
||
|
struct pcap_if;
|
||
|
typedef struct pcap_if pcap_if_t;
|
||
|
|
||
|
/* How many bytes to reserve for error messages. This is the number specified
|
||
|
* in libpcap, smaller numbers can crash */
|
||
|
enum {
|
||
|
PCAP_ERRBUF_SIZE=256,
|
||
|
};
|
||
|
|
||
|
/* used in pcap_setdirection() */
|
||
|
typedef enum {
|
||
|
PCAP_D_INOUT = 0,
|
||
|
PCAP_D_IN = 1,
|
||
|
PCAP_D_OUT = 2,
|
||
|
} pcap_direction_t;
|
||
|
|
||
|
enum {
|
||
|
PCAP_ERROR = -1,
|
||
|
PCAP_ERROR_BREAK = -2,
|
||
|
PCAP_ERROR_NOT_ACTIVATED = -3,
|
||
|
PCAP_ERROR_ACTIVATED = -4,
|
||
|
PCAP_ERROR_NO_SUCH_DEVICE = -5,
|
||
|
PCAP_ERROR_RFMON_NOTSUP = -6,
|
||
|
PCAP_ERROR_NOT_RFMON = -7,
|
||
|
PCAP_ERROR_PERM_DENIED = -8,
|
||
|
PCAP_ERROR_IFACE_NOT_UP = -9,
|
||
|
PCAP_ERROR_CANTSET_TSTAMP_TYPE = -10,
|
||
|
PCAP_ERROR_PROMISC_PERM_DENIED = -11,
|
||
|
PCAP_ERROR_TSTAMP_PRECISION_NOTSUP = -12,
|
||
|
|
||
|
/* warnings, not errors */
|
||
|
PCAP_WARNING = 1,
|
||
|
PCAP_WARNING_PROMISC_NOTSUP = 2,
|
||
|
PCAP_WARNING_TSTAMP_TYPE_NOTSUP = 3,
|
||
|
};
|
||
|
|
||
|
/* The packet header for capturing packets. Apple macOS inexplicably adds
|
||
|
* an extra comment-field onto the end of this, so the definition needs
|
||
|
* to be careful to match the real definition */
|
||
|
struct pcap_pkthdr {
|
||
|
struct pcap_timeval ts;
|
||
|
unsigned caplen;
|
||
|
unsigned len;
|
||
|
#ifdef __APPLE__
|
||
|
char comment[256];
|
||
|
#endif
|
||
|
};
|
||
|
|
||
|
|
||
|
/*
|
||
|
* This block is for function declarations. Consult the libpcap
|
||
|
* documentation for what these functions really mean
|
||
|
*/
|
||
|
typedef void (*PCAP_HANDLE_PACKET)(unsigned char *v_seap, const struct pcap_pkthdr *framehdr, const unsigned char *buf);
|
||
|
typedef void (*PCAP_CLOSE)(void *hPcap);
|
||
|
typedef unsigned (*PCAP_DATALINK)(void *hPcap);
|
||
|
typedef unsigned (*PCAP_DISPATCH)(void *hPcap, unsigned how_many_packets, PCAP_HANDLE_PACKET handler, void *handle_data);
|
||
|
typedef int (*PCAP_FINDALLDEVS)(pcap_if_t **alldevs, char *errbuf);
|
||
|
typedef const char *(*PCAP_LIB_VERSION)(void);
|
||
|
typedef char * (*PCAP_LOOKUPDEV)(char *errbuf);
|
||
|
typedef int (*PCAP_MAJOR_VERSION)(void *p);
|
||
|
typedef int (*PCAP_MINOR_VERSION)(void *p);
|
||
|
typedef void * (*PCAP_OPEN_LIVE)(const char *devicename, unsigned snap_length, unsigned is_promiscuous, unsigned read_timeout, char *errbuf);
|
||
|
typedef void (*PCAP_FREEALLDEVS)(pcap_if_t *alldevs);
|
||
|
typedef pcap_t * (*PCAP_OPEN_OFFLINE)(const char *fname, char *errbuf);
|
||
|
typedef int (*PCAP_SENDPACKET)(pcap_t *p, const unsigned char *buf, int size);
|
||
|
typedef const unsigned char *(*PCAP_NEXT)(pcap_t *p, struct pcap_pkthdr *h);
|
||
|
typedef int (*PCAP_SETDIRECTION)(pcap_t *, pcap_direction_t);
|
||
|
typedef const char *(*PCAP_DATALINK_VAL_TO_NAME)(int dlt);
|
||
|
typedef void (*PCAP_PERROR)(pcap_t *p, char *prefix);
|
||
|
typedef const char *(*PCAP_GETERR)(pcap_t *p);
|
||
|
typedef const char *(*PCAP_DEV_NAME)(const pcap_if_t *dev);
|
||
|
typedef const char *(*PCAP_DEV_DESCRIPTION)(const pcap_if_t *dev);
|
||
|
typedef const pcap_if_t *(*PCAP_DEV_NEXT)(const pcap_if_t *dev);
|
||
|
|
||
|
/*
|
||
|
pcap_open() replaced with a series of calls to:
|
||
|
p = pcap_create(device, errbuf);
|
||
|
pcap_set_snaplen(p, snaplen);
|
||
|
pcap_set_promisc(p, promisc);
|
||
|
pcap_set_timeout(p, to_ms);
|
||
|
pcap_activate(p);
|
||
|
*/
|
||
|
typedef pcap_t *(*PCAP_CREATE)(const char *source, char *errbuf);
|
||
|
typedef int (*PCAP_SET_SNAPLEN)(pcap_t *p, int snaplen);
|
||
|
typedef int (*PCAP_SET_PROMISC)(pcap_t *p, int promisc);
|
||
|
typedef int (*PCAP_SET_TIMEOUT)(pcap_t *p, int to_ms);
|
||
|
typedef int (*PCAP_SET_IMMEDIATE_MODE)(pcap_t *p, int immediate_mode);
|
||
|
typedef int (*PCAP_SET_BUFFER_SIZE)(pcap_t *p, int buffer_size);
|
||
|
typedef int (*PCAP_SET_RFMON)(pcap_t *p, int rfmon);
|
||
|
typedef int (*PCAP_CAN_SET_RFMON)(pcap_t *p);
|
||
|
typedef int (*PCAP_ACTIVATE)(pcap_t *p);
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
* PORTABILITY: Windows supports the "sendq" feature, and is really slow
|
||
|
* without this feature. It's not needed on Linux, so we just create
|
||
|
* equivalent functions that do nothing
|
||
|
*/
|
||
|
struct pcap_send_queue;
|
||
|
typedef struct pcap_send_queue pcap_send_queue;
|
||
|
|
||
|
typedef pcap_send_queue *(*PCAP_SENDQUEUE_ALLOC)(size_t size);
|
||
|
typedef unsigned (*PCAP_SENDQUEUE_TRANSMIT)(pcap_t *p, pcap_send_queue *queue, int sync);
|
||
|
typedef void (*PCAP_SENDQUEUE_DESTROY)(pcap_send_queue *queue);
|
||
|
typedef int (*PCAP_SENDQUEUE_QUEUE)(pcap_send_queue *queue, const struct pcap_pkthdr *pkt_header, const unsigned char *pkt_data);
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
struct PcapFunctions {
|
||
|
unsigned func_err:1;
|
||
|
unsigned is_available:1;
|
||
|
unsigned is_printing_debug:1;
|
||
|
unsigned status;
|
||
|
unsigned errcode;
|
||
|
|
||
|
PCAP_CLOSE close;
|
||
|
PCAP_DATALINK datalink;
|
||
|
PCAP_DISPATCH dispatch;
|
||
|
PCAP_FINDALLDEVS findalldevs;
|
||
|
PCAP_FREEALLDEVS freealldevs;
|
||
|
PCAP_LOOKUPDEV lookupdev;
|
||
|
PCAP_LIB_VERSION lib_version;
|
||
|
PCAP_MAJOR_VERSION major_version;
|
||
|
PCAP_MINOR_VERSION minor_version;
|
||
|
PCAP_OPEN_LIVE open_live;
|
||
|
|
||
|
|
||
|
PCAP_OPEN_OFFLINE open_offline;
|
||
|
PCAP_SENDPACKET sendpacket;
|
||
|
PCAP_NEXT next;
|
||
|
PCAP_SETDIRECTION setdirection;
|
||
|
PCAP_DATALINK_VAL_TO_NAME datalink_val_to_name;
|
||
|
PCAP_PERROR perror;
|
||
|
PCAP_GETERR geterr;
|
||
|
|
||
|
/* Accessor functions for opaque data structure, don't really
|
||
|
* exist in libpcap */
|
||
|
PCAP_DEV_NAME dev_name;
|
||
|
PCAP_DEV_DESCRIPTION dev_description;
|
||
|
PCAP_DEV_NEXT dev_next;
|
||
|
|
||
|
/* Windows-only functions */
|
||
|
PCAP_SENDQUEUE_ALLOC sendqueue_alloc;
|
||
|
PCAP_SENDQUEUE_TRANSMIT sendqueue_transmit;
|
||
|
PCAP_SENDQUEUE_DESTROY sendqueue_destroy;
|
||
|
PCAP_SENDQUEUE_QUEUE sendqueue_queue;
|
||
|
|
||
|
PCAP_CREATE create;
|
||
|
PCAP_SET_SNAPLEN set_snaplen;
|
||
|
PCAP_SET_PROMISC set_promisc;
|
||
|
PCAP_SET_TIMEOUT set_timeout;
|
||
|
PCAP_SET_IMMEDIATE_MODE set_immediate_mode;
|
||
|
PCAP_SET_BUFFER_SIZE set_buffer_size;
|
||
|
PCAP_SET_RFMON set_rfmon;
|
||
|
PCAP_CAN_SET_RFMON can_set_rfmon;
|
||
|
PCAP_ACTIVATE activate;
|
||
|
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* This is global structure containing all the libpcap function pointers.
|
||
|
* use in the form "PCAP.functionname()" rather than "pcap_functioname()".
|
||
|
*/
|
||
|
extern struct PcapFunctions PCAP;
|
||
|
|
||
|
/**
|
||
|
* Dynamically loads the shared library (libpcap.so, libpcap.dynlib,
|
||
|
* or libpcap.dll. Call this during program startup like main() in order
|
||
|
* to load the libraries. Not thread safe, so call from the startup
|
||
|
* thread, but not within threads.
|
||
|
* @return
|
||
|
* 0 on success or
|
||
|
* -1 on failure
|
||
|
*/
|
||
|
int pcap_init(void);
|
||
|
|
||
|
|
||
|
#endif
|