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 Aug 31, 2020
1 parent afcfd1b commit 71585e5
Show file tree
Hide file tree
Showing 7 changed files with 299 additions and 0 deletions.
13 changes: 13 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1833,6 +1833,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 @@ -2085,6 +2097,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 @@ -325,6 +325,9 @@
/* target host supports RDMA sniffing */
#cmakedefine PCAP_SUPPORT_RDMASNIFF 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
41 changes: 41 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,7 @@ ac_subst_vars='LTLIBOBJS
INSTALL_DATA
INSTALL_SCRIPT
INSTALL_PROGRAM
PCAP_SUPPORT_OPENVIZSLA
PCAP_SUPPORT_RDMASNIFF
PCAP_SUPPORT_DBUS
PCAP_SUPPORT_BT
Expand Down Expand Up @@ -765,6 +766,7 @@ with_dpdk
enable_bluetooth
enable_dbus
enable_rdma
enable_openvizsla
'
ac_precious_vars='build_alias
host_alias
Expand Down Expand Up @@ -1414,6 +1416,8 @@ Optional Features:
support available]
--enable-rdma enable RDMA capture support [default=yes, if support
available]
--enable-openvizsla enable OpenVizsla support [default=yes, if support
available]
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
Expand Down Expand Up @@ -11744,6 +11748,43 @@ fi
fi


fi

# Check whether --enable-openvizsla was given.
if test "${enable_openvizsla+set}" = set; then :
enableval=$enable_openvizsla;
else
enable_openvizsla=ifavailable
fi


if test "xxx_only" = yes; then
# User requested something-else-only pcap, so they don't
# want OpenVizsla support.
enable_openvizsla=no
fi

if test "x$enable_openvizsla" != "xno"; then
if test "x$PKGCONFIG" != "xno"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libopenvizsla" >&5
$as_echo_n "checking for libopenvizsla... " >&6; }
if "$PKGCONFIG" openvizsla; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
OPENVIZSLA_CFLAGS=`"$PKGCONFIG" --cflags openvizsla`
OPENVIZSLA_LIBS=`"$PKGCONFIG" --libs openvizsla`
CFLAGS="$CFLAGS $OPENVIZSLA_CFLAGS"
LIBS="$LIBS $OPENVIZSLA_LIBS"
MODULE_C_SRC="$MODULE_C_SRC pcap-openvizsla.c"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
if test "x$enable_openvizsla" = "xyes"; then
as_fn_error $? "--enable-openvizsla was given, but the openvizsla package is not installed" "$LINENO" 5
fi
fi
fi

fi

# Find a good install program. We prefer a C program (faster),
Expand Down
31 changes: 31 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2788,6 +2788,37 @@ if test "x$enable_rdma" != "xno"; then
AC_SUBST(PCAP_SUPPORT_RDMASNIFF)
fi

AC_ARG_ENABLE([openvizsla],
[AC_HELP_STRING([--enable-openvizsla],[enable OpenVizsla support @<:@default=yes, if support available@:>@])],
[],
[enable_openvizsla=ifavailable])

if test "xxx_only" = yes; then
# User requested something-else-only pcap, so they don't
# want OpenVizsla support.
enable_openvizsla=no
fi

if test "x$enable_openvizsla" != "xno"; then
if test "x$PKGCONFIG" != "xno"; then
AC_MSG_CHECKING([for libopenvizsla])
if "$PKGCONFIG" openvizsla; then
AC_MSG_RESULT([yes])
OPENVIZSLA_CFLAGS=`"$PKGCONFIG" --cflags openvizsla`
OPENVIZSLA_LIBS=`"$PKGCONFIG" --libs openvizsla`
CFLAGS="$CFLAGS $OPENVIZSLA_CFLAGS"
LIBS="$LIBS $OPENVIZSLA_LIBS"
MODULE_C_SRC="$MODULE_C_SRC pcap-openvizsla.c"
else
AC_MSG_RESULT([no])
if test "x$enable_openvizsla" = "xyes"; then
AC_MSG_ERROR([--enable-openvizsla was given, but the openvizsla package is not installed])
fi
fi
fi
AC_SUBST(PCAP_SUPPORT_OPENVIZSLA)
fi

AC_PROG_INSTALL

AC_CONFIG_HEADER(config.h)
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 <openvizsla.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, 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 @@ -129,6 +129,10 @@ struct rtentry; /* declarations in <net/if.h> */
#include "pcap-airpcap.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 @@ -697,6 +701,9 @@ static struct capture_source_type {
#endif
#ifdef HAVE_AIRPCAP_API
{ airpcap_findalldevs, airpcap_create },
#endif
#ifdef PCAP_SUPPORT_OPENVIZSLA
{ openvizsla_findalldevs, openvizsla_create },
#endif
{ NULL, NULL }
};
Expand Down

0 comments on commit 71585e5

Please sign in to comment.