Skip to content

Commit

Permalink
Add initial implementation for pcap-openvizsla module
Browse files Browse the repository at this point in the history
The module requires libopenvizsla library to communicate with the device.
  • Loading branch information
matwey committed Sep 1, 2019
1 parent c805a8e commit 48341c7
Show file tree
Hide file tree
Showing 5 changed files with 227 additions and 0 deletions.
13 changes: 13 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1780,6 +1780,18 @@ if(NOT DISABLE_TC)
endif()
endif()

#
# OpenVizsla
#
pkg_check_modules(OPENVIZSLA openvizsla)
if(OPENVIZSLA_FOUND)
set(PROJECT_SOURCE_LIST_C ${PROJECT_SOURCE_LIST_C} pcap-openvizsla.c)
include_directories(AFTER ${OPENVIZSLA_INCLUDE_DIRS})
link_directories(AFTER ${OPENVIZSLA_LIBRARY_DIRS})
set(PCAP_LINK_LIBRARIES ${PCAP_LINK_LIBRARIES} ${OPENVIZSLA_LIBRARIES})
set(PCAP_SUPPORT_OPENVIZSLA TRUE)
endif(OPENVIZSLA_FOUND)

#
# Remote capture support.
#
Expand Down Expand Up @@ -2027,6 +2039,7 @@ set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/grammar.c PROPERTIES
OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/scanner.h
)


#
# Add grammar.c to the list of sources.
#
Expand Down
3 changes: 3 additions & 0 deletions cmakeconfig.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,9 @@
/* target host supports USB sniffing */
#cmakedefine PCAP_SUPPORT_USB 1

/* target host supports OpenVizsla */
#cmakedefine PCAP_SUPPORT_OPENVIZSLA 1

/* Define to 1 if you have the ANSI C header files. */
#cmakedefine STDC_HEADERS 1

Expand Down
199 changes: 199 additions & 0 deletions pcap-openvizsla.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <errno.h>
#include <stdlib.h>
#include <string.h>

#include "pcap-int.h"
#include "pcap-openvizsla.h"

#include <ov.h>

#define OPENVIZSLA_IFACE "openvizsla"

struct pcap_openvizsla {
enum ov_usb_speed usb_speed;
struct ov_device* ov;
};

struct pcap_openvizsla_read {
pcap_handler callback;
u_char *user;
};

static void openvizsla_read_cb(struct ov_packet* packet, void* data) {
struct pcap_openvizsla_read* r = (struct pcap_openvizsla_read*)data;

struct pcap_pkthdr pkth;
pkth.caplen = ov_to_host_16(packet->size) + sizeof(struct ov_packet);
pkth.len = pkth.caplen;
pkth.ts.tv_sec = 0;
pkth.ts.tv_usec = 0;

r->callback(r->user, &pkth, (const u_char*)packet);
}

static int openvizsla_read(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
{
struct pcap_openvizsla* handlep = handle->priv;
struct pcap_openvizsla_read r;

r.callback = callback;
r.user = user;

int ret = 0;

if ((ret = ov_capture_start(handlep->ov, handle->buffer, handle->bufsize, openvizsla_read_cb, &r)) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't start capture: %s", ov_get_error_string(handlep->ov));
return PCAP_ERROR;
}

if ((ret = ov_capture_dispatch(handlep->ov, max_packets)) < 0) {
if (handle->break_loop) {
handle->break_loop = 0;

ov_capture_stop(handlep->ov);

return PCAP_ERROR_BREAK;
}

snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"An error occured during capturing: %s", ov_get_error_string(handlep->ov));
return PCAP_ERROR;
}

ov_capture_stop(handlep->ov);

return ret;
}

static void openvizsla_cleanup(pcap_t* handle)
{
struct pcap_openvizsla* handlep = handle->priv;

ov_free(handlep->ov);
pcap_cleanup_live_common(handle);
}

static int openvizsla_activate(pcap_t* handle)
{
struct pcap_openvizsla* handlep = handle->priv;
int ret = 0;

if (handle->snapshot <= 0 || handle->snapshot > MAXIMUM_SNAPLEN)
handle->snapshot = MAXIMUM_SNAPLEN;

handle->bufsize = handle->snapshot;
handle->offset = 0;
handle->linktype = DLT_OPENVIZSLA;
handle->buffer = malloc(handle->bufsize);
if (!handle->buffer) {
pcap_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, errno, "malloc");
goto fail_buffer_malloc;
}

handle->cleanup_op = openvizsla_cleanup;
handle->read_op = openvizsla_read;
handle->setfilter_op = install_bpf_program; /* no kernel filtering */

handlep->ov = ov_new(NULL);
if (!handlep->ov) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't create OpenVizsla device handler");
goto fail_ov_init;
}

ret = ov_open(handlep->ov);
if (ret < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't open device: %s", ov_get_error_string(handlep->ov));
goto fail_ov_open;
}

ret = ov_set_usb_speed(handlep->ov, handlep->usb_speed);
if (ret < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't set USB speed: %s", ov_get_error_string(handlep->ov));
goto fail_ov_set_usb_speed;
}

return 0;

fail_ov_set_usb_speed:
fail_ov_open:
ov_free(handlep->ov);
fail_ov_init:
free(handle->buffer);
handle->buffer = NULL;
fail_buffer_malloc:
return PCAP_ERROR;
}

int openvizsla_findalldevs(pcap_if_list_t *devlistp, char *err_str)
{
/* Always find one device */
return 0;
}

pcap_t *openvizsla_create(const char *device, char *ebuf, int *is_ours)
{
const char *cp;
char *cpend;
long devnum;
pcap_t *p;
struct pcap_openvizsla* handlep;
enum ov_usb_speed usb_speed;

cp = strrchr(device, '/');
if (cp == NULL)
cp = device;

if (strncmp(cp, OPENVIZSLA_IFACE, sizeof (OPENVIZSLA_IFACE - 1)) != 0) {
*is_ours = 0;
return NULL;
}

cp += sizeof OPENVIZSLA_IFACE - 1;
devnum = strtol(cp, &cpend, 10);
if (cpend == cp) {
*is_ours = 0;
return NULL;
}
if (devnum < 0) {
*is_ours = 0;
return NULL;
}

switch (*cpend) {
case '\0': /* Fallback to 'l' */
case 'l': {
usb_speed = OV_LOW_SPEED;
} break;
case 'f': {
usb_speed = OV_FULL_SPEED;
} break;
case 'h': {
usb_speed = OV_HIGH_SPEED;
} break;
default: {
*is_ours = 0;
return NULL;
}
}

*is_ours = 1;

p = pcap_create_common(ebuf, sizeof(struct pcap_openvizsla));
if (p == NULL)
return NULL;

p->activate_op = openvizsla_activate;

handlep = p->priv;
handlep->usb_speed = usb_speed;

return p;
}
5 changes: 5 additions & 0 deletions pcap-openvizsla.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/*
* Prototypes for OpenVizsla-related functions
*/
int openvizsla_findalldevs(pcap_if_list_t *devlistp, char *err_str);
pcap_t *openvizsla_create(const char *device, char *ebuf, int *is_ours);
7 changes: 7 additions & 0 deletions pcap.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ struct rtentry; /* declarations in <net/if.h> */
#include "pcap-dpdk.h"
#endif

#ifdef PCAP_SUPPORT_OPENVIZSLA
#include "pcap-openvizsla.h"
#endif

#ifdef _WIN32
/*
* DllMain(), required when built as a Windows DLL.
Expand Down Expand Up @@ -541,6 +545,9 @@ static struct capture_source_type {
#endif
#ifdef PCAP_SUPPORT_DPDK
{ pcap_dpdk_findalldevs, pcap_dpdk_create },
#endif
#ifdef PCAP_SUPPORT_OPENVIZSLA
{ openvizsla_findalldevs, openvizsla_create },
#endif
{ NULL, NULL }
};
Expand Down

0 comments on commit 48341c7

Please sign in to comment.