mirror of https://gerrit.osmocom.org/osmo-pcap
Compare commits
105 Commits
Author | SHA1 | Date |
---|---|---|
Vadim Yanitskiy | 9f47bedf37 | |
Andreas Eversberg | 13b41bc206 | |
Pau Espin | 88b5dc63a9 | |
Vadim Yanitskiy | 7f4debf1b9 | |
Oliver Smith | 2ec703f7c8 | |
Oliver Smith | b8d16e4e44 | |
Max | 17da7b38b9 | |
Pau Espin | 3092167e4e | |
Daniel Willmann | fa47880575 | |
Daniel Willmann | 4e934bb546 | |
Daniel Willmann | 50cc638ac7 | |
arehbein | 9d7556a73e | |
Pau Espin | 97c5c0c15c | |
Vadim Yanitskiy | af54579bd4 | |
Max | 36061e0d37 | |
Pau Espin | bddebaecb2 | |
Pau Espin | 5364393417 | |
Harald Welte | 57be1059bd | |
Pau Espin | a55253f438 | |
Pau Espin | 50dcc15a2e | |
Pau Espin | 6bbda89308 | |
Pau Espin | d72581492f | |
Pau Espin | b9be6767ab | |
Oliver Smith | 235eba3e9b | |
Harald Welte | 2c2eadcadf | |
Vadim Yanitskiy | b9392bfde0 | |
Pau Espin | 02d9d05143 | |
Pau Espin | 30bc1885e4 | |
Oliver Smith | eedd83c113 | |
Oliver Smith | 22f3d95ac9 | |
Pau Espin | ef92a539e8 | |
Harald Welte | 6e564a97b9 | |
Harald Welte | 8b73a2a530 | |
Harald Welte | dd1389c3d3 | |
Harald Welte | 9148d49841 | |
Harald Welte | 831494ed34 | |
Vadim Yanitskiy | 69ce121c6c | |
Harald Welte | a663ed23b1 | |
Harald Welte | 8a119642ac | |
Harald Welte | b0b2a2d542 | |
Vadim Yanitskiy | ff3f4b3bef | |
Vadim Yanitskiy | d59783e601 | |
Joachim Steiger | 52f06fd54b | |
Harald Welte | 611fd19fa3 | |
Pau Espin Pedrol | 06303a6dc5 | |
Oliver Smith | 288c39be10 | |
Harald Welte | 72cc2a508d | |
Pau Espin | 716a4db54c | |
Harald Welte | 5899cb4fbf | |
Harald Welte | a9600141b8 | |
Harald Welte | 20c6ba5a9e | |
Oliver Smith | f93e3dc1f8 | |
Oliver Smith | fd387ecec3 | |
Oliver Smith | 9d5fadcc79 | |
Pau Espin | d8368cebf8 | |
Oliver Smith | 7aa63021b6 | |
Oliver Smith | 47ea18eb8e | |
Oliver Smith | fdd62daa66 | |
Oliver Smith | 380305ee09 | |
Pau Espin | 5e10f1db12 | |
Pau Espin | ce0660cfe1 | |
Pau Espin | 210ed934bb | |
Pau Espin | 901543a788 | |
Pau Espin | 300cb49540 | |
Oliver Smith | d567571180 | |
Oliver Smith | e524725f9b | |
Pau Espin | d68773c4dc | |
Harald Welte | 407f7f9307 | |
Harald Welte | 066fc59ed0 | |
Oliver Smith | 5edc9b2382 | |
Oliver Smith | 14512ddae8 | |
Pau Espin | 3ad56f0408 | |
Pau Espin | a3a6ceb5f7 | |
Pau Espin | 45283d84e3 | |
Pau Espin | b29f84ff6c | |
Pau Espin | b96c957a22 | |
Pau Espin | 80d2b7b8dd | |
Pau Espin | a82aaef507 | |
Pau Espin | 868a501213 | |
Pau Espin | b799344ecd | |
Pau Espin | f946fa21ee | |
Pau Espin | 168949e119 | |
Pau Espin | db7be44632 | |
Pau Espin | f10c57801a | |
Pau Espin | 78262bda57 | |
Pau Espin | e241eada55 | |
Pau Espin | f59fabf9dc | |
Pau Espin | d475673b69 | |
Pau Espin | dc27ca85aa | |
Pau Espin | 5f3c30c40c | |
Pau Espin | 2828690633 | |
Pau Espin | 6e9bf9aa15 | |
Pau Espin | 3dfdbc21dc | |
Harald Welte | e89231d8b0 | |
Harald Welte | f335e37ed5 | |
Max | 53044df9d5 | |
Max | 93ac357b48 | |
Harald Welte | 5f071cd2c6 | |
Harald Welte | f266924bac | |
Harald Welte | 2fe9cb937d | |
Harald Welte | 2aea8704f3 | |
Harald Welte | 604e071159 | |
Holger Hans Peter Freyther | 4776b2972e | |
Holger Hans Peter Freyther | 17f5b00506 | |
Holger Hans Peter Freyther | 40c1e85499 |
|
@ -17,6 +17,8 @@ depcomp
|
|||
install-sh
|
||||
missing
|
||||
stamp-h1
|
||||
compile
|
||||
configure~
|
||||
|
||||
osmopcapconfig.h*
|
||||
|
||||
|
@ -26,11 +28,22 @@ osmopcapconfig.h*
|
|||
|
||||
|
||||
# apps
|
||||
src/osmo_pcap_client
|
||||
src/osmo_pcap_server
|
||||
src/osmo-pcap-client
|
||||
src/osmo-pcap-server
|
||||
|
||||
# tests
|
||||
tests/atconfig
|
||||
tests/package.m4
|
||||
tests/testsuite
|
||||
tests/testsuite.log
|
||||
|
||||
contrib/osmo-pcap.spec
|
||||
|
||||
# manuals
|
||||
doc/manuals/generated/
|
||||
doc/manuals/vty/osmo-pcap-*-vty-reference.pdf
|
||||
doc/manuals/vty/osmo-pcap-*-vty-reference.xml
|
||||
doc/manuals/vty/osmo-pcap-*-vty-reference.xml.inc.gen
|
||||
doc/manuals/vty/osmo-pcap-*-vty-reference.xml.inc.merged
|
||||
doc/manuals/common
|
||||
doc/manuals/build
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
[gerrit]
|
||||
host=gerrit.osmocom.org
|
||||
project=osmo-pcap
|
25
.travis.yml
25
.travis.yml
|
@ -1,25 +0,0 @@
|
|||
language: c
|
||||
os:
|
||||
- linux
|
||||
sudo: required
|
||||
dist: trusty
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- autoconf
|
||||
- automake
|
||||
- make
|
||||
- gcc
|
||||
- debhelper
|
||||
- devscripts
|
||||
- libtool
|
||||
- build-essential
|
||||
- pkg-config
|
||||
- libtalloc-dev
|
||||
- libpcsclite-dev
|
||||
- libpcap-dev
|
||||
- libzmq3-dev
|
||||
- libgnutls28-dev
|
||||
|
||||
script:
|
||||
- contrib/travis.sh
|
17
Makefile.am
17
Makefile.am
|
@ -1,9 +1,22 @@
|
|||
AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6
|
||||
|
||||
SUBDIRS = include src contrib tests
|
||||
SUBDIRS = include src contrib doc tests
|
||||
|
||||
BUILT_SOURCES = $(top_srcdir)/.version
|
||||
EXTRA_DIST = git-version-gen .version
|
||||
EXTRA_DIST = \
|
||||
.version \
|
||||
README.md \
|
||||
contrib/osmo-pcap.spec.in \
|
||||
debian \
|
||||
git-version-gen \
|
||||
$(NULL)
|
||||
|
||||
AM_DISTCHECK_CONFIGURE_FLAGS = \
|
||||
--with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)
|
||||
|
||||
|
||||
@RELMAKE@
|
||||
|
||||
$(top_srcdir)/.version:
|
||||
echo $(VERSION) > $@-t && mv $@-t $@
|
||||
dist-hook:
|
||||
|
|
17
README.md
17
README.md
|
@ -1,11 +1,11 @@
|
|||
# osmo-pcap distributed network capture
|
||||
|
||||
osmo-pcap has been created to collect network traces at different nodes
|
||||
but store them centrally at a dedicated note for further analysis. This
|
||||
but store them centrally at a dedicated node for further analysis. This
|
||||
might be needed for auditing, resolving conflicts, post processing or
|
||||
debugging a distributed system.
|
||||
|
||||
The system consists out of the *osmo-pcap-client* to cpature traffic at a
|
||||
The system consists out of the *osmo-pcap-client* to capture traffic at a
|
||||
host and *osmo-pcap-server* to receive the traffic, store and rotate the
|
||||
traffic at a centralized server. There is a shell script to compress
|
||||
and expire old traces.
|
||||
|
@ -34,12 +34,21 @@ need to be tuned in the script itself.
|
|||
|
||||
## Installation and Configuration
|
||||
|
||||
There are Debian, Ubuntu, SLES, OpenSUSE and CentOS packages available via the excellent
|
||||
[openSUSE Build Service](https://build.opensuse.org/project/show/home:zecke23:osmo-pcap).
|
||||
There are Debian, Ubuntu, Raspbian packages available via the excellent
|
||||
[openSUSE Build Service](https://build.opensuse.org/package/show/network:osmocom:nightly/osmo-pcap).
|
||||
|
||||
Please see the *contrib/osmo-pcap-server.cfg* and *contrib/osmo-pcap-client.cfg*
|
||||
file in the repository
|
||||
|
||||
## Running tests
|
||||
|
||||
In order to run all tests, do the following:
|
||||
|
||||
$ ./configure --enable-external-tests
|
||||
$ make -j5
|
||||
$ sudo setcap 'CAP_NET_RAW+eip CAP_NET_ADMIN+eip' src/osmo-pcap-client
|
||||
$ make check
|
||||
|
||||
## Wishlist/TODO
|
||||
|
||||
- [ ] Add non-blocking TLS (probably GNUtls) support between client and server.
|
||||
|
|
111
configure.ac
111
configure.ac
|
@ -5,19 +5,117 @@ AC_INIT([osmo-pcap],
|
|||
|
||||
AM_INIT_AUTOMAKE([dist-bzip2])
|
||||
AC_CONFIG_TESTDIR(tests)
|
||||
AC_ARG_ENABLE(manuals,
|
||||
[AS_HELP_STRING(
|
||||
[--enable-manuals],
|
||||
[Generate manual PDFs [default=no]],
|
||||
)],
|
||||
[osmo_ac_build_manuals=$enableval], [osmo_ac_build_manuals="no"])
|
||||
AM_CONDITIONAL([BUILD_MANUALS], [test x"$osmo_ac_build_manuals" = x"yes"])
|
||||
AC_ARG_VAR(OSMO_GSM_MANUALS_DIR, [path to common osmo-gsm-manuals files, overriding pkg-config and "../osmo-gsm-manuals"
|
||||
fallback])
|
||||
if test x"$osmo_ac_build_manuals" = x"yes"
|
||||
then
|
||||
# Find OSMO_GSM_MANUALS_DIR (env, pkg-conf, fallback)
|
||||
if test -n "$OSMO_GSM_MANUALS_DIR"; then
|
||||
echo "checking for OSMO_GSM_MANUALS_DIR... $OSMO_GSM_MANUALS_DIR (from env)"
|
||||
else
|
||||
OSMO_GSM_MANUALS_DIR="$($PKG_CONFIG osmo-gsm-manuals --variable=osmogsmmanualsdir 2>/dev/null)"
|
||||
if test -n "$OSMO_GSM_MANUALS_DIR"; then
|
||||
echo "checking for OSMO_GSM_MANUALS_DIR... $OSMO_GSM_MANUALS_DIR (from pkg-conf)"
|
||||
else
|
||||
OSMO_GSM_MANUALS_DIR="../osmo-gsm-manuals"
|
||||
echo "checking for OSMO_GSM_MANUALS_DIR... $OSMO_GSM_MANUALS_DIR (fallback)"
|
||||
fi
|
||||
fi
|
||||
if ! test -d "$OSMO_GSM_MANUALS_DIR"; then
|
||||
AC_MSG_ERROR("OSMO_GSM_MANUALS_DIR does not exist! Install osmo-gsm-manuals or set OSMO_GSM_MANUALS_DIR.")
|
||||
fi
|
||||
|
||||
# Find and run check-depends
|
||||
CHECK_DEPENDS="$OSMO_GSM_MANUALS_DIR/check-depends.sh"
|
||||
if ! test -x "$CHECK_DEPENDS"; then
|
||||
CHECK_DEPENDS="osmo-gsm-manuals-check-depends"
|
||||
fi
|
||||
if ! $CHECK_DEPENDS; then
|
||||
AC_MSG_ERROR("missing dependencies for --enable-manuals")
|
||||
fi
|
||||
|
||||
# Put in Makefile with absolute path
|
||||
OSMO_GSM_MANUALS_DIR="$(realpath "$OSMO_GSM_MANUALS_DIR")"
|
||||
AC_SUBST([OSMO_GSM_MANUALS_DIR])
|
||||
fi
|
||||
|
||||
CFLAGS="$CFLAGS -std=gnu11"
|
||||
|
||||
dnl kernel style compile messages
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
|
||||
dnl include release helper
|
||||
RELMAKE='-include osmo-release.mk'
|
||||
AC_SUBST([RELMAKE])
|
||||
|
||||
dnl checks for programs
|
||||
AC_PROG_MAKE_SET
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_RANLIB
|
||||
|
||||
dnl check for pkg-config (explained in detail in libosmocore/configure.ac)
|
||||
AC_PATH_PROG(PKG_CONFIG_INSTALLED, pkg-config, no)
|
||||
if test "x$PKG_CONFIG_INSTALLED" = "xno"; then
|
||||
AC_MSG_WARN([You need to install pkg-config])
|
||||
fi
|
||||
PKG_PROG_PKG_CONFIG([0.20])
|
||||
|
||||
dnl checks for header files
|
||||
AC_HEADER_STDC
|
||||
|
||||
AC_ARG_ENABLE(sanitize,
|
||||
[AS_HELP_STRING(
|
||||
[--enable-sanitize],
|
||||
[Compile with address sanitizer enabled],
|
||||
)],
|
||||
[sanitize=$enableval], [sanitize="no"])
|
||||
if test x"$sanitize" = x"yes"
|
||||
then
|
||||
CFLAGS="$CFLAGS -fsanitize=address -fsanitize=undefined"
|
||||
CPPFLAGS="$CPPFLAGS -fsanitize=address -fsanitize=undefined"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(werror,
|
||||
[AS_HELP_STRING(
|
||||
[--enable-werror],
|
||||
[Turn all compiler warnings into errors, with exceptions:
|
||||
a) deprecation (allow upstream to mark deprecation without breaking builds);
|
||||
b) "#warning" pragmas (allow to remind ourselves of errors without breaking builds)
|
||||
]
|
||||
)],
|
||||
[werror=$enableval], [werror="no"])
|
||||
if test x"$werror" = x"yes"
|
||||
then
|
||||
WERROR_FLAGS="-Werror"
|
||||
WERROR_FLAGS+=" -Wno-error=deprecated -Wno-error=deprecated-declarations"
|
||||
WERROR_FLAGS+=" -Wno-error=cpp" # "#warning"
|
||||
CFLAGS="$CFLAGS $WERROR_FLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $WERROR_FLAGS"
|
||||
fi
|
||||
|
||||
# https://www.freedesktop.org/software/systemd/man/daemon.html
|
||||
AC_ARG_WITH([systemdsystemunitdir],
|
||||
[AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files])],,
|
||||
[with_systemdsystemunitdir=auto])
|
||||
AS_IF([test "x$with_systemdsystemunitdir" = "xyes" -o "x$with_systemdsystemunitdir" = "xauto"], [
|
||||
def_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)
|
||||
AS_IF([test "x$def_systemdsystemunitdir" = "x"],
|
||||
[AS_IF([test "x$with_systemdsystemunitdir" = "xyes"],
|
||||
[AC_MSG_ERROR([systemd support requested but pkg-config unable to query systemd package])])
|
||||
with_systemdsystemunitdir=no],
|
||||
[with_systemdsystemunitdir="$def_systemdsystemunitdir"])])
|
||||
AS_IF([test "x$with_systemdsystemunitdir" != "xno"],
|
||||
[AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])])
|
||||
AM_CONDITIONAL([HAVE_SYSTEMD], [test "x$with_systemdsystemunitdir" != "xno"])
|
||||
|
||||
AC_ARG_ENABLE([external_tests],
|
||||
AC_HELP_STRING([--enable-external-tests],
|
||||
[Include the VTY tests in make check [default=no]]),
|
||||
|
@ -59,9 +157,11 @@ AC_SUBST([PCAP_LIBS])
|
|||
AC_SUBST([PCAP_CFLAGS])
|
||||
|
||||
dnl checks for libraries
|
||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.3.2)
|
||||
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 0.3.2)
|
||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.3.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.9.0)
|
||||
# libosmogb: needed for osmocom/gprs includes
|
||||
PKG_CHECK_MODULES(LIBOSMOGB, libosmogb >= 1.9.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.9.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.9.0)
|
||||
PKG_CHECK_MODULES(LIBZMQ, libzmq >= 3.2.2)
|
||||
PKG_CHECK_MODULES(LIBGNUTLS, gnutls)
|
||||
|
||||
|
@ -88,5 +188,10 @@ AC_OUTPUT(
|
|||
include/osmo-pcap/Makefile
|
||||
src/Makefile
|
||||
contrib/Makefile
|
||||
contrib/systemd/Makefile
|
||||
contrib/osmo-pcap.spec
|
||||
doc/Makefile
|
||||
doc/examples/Makefile
|
||||
doc/manuals/Makefile
|
||||
tests/Makefile
|
||||
Makefile)
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
SUBDIRS = systemd
|
||||
dist_pkgdata_DATA = osmo_pcap_clean_old
|
||||
EXTRA_DIST = osmo-pcap-server.cfg osmo-pcap-client.cfg
|
||||
|
|
|
@ -1,19 +1,62 @@
|
|||
#!/usr/bin/env bash
|
||||
# jenkins build helper script for osmo-pcap. This is how we build on jenkins.osmocom.org
|
||||
|
||||
if ! [ -x "$(command -v osmo-build-dep.sh)" ]; then
|
||||
echo "Error: We need to have scripts/osmo-deps.sh from http://git.osmocom.org/osmo-ci/ in PATH !"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
set -ex
|
||||
|
||||
rm -rf deps/install
|
||||
mkdir deps || true
|
||||
cd deps
|
||||
osmo-deps.sh libosmocore
|
||||
|
||||
cd libosmocore
|
||||
autoreconf --install --force
|
||||
./configure --prefix=$PWD/../install
|
||||
$MAKE $PARALLEL_MAKE install
|
||||
base="$PWD"
|
||||
deps="$base/deps"
|
||||
inst="$deps/install"
|
||||
export deps inst
|
||||
|
||||
cd ../../
|
||||
osmo-clean-workspace.sh
|
||||
|
||||
mkdir "$deps" || true
|
||||
|
||||
verify_value_string_arrays_are_terminated.py $(find . -name "*.[hc]")
|
||||
|
||||
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
export LD_LIBRARY_PATH="$inst/lib"
|
||||
osmo-build-dep.sh libosmocore "" '--disable-doxygen --enable-gnutls'
|
||||
|
||||
# Additional configure options and depends
|
||||
CONFIG=""
|
||||
if [ "$WITH_MANUALS" = "1" ]; then
|
||||
osmo-build-dep.sh osmo-gsm-manuals
|
||||
CONFIG="--enable-manuals"
|
||||
fi
|
||||
|
||||
set +x
|
||||
echo
|
||||
echo
|
||||
echo
|
||||
echo " =============================== osmo-pcap ==============================="
|
||||
echo
|
||||
set -x
|
||||
|
||||
|
||||
cd "$base"
|
||||
autoreconf --install --force
|
||||
PCAP_LIBS="-lpcap" PCAP_CFLAGS="" PKG_CONFIG_PATH=$PWD/deps/install/lib/pkgconfig ./configure --with-pcap-config=/bin/true
|
||||
PKG_CONFIG_PATH=$PWD/deps/install/lib/pkgconfig $MAKE $PARALLEL_MAKE
|
||||
DISTCHECK_CONFIGURE_FLAGS="--with-pcap-config=/bin/true" PCAP_LIBS="-lpcap" PCAP_CFLAGS="" PKG_CONFIG_PATH=$PWD/deps/install/lib/pkgconfig LD_LIBRARY_PATH=$PWD/deps/install/lib $MAKE distcheck
|
||||
PCAP_LIBS="-lpcap" PCAP_CFLAGS="" ./configure \
|
||||
--with-pcap-config=/bin/true \
|
||||
--enable-sanitize \
|
||||
--enable-werror \
|
||||
$CONFIG
|
||||
$MAKE $PARALLEL_MAKE
|
||||
$MAKE check || cat-testlogs.sh
|
||||
DISTCHECK_CONFIGURE_FLAGS="--with-pcap-config=/bin/true $CONFIG" \
|
||||
PCAP_LIBS="-lpcap" PCAP_CFLAGS="" \
|
||||
$MAKE distcheck || cat-testlogs.sh
|
||||
|
||||
if [ "$WITH_MANUALS" = "1" ] && [ "$PUBLISH" = "1" ]; then
|
||||
make -C "$base/doc/manuals" publish
|
||||
fi
|
||||
|
||||
$MAKE maintainer-clean
|
||||
|
||||
osmo-clean-workspace.sh
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
#
|
||||
# spec file for package osmo-pcap
|
||||
#
|
||||
# Copyright (c) 2015, Martin Hauke <mardnh@gmx.de>
|
||||
#
|
||||
# All modifications and additions to the file contributed by third parties
|
||||
# remain the property of their copyright owners, unless otherwise agreed
|
||||
# upon. The license for this file, and modifications and additions to the
|
||||
# file, is the same license as for the pristine package itself (unless the
|
||||
# license for the pristine package is not an Open Source License, in which
|
||||
# case the license is the MIT License). An "Open Source License" is a
|
||||
# license that conforms to the Open Source Definition (Version 1.9)
|
||||
# published by the Open Source Initiative.
|
||||
|
||||
Name: osmo-pcap
|
||||
Version: @VERSION@
|
||||
Release: 0
|
||||
Summary: Osmocom's PCAP client and server
|
||||
License: AGPL-3.0-or-later AND GPL-2.0-or-later
|
||||
Group: Productivity/Telephony/Servers
|
||||
URL: https://osmocom.org/projects/osmo-pcap
|
||||
Source: %{name}-%{version}.tar.xz
|
||||
BuildRequires: autoconf
|
||||
BuildRequires: automake >= 1.6
|
||||
BuildRequires: libpcap-devel
|
||||
BuildRequires: libtool
|
||||
%if 0%{?suse_version}
|
||||
BuildRequires: systemd-rpm-macros
|
||||
%endif
|
||||
BuildRequires: pkgconfig
|
||||
BuildRequires: pkgconfig(gnutls)
|
||||
BuildRequires: pkgconfig(libosmocore) >= 1.9.0
|
||||
BuildRequires: pkgconfig(libosmogb) >= 1.9.0
|
||||
BuildRequires: pkgconfig(libosmogsm) >= 1.9.0
|
||||
BuildRequires: pkgconfig(libosmovty) >= 1.9.0
|
||||
BuildRequires: pkgconfig(libzmq) >= 3.2.2
|
||||
%{?systemd_requires}
|
||||
|
||||
%description
|
||||
Osmocom tools to help with pcap tracing.
|
||||
Run osmo_pcap_client locally and send traces to a different system.
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
echo "%{version}" >.tarball-version
|
||||
autoreconf -fi
|
||||
%configure \
|
||||
--docdir=%{_docdir}/%{name} \
|
||||
--with-systemdsystemunitdir=%{_unitdir}
|
||||
make %{?_smp_mflags}
|
||||
|
||||
%install
|
||||
%make_install
|
||||
|
||||
%if 0%{?suse_version}
|
||||
%preun
|
||||
%service_del_preun osmo-pcap-client.service osmo-pcap-server.service
|
||||
|
||||
%postun
|
||||
%service_del_postun osmo-pcap-client.service osmo-pcap-server.service
|
||||
|
||||
%pre
|
||||
%service_add_pre osmo-pcap-client.service osmo-pcap-server.service
|
||||
|
||||
%post
|
||||
%service_add_post osmo-pcap-client.service osmo-pcap-server.service
|
||||
%endif
|
||||
|
||||
%check
|
||||
make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +)
|
||||
|
||||
%files
|
||||
%license COPYING
|
||||
%doc AUTHORS
|
||||
%doc %{_docdir}/%{name}/examples
|
||||
%dir %{_sysconfdir}/osmocom
|
||||
%config(noreplace) %{_sysconfdir}/osmocom/osmo-pcap-client.cfg
|
||||
%config(noreplace) %{_sysconfdir}/osmocom/osmo-pcap-server.cfg
|
||||
%{_bindir}/osmo-pcap-client
|
||||
%{_bindir}/osmo-pcap-server
|
||||
%{_unitdir}/osmo-pcap-client.service
|
||||
%{_unitdir}/osmo-pcap-server.service
|
||||
%dir %{_datadir}/%{name}
|
||||
%{_datadir}/%{name}/osmo_pcap_clean_old
|
||||
|
||||
%changelog
|
|
@ -0,0 +1,11 @@
|
|||
EXTRA_DIST = \
|
||||
osmo-pcap-client.service \
|
||||
osmo-pcap-server.service
|
||||
|
||||
if HAVE_SYSTEMD
|
||||
SYSTEMD_SERVICES = \
|
||||
osmo-pcap-client.service \
|
||||
osmo-pcap-server.service
|
||||
|
||||
systemdsystemunit_DATA = $(SYSTEMD_SERVICES)
|
||||
endif
|
|
@ -0,0 +1,16 @@
|
|||
[Unit]
|
||||
Description=PCAP Client for the PCAP aggregation
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Restart=always
|
||||
StateDirectory=osmocom
|
||||
WorkingDirectory=%S/osmocom
|
||||
ExecStart=/usr/bin/osmo-pcap-client -c /etc/osmocom/osmo-pcap-client.cfg
|
||||
RestartSec=2
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
[Unit]
|
||||
Description=PCAP Server for the PCAP aggregation
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Restart=always
|
||||
StateDirectory=osmocom
|
||||
WorkingDirectory=%S/osmocom
|
||||
ExecStart=/usr/bin/osmo-pcap-server -c /etc/osmocom/osmo-pcap-server.cfg
|
||||
RestartSec=2
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -ex
|
||||
|
||||
rm -rf deps/install
|
||||
mkdir deps || true
|
||||
cd deps
|
||||
git clone git://git.osmocom.org/libosmocore
|
||||
|
||||
cd libosmocore
|
||||
git reset --hard 460f9ef7da1db11b104fdfe635ebcbd8a071f205
|
||||
autoreconf --install --force
|
||||
./configure --prefix=$PWD/../install
|
||||
make -j 4 install
|
||||
export LD_LIBRARY_PATH=$PWD/../install/lib
|
||||
|
||||
cd ../
|
||||
git clone git://git.osmocom.org/python/osmo-python-tests
|
||||
cd osmo-python-tests
|
||||
sudo ./setup.py install
|
||||
|
||||
cd ../../
|
||||
autoreconf --install --force
|
||||
PCAP_LIBS="-lpcap" PCAP_CFLAGS="" PKG_CONFIG_PATH=$PWD/deps/install/lib/pkgconfig ./configure --with-pcap-config=/bin/true --enable-external-tests
|
||||
PKG_CONFIG_PATH=$PWD/deps/install/lib/pkgconfig make -j 4
|
||||
PKG_CONFIG_PATH=$PWD/deps/install/lib/pkgconfig make check
|
||||
DISTCHECK_CONFIGURE_FLAGS="--with-pcap-config=/bin/true" PCAP_LIBS="-lpcap" PCAP_CFLAGS="" PKG_CONFIG_PATH=$PWD/deps/install/lib/pkgconfig LD_LIBRARY_PATH=$PWD/deps/install/lib make distcheck
|
|
@ -1,6 +0,0 @@
|
|||
The Debian Package osmo-pcap
|
||||
----------------------------
|
||||
|
||||
Comments regarding the Package
|
||||
|
||||
-- Holger Hans Peter Freyther <zecke@selfish.org> Wed, 01 Jun 2011 14:51:32 +0200
|
|
@ -1,3 +1,195 @@
|
|||
osmo-pcap (0.4.2) unstable; urgency=medium
|
||||
|
||||
[ arehbein ]
|
||||
* Transition to use of 'telnet_init_default'
|
||||
|
||||
[ Daniel Willmann ]
|
||||
* osmo_{client,server}_main: Remove tall_ctr_ctx and tall_msgb_ctx
|
||||
* osmo_{client,server}_main: Remove is_config_node in vty_app_info
|
||||
* cosmetic: Remove trailing whitespace
|
||||
|
||||
[ Pau Espin Pedrol ]
|
||||
* server: Call osmo_fd_unregister() before closing and changing bfd->fd
|
||||
|
||||
[ Max ]
|
||||
* CI/CD: drop travis support
|
||||
|
||||
[ Oliver Smith ]
|
||||
* debian: set compat level to 10
|
||||
* systemd: depend on networking-online.target
|
||||
|
||||
[ Vadim Yanitskiy ]
|
||||
* tests: $(BUILT_SOURCES) is not defined
|
||||
|
||||
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 12 Sep 2023 15:50:49 +0200
|
||||
|
||||
osmo-pcap (0.4.1) unstable; urgency=medium
|
||||
|
||||
[ Max ]
|
||||
* Set working directory in systemd service file
|
||||
|
||||
[ Vadim Yanitskiy ]
|
||||
* doc/manuals: update git URLs (git -> https; gitea)
|
||||
|
||||
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 07 Feb 2023 17:11:46 +0100
|
||||
|
||||
osmo-pcap (0.4.0) unstable; urgency=medium
|
||||
|
||||
[ Pau Espin Pedrol ]
|
||||
* client: Increase wqueue transmit length
|
||||
* client: Log wqueue capacity when failing to enqueue
|
||||
* client: Add 'wqueue max-length <0-4294967295>' VTY command
|
||||
* .gitignore: blacklist configure~
|
||||
|
||||
[ Harald Welte ]
|
||||
* update git URLs (git -> https; gitea)
|
||||
|
||||
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 28 Jun 2022 17:36:44 +0200
|
||||
|
||||
osmo-pcap (0.3.0) unstable; urgency=medium
|
||||
|
||||
[ Vadim Yanitskiy ]
|
||||
* debian/control: minimum version for libzmq3-dev is 3.2.2
|
||||
|
||||
[ Harald Welte ]
|
||||
* configure.ac: don't depend on libosmogb.
|
||||
|
||||
[ Oliver Smith ]
|
||||
* Revert "configure.ac: don't depend on libosmogb."
|
||||
|
||||
[ Pau Espin Pedrol ]
|
||||
* server: Add vty command file-permission-mask
|
||||
|
||||
-- Pau Espin Pedrol <pespin@sysmocom.de> Thu, 13 Jan 2022 10:06:14 +0100
|
||||
|
||||
osmo-pcap (0.2.1) unstable; urgency=medium
|
||||
|
||||
[ Pau Espin Pedrol ]
|
||||
* Use new stat item/ctr getter APIs
|
||||
* Explicitly depend on required libosmogb
|
||||
|
||||
[ Oliver Smith ]
|
||||
* README.md: fix typo
|
||||
* Change default ports of client, server
|
||||
|
||||
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 16 Nov 2021 13:40:07 +0100
|
||||
|
||||
osmo-pcap (0.2.0) unstable; urgency=medium
|
||||
|
||||
[ Harald Welte ]
|
||||
* vty: Add space after prompt, as customary
|
||||
* add "--version" to osmo-pcap-client and -server
|
||||
* update copyright statement; Holger worked on it until 2017
|
||||
* Add user manual for osmo-pcap
|
||||
* use osmo_wqueue_enqueue_quiet() as we log anyway
|
||||
* client: Ensure the "file" header is sent on connect
|
||||
* use telnet_init_dynif() to allow VTY bind to non-loopack address
|
||||
* vty: call telnet_init_dynif() after config file is read
|
||||
|
||||
[ Joachim Steiger ]
|
||||
* manuals: generate VTY reference for osmo-pcap-{client,server}
|
||||
|
||||
[ Vadim Yanitskiy ]
|
||||
* vty: register commands for talloc context introspection
|
||||
* vty_{client,server}_init(): remove unused argument
|
||||
* contrib/jenkins.sh: fix: pass '--enable-manuals' to configure
|
||||
|
||||
-- Harald Welte <laforge@osmocom.org> Sat, 24 Apr 2021 23:03:34 +0200
|
||||
|
||||
osmo-pcap (0.1.3) unstable; urgency=medium
|
||||
|
||||
[ Oliver Smith ]
|
||||
* contrib: import RPM spec
|
||||
* contrib: integrate RPM spec
|
||||
* Makefile.am: EXTRA_DIST: debian, contrib/*.spec.in
|
||||
* configure.ac: set -std=gnu11
|
||||
|
||||
[ Harald Welte ]
|
||||
* Use OSMO_FD_* instead of deprecated BSC_FD_*
|
||||
* Use osmo_fd_setup() whenever applicable
|
||||
* Use osmo_fd_*_{disable,enable}
|
||||
* reformat debian/control for osmo-release.sh compatibility
|
||||
|
||||
[ Pau Espin Pedrol ]
|
||||
* main: generate coredump and exit upon SIGABRT received
|
||||
|
||||
-- Pau Espin Pedrol <pespin@espeweb.net> Tue, 23 Feb 2021 13:19:37 +0100
|
||||
|
||||
osmo-pcap (0.1.2) unstable; urgency=medium
|
||||
|
||||
[ Oliver Smith ]
|
||||
* Cosmetic: README.md: fix typo
|
||||
* osmoappdesc.py: fix paths to configs
|
||||
* Cosmetic: README.md: document how to run tests
|
||||
* osmoappdesc.py: switch to python 3
|
||||
|
||||
-- Pau Espin Pedrol <pespin@sysmocom.de> Thu, 02 Jan 2020 20:19:28 +0100
|
||||
|
||||
osmo-pcap (0.1.1) unstable; urgency=medium
|
||||
|
||||
* Remove undefined param passed to {logging,osmo_stats}_vty_add_cmds
|
||||
* Require libosmocore 0.11.0
|
||||
|
||||
-- Pau Espin Pedrol <pespin@sysmocom.de> Wed, 07 Aug 2019 13:12:47 +0200
|
||||
|
||||
osmo-pcap (0.1.0) unstable; urgency=medium
|
||||
|
||||
[ Harald Welte ]
|
||||
* sock_src_init(): Don't freeaddrinfo() undefined src_result
|
||||
* Use TCP port numbers for VTY that don't overlap with other Osmocom Software
|
||||
* Rename osmo_pcap_{client_server} executables to osmo-pcap-{client,server}
|
||||
* Use libosmocore osmo_sock_init2() instead of local implementation
|
||||
* client: Move to osmo_sock_init2_ofd()
|
||||
* Add support for generating IPIP to osmo-pcap-client
|
||||
* debian/control: Fix URLs for homepage, git, gitweb
|
||||
* change binary builds URL to network:osmocom as that's more maintained
|
||||
* Fix compiler warning about deprecated _BSD_SOURCE
|
||||
|
||||
[ Max ]
|
||||
* Add gitreview config
|
||||
* Use release helper from libosmocore
|
||||
|
||||
[ Pau Espin Pedrol ]
|
||||
* cosmetic: client: rename forward_packet function
|
||||
* vty: skip installing cmds now always installed by default
|
||||
* client: Properly name main talloc ctx
|
||||
* server: Properly name main talloc ctx
|
||||
* Drop osmo_init_logging and use osmo_init_logging2
|
||||
* osmo_client_send_data: Fix wrong log format
|
||||
* configure.ac: Add --enable-werror flag
|
||||
* configure.ac: Add --enable-sanitize flag
|
||||
* jenkins.sh: enable werror and sanitize configure flags
|
||||
* Replace '.' in counter names with ':'
|
||||
* Use enum for PKT_LINK_*
|
||||
* client: Set snaplen to MAXIMUM_SNAPLEN
|
||||
* client: Add pcap snaplen VTY cmd
|
||||
* client_send_link: snaplen not needed during allocation
|
||||
* server: Improve verification of messages from client
|
||||
* server: Add pcap snaplen VTY cmd
|
||||
* contrib/jenkins.sh: Update to current osmocom infra
|
||||
* debian: Clean up to look like other osmocom projects
|
||||
* Install systemd services with autotools
|
||||
* Install cfg files with autotools
|
||||
* gitignore: Add compile
|
||||
* debian: Install osmo_pcap_clean_old in osmo-pcap-server pkg
|
||||
* tests/Makefile.am: Fix "./configure && make clean && make"
|
||||
* debian/changelog: Mark 0.0.11 as released
|
||||
|
||||
[ Oliver Smith ]
|
||||
* Fix DISTCHECK_CONFIGURE_FLAGS override
|
||||
* contrib: fix makedistcheck with disabled systemd
|
||||
* gitignore: fix application names
|
||||
* contrib/jenkins.sh: run "make maintainer-clean"
|
||||
|
||||
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 16 Jul 2019 19:01:15 +0200
|
||||
|
||||
osmo-pcap (0.0.11) unstable; urgency=medium
|
||||
|
||||
* Add "source ip A.B.C.D" option to use specific address.
|
||||
* Add osmo-pcap-client-dbg/osmo-pcap-server-dbg package
|
||||
|
||||
-- Holger Hans Peter Freyther <holger@moiji-mobile.com> Tue, 17 Jan 2017 09:12:52 +0100
|
||||
|
||||
osmo-pcap (0.0.10) unstable; urgency=medium
|
||||
|
||||
* New release with new features
|
||||
|
|
|
@ -1 +1 @@
|
|||
7
|
||||
10
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
Source: osmo-pcap
|
||||
Section: unknown
|
||||
Section: net
|
||||
Priority: extra
|
||||
Maintainer: Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
Build-Depends: debhelper (>= 7.0.50~), dh-autoreconf, autotools-dev, libpcap0.8-dev, pkg-config, libosmocore-dev, libgnutls28-dev, libzmq3-dev
|
||||
Maintainer: Osmocom team <openbsc@lists.osmocom.org>
|
||||
Build-Depends: debhelper (>= 10),
|
||||
dh-autoreconf,
|
||||
autotools-dev,
|
||||
libpcap0.8-dev,
|
||||
pkg-config,
|
||||
libosmocore-dev (>= 1.9.0),
|
||||
libgnutls28-dev,
|
||||
libzmq3-dev (>= 3.2.2)
|
||||
Standards-Version: 3.9.1
|
||||
Homepage: http://openbsc.osmocom.org
|
||||
#Vcs-Git: git://git.debian.org/collab-maint/osmo-pcap.git
|
||||
#Vcs-Browser: http://git.debian.org/?p=collab-maint/osmo-pcap.git;a=summary
|
||||
Homepage: https://osmocom.org/projects/osmo-pcap
|
||||
Vcs-Git: https://gitea.osmocom.org/osmocom/osmo-pcap
|
||||
Vcs-Browser: https://gitea.osmocom.org/osmocom/osmo-pcap
|
||||
|
||||
Package: osmo-pcap-client
|
||||
Architecture: any
|
||||
|
@ -17,3 +24,13 @@ Package: osmo-pcap-server
|
|||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Description: Collect traces from other systems.
|
||||
|
||||
Package: osmo-pcap-client-dbg
|
||||
Architecture: any
|
||||
Depends: osmo-pcap-client (= ${binary:Version})
|
||||
Description: Debug symbols of osmo-pcap-client-dbg
|
||||
|
||||
Package: osmo-pcap-server-dbg
|
||||
Architecture: any
|
||||
Depends: osmo-pcap-server (= ${binary:Version})
|
||||
Description: Debug symbols of osmo-pcap-server-dbg
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: OsmoPCAP
|
||||
Source: https://gitea.osmocom.org/osmocom/osmo-pcap
|
||||
|
||||
Files: *
|
||||
Copyright: 2011 Holger Freyther and On-Waves
|
||||
2018 sysmocom s. f. m. c. GmbH <info@sysmocom.de>
|
||||
License: AGPL-3+
|
||||
|
||||
License: AGPL-3+
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
@ -1,154 +0,0 @@
|
|||
#!/bin/sh
|
||||
### BEGIN INIT INFO
|
||||
# Provides: osmo-pcap
|
||||
# Required-Start: $network $local_fs
|
||||
# Required-Stop:
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: <Enter a short description of the sortware>
|
||||
# Description: <Enter a long description of the software>
|
||||
# <...>
|
||||
# <...>
|
||||
### END INIT INFO
|
||||
|
||||
# Author: Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
|
||||
# PATH should only include /usr/* if it runs after the mountnfs.sh script
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||
DESC=osmo-pcap # Introduce a short description here
|
||||
NAME=osmo-pcap # Introduce the short server's name here
|
||||
DAEMON=/usr/sbin/osmo-pcap # Introduce the server's location here
|
||||
DAEMON_ARGS="" # Arguments to run the daemon with
|
||||
PIDFILE=/var/run/$NAME.pid
|
||||
SCRIPTNAME=/etc/init.d/$NAME
|
||||
|
||||
# Exit if the package is not installed
|
||||
[ -x $DAEMON ] || exit 0
|
||||
|
||||
# Read configuration variable file if it is present
|
||||
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
|
||||
|
||||
# Load the VERBOSE setting and other rcS variables
|
||||
. /lib/init/vars.sh
|
||||
|
||||
# Define LSB log_* functions.
|
||||
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
#
|
||||
# Function that starts the daemon/service
|
||||
#
|
||||
do_start()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been started
|
||||
# 1 if daemon was already running
|
||||
# 2 if daemon could not be started
|
||||
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
|
||||
|| return 1
|
||||
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
|
||||
$DAEMON_ARGS \
|
||||
|| return 2
|
||||
# Add code here, if necessary, that waits for the process to be ready
|
||||
# to handle requests from services started subsequently which depend
|
||||
# on this one. As a last resort, sleep for some time.
|
||||
}
|
||||
|
||||
#
|
||||
# Function that stops the daemon/service
|
||||
#
|
||||
do_stop()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been stopped
|
||||
# 1 if daemon was already stopped
|
||||
# 2 if daemon could not be stopped
|
||||
# other if a failure occurred
|
||||
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
|
||||
RETVAL="$?"
|
||||
[ "$RETVAL" = 2 ] && return 2
|
||||
# Wait for children to finish too if this is a daemon that forks
|
||||
# and if the daemon is only ever run from this initscript.
|
||||
# If the above conditions are not satisfied then add some other code
|
||||
# that waits for the process to drop all resources that could be
|
||||
# needed by services started subsequently. A last resort is to
|
||||
# sleep for some time.
|
||||
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
|
||||
[ "$?" = 2 ] && return 2
|
||||
# Many daemons don't delete their pidfiles when they exit.
|
||||
rm -f $PIDFILE
|
||||
return "$RETVAL"
|
||||
}
|
||||
|
||||
#
|
||||
# Function that sends a SIGHUP to the daemon/service
|
||||
#
|
||||
do_reload() {
|
||||
#
|
||||
# If the daemon can reload its configuration without
|
||||
# restarting (for example, when it is sent a SIGHUP),
|
||||
# then implement that here.
|
||||
#
|
||||
start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
|
||||
return 0
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME"
|
||||
do_start
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
stop)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
status)
|
||||
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
|
||||
;;
|
||||
#reload|force-reload)
|
||||
#
|
||||
# If do_reload() is not implemented then leave this commented out
|
||||
# and leave 'force-reload' as an alias for 'restart'.
|
||||
#
|
||||
#log_daemon_msg "Reloading $DESC" "$NAME"
|
||||
#do_reload
|
||||
#log_end_msg $?
|
||||
#;;
|
||||
restart|force-reload)
|
||||
#
|
||||
# If the "reload" option is implemented then remove the
|
||||
# 'force-reload' alias
|
||||
#
|
||||
log_daemon_msg "Restarting $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1)
|
||||
do_start
|
||||
case "$?" in
|
||||
0) log_end_msg 0 ;;
|
||||
1) log_end_msg 1 ;; # Old process is still running
|
||||
*) log_end_msg 1 ;; # Failed to start
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
# Failed to stop
|
||||
log_end_msg 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
|
||||
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
|
||||
:
|
|
@ -1,152 +0,0 @@
|
|||
#!/bin/sh
|
||||
### BEGIN INIT INFO
|
||||
# Provides: osmo-pcap-client
|
||||
# Required-Start: $network $local_fs
|
||||
# Required-Stop:
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: Start the pcap client
|
||||
# Description: PCAP Client for the PCAP aggregation
|
||||
### END INIT INFO
|
||||
|
||||
# Author: Holger Hans Peter Freyther <holger@freyther.de>
|
||||
|
||||
# PATH should only include /usr/* if it runs after the mountnfs.sh script
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||
DESC=osmo-pcap-client # Introduce a short description here
|
||||
NAME=osmo-pcap-client # Introduce the short server's name here
|
||||
DAEMON=/usr/bin/osmo_pcap_client # Introduce the server's location here
|
||||
DAEMON_ARGS="-c /etc/osmo-pcap/osmo-pcap-client.cfg" # Arguments to run the daemon with
|
||||
PIDFILE=/var/run/$NAME.pid
|
||||
SCRIPTNAME=/etc/init.d/$NAME
|
||||
|
||||
# Exit if the package is not installed
|
||||
[ -x $DAEMON ] || exit 0
|
||||
|
||||
# Read configuration variable file if it is present
|
||||
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
|
||||
|
||||
# Load the VERBOSE setting and other rcS variables
|
||||
. /lib/init/vars.sh
|
||||
|
||||
# Define LSB log_* functions.
|
||||
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
#
|
||||
# Function that starts the daemon/service
|
||||
#
|
||||
do_start()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been started
|
||||
# 1 if daemon was already running
|
||||
# 2 if daemon could not be started
|
||||
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
|
||||
|| return 1
|
||||
start-stop-daemon -b -m --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
|
||||
$DAEMON_ARGS \
|
||||
|| return 2
|
||||
# Add code here, if necessary, that waits for the process to be ready
|
||||
# to handle requests from services started subsequently which depend
|
||||
# on this one. As a last resort, sleep for some time.
|
||||
}
|
||||
|
||||
#
|
||||
# Function that stops the daemon/service
|
||||
#
|
||||
do_stop()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been stopped
|
||||
# 1 if daemon was already stopped
|
||||
# 2 if daemon could not be stopped
|
||||
# other if a failure occurred
|
||||
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE
|
||||
RETVAL="$?"
|
||||
[ "$RETVAL" = 2 ] && return 2
|
||||
# Wait for children to finish too if this is a daemon that forks
|
||||
# and if the daemon is only ever run from this initscript.
|
||||
# If the above conditions are not satisfied then add some other code
|
||||
# that waits for the process to drop all resources that could be
|
||||
# needed by services started subsequently. A last resort is to
|
||||
# sleep for some time.
|
||||
#start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
|
||||
#[ "$?" = 2 ] && return 2
|
||||
# Many daemons don't delete their pidfiles when they exit.
|
||||
rm -f $PIDFILE
|
||||
return "$RETVAL"
|
||||
}
|
||||
|
||||
#
|
||||
# Function that sends a SIGHUP to the daemon/service
|
||||
#
|
||||
do_reload() {
|
||||
#
|
||||
# If the daemon can reload its configuration without
|
||||
# restarting (for example, when it is sent a SIGHUP),
|
||||
# then implement that here.
|
||||
#
|
||||
start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
|
||||
return 0
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME"
|
||||
do_start
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
stop)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
status)
|
||||
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
|
||||
;;
|
||||
#reload|force-reload)
|
||||
#
|
||||
# If do_reload() is not implemented then leave this commented out
|
||||
# and leave 'force-reload' as an alias for 'restart'.
|
||||
#
|
||||
#log_daemon_msg "Reloading $DESC" "$NAME"
|
||||
#do_reload
|
||||
#log_end_msg $?
|
||||
#;;
|
||||
restart|force-reload)
|
||||
#
|
||||
# If the "reload" option is implemented then remove the
|
||||
# 'force-reload' alias
|
||||
#
|
||||
log_daemon_msg "Restarting $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1)
|
||||
do_start
|
||||
case "$?" in
|
||||
0) log_end_msg 0 ;;
|
||||
1) log_end_msg 1 ;; # Old process is still running
|
||||
*) log_end_msg 1 ;; # Failed to start
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
# Failed to stop
|
||||
log_end_msg 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
|
||||
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
|
||||
:
|
|
@ -1 +1,5 @@
|
|||
usr/bin/osmo_pcap_client
|
||||
etc/osmocom/osmo-pcap-client.cfg
|
||||
lib/systemd/system/osmo-pcap-client.service
|
||||
usr/bin/osmo-pcap-client
|
||||
usr/share/doc/osmo-pcap/examples/osmo-pcap-client/osmo-pcap-client.cfg
|
||||
usr/share/doc/osmo-pcap/examples/osmo-pcap-client/osmo-pcap-client-tls.cfg
|
||||
|
|
|
@ -1 +1,6 @@
|
|||
usr/bin/osmo_pcap_server
|
||||
etc/osmocom/osmo-pcap-server.cfg
|
||||
lib/systemd/system/osmo-pcap-server.service
|
||||
usr/bin/osmo-pcap-server
|
||||
usr/share/doc/osmo-pcap/examples/osmo-pcap-server/osmo-pcap-server.cfg
|
||||
usr/share/doc/osmo-pcap/examples/osmo-pcap-server/osmo-pcap-server-tls.cfg
|
||||
usr/share/osmo-pcap/osmo_pcap_clean_old
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
# Defaults for osmo-pcap initscript
|
||||
# sourced by /etc/init.d/osmo-pcap
|
||||
# installed at /etc/default/osmo-pcap by the maintainer scripts
|
||||
|
||||
#
|
||||
# This is a POSIX shell fragment
|
||||
#
|
||||
|
||||
# Additional options that are passed to the Daemon.
|
||||
DAEMON_OPTS=""
|
|
@ -1,41 +1,26 @@
|
|||
#!/usr/bin/make -f
|
||||
# -*- makefile -*-
|
||||
# Sample debian/rules that uses debhelper.
|
||||
#
|
||||
# This file was originally written by Joey Hess and Craig Small.
|
||||
# As a special exception, when this file is copied by dh-make into a
|
||||
# dh-make output file, you may use that output file without restriction.
|
||||
# This special exception was added by Craig Small in version 0.37 of dh-make.
|
||||
#
|
||||
# Modified to make a template file for a multi-binary package with separated
|
||||
# build-arch and build-indep targets by Bill Allombert 2001
|
||||
|
||||
# Uncomment this to turn on verbose mode.
|
||||
DEBIAN := $(shell dpkg-parsechangelog | grep ^Version: | cut -d' ' -f2)
|
||||
DEBVERS := $(shell echo '$(DEBIAN)' | cut -d- -f1)
|
||||
VERSION := $(shell echo '$(DEBVERS)' | sed -e 's/[+-].*//' -e 's/~//g')
|
||||
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
# This has to be exported to make some magic below work.
|
||||
export DH_OPTIONS
|
||||
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
|
||||
|
||||
# Maybe we require some moreadvanced testing in the future
|
||||
PCAP_CFLAGS="-I/usr/include"
|
||||
PCAP_LIBS="-lpcap"
|
||||
|
||||
%:
|
||||
dh --with autoreconf $@
|
||||
dh $@ --with autoreconf --fail-missing
|
||||
|
||||
override_dh_auto_configure:
|
||||
dh_auto_configure -- \
|
||||
--with-systemdsystemunitdir=/lib/systemd/system \
|
||||
--with-pcap-config=/bin/false \
|
||||
PCAP_CFLAGS=$(PCAP_CFLAGS) \
|
||||
PCAP_LIBS=$(PCAP_LIBS)
|
||||
|
||||
override_dh_auto_install:
|
||||
dh_auto_install $@
|
||||
install -d -m 0755 $(CURDIR)/debian/osmo-pcap-client/etc/osmo-pcap/
|
||||
install -m 0644 $(CURDIR)/contrib/osmo-pcap-client.cfg $(CURDIR)/debian/osmo-pcap-client/etc/osmo-pcap
|
||||
|
||||
install -d -m 0755 $(CURDIR)/debian/osmo-pcap-server/etc/osmo-pcap/
|
||||
install -m 0644 $(CURDIR)/contrib/osmo-pcap-server.cfg $(CURDIR)/debian/osmo-pcap-server/etc/osmo-pcap
|
||||
|
||||
install -d -m 0755 $(CURDIR)/debian/osmo-pcap-server/etc/cron.daily/
|
||||
install -m 0755 $(CURDIR)/contrib/osmo_pcap_clean_old $(CURDIR)/debian/osmo-pcap-server/etc/cron.daily/
|
||||
override_dh_strip:
|
||||
dh_strip -posmo-pcap-client --dbg-package=osmo-pcap-client-dbg
|
||||
dh_strip -posmo-pcap-server --dbg-package=osmo-pcap-server-dbg
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
SUBDIRS = \
|
||||
examples \
|
||||
manuals \
|
||||
$(NULL)
|
|
@ -0,0 +1,30 @@
|
|||
OSMOCONF_FILES = \
|
||||
osmo-pcap-client/osmo-pcap-client.cfg \
|
||||
osmo-pcap-server/osmo-pcap-server.cfg
|
||||
|
||||
osmoconfdir = $(sysconfdir)/osmocom
|
||||
osmoconf_DATA = $(OSMOCONF_FILES)
|
||||
EXTRA_DIST = $(OSMOCONF_FILES)
|
||||
|
||||
CFG_FILES = find $(srcdir) -type f -name '*.cfg*' | sed -e 's,^$(srcdir),,'
|
||||
|
||||
dist-hook:
|
||||
for f in $$($(CFG_FILES)); do \
|
||||
j="$(distdir)/$$f" && \
|
||||
mkdir -p "$$(dirname $$j)" && \
|
||||
$(INSTALL_DATA) $(srcdir)/$$f $$j; \
|
||||
done
|
||||
|
||||
install-data-hook:
|
||||
for f in $$($(CFG_FILES)); do \
|
||||
j="$(DESTDIR)$(docdir)/examples/$$f" && \
|
||||
mkdir -p "$$(dirname $$j)" && \
|
||||
$(INSTALL_DATA) $(srcdir)/$$f $$j; \
|
||||
done
|
||||
|
||||
uninstall-hook:
|
||||
@$(PRE_UNINSTALL)
|
||||
for f in $$($(CFG_FILES)); do \
|
||||
j="$(DESTDIR)$(docdir)/examples/$$f" && \
|
||||
$(RM) $$j; \
|
||||
done
|
|
@ -3,6 +3,14 @@
|
|||
!!
|
||||
!
|
||||
!
|
||||
log stderr
|
||||
logging color 1
|
||||
logging print category-hex 0
|
||||
logging print category 1
|
||||
logging timestamp 0
|
||||
logging print file basename last
|
||||
logging print level 1
|
||||
|
||||
line vty
|
||||
no login
|
||||
!
|
|
@ -3,6 +3,14 @@
|
|||
!!
|
||||
!
|
||||
!
|
||||
log stderr
|
||||
logging color 1
|
||||
logging print category-hex 0
|
||||
logging print category 1
|
||||
logging timestamp 0
|
||||
logging print file basename last
|
||||
logging print level 1
|
||||
|
||||
line vty
|
||||
no login
|
||||
!
|
|
@ -4,7 +4,11 @@
|
|||
!
|
||||
log stderr
|
||||
logging color 1
|
||||
logging print category-hex 0
|
||||
logging print category 1
|
||||
logging timestamp 0
|
||||
logging print file basename last
|
||||
logging print level 1
|
||||
logging level all everything
|
||||
logging level pcap notice
|
||||
logging level client notice
|
||||
|
@ -16,6 +20,7 @@ line vty
|
|||
!
|
||||
server
|
||||
base-path /tmp
|
||||
file-permission-mask 0440
|
||||
server ip 127.0.0.1
|
||||
server port 6001
|
||||
max-file-size 262144000
|
|
@ -4,7 +4,11 @@
|
|||
!
|
||||
log stderr
|
||||
logging color 1
|
||||
logging print category-hex 0
|
||||
logging print category 1
|
||||
logging timestamp 0
|
||||
logging print file basename last
|
||||
logging print level 1
|
||||
logging level all everything
|
||||
logging level pcap notice
|
||||
logging level client notice
|
||||
|
@ -16,6 +20,7 @@ line vty
|
|||
!
|
||||
server
|
||||
base-path /tmp
|
||||
file-permission-mask 0440
|
||||
server ip 127.0.0.1
|
||||
server port 6001
|
||||
max-file-size 262144000
|
|
@ -0,0 +1,18 @@
|
|||
EXTRA_DIST = osmopcap-usermanual.adoc \
|
||||
osmopcap-usermanual-docinfo.xml \
|
||||
chapters \
|
||||
vty
|
||||
|
||||
if BUILD_MANUALS
|
||||
ASCIIDOC = osmopcap-usermanual.adoc
|
||||
ASCIIDOC_DEPS = $(srcdir)/chapters/*.adoc
|
||||
include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.asciidoc.inc
|
||||
|
||||
# This is a significantly modified, multi-target adopted copy of
|
||||
# $(OSMO_GSM_MANUALS_DIR)/build/Makefile.vty-reference.inc
|
||||
VARIANTS = client server
|
||||
include $(srcdir)/vty/Makefile.vty-reference.inc
|
||||
|
||||
OSMO_REPOSITORY = osmo-pcap
|
||||
include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.common.inc
|
||||
endif
|
|
@ -0,0 +1,132 @@
|
|||
== osmo-pcap-client
|
||||
|
||||
The osmo-pcap-client program runs at a location of your network
|
||||
where you would like to record some packets. It captures those
|
||||
packets (with or without filter) and forwards them to one or multiple
|
||||
remote servers.
|
||||
|
||||
=== Running osmo-pcap-client
|
||||
|
||||
==== SYNOPSIS
|
||||
|
||||
*osmo-pcap-client* [-D] [-c CFG_FILE] | -h | -V
|
||||
|
||||
==== OPTIONS
|
||||
|
||||
*-h, --help*::
|
||||
Print a short help message about the supported options.
|
||||
*-V, --version*::
|
||||
Print the compile-time version number of the program.
|
||||
*-D, --daemonize*::
|
||||
Fork the process as a daemon into background.
|
||||
*-c, --config-file 'CONFIGFILE'*::
|
||||
Specify the file and path name of the configuration file to be
|
||||
used. If none is specified, use `osmo-pcap-client.cfg` in the current
|
||||
working directory.
|
||||
|
||||
Capturing network packets requires you to be superuser or have the CAP_NET_RAW capability.
|
||||
|
||||
There are several options to achieve this:
|
||||
|
||||
- start the program as root user (strongly discouraged)
|
||||
- globally enable the CAP_NET_RAW capability for the program using e.g. the tool `setcap`
|
||||
- asking `systemd` to start the program with the required capability
|
||||
|
||||
NOTE:: This potentially opens a privilege escalation, as `osmo-pcap-client` can be configured
|
||||
via the VTY interface (telnet) which is by default accessible by any user on the local machine (access to the loopback device). Please make sure to protect access to the VTY interface accordingly.
|
||||
|
||||
|
||||
=== Configuring the packet capture
|
||||
|
||||
The VTY configuration node of osmo-pcap-client contains a `client` node,
|
||||
in which the packet capturing is configured
|
||||
|
||||
.osmo-pcap-client VTY configuration for packet capture
|
||||
----
|
||||
client
|
||||
pcap device eth0 <1>
|
||||
pcap filter udp port 23000 <2>
|
||||
pcap detect-loop 1 <3>
|
||||
----
|
||||
<1> the network device from which to obtain a capture
|
||||
<2> the libpcap filter string (`udp port 23000` in this example)
|
||||
<3> instruct osmo-pcap-client to automatically add a filter that prevents capturing
|
||||
the traffic between osmo-pcap-client and osmo-pcap-server, which would create a loop.
|
||||
|
||||
|
||||
=== Configuring the primary server
|
||||
|
||||
.osmo-pcap-client configuration for the primary remote server
|
||||
----
|
||||
client
|
||||
server ip 192.168.11.20 <1>
|
||||
server port 54321 <2>
|
||||
source ip 192.168.11.1 <3>
|
||||
----
|
||||
<1> IP address of the server to which to send the traces
|
||||
<2> port number of the server to which to send the traces
|
||||
<3> local IP address to use when sending traffic to the server
|
||||
|
||||
By default, a custom osmo-pcap specific protocol is used to transport
|
||||
the captured packets from client to server. However, the `protocol`
|
||||
VTY configuration command can be used to switch to to using a simple `ipip`
|
||||
encapsulation. `ipip` can be transparently decoded by protocol analysis
|
||||
tools like wireshark.
|
||||
|
||||
|
||||
=== Configuring additional servers
|
||||
|
||||
In some use cases, you may want to send the captured packets to multiple
|
||||
remote destinations.
|
||||
|
||||
The primary and each of the remote destinations each receive a copy
|
||||
of each captured packet.
|
||||
|
||||
.osmo-pcap-client configuration for an additional remote server
|
||||
----
|
||||
client
|
||||
pcap-store-connection my_server <1>
|
||||
server ip 192.168.11.10 <2>
|
||||
server port 54321 <3>
|
||||
source ip 192.168.11.1 <4>
|
||||
connect <5>
|
||||
----
|
||||
<1> a human-readable identifier for this specific connection (`my_server`)
|
||||
<2> IP address of the server to which to send the traces
|
||||
<3> port number of the server to which to send the traces
|
||||
<4> local IP address to use when sending traffic to the server
|
||||
<5> request connection to the remote server specified in this section
|
||||
|
||||
|
||||
=== Configuring TLS
|
||||
|
||||
By default, the captured packets are sent in plain-text without any additional
|
||||
layer of encryption or authentication. This means that there is no confidentiality,
|
||||
nor any integrity protection, unless the original captured packet already featured
|
||||
such properties.
|
||||
|
||||
If desired, `osmo-pcap-client` can be configured to use TLS (transport layer security)
|
||||
on the protocol between client and server.
|
||||
|
||||
TLS is configured separately for each remote server, whether primary or additional.
|
||||
|
||||
.osmo-pcap-client configuration with TLS
|
||||
----
|
||||
client
|
||||
server ip 192.168.11.20
|
||||
server port 54321
|
||||
source ip 192.168.11.1
|
||||
enable tls <1>
|
||||
tls hostname pcapserver.example.test<2>
|
||||
tls verify-cert <3>
|
||||
tls capath /etc/osmo-pcap/ca-certificates <4>
|
||||
tls client-cert /etc/osmo-pcap/client.crt <5>
|
||||
tls client-key /etc/osmo-pcap/client.key <6>
|
||||
----
|
||||
<1> enable TLS for this server
|
||||
<2> set the hostname we expect the server to have a certificate for
|
||||
<3> enable certificate verification
|
||||
<4> path of all CA certificates we consider valid for signing the server cert
|
||||
<5> file containing the client certificate
|
||||
<6> file containing the private key for the client certificate
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
[[overview]]
|
||||
== OsmoPCAP Overview
|
||||
|
||||
=== Package Capturing in distributed telecoms networks
|
||||
|
||||
Obtaining raw, binary protocol traces [for later analysis] is an
|
||||
essential capability in order to investigate any kind of problem
|
||||
in any computer networking system.
|
||||
|
||||
The very distributed, heterogenuous nature of cellular networks
|
||||
(compared to end-to-end IP networks) results in a lot of relevant
|
||||
information being present only at some specific interfaces / points
|
||||
in the network. This in turn means that packet captures have to
|
||||
be performed at a variety of different network elements in order
|
||||
to get the full picture of what is happening.
|
||||
|
||||
Recording protocol traces at various different points in the network
|
||||
inevitably raises the question of how to aggregate these.
|
||||
|
||||
[[about]]
|
||||
=== About OsmoPCAP
|
||||
|
||||
OsmoPCAP is a software suite consisting of two programs, a client and a
|
||||
server component.
|
||||
|
||||
- osmo-pcap-client obtains protocol traces by using AF_PACKET sockets,
|
||||
optionally with a capture filter. It then forwards the captures to
|
||||
a remote server.
|
||||
- osmo-pcap-server accepts incoming connections from clients. It
|
||||
receives captured packets from those clients and stores them.
|
||||
|
||||
The server and client communicate using a custom, TCP based protocol
|
||||
for passing captured packets from client to server. Based on your
|
||||
configuration, it can optionally be secured by TLS transport-level
|
||||
encryption and authentication.
|
||||
|
||||
NOTE:: The osmo-pcap programs runs as normal, single-threaded userspace
|
||||
programs, without any specific emphasis on efficiency. It doesn't use
|
||||
any of the advanced zero-copy mechanisms available on many modern OSs.
|
||||
The goal is to capture telecom signaling (control plane) traffic, whose
|
||||
bandwidth is (unlike that of the user plane) typically relatively low
|
||||
compared to the available CPU / IO speeds. Don't expect osmo-pcap to
|
||||
handle wire-rate multi-gigabit throughput.
|
|
@ -0,0 +1,90 @@
|
|||
== osmo-pcap-server
|
||||
|
||||
The osmo-pcap-server program can run anywhere in your network, as long
|
||||
as it can be reached by the remote osmo-pcap-client instances.
|
||||
|
||||
=== Running osmo-pcap-server
|
||||
|
||||
==== SYNOPSIS
|
||||
|
||||
*osmo-pcap-server* [-D] [-c CFG_FILE] | -h | -V
|
||||
|
||||
==== OPTIONS
|
||||
|
||||
*-h, --help*::
|
||||
Print a short help message about the supported options.
|
||||
*-V, --version*::
|
||||
Print the compile-time version number of the program.
|
||||
*-D, --daemonize*::
|
||||
Fork the process as a daemon into background.
|
||||
*-c, --config-file 'CONFIGFILE'*::
|
||||
Specify the file and path name of the configuration file to be
|
||||
used. If none is specified, use `osmo-pcap-client.cfg` in the current
|
||||
working directory.
|
||||
|
||||
As osmo-pcap-server doesn't capture any packets itself and only receives streams of
|
||||
captured packets from [remote] osmo-pcap-clients, there is no need to run it as root
|
||||
or with elevated privileges.
|
||||
|
||||
=== Configuring osmo-pcap-server
|
||||
|
||||
The osmo-pcap-server configuration consists mainly of the following parts:
|
||||
|
||||
* the global server configuration, optionally including TLS related settings
|
||||
* the per-client (per-connection) configuration
|
||||
|
||||
.osmo-pcap-server example global configuration
|
||||
----
|
||||
server
|
||||
base-path /var/lib/osmo-pcap-server <1>
|
||||
server ip 192.168.11.20 <2>
|
||||
server port 54321 <3>
|
||||
max-file-size 100000000 <4>
|
||||
max-snaplen 100000 <5>
|
||||
----
|
||||
<1> directory to which the pcap files are stored
|
||||
<2> IP address to which to bind/listen
|
||||
<3> TCP port number to which to bind/listen
|
||||
<4> maximum size for pcap files; create a new file once max-file-size is reached
|
||||
<5> maximum pcap snapshot length (per packet, in bytes; default: 9000)
|
||||
|
||||
The received packets are stored to a pcap file below the `base-path` using a filename
|
||||
encoding both the client name and the date/time at time of file creation.
|
||||
|
||||
.osmo-pcap-server example global configuration
|
||||
----
|
||||
server
|
||||
client foo 192.168.100.1 <1>
|
||||
client bar 192.168.200.2 tls <2>
|
||||
----
|
||||
<1> Client `foo` connects from 192.168.100.1 and uses no TLS
|
||||
<2> Client `bar` connects from 192.168.2.00.2 and uses TLS
|
||||
|
||||
=== Configuring TLS
|
||||
|
||||
By default, the captured packets are received in plain-text without any additional
|
||||
layer of encryption or authentication. This means that there is no confidentiality,
|
||||
nor any integrity protection, unless the original captured packet already featured
|
||||
such properties.
|
||||
|
||||
If desired, `osmo-pcap-server` can be configured to use TLS (transport layer security)
|
||||
on the protocol between client and server.
|
||||
|
||||
TLS is configured separately for each remote server, whether primary or additional.
|
||||
|
||||
NOTE:: osmo-pcap-server uses the gnutls library for TLS support. See its documentation in terms of supported file formats for CRL, certificates, keys, etc.
|
||||
|
||||
.osmo-pcap-server configuration with TLS
|
||||
----
|
||||
server
|
||||
tls allow-auth x509 <1>
|
||||
tls capath /etc/osmocom/osmo-pcap-ca <2>
|
||||
tls crlfile /etc/osmocom/osmo-pcap-ca.crl <3>
|
||||
tls server-cert /etc/osmocom/osmo-pcap-server.crt <4>
|
||||
tls server-key /etc/osmocom/osmo-pcap-server.key <5>
|
||||
----
|
||||
<1> require clients to authenticate using a X.509 client certificate
|
||||
<2> path of all CA certificates we consider valid for signing the client cert
|
||||
<3> file containing the certificate revocation list
|
||||
<4> file containing the server certificate
|
||||
<5> file containing the private key for the server certificate
|
|
@ -0,0 +1,47 @@
|
|||
<revhistory>
|
||||
<revision>
|
||||
<revnumber>1</revnumber>
|
||||
<date>January 4th, 2021</date>
|
||||
<authorinitials>HW</authorinitials>
|
||||
<revremark>
|
||||
Initial version
|
||||
</revremark>
|
||||
</revision>
|
||||
</revhistory>
|
||||
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>Harald</firstname>
|
||||
<surname>Welte</surname>
|
||||
<email>hwelte@sysmocom.de</email>
|
||||
<authorinitials>HW</authorinitials>
|
||||
<affiliation>
|
||||
<shortaffil>sysmocom</shortaffil>
|
||||
<orgname>sysmocom - s.f.m.c. GmbH</orgname>
|
||||
<jobtitle>Managing Director</jobtitle>
|
||||
</affiliation>
|
||||
</author>
|
||||
</authorgroup>
|
||||
|
||||
<copyright>
|
||||
<year>2021</year>
|
||||
<holder>sysmocom - s.f.m.c. GmbH</holder>
|
||||
</copyright>
|
||||
|
||||
<legalnotice>
|
||||
<para>
|
||||
Permission is granted to copy, distribute and/or modify this
|
||||
document under the terms of the GNU Free Documentation License,
|
||||
Version 1.3 or any later version published by the Free Software
|
||||
Foundation; with the Invariant Sections being just 'Foreword',
|
||||
'Acknowledgements' and 'Preface', with no Front-Cover Texts,
|
||||
and no Back-Cover Texts. A copy of the license is included in
|
||||
the section entitled "GNU Free Documentation License".
|
||||
</para>
|
||||
<para>
|
||||
The Asciidoc source code of this manual can be found at
|
||||
<ulink url="https://gitea.osmocom.org/cellular-infrastructure/osmo-gsm-manuals">
|
||||
https://gitea.osmocom.org/cellular-infrastructure/osmo-gsm-manuals
|
||||
</ulink>
|
||||
</para>
|
||||
</legalnotice>
|
|
@ -0,0 +1,32 @@
|
|||
:gfdl-enabled:
|
||||
:program-name: OsmoPCAP
|
||||
|
||||
OsmoPCAP User Manual
|
||||
====================
|
||||
Harald Welte <hwelte@sysmocom.de>
|
||||
|
||||
|
||||
include::./common/chapters/preface.adoc[]
|
||||
|
||||
include::{srcdir}/chapters/overview.adoc[]
|
||||
|
||||
include::{srcdir}/chapters/client.adoc[]
|
||||
|
||||
include::{srcdir}/chapters/server.adoc[]
|
||||
|
||||
|
||||
include::./common/chapters/counters-overview.adoc[]
|
||||
|
||||
|
||||
|
||||
include::./common/chapters/vty.adoc[]
|
||||
|
||||
include::./common/chapters/logging.adoc[]
|
||||
|
||||
include::./common/chapters/port_numbers.adoc[]
|
||||
|
||||
include::./common/chapters/bibliography.adoc[]
|
||||
|
||||
include::./common/chapters/glossary.adoc[]
|
||||
|
||||
include::./common/chapters/gfdl.adoc[]
|
|
@ -0,0 +1,37 @@
|
|||
DOCBOOKS = $(foreach v,$(VARIANTS),vty/osmo-pcap-$(v)-vty-reference.xml)
|
||||
DOCBOOKS_DEPS = $(DOCBOOKS) $(addsuffix .inc,$(DOCBOOKS))
|
||||
INC_DIR = $(abspath $(builddir)/vty)
|
||||
|
||||
include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.docbook.inc
|
||||
|
||||
CLEAN_FILES += $(DOCBOOKS_DEPS)
|
||||
CLEAN_FILES += $(addsuffix .inc.gen,$(DOCBOOKS))
|
||||
CLEAN_FILES += $(addsuffix .inc.merged,$(DOCBOOKS))
|
||||
|
||||
$(INC_DIR):
|
||||
mkdir -p $@
|
||||
|
||||
vty/osmo-pcap-%-vty-reference.xml: $(top_builddir)/src/osmo-pcap-% $(INC_DIR)
|
||||
sed -e "s|@@GENERATED@@|$@.inc|" \
|
||||
-e "s|@@VARIANT@@|$(notdir $<)|" \
|
||||
-e "s|@@REV_NUMBER@@|$(VERSION)|" \
|
||||
-e "s|@@REV_DATE@@|$(shell date +"%dth %B %Y")|" \
|
||||
-e "s|@@CR_YEAR@@|$(shell date +"%Y")|" \
|
||||
$(srcdir)/vty/osmo-pcap-vty-reference.xml > $@
|
||||
|
||||
vty/osmo-pcap-%-vty-reference.xml.inc: $(top_builddir)/src/osmo-pcap-% \
|
||||
$(OSMO_GSM_MANUALS_DIR)/common/vty_additions.xml \
|
||||
$(OSMO_GSM_MANUALS_DIR)/common/chapters/vty.xml \
|
||||
$(OSMO_GSM_MANUALS_DIR)/vty_reference.xsl \
|
||||
$(srcdir)/vty/*.xml $(INC_DIR)
|
||||
# a) Invoke osmo-pcap-% to generate the list of commands first
|
||||
$< --vty-ref-mode default --vty-ref-xml > "$@.gen"
|
||||
# ... filter garbage potentially printed by libraries to stdout
|
||||
sed -i '/^<vtydoc/,$$!d' "$@.gen"
|
||||
# b) Merge the result of a) with global and local additions
|
||||
$(OSMO_GSM_MANUALS_DIR)/build/vty_reference_combine.sh \
|
||||
$(realpath $(OSMO_GSM_MANUALS_DIR)/merge_doc.xsl) "$@.gen" \
|
||||
$(OSMO_GSM_MANUALS_DIR)/common/vty_additions.xml \
|
||||
$(srcdir)/vty/vty_additions.xml > "$@.merged"
|
||||
# c) Convert the result of b) into a valid docbook
|
||||
xsltproc $(OSMO_GSM_MANUALS_DIR)/vty_reference.xsl "$@.merged" > $@
|
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML 5.0//EN"
|
||||
"http://docbook.org/xml/5.0/dtd/docbook.dtd" [
|
||||
<!ENTITY chapter-vty SYSTEM "./common/chapters/vty.xml" >
|
||||
<!ENTITY sections-vty SYSTEM "@@GENERATED@@" >
|
||||
]>
|
||||
|
||||
<book>
|
||||
<info>
|
||||
<revhistory>
|
||||
<revision>
|
||||
<revnumber>v1</revnumber>
|
||||
<date>@@REV_DATE@@</date>
|
||||
<authorinitials>s.f.m.c.</authorinitials>
|
||||
<revremark>Automatic build (@@REV_NUMBER@@)</revremark>
|
||||
</revision>
|
||||
</revhistory>
|
||||
|
||||
<title>OsmoPCAP VTY Reference</title>
|
||||
<subtitle>@@VARIANT@@</subtitle>
|
||||
|
||||
<copyright>
|
||||
<year>@@CR_YEAR@@</year>
|
||||
</copyright>
|
||||
|
||||
<legalnotice>
|
||||
<para>This work is copyright by <orgname>sysmocom - s.f.m.c. GmbH</orgname>. All rights reserved.
|
||||
</para>
|
||||
</legalnotice>
|
||||
</info>
|
||||
|
||||
<!-- Main chapters-->
|
||||
&chapter-vty;
|
||||
</book>
|
|
@ -0,0 +1,2 @@
|
|||
<vtydoc xmlns='urn:osmocom:xml:libosmocore:vty:doc:1.0'>
|
||||
</vtydoc>
|
|
@ -28,6 +28,15 @@
|
|||
#include <osmocom/vty/vty.h>
|
||||
#include <osmocom/vty/buffer.h>
|
||||
#include <osmocom/vty/command.h>
|
||||
#include <osmocom/vty/ports.h>
|
||||
|
||||
/* support old versions of libosmocore */
|
||||
#ifndef OSMO_VTY_PORT_PCAP_CLIENT
|
||||
#define OSMO_VTY_PORT_PCAP_CLIENT 4227
|
||||
#endif
|
||||
#ifndef OSMO_VTY_PORT_PCAP_SERVER
|
||||
#define OSMO_VTY_PORT_PCAP_SERVER 4228
|
||||
#endif
|
||||
|
||||
enum {
|
||||
DPCAP,
|
||||
|
@ -49,4 +58,11 @@ extern const char *osmopcap_copyright;
|
|||
extern int osmopcap_go_parent(struct vty *vty);
|
||||
extern int osmopcap_is_config_node(struct vty *vty, int node);
|
||||
|
||||
/* defined in libpcap's pcap-int.h, which is not public */
|
||||
#ifndef MAXIMUM_SNAPLEN
|
||||
#define MAXIMUM_SNAPLEN 262144
|
||||
#endif
|
||||
|
||||
#define DEFAULT_SNAPLEN 9000
|
||||
|
||||
#endif
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
|
||||
struct rate_ctr_group;
|
||||
|
||||
#define WQUEUE_MAXLEN_DEFAULT 1000
|
||||
|
||||
enum {
|
||||
CLIENT_CTR_CONNECT,
|
||||
CLIENT_CTR_BYTES,
|
||||
|
@ -46,14 +48,21 @@ enum {
|
|||
CLIENT_CTR_P_IFDROP,
|
||||
};
|
||||
|
||||
enum osmo_pcap_protocol {
|
||||
PROTOCOL_OSMOPCAP,
|
||||
PROTOCOL_IPIP,
|
||||
};
|
||||
|
||||
struct osmo_pcap_client_conn {
|
||||
struct llist_head entry;
|
||||
const char *name;
|
||||
|
||||
char *srv_ip;
|
||||
int srv_port;
|
||||
char *source_ip;
|
||||
struct osmo_wqueue wqueue;
|
||||
struct osmo_timer_list timer;
|
||||
enum osmo_pcap_protocol protocol;
|
||||
|
||||
/* TLS handling */
|
||||
bool tls_on;
|
||||
|
@ -87,6 +96,7 @@ struct osmo_pcap_client {
|
|||
char *filter_string;
|
||||
int filter_itself;
|
||||
int gprs_filtering;
|
||||
int snaplen;
|
||||
struct osmo_fd fd;
|
||||
|
||||
struct osmo_pcap_client_conn conn;
|
||||
|
@ -98,7 +108,8 @@ struct osmo_pcap_client {
|
|||
|
||||
extern struct osmo_pcap_client *pcap_client;
|
||||
|
||||
int vty_client_init(struct osmo_pcap_client *);
|
||||
struct osmo_pcap_client *osmo_pcap_client_alloc(void *tall_ctx);
|
||||
int vty_client_init(void);
|
||||
|
||||
int osmo_client_capture(struct osmo_pcap_client *client, const char *device);
|
||||
int osmo_client_filter(struct osmo_pcap_client *client, const char *filter);
|
||||
|
|
|
@ -48,8 +48,6 @@ struct osmo_pcap_server;
|
|||
#define STATE_INITIAL 0
|
||||
#define STATE_DATA 1
|
||||
|
||||
#define SERVER_MAX_DATA_SIZE 10000
|
||||
|
||||
enum {
|
||||
PEER_CTR_CONNECT,
|
||||
PEER_CTR_BYTES,
|
||||
|
@ -91,7 +89,6 @@ struct osmo_pcap_conn {
|
|||
int state;
|
||||
int pend;
|
||||
int reopen;
|
||||
char buf[SERVER_MAX_DATA_SIZE + sizeof(struct osmo_pcap_data)];
|
||||
struct osmo_pcap_data *data;
|
||||
|
||||
/* statistics */
|
||||
|
@ -132,7 +129,9 @@ struct osmo_pcap_server {
|
|||
bool dh_params_allocated;
|
||||
|
||||
char *base_path;
|
||||
mode_t permission_mask;
|
||||
off_t max_size;
|
||||
int max_snaplen;
|
||||
|
||||
/* statistics */
|
||||
struct rate_ctr_group *ctrg;
|
||||
|
@ -146,7 +145,7 @@ int osmo_pcap_server_listen(struct osmo_pcap_server *server);
|
|||
struct osmo_pcap_conn *osmo_pcap_server_find(struct osmo_pcap_server *ser,
|
||||
const char *name);
|
||||
void osmo_pcap_server_delete(struct osmo_pcap_conn *conn);
|
||||
void vty_server_init(struct osmo_pcap_server *server);
|
||||
void vty_server_init(void);
|
||||
void osmo_pcap_server_close_trace(struct osmo_pcap_conn *conn);
|
||||
void osmo_pcap_server_close_conn(struct osmo_pcap_conn *conn);
|
||||
|
||||
|
|
|
@ -26,15 +26,10 @@
|
|||
#include <inttypes.h>
|
||||
#include <pcap.h>
|
||||
|
||||
/*
|
||||
* Should send an entire pcap header
|
||||
*/
|
||||
#define PKT_LINK_HDR 0
|
||||
|
||||
/*
|
||||
* Should send one packet...
|
||||
*/
|
||||
#define PKT_LINK_DATA 1
|
||||
enum OsmoPcapDataType {
|
||||
PKT_LINK_HDR, /* Should send an entire pcap header */
|
||||
PKT_LINK_DATA /* Should send one packet */
|
||||
};
|
||||
|
||||
struct osmo_pcap_data {
|
||||
uint8_t type;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# (C) 2016 by Holger Hans Peter Freyther
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
|
@ -15,16 +15,18 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
app_configs = {
|
||||
"osmo-pcap-client": ["contrib/osmo-pcap-client.cfg", "contrib/osmo-pcap-client-tls.cfg"],
|
||||
"osmo-pcap-server": ["contrib/osmo-pcap-server.cfg", "contrib/osmo-pcap-server-tls.cfg"]
|
||||
"osmo-pcap-client": ["doc/examples/osmo-pcap-client/osmo-pcap-client.cfg",
|
||||
"doc/examples/osmo-pcap-client/osmo-pcap-client-tls.cfg"],
|
||||
"osmo-pcap-server": ["doc/examples/osmo-pcap-server/osmo-pcap-server.cfg",
|
||||
"doc/examples/osmo-pcap-server/osmo-pcap-server-tls.cfg"]
|
||||
}
|
||||
|
||||
apps = [
|
||||
(4241, "src/osmo_pcap_server", "OsmoPCAPServer", "osmo-pcap-server"),
|
||||
(4240, "src/osmo_pcap_client", "OsmoPCAPClient", "osmo-pcap-client"),
|
||||
(4228, "src/osmo-pcap-server", "OsmoPCAPServer", "osmo-pcap-server"),
|
||||
(4227, "src/osmo-pcap-client", "OsmoPCAPClient", "osmo-pcap-client"),
|
||||
]
|
||||
|
||||
vty_command = ["src/osmo_pcap_server", "-c", "contrib/osmo-pcap-server.cfg"]
|
||||
vty_command = ["src/osmo-pcap-server", "-c", "doc/examples/osmo-pcap-server/osmo-pcap-server.cfg"]
|
||||
vty_app = apps[0]
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)/
|
||||
AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(PCAP_CFLAGS) $(LIBGNUTLS_CFLAGS)
|
||||
AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOGB_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(PCAP_CFLAGS) $(LIBGNUTLS_CFLAGS)
|
||||
|
||||
bin_PROGRAMS = osmo_pcap_client osmo_pcap_server
|
||||
bin_PROGRAMS = osmo-pcap-client osmo-pcap-server
|
||||
|
||||
osmo_pcap_client_SOURCES = osmo_client_main.c osmo_common.c \
|
||||
osmo_client_core.c osmo_client_vty.c \
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#define _BSD_SOURCE
|
||||
#define _DEFAULT_SOURCE
|
||||
#include <osmo-pcap/osmo_pcap_client.h>
|
||||
#include <osmo-pcap/common.h>
|
||||
|
||||
|
@ -100,7 +100,7 @@ static int check_gprs(const u_char *data, bpf_u_int32 len)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int forward_packet(
|
||||
static int can_forward_packet(
|
||||
struct osmo_pcap_client *client,
|
||||
struct pcap_pkthdr *hdr,
|
||||
const u_char *data)
|
||||
|
@ -161,11 +161,11 @@ static int pcap_read_cb(struct osmo_fd *fd, unsigned int what)
|
|||
|
||||
data = pcap_next(client->handle, &hdr);
|
||||
if (!data) {
|
||||
rate_ctr_inc(&client->ctrg->ctr[CLIENT_CTR_PERR]);
|
||||
rate_ctr_inc(rate_ctr_group_get_ctr(client->ctrg, CLIENT_CTR_PERR));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!forward_packet(client, &hdr, data))
|
||||
if (!can_forward_packet(client, &hdr, data))
|
||||
return 0;
|
||||
|
||||
osmo_client_send_data(&client->conn, &hdr, data);
|
||||
|
@ -190,14 +190,14 @@ static void add_psbl_wrapped_ctr(struct osmo_pcap_client *client,
|
|||
* Only issue is we don't know sizeof(u_int)
|
||||
*/
|
||||
if (*old_val > new_val) {
|
||||
rate_ctr_add(&client->ctrg->ctr[ctr], P_CAP_UINT_MAX() - *old_val);
|
||||
rate_ctr_add(&client->ctrg->ctr[ctr], new_val);
|
||||
rate_ctr_add(rate_ctr_group_get_ctr(client->ctrg, ctr), P_CAP_UINT_MAX() - *old_val);
|
||||
rate_ctr_add(rate_ctr_group_get_ctr(client->ctrg, ctr), new_val);
|
||||
*old_val = new_val;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Just increment it */
|
||||
rate_ctr_add(&client->ctrg->ctr[ctr], new_val - *old_val);
|
||||
rate_ctr_add(rate_ctr_group_get_ctr(client->ctrg, ctr), new_val - *old_val);
|
||||
*old_val = new_val;
|
||||
}
|
||||
|
||||
|
@ -215,7 +215,7 @@ static void pcap_check_stats_cb(void *_client)
|
|||
if (rc != 0) {
|
||||
LOGP(DCLIENT, LOGL_ERROR, "Failed to query pcap stats: %s\n",
|
||||
pcap_geterr(client->handle));
|
||||
rate_ctr_inc(&client->ctrg->ctr[CLIENT_CTR_PERR]);
|
||||
rate_ctr_inc(rate_ctr_group_get_ctr(client->ctrg, CLIENT_CTR_PERR));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -287,7 +287,9 @@ int osmo_client_capture(struct osmo_pcap_client *client, const char *device)
|
|||
return 1;
|
||||
}
|
||||
|
||||
client->handle = pcap_open_live(client->device, 9000, 0,
|
||||
LOGP(DCLIENT, LOGL_INFO, "Opening device %s for capture with snaplen %zu\n",
|
||||
client->device, (size_t) client->snaplen);
|
||||
client->handle = pcap_open_live(client->device, client->snaplen, 0,
|
||||
1000, client->errbuf);
|
||||
if (!client->handle) {
|
||||
LOGP(DCLIENT, LOGL_ERROR,
|
||||
|
@ -303,10 +305,7 @@ int osmo_client_capture(struct osmo_pcap_client *client, const char *device)
|
|||
return 3;
|
||||
}
|
||||
|
||||
client->fd.fd = fd;
|
||||
client->fd.when = BSC_FD_READ;
|
||||
client->fd.cb = pcap_read_cb;
|
||||
client->fd.data = client;
|
||||
osmo_fd_setup(&client->fd, fd, OSMO_FD_READ, pcap_read_cb, client, 0);
|
||||
if (osmo_fd_register(&client->fd) != 0) {
|
||||
LOGP(DCLIENT, LOGL_ERROR,
|
||||
"Failed to register the fd.\n");
|
||||
|
@ -342,10 +341,20 @@ void osmo_client_conn_init(struct osmo_pcap_client_conn *conn,
|
|||
{
|
||||
conn->client = client;
|
||||
conn->tls_verify = true;
|
||||
osmo_wqueue_init(&conn->wqueue, 10);
|
||||
osmo_wqueue_init(&conn->wqueue, WQUEUE_MAXLEN_DEFAULT);
|
||||
conn->wqueue.bfd.fd = -1;
|
||||
}
|
||||
|
||||
struct osmo_pcap_client *osmo_pcap_client_alloc(void *tall_ctx)
|
||||
{
|
||||
struct osmo_pcap_client *client;
|
||||
client = talloc_zero(tall_ctx, struct osmo_pcap_client);
|
||||
if (!client)
|
||||
return NULL;
|
||||
client->fd.fd = -1;
|
||||
client->snaplen = DEFAULT_SNAPLEN;
|
||||
return client;
|
||||
}
|
||||
|
||||
void osmo_client_free(struct osmo_pcap_client_conn *conn)
|
||||
{
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <osmocom/vty/logging.h>
|
||||
#include <osmocom/vty/telnet_interface.h>
|
||||
#include <osmocom/vty/stats.h>
|
||||
#include <osmocom/vty/misc.h>
|
||||
|
||||
#include <pcap.h>
|
||||
#include <signal.h>
|
||||
|
@ -48,28 +49,26 @@
|
|||
static const char *config_file = "osmo-pcap-client.cfg";
|
||||
static int daemonize = 0;
|
||||
|
||||
void *tall_bsc_ctx;
|
||||
void *tall_cli_ctx;
|
||||
struct osmo_pcap_client *pcap_client;
|
||||
extern void *tall_msgb_ctx;
|
||||
extern void *tall_ctr_ctx;
|
||||
|
||||
|
||||
static const struct rate_ctr_desc pcap_client_ctr_desc[] = {
|
||||
[CLIENT_CTR_CONNECT] = { "server.connect", "Connects to the server" },
|
||||
[CLIENT_CTR_BYTES] = { "captured.bytes", "Captured bytes " },
|
||||
[CLIENT_CTR_PKTS] = { "captured.pkts", "Captured packets " },
|
||||
[CLIENT_CTR_2BIG] = { "bpf.too_big", "Captured data too big " },
|
||||
[CLIENT_CTR_NOMEM] = { "client.no_mem", "No memory available " },
|
||||
[CLIENT_CTR_QERR] = { "client.queue_err", "Can not queue data " },
|
||||
[CLIENT_CTR_PERR] = { "client.pcap_err", "libpcap error " },
|
||||
[CLIENT_CTR_WERR] = { "client.write_err", "Write error " },
|
||||
[CLIENT_CTR_P_RECV] = { "pcap.recv", "PCAP received packets " },
|
||||
[CLIENT_CTR_P_DROP] = { "pcap.drop", "PCAP dropped packets " },
|
||||
[CLIENT_CTR_P_IFDROP] = { "pcap.ifdrop", "iface dropped packets " },
|
||||
[CLIENT_CTR_CONNECT] = { "server:connect", "Connects to the server" },
|
||||
[CLIENT_CTR_BYTES] = { "captured:bytes", "Captured bytes " },
|
||||
[CLIENT_CTR_PKTS] = { "captured:pkts", "Captured packets " },
|
||||
[CLIENT_CTR_2BIG] = { "bpf:too_big", "Captured data too big " },
|
||||
[CLIENT_CTR_NOMEM] = { "client:no_mem", "No memory available " },
|
||||
[CLIENT_CTR_QERR] = { "client:queue_err", "Can not queue data " },
|
||||
[CLIENT_CTR_PERR] = { "client:pcap_err", "libpcap error " },
|
||||
[CLIENT_CTR_WERR] = { "client:write_err", "Write error " },
|
||||
[CLIENT_CTR_P_RECV] = { "pcap:recv", "PCAP received packets " },
|
||||
[CLIENT_CTR_P_DROP] = { "pcap:drop", "PCAP dropped packets " },
|
||||
[CLIENT_CTR_P_IFDROP] = { "pcap:ifdrop", "iface dropped packets " },
|
||||
};
|
||||
|
||||
static const struct rate_ctr_group_desc pcap_client_ctr_group_desc = {
|
||||
.group_name_prefix = "pcap.client",
|
||||
.group_name_prefix = "pcap:client",
|
||||
.group_description = "PCAP Client statistics",
|
||||
.num_ctr = ARRAY_SIZE(pcap_client_ctr_desc),
|
||||
.ctr_desc = pcap_client_ctr_desc,
|
||||
|
@ -80,7 +79,6 @@ static struct vty_app_info vty_info = {
|
|||
.name = "OsmoPCAPClient",
|
||||
.version = PACKAGE_VERSION,
|
||||
.go_parent_cb = osmopcap_go_parent,
|
||||
.is_config_node = osmopcap_is_config_node,
|
||||
};
|
||||
|
||||
static void print_usage()
|
||||
|
@ -93,25 +91,58 @@ static void print_help()
|
|||
printf(" Some useful help...\n");
|
||||
printf(" -h --help this text\n");
|
||||
printf(" -D --daemonize Fork the process into a background daemon\n");
|
||||
printf(" -V --version Print the version number\n");
|
||||
printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
|
||||
printf(" -s --disable-color\n");
|
||||
printf(" -T --timestamp. Print a timestamp in the debug output.\n");
|
||||
printf(" -e --log-level number. Set a global loglevel.\n");
|
||||
printf(" -c --config-file filename The config file to use.\n");
|
||||
|
||||
printf("\nVTY reference generation:\n");
|
||||
printf(" --vty-ref-mode MODE VTY reference generation mode (e.g. 'expert').\n");
|
||||
printf(" --vty-ref-xml Generate the VTY reference XML output and exit.\n");
|
||||
}
|
||||
|
||||
static void handle_long_options(const char *prog_name, const int long_option)
|
||||
{
|
||||
static int vty_ref_mode = VTY_REF_GEN_MODE_DEFAULT;
|
||||
switch (long_option) {
|
||||
case 1:
|
||||
vty_ref_mode = get_string_value(vty_ref_gen_mode_names, optarg);
|
||||
if (vty_ref_mode < 0) {
|
||||
fprintf(stderr, "%s: Unknown VTY reference generation "
|
||||
"mode '%s'\n", prog_name, optarg);
|
||||
exit(2);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
fprintf(stderr, "Generating the VTY reference in mode '%s' (%s)\n",
|
||||
get_value_string(vty_ref_gen_mode_names, vty_ref_mode),
|
||||
get_value_string(vty_ref_gen_mode_desc, vty_ref_mode));
|
||||
vty_dump_xml_ref_mode(stdout, (enum vty_ref_gen_mode) vty_ref_mode);
|
||||
exit(0);
|
||||
default:
|
||||
fprintf(stderr, "%s: error parsing cmdline options\n", prog_name);
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_options(int argc, char **argv)
|
||||
{
|
||||
while (1) {
|
||||
int option_index = 0, c;
|
||||
static int long_option = 0;
|
||||
static struct option long_options[] = {
|
||||
{"help", 0, 0, 'h'},
|
||||
{"daemonize", 0, 0, 'D'},
|
||||
{"debug", 1, 0, 'd'},
|
||||
{"version", 0, 0, 'V'},
|
||||
{"disable-color", 0, 0, 's'},
|
||||
{"timestamp", 0, 0, 'T'},
|
||||
{"log-level", 1, 0, 'e'},
|
||||
{"config-file", 1, 0, 'c'},
|
||||
{"vty-ref-mode", 1, &long_option, 1},
|
||||
{"vty-ref-xml", 0, &long_option, 2},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
@ -125,12 +156,19 @@ static void handle_options(int argc, char **argv)
|
|||
print_usage();
|
||||
print_help();
|
||||
exit(0);
|
||||
case 0:
|
||||
handle_long_options(argv[0], long_option);
|
||||
break;
|
||||
case 'D':
|
||||
daemonize = 1;
|
||||
break;
|
||||
case 'd':
|
||||
log_parse_category_mask(osmo_stderr_target, optarg);
|
||||
break;
|
||||
case 'V':
|
||||
print_version(1);
|
||||
exit(0);
|
||||
break;
|
||||
case 's':
|
||||
log_set_use_color(osmo_stderr_target, 0);
|
||||
break;
|
||||
|
@ -150,20 +188,29 @@ static void handle_options(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
static void signal_handler(int signal)
|
||||
static void signal_handler(int signum)
|
||||
{
|
||||
fprintf(stdout, "signal %u received\n", signal);
|
||||
fprintf(stdout, "signal %u received\n", signum);
|
||||
|
||||
switch (signal) {
|
||||
switch (signum) {
|
||||
case SIGINT:
|
||||
exit(0);
|
||||
break;
|
||||
case SIGABRT:
|
||||
/* in case of abort, we want to obtain a talloc report
|
||||
* and then return to the caller, who will abort the process */
|
||||
/* in case of abort, we want to obtain a talloc report and
|
||||
* then run default SIGABRT handler, who will generate coredump
|
||||
* and abort the process. abort() should do this for us after we
|
||||
* return, but program wouldn't exit if an external SIGABRT is
|
||||
* received.
|
||||
*/
|
||||
talloc_report(tall_vty_ctx, stderr);
|
||||
talloc_report_full(tall_cli_ctx, stderr);
|
||||
signal(SIGABRT, SIG_DFL);
|
||||
raise(SIGABRT);
|
||||
break;
|
||||
case SIGUSR1:
|
||||
talloc_report(tall_vty_ctx, stderr);
|
||||
talloc_report_full(tall_bsc_ctx, stderr);
|
||||
talloc_report_full(tall_cli_ctx, stderr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -172,9 +219,8 @@ static void signal_handler(int signal)
|
|||
|
||||
static void talloc_init_ctx()
|
||||
{
|
||||
tall_bsc_ctx = talloc_named_const(NULL, 0, "nat");
|
||||
tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 0, "msgb");
|
||||
tall_ctr_ctx = talloc_named_const(tall_bsc_ctx, 0, "counter");
|
||||
tall_cli_ctx = talloc_named_const(NULL, 0, "client");
|
||||
msgb_talloc_ctx_init(tall_cli_ctx, 0);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
@ -182,18 +228,21 @@ int main(int argc, char **argv)
|
|||
int rc;
|
||||
|
||||
talloc_init_ctx();
|
||||
osmo_init_logging(&log_info);
|
||||
osmo_init_logging2(tall_cli_ctx, &log_info);
|
||||
|
||||
vty_info.copyright = osmopcap_copyright;
|
||||
vty_info.tall_ctx = tall_cli_ctx;
|
||||
vty_init(&vty_info);
|
||||
logging_vty_add_cmds(&log_info);
|
||||
osmo_stats_vty_add_cmds(&log_info);
|
||||
logging_vty_add_cmds();
|
||||
osmo_stats_vty_add_cmds();
|
||||
osmo_talloc_vty_add_cmds();
|
||||
vty_client_init();
|
||||
|
||||
/* parse options */
|
||||
handle_options(argc, argv);
|
||||
|
||||
rate_ctr_init(tall_bsc_ctx);
|
||||
osmo_stats_init(tall_bsc_ctx);
|
||||
rate_ctr_init(tall_cli_ctx);
|
||||
osmo_stats_init(tall_cli_ctx);
|
||||
|
||||
/* seed the PRNG */
|
||||
srand(time(NULL));
|
||||
|
@ -206,19 +255,11 @@ int main(int argc, char **argv)
|
|||
|
||||
osmo_tls_init();
|
||||
|
||||
rc = telnet_init(tall_bsc_ctx, NULL, 4240);
|
||||
if (rc < 0) {
|
||||
LOGP(DCLIENT, LOGL_ERROR, "Failed to bind telnet interface\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pcap_client = talloc_zero(tall_bsc_ctx, struct osmo_pcap_client);
|
||||
pcap_client = osmo_pcap_client_alloc(tall_cli_ctx);
|
||||
if (!pcap_client) {
|
||||
LOGP(DCLIENT, LOGL_ERROR, "Failed to allocate osmo_pcap_client.\n");
|
||||
exit(1);
|
||||
}
|
||||
pcap_client->fd.fd = -1;
|
||||
vty_client_init(pcap_client);
|
||||
|
||||
/* initialize the queue */
|
||||
INIT_LLIST_HEAD(&pcap_client->conns);
|
||||
|
@ -238,6 +279,13 @@ int main(int argc, char **argv)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
rc = telnet_init_default(tall_cli_ctx, NULL, OSMO_VTY_PORT_PCAP_CLIENT);
|
||||
if (rc < 0) {
|
||||
LOGP(DCLIENT, LOGL_ERROR, "Failed to bind telnet interface\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/* attempt to connect to the remote */
|
||||
if (pcap_client->conn.srv_ip && pcap_client->conn.srv_port > 0)
|
||||
osmo_client_connect(&pcap_client->conn);
|
||||
|
|
|
@ -31,10 +31,13 @@
|
|||
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
@ -55,9 +58,10 @@ static void lost_connection(struct osmo_pcap_client_conn *conn)
|
|||
|
||||
static void write_data(struct osmo_pcap_client_conn *conn, struct msgb *msg)
|
||||
{
|
||||
if (osmo_wqueue_enqueue(&conn->wqueue, msg) != 0) {
|
||||
LOGP(DCLIENT, LOGL_ERROR, "Failed to enqueue conn=%s\n", conn->name);
|
||||
rate_ctr_inc(&conn->client->ctrg->ctr[CLIENT_CTR_QERR]);
|
||||
if (osmo_wqueue_enqueue_quiet(&conn->wqueue, msg) != 0) {
|
||||
LOGP(DCLIENT, LOGL_ERROR, "Failed to enqueue conn=%s (capacity: %u/%u)\n",
|
||||
conn->name, conn->wqueue.current_length, conn->wqueue.max_length);
|
||||
rate_ctr_inc(rate_ctr_group_get_ctr(conn->client->ctrg, CLIENT_CTR_QERR));
|
||||
msgb_free(msg);
|
||||
return;
|
||||
}
|
||||
|
@ -89,7 +93,7 @@ static int write_cb(struct osmo_fd *fd, struct msgb *msg)
|
|||
struct osmo_pcap_client_conn *conn = fd->data;
|
||||
LOGP(DCLIENT, LOGL_ERROR, "Lost connection on write to %s %s:%d.\n",
|
||||
conn->name, conn->srv_ip, conn->srv_port);
|
||||
rate_ctr_inc(&conn->client->ctrg->ctr[CLIENT_CTR_WERR]);
|
||||
rate_ctr_inc(rate_ctr_group_get_ctr(conn->client->ctrg, CLIENT_CTR_WERR));
|
||||
lost_connection(conn);
|
||||
return -1;
|
||||
}
|
||||
|
@ -117,7 +121,7 @@ static void tls_error_cb(struct osmo_tls_session *session)
|
|||
int conn_cb(struct osmo_fd *fd, unsigned int what)
|
||||
{
|
||||
/* finally the socket is connected... continue */
|
||||
if (what & BSC_FD_WRITE) {
|
||||
if (what & OSMO_FD_WRITE) {
|
||||
struct osmo_pcap_client_conn *conn = fd->data;
|
||||
/*
|
||||
* The write queue needs to work differently for GNUtls. Before we can
|
||||
|
@ -141,48 +145,81 @@ int conn_cb(struct osmo_fd *fd, unsigned int what)
|
|||
}
|
||||
}
|
||||
|
||||
if (what & BSC_FD_READ)
|
||||
if (what & OSMO_FD_READ)
|
||||
read_cb(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_iphdr_offset(int dlt)
|
||||
{
|
||||
switch (dlt) {
|
||||
case DLT_EN10MB:
|
||||
return 14;
|
||||
case DLT_LINUX_SLL:
|
||||
return 16;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void osmo_client_send_data(struct osmo_pcap_client_conn *conn,
|
||||
struct pcap_pkthdr *in_hdr, const uint8_t *data)
|
||||
{
|
||||
struct osmo_pcap_data *om_hdr;
|
||||
struct osmo_pcap_pkthdr *hdr;
|
||||
struct msgb *msg;
|
||||
int offset, ip_len;
|
||||
|
||||
if (in_hdr->caplen > 9000) {
|
||||
if (in_hdr->len > in_hdr->caplen) {
|
||||
LOGP(DCLIENT, LOGL_ERROR,
|
||||
"Capture len too big %zu\n", in_hdr->caplen);
|
||||
rate_ctr_inc(&conn->client->ctrg->ctr[CLIENT_CTR_2BIG]);
|
||||
return;
|
||||
"Recording truncated packet, len %zu > snaplen %zu\n",
|
||||
(size_t) in_hdr->len, (size_t) in_hdr->caplen);
|
||||
rate_ctr_inc(rate_ctr_group_get_ctr(conn->client->ctrg, CLIENT_CTR_2BIG));
|
||||
}
|
||||
|
||||
msg = msgb_alloc(9000 + sizeof(*om_hdr) + sizeof(*hdr), "data-data");
|
||||
msg = msgb_alloc(in_hdr->caplen + sizeof(*om_hdr) + sizeof(*hdr), "data-data");
|
||||
if (!msg) {
|
||||
LOGP(DCLIENT, LOGL_ERROR, "Failed to allocate.\n");
|
||||
rate_ctr_inc(&conn->client->ctrg->ctr[CLIENT_CTR_NOMEM]);
|
||||
rate_ctr_inc(rate_ctr_group_get_ctr(conn->client->ctrg, CLIENT_CTR_NOMEM));
|
||||
return;
|
||||
}
|
||||
|
||||
om_hdr = (struct osmo_pcap_data *) msgb_put(msg, sizeof(*om_hdr));
|
||||
om_hdr->type = PKT_LINK_DATA;
|
||||
switch (conn->protocol) {
|
||||
case PROTOCOL_OSMOPCAP:
|
||||
om_hdr = (struct osmo_pcap_data *) msgb_put(msg, sizeof(*om_hdr));
|
||||
om_hdr->type = PKT_LINK_DATA;
|
||||
|
||||
msg->l2h = msgb_put(msg, sizeof(*hdr));
|
||||
hdr = (struct osmo_pcap_pkthdr *) msg->l2h;
|
||||
hdr->ts_sec = in_hdr->ts.tv_sec;
|
||||
hdr->ts_usec = in_hdr->ts.tv_usec;
|
||||
hdr->caplen = in_hdr->caplen;
|
||||
hdr->len = in_hdr->len;
|
||||
msg->l2h = msgb_put(msg, sizeof(*hdr));
|
||||
hdr = (struct osmo_pcap_pkthdr *) msg->l2h;
|
||||
hdr->ts_sec = in_hdr->ts.tv_sec;
|
||||
hdr->ts_usec = in_hdr->ts.tv_usec;
|
||||
hdr->caplen = in_hdr->caplen;
|
||||
hdr->len = in_hdr->len;
|
||||
|
||||
msg->l3h = msgb_put(msg, in_hdr->caplen);
|
||||
memcpy(msg->l3h, data, in_hdr->caplen);
|
||||
msg->l3h = msgb_put(msg, in_hdr->caplen);
|
||||
memcpy(msg->l3h, data, in_hdr->caplen);
|
||||
|
||||
om_hdr->len = htons(msgb_l2len(msg));
|
||||
rate_ctr_add(&conn->client->ctrg->ctr[CLIENT_CTR_BYTES], hdr->caplen);
|
||||
rate_ctr_inc(&conn->client->ctrg->ctr[CLIENT_CTR_PKTS]);
|
||||
om_hdr->len = htons(msgb_l2len(msg));
|
||||
rate_ctr_add(rate_ctr_group_get_ctr(conn->client->ctrg, CLIENT_CTR_BYTES), hdr->caplen);
|
||||
rate_ctr_inc(rate_ctr_group_get_ctr(conn->client->ctrg, CLIENT_CTR_PKTS));
|
||||
break;
|
||||
case PROTOCOL_IPIP:
|
||||
offset = get_iphdr_offset(pcap_datalink(conn->client->handle));
|
||||
if (offset < 0) {
|
||||
msgb_free(msg);
|
||||
return;
|
||||
}
|
||||
ip_len = in_hdr->caplen - offset;
|
||||
if (ip_len < 0) {
|
||||
msgb_free(msg);
|
||||
return;
|
||||
}
|
||||
msg->l2h = msgb_put(msg, ip_len);
|
||||
memcpy(msg->l2h, data+offset, ip_len);
|
||||
break;
|
||||
default:
|
||||
OSMO_ASSERT(0);
|
||||
}
|
||||
|
||||
write_data(conn, msg);
|
||||
}
|
||||
|
@ -193,13 +230,17 @@ void osmo_client_send_link(struct osmo_pcap_client_conn *conn)
|
|||
struct osmo_pcap_data *om_hdr;
|
||||
struct msgb *msg;
|
||||
|
||||
/* IPIP encapsulation has no linktype header */
|
||||
if (conn->protocol == PROTOCOL_IPIP)
|
||||
return;
|
||||
|
||||
if (!conn->client->handle) {
|
||||
LOGP(DCLIENT, LOGL_ERROR,
|
||||
"No pcap_handle not sending link info to conn=%s\n", conn->name);
|
||||
return;
|
||||
}
|
||||
|
||||
msg = msgb_alloc(9000 + sizeof(*om_hdr) + sizeof(*hdr), "link-data");
|
||||
msg = msgb_alloc(sizeof(*om_hdr) + sizeof(*hdr), "link-data");
|
||||
if (!msg) {
|
||||
LOGP(DCLIENT, LOGL_ERROR, "Failed to allocate data.\n");
|
||||
return;
|
||||
|
@ -216,7 +257,7 @@ void osmo_client_send_link(struct osmo_pcap_client_conn *conn)
|
|||
hdr->version_minor = 4;
|
||||
hdr->thiszone = 0;
|
||||
hdr->sigfigs = 0;
|
||||
hdr->snaplen = UINT_MAX;
|
||||
hdr->snaplen = conn->client->snaplen;
|
||||
hdr->linktype = pcap_datalink(conn->client->handle);
|
||||
|
||||
write_data(conn, msg);
|
||||
|
@ -224,38 +265,48 @@ void osmo_client_send_link(struct osmo_pcap_client_conn *conn)
|
|||
|
||||
void osmo_client_connect(struct osmo_pcap_client_conn *conn)
|
||||
{
|
||||
int fd;
|
||||
int rc;
|
||||
uint16_t srv_port;
|
||||
int sock_type, sock_proto;
|
||||
unsigned int when;
|
||||
|
||||
osmo_client_disconnect(conn);
|
||||
|
||||
conn->wqueue.read_cb = read_cb;
|
||||
conn->wqueue.write_cb = write_cb;
|
||||
conn->wqueue.bfd.when = BSC_FD_READ;
|
||||
osmo_wqueue_clear(&conn->wqueue);
|
||||
|
||||
fd = osmo_sock_init(AF_INET, SOCK_STREAM, IPPROTO_TCP,
|
||||
conn->srv_ip, conn->srv_port,
|
||||
OSMO_SOCK_F_CONNECT | OSMO_SOCK_F_NONBLOCK);
|
||||
if (fd < 0) {
|
||||
switch (conn->protocol) {
|
||||
case PROTOCOL_OSMOPCAP:
|
||||
srv_port = conn->srv_port;
|
||||
sock_type = SOCK_STREAM;
|
||||
sock_proto = IPPROTO_TCP;
|
||||
when = OSMO_FD_READ | OSMO_FD_WRITE;
|
||||
break;
|
||||
case PROTOCOL_IPIP:
|
||||
srv_port = 0;
|
||||
sock_type = SOCK_RAW;
|
||||
sock_proto = IPPROTO_IPIP;
|
||||
when = OSMO_FD_WRITE;
|
||||
break;
|
||||
default:
|
||||
OSMO_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
rc = osmo_sock_init2(AF_INET, sock_type, sock_proto, conn->source_ip, 0, conn->srv_ip, srv_port,
|
||||
OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT | OSMO_SOCK_F_NONBLOCK);
|
||||
if (rc < 0) {
|
||||
LOGP(DCLIENT, LOGL_ERROR,
|
||||
"Failed to connect conn=%s to %s:%d\n",
|
||||
conn->name, conn->srv_ip, conn->srv_port);
|
||||
lost_connection(conn);
|
||||
return;
|
||||
}
|
||||
osmo_fd_setup(&conn->wqueue.bfd, rc, when, conn_cb, conn, 0);
|
||||
osmo_fd_register(&conn->wqueue.bfd);
|
||||
|
||||
conn->wqueue.bfd.fd = fd;
|
||||
if (osmo_fd_register(&conn->wqueue.bfd) != 0) {
|
||||
LOGP(DCLIENT, LOGL_ERROR,
|
||||
"Failed to register to BFD conn=%s\n", conn->name);
|
||||
lost_connection(conn);
|
||||
return;
|
||||
}
|
||||
|
||||
rate_ctr_inc(&conn->client->ctrg->ctr[CLIENT_CTR_CONNECT]);
|
||||
conn->wqueue.bfd.cb = conn_cb;
|
||||
conn->wqueue.bfd.data = conn;
|
||||
conn->wqueue.bfd.when = BSC_FD_READ | BSC_FD_WRITE;
|
||||
rate_ctr_inc(rate_ctr_group_get_ctr(conn->client->ctrg, CLIENT_CTR_CONNECT));
|
||||
}
|
||||
|
||||
void osmo_client_reconnect(struct osmo_pcap_client_conn *conn)
|
||||
|
|
|
@ -31,6 +31,12 @@
|
|||
#define PCAP_STRING "PCAP related functions\n"
|
||||
#define SERVER_STRING "Server string\n"
|
||||
|
||||
static const struct value_string osmopcap_protocol_names[] = {
|
||||
{ PROTOCOL_OSMOPCAP, "osmo-pcap" },
|
||||
{ PROTOCOL_IPIP, "ipip" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static struct osmo_pcap_client_conn *get_conn(struct vty *vty)
|
||||
{
|
||||
if (vty->node == CLIENT_NODE)
|
||||
|
@ -40,13 +46,13 @@ static struct osmo_pcap_client_conn *get_conn(struct vty *vty)
|
|||
|
||||
static struct cmd_node client_node = {
|
||||
CLIENT_NODE,
|
||||
"%s(client)#",
|
||||
"%s(client)# ",
|
||||
1,
|
||||
};
|
||||
|
||||
static struct cmd_node server_node = {
|
||||
CLIENT_SERVER_NODE,
|
||||
"%s(server)#",
|
||||
"%s(server)# ",
|
||||
1,
|
||||
};
|
||||
|
||||
|
@ -91,6 +97,17 @@ static void write_client_conn_data(
|
|||
if (conn->srv_port > 0)
|
||||
vty_out(vty, "%s server port %d%s", indent,
|
||||
conn->srv_port, VTY_NEWLINE);
|
||||
if (conn->source_ip)
|
||||
vty_out(vty, "%s source ip %s%s", indent,
|
||||
conn->source_ip, VTY_NEWLINE);
|
||||
|
||||
if (conn->protocol != PROTOCOL_OSMOPCAP)
|
||||
vty_out(vty, "%s protocol %s%s", indent,
|
||||
get_value_string(osmopcap_protocol_names, conn->protocol), VTY_NEWLINE);
|
||||
|
||||
if (conn->wqueue.max_length != WQUEUE_MAXLEN_DEFAULT)
|
||||
vty_out(vty, "%s wqueue max-length %u%s", indent,
|
||||
conn->wqueue.max_length, VTY_NEWLINE);
|
||||
}
|
||||
|
||||
static int config_write_server(struct vty *vty)
|
||||
|
@ -112,7 +129,9 @@ static int config_write_client(struct vty *vty)
|
|||
if (pcap_client->device)
|
||||
vty_out(vty, " pcap device %s%s",
|
||||
pcap_client->device, VTY_NEWLINE);
|
||||
|
||||
if (pcap_client->snaplen != DEFAULT_SNAPLEN)
|
||||
vty_out(vty, " pcap snaplen %d%s",
|
||||
pcap_client->snaplen, VTY_NEWLINE);
|
||||
if (pcap_client->filter_string)
|
||||
vty_out(vty, " pcap filter %s%s",
|
||||
pcap_client->filter_string, VTY_NEWLINE);
|
||||
|
@ -135,6 +154,19 @@ DEFUN(cfg_client_device,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_client_snaplen,
|
||||
cfg_client_snaplen_cmd,
|
||||
"pcap snaplen <1-262144>", /* MAXIMUM_SNAPLEN */
|
||||
PCAP_STRING "snapshot length\n" "Bytes\n")
|
||||
{
|
||||
if (pcap_client->handle) {
|
||||
vty_out(vty, "'pcap snaplen' must be set before 'pcap device' to take effect!%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
pcap_client->snaplen = atoi(argv[0]);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_client_add_gprs,
|
||||
cfg_client_add_gprs_cmd,
|
||||
"pcap add-filter gprs",
|
||||
|
@ -393,6 +425,19 @@ DEFUN(cfg_server_port,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_source_ip,
|
||||
cfg_source_ip_cmd,
|
||||
"source ip A.B.C.D",
|
||||
SERVER_STRING "Source IP Address\n" "IP\n")
|
||||
{
|
||||
struct osmo_pcap_client_conn *conn = get_conn(vty);
|
||||
|
||||
talloc_free(conn->source_ip);
|
||||
conn->source_ip = talloc_strdup(pcap_client, argv[0]);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
DEFUN(cfg_pcap_store,
|
||||
cfg_pcap_store_cmd,
|
||||
"pcap-store-connection .NAME",
|
||||
|
@ -450,21 +495,63 @@ DEFUN(cfg_client_disconnect,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
int vty_client_init(struct osmo_pcap_client *pcap)
|
||||
#define PROTOCOL_STR "protocol (osmo-pcap|ipip)"
|
||||
#define PROTOCOL_HELP "Configure the Protocol used for transfer\n" \
|
||||
"OsmoPCAP protocol (over TCP)\n" \
|
||||
"IPIP encapsulation (for real-time streaming to wireshark)\n"
|
||||
|
||||
DEFUN(cfg_protocol,
|
||||
cfg_protocol_cmd,
|
||||
PROTOCOL_STR,
|
||||
PROTOCOL_HELP)
|
||||
{
|
||||
struct osmo_pcap_client_conn *conn = get_conn(vty);
|
||||
|
||||
conn->protocol = get_string_value(osmopcap_protocol_names, argv[0]);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_client_protocol,
|
||||
cfg_client_protocol_cmd,
|
||||
PROTOCOL_STR,
|
||||
PROTOCOL_HELP)
|
||||
{
|
||||
struct osmo_pcap_client_conn *conn = get_conn(vty);
|
||||
|
||||
conn->protocol = get_string_value(osmopcap_protocol_names, argv[0]);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_wqueue_maxlength,
|
||||
cfg_wqueue_maxlength_cmd,
|
||||
"wqueue max-length <1-4294967295>",
|
||||
"Configure the write-queue used for transfer\n"
|
||||
"Configure the maximum amount of packets to be stored in the write-queue\n"
|
||||
"Maximum amount of packets before dropping starts\n")
|
||||
{
|
||||
struct osmo_pcap_client_conn *conn = get_conn(vty);
|
||||
|
||||
conn->wqueue.max_length = atoi(argv[0]);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
int vty_client_init(void)
|
||||
{
|
||||
install_element(CONFIG_NODE, &cfg_client_cmd);
|
||||
install_node(&client_node, config_write_client);
|
||||
install_default(CLIENT_NODE);
|
||||
|
||||
install_node(&server_node, config_write_server);
|
||||
install_default(CLIENT_SERVER_NODE);
|
||||
|
||||
install_element(CLIENT_NODE, &cfg_client_device_cmd);
|
||||
install_element(CLIENT_NODE, &cfg_client_snaplen_cmd);
|
||||
install_element(CLIENT_NODE, &cfg_client_filter_cmd);
|
||||
install_element(CLIENT_NODE, &cfg_client_loop_cmd);
|
||||
|
||||
install_element(CLIENT_NODE, &cfg_server_ip_cmd);
|
||||
install_element(CLIENT_NODE, &cfg_server_port_cmd);
|
||||
install_element(CLIENT_NODE, &cfg_source_ip_cmd);
|
||||
install_element(CLIENT_NODE, &cfg_protocol_cmd);
|
||||
install_element(CLIENT_NODE, &cfg_wqueue_maxlength_cmd);
|
||||
|
||||
install_element(CLIENT_NODE, &cfg_enable_tls_cmd);
|
||||
install_element(CLIENT_NODE, &cfg_disable_tls_cmd);
|
||||
|
@ -491,6 +578,7 @@ int vty_client_init(struct osmo_pcap_client *pcap)
|
|||
install_element(CLIENT_NODE, &cfg_no_pcap_store_cmd);
|
||||
install_element(CLIENT_SERVER_NODE, &cfg_server_ip_cmd);
|
||||
install_element(CLIENT_SERVER_NODE, &cfg_server_port_cmd);
|
||||
install_element(CLIENT_SERVER_NODE, &cfg_source_ip_cmd);
|
||||
install_element(CLIENT_SERVER_NODE, &cfg_enable_tls_cmd);
|
||||
install_element(CLIENT_SERVER_NODE, &cfg_disable_tls_cmd);
|
||||
install_element(CLIENT_SERVER_NODE, &cfg_tls_hostname_cmd);
|
||||
|
@ -508,6 +596,7 @@ int vty_client_init(struct osmo_pcap_client *pcap)
|
|||
install_element(CLIENT_SERVER_NODE, &cfg_tls_log_level_cmd);
|
||||
install_element(CLIENT_SERVER_NODE, &cfg_client_connect_cmd);
|
||||
install_element(CLIENT_SERVER_NODE, &cfg_client_disconnect_cmd);
|
||||
install_element(CLIENT_SERVER_NODE, &cfg_client_protocol_cmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -62,8 +62,8 @@ const struct log_info log_info = {
|
|||
.num_cat = ARRAY_SIZE(default_categories),
|
||||
};
|
||||
|
||||
const char *osmopcap_copyright =
|
||||
"Copyright (C) 2011 Holger Freyther\r\n"
|
||||
const char *osmopcap_copyright =
|
||||
"Copyright (C) 2011-2017 Holger Freyther and contributors\r\n"
|
||||
"License AGPLv3+: GNU AGPL version 3 or later <http://gnu.org/licenses/agpl-3.0.html>\r\n"
|
||||
"This is free software: you are free to change and redistribute it.\r\n"
|
||||
"There is NO WARRANTY, to the extent permitted by law.\r\n";
|
||||
|
@ -86,15 +86,5 @@ int osmopcap_go_parent(struct vty *vty)
|
|||
break;
|
||||
}
|
||||
|
||||
return vty->node;
|
||||
}
|
||||
|
||||
int osmopcap_is_config_node(struct vty *vty, int node)
|
||||
{
|
||||
switch (node) {
|
||||
case CONFIG_NODE:
|
||||
return 0;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
return vty->node;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <osmocom/vty/logging.h>
|
||||
#include <osmocom/vty/telnet_interface.h>
|
||||
#include <osmocom/vty/stats.h>
|
||||
#include <osmocom/vty/misc.h>
|
||||
|
||||
#include <pcap.h>
|
||||
#include <signal.h>
|
||||
|
@ -49,25 +50,23 @@
|
|||
static const char *config_file = "osmo-pcap-server.cfg";
|
||||
static int daemonize = 0;
|
||||
|
||||
void *tall_bsc_ctx;
|
||||
void *tall_srv_ctx;
|
||||
struct osmo_pcap_server *pcap_server;
|
||||
extern void *tall_msgb_ctx;
|
||||
extern void *tall_ctr_ctx;
|
||||
|
||||
|
||||
static const struct rate_ctr_desc pcap_peer_ctr_desc[] = {
|
||||
[PEER_CTR_CONNECT] = { "peer.connect", "Connect of a peer " },
|
||||
[PEER_CTR_BYTES] = { "peer.bytes", "Received bytes " },
|
||||
[PEER_CTR_PKTS] = { "peer.pkts", "Received packets " },
|
||||
[PEER_CTR_PROTATE] = { "peer.file_rotated","Capture file rotated" },
|
||||
[PEER_CTR_CONNECT] = { "peer:connect", "Connect of a peer " },
|
||||
[PEER_CTR_BYTES] = { "peer:bytes", "Received bytes " },
|
||||
[PEER_CTR_PKTS] = { "peer:pkts", "Received packets " },
|
||||
[PEER_CTR_PROTATE] = { "peer:file_rotated","Capture file rotated" },
|
||||
};
|
||||
|
||||
static const struct rate_ctr_desc pcap_server_ctr_desc[] = {
|
||||
[SERVER_CTR_CONNECT] = { "server.connect", "Connect of a peer " },
|
||||
[SERVER_CTR_BYTES] = { "server.bytes", "Received bytes " },
|
||||
[SERVER_CTR_PKTS] = { "server.pkts", "Received packets " },
|
||||
[SERVER_CTR_PROTATE] = { "server.file_rotated", "Capture file rotated" },
|
||||
[SERVER_CTR_NOCLIENT] = { "server.no_client", "Unknown connected " },
|
||||
[SERVER_CTR_CONNECT] = { "server:connect", "Connect of a peer " },
|
||||
[SERVER_CTR_BYTES] = { "server:bytes", "Received bytes " },
|
||||
[SERVER_CTR_PKTS] = { "server:pkts", "Received packets " },
|
||||
[SERVER_CTR_PROTATE] = { "server:file_rotated", "Capture file rotated" },
|
||||
[SERVER_CTR_NOCLIENT] = { "server:no_client", "Unknown connected " },
|
||||
};
|
||||
|
||||
const struct rate_ctr_group_desc pcap_peer_group_desc = {
|
||||
|
@ -79,7 +78,7 @@ const struct rate_ctr_group_desc pcap_peer_group_desc = {
|
|||
};
|
||||
|
||||
static const struct rate_ctr_group_desc pcap_server_group_desc = {
|
||||
.group_name_prefix = "pcap.server",
|
||||
.group_name_prefix = "pcap:server",
|
||||
.group_description = "PCAP Server global statistics",
|
||||
.num_ctr = ARRAY_SIZE(pcap_server_ctr_desc),
|
||||
.ctr_desc = pcap_server_ctr_desc,
|
||||
|
@ -90,7 +89,6 @@ static struct vty_app_info vty_info = {
|
|||
.name = "OsmoPCAPServer",
|
||||
.version = PACKAGE_VERSION,
|
||||
.go_parent_cb = osmopcap_go_parent,
|
||||
.is_config_node = osmopcap_is_config_node,
|
||||
};
|
||||
|
||||
static void print_usage()
|
||||
|
@ -103,25 +101,58 @@ static void print_help()
|
|||
printf(" Some useful help...\n");
|
||||
printf(" -h --help this text\n");
|
||||
printf(" -D --daemonize Fork the process into a background daemon\n");
|
||||
printf(" -V --version Print the version number\n");
|
||||
printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
|
||||
printf(" -s --disable-color\n");
|
||||
printf(" -T --timestamp. Print a timestamp in the debug output.\n");
|
||||
printf(" -e --log-level number. Set a global loglevel.\n");
|
||||
printf(" -c --config-file filename The config file to use.\n");
|
||||
|
||||
printf("\nVTY reference generation:\n");
|
||||
printf(" --vty-ref-mode MODE VTY reference generation mode (e.g. 'expert').\n");
|
||||
printf(" --vty-ref-xml Generate the VTY reference XML output and exit.\n");
|
||||
}
|
||||
|
||||
static void handle_long_options(const char *prog_name, const int long_option)
|
||||
{
|
||||
static int vty_ref_mode = VTY_REF_GEN_MODE_DEFAULT;
|
||||
switch (long_option) {
|
||||
case 1:
|
||||
vty_ref_mode = get_string_value(vty_ref_gen_mode_names, optarg);
|
||||
if (vty_ref_mode < 0) {
|
||||
fprintf(stderr, "%s: Unknown VTY reference generation "
|
||||
"mode '%s'\n", prog_name, optarg);
|
||||
exit(2);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
fprintf(stderr, "Generating the VTY reference in mode '%s' (%s)\n",
|
||||
get_value_string(vty_ref_gen_mode_names, vty_ref_mode),
|
||||
get_value_string(vty_ref_gen_mode_desc, vty_ref_mode));
|
||||
vty_dump_xml_ref_mode(stdout, (enum vty_ref_gen_mode) vty_ref_mode);
|
||||
exit(0);
|
||||
default:
|
||||
fprintf(stderr, "%s: error parsing cmdline options\n", prog_name);
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_options(int argc, char **argv)
|
||||
{
|
||||
while (1) {
|
||||
int option_index = 0, c;
|
||||
static int long_option = 0;
|
||||
static struct option long_options[] = {
|
||||
{"help", 0, 0, 'h'},
|
||||
{"daemonize", 0, 0, 'D'},
|
||||
{"debug", 1, 0, 'd'},
|
||||
{"version", 0, 0, 'V'},
|
||||
{"disable-color", 0, 0, 's'},
|
||||
{"timestamp", 0, 0, 'T'},
|
||||
{"log-level", 1, 0, 'e'},
|
||||
{"config-file", 1, 0, 'c'},
|
||||
{"vty-ref-mode", 1, &long_option, 1},
|
||||
{"vty-ref-xml", 0, &long_option, 2},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
@ -135,12 +166,18 @@ static void handle_options(int argc, char **argv)
|
|||
print_usage();
|
||||
print_help();
|
||||
exit(0);
|
||||
case 0:
|
||||
handle_long_options(argv[0], long_option);
|
||||
break;
|
||||
case 'D':
|
||||
daemonize = 1;
|
||||
break;
|
||||
case 'd':
|
||||
log_parse_category_mask(osmo_stderr_target, optarg);
|
||||
break;
|
||||
case 'V':
|
||||
print_version(1);
|
||||
exit(0);
|
||||
case 's':
|
||||
log_set_use_color(osmo_stderr_target, 0);
|
||||
break;
|
||||
|
@ -160,20 +197,29 @@ static void handle_options(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
static void signal_handler(int signal)
|
||||
static void signal_handler(int signum)
|
||||
{
|
||||
fprintf(stdout, "signal %u received\n", signal);
|
||||
fprintf(stdout, "signal %u received\n", signum);
|
||||
|
||||
switch (signal) {
|
||||
switch (signum) {
|
||||
case SIGINT:
|
||||
exit(0);
|
||||
break;
|
||||
case SIGABRT:
|
||||
/* in case of abort, we want to obtain a talloc report
|
||||
* and then return to the caller, who will abort the process */
|
||||
/* in case of abort, we want to obtain a talloc report and
|
||||
* then run default SIGABRT handler, who will generate coredump
|
||||
* and abort the process. abort() should do this for us after we
|
||||
* return, but program wouldn't exit if an external SIGABRT is
|
||||
* received.
|
||||
*/
|
||||
talloc_report(tall_vty_ctx, stderr);
|
||||
talloc_report_full(tall_srv_ctx, stderr);
|
||||
signal(SIGABRT, SIG_DFL);
|
||||
raise(SIGABRT);
|
||||
break;
|
||||
case SIGUSR1:
|
||||
talloc_report(tall_vty_ctx, stderr);
|
||||
talloc_report_full(tall_bsc_ctx, stderr);
|
||||
talloc_report_full(tall_srv_ctx, stderr);
|
||||
break;
|
||||
case SIGHUP:
|
||||
osmo_pcap_server_reopen(pcap_server);
|
||||
|
@ -185,9 +231,8 @@ static void signal_handler(int signal)
|
|||
|
||||
static void talloc_init_ctx()
|
||||
{
|
||||
tall_bsc_ctx = talloc_named_const(NULL, 0, "server");
|
||||
tall_msgb_ctx = talloc_named_const(tall_bsc_ctx, 0, "msgb");
|
||||
tall_ctr_ctx = talloc_named_const(tall_bsc_ctx, 0, "counter");
|
||||
tall_srv_ctx = talloc_named_const(NULL, 0, "server");
|
||||
msgb_talloc_ctx_init(tall_srv_ctx, 0);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
@ -195,18 +240,21 @@ int main(int argc, char **argv)
|
|||
int rc;
|
||||
|
||||
talloc_init_ctx();
|
||||
osmo_init_logging(&log_info);
|
||||
osmo_init_logging2(tall_srv_ctx, &log_info);
|
||||
|
||||
vty_info.copyright = osmopcap_copyright;
|
||||
vty_info.tall_ctx = tall_srv_ctx;
|
||||
vty_init(&vty_info);
|
||||
logging_vty_add_cmds(&log_info);
|
||||
osmo_stats_vty_add_cmds(&log_info);
|
||||
logging_vty_add_cmds();
|
||||
osmo_stats_vty_add_cmds();
|
||||
osmo_talloc_vty_add_cmds();
|
||||
vty_server_init();
|
||||
|
||||
/* parse options */
|
||||
handle_options(argc, argv);
|
||||
|
||||
rate_ctr_init(tall_bsc_ctx);
|
||||
osmo_stats_init(tall_bsc_ctx);
|
||||
rate_ctr_init(tall_srv_ctx);
|
||||
osmo_stats_init(tall_srv_ctx);
|
||||
|
||||
/* seed the PRNG */
|
||||
srand(time(NULL));
|
||||
|
@ -219,13 +267,7 @@ int main(int argc, char **argv)
|
|||
|
||||
osmo_tls_init();
|
||||
|
||||
rc = telnet_init(tall_bsc_ctx, NULL, 4241);
|
||||
if (rc < 0) {
|
||||
LOGP(DCLIENT, LOGL_ERROR, "Failed to bind telnet interface\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pcap_server = talloc_zero(tall_bsc_ctx, struct osmo_pcap_server);
|
||||
pcap_server = talloc_zero(tall_srv_ctx, struct osmo_pcap_server);
|
||||
if (!pcap_server) {
|
||||
LOGP(DSERVER, LOGL_ERROR, "Failed to allocate osmo_pcap_server.\n");
|
||||
exit(1);
|
||||
|
@ -238,8 +280,9 @@ int main(int argc, char **argv)
|
|||
|
||||
INIT_LLIST_HEAD(&pcap_server->conn);
|
||||
pcap_server->base_path = talloc_strdup(pcap_server, "./");
|
||||
pcap_server->permission_mask = 0440;
|
||||
pcap_server->max_size = 1073741824;
|
||||
vty_server_init(pcap_server);
|
||||
pcap_server->max_snaplen = DEFAULT_SNAPLEN;
|
||||
|
||||
if (vty_read_config_file(config_file, NULL) < 0) {
|
||||
LOGP(DSERVER, LOGL_ERROR,
|
||||
|
@ -247,6 +290,12 @@ int main(int argc, char **argv)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
rc = telnet_init_default(tall_srv_ctx, NULL, OSMO_VTY_PORT_PCAP_SERVER);
|
||||
if (rc < 0) {
|
||||
LOGP(DCLIENT, LOGL_ERROR, "Failed to bind telnet interface\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
osmo_tls_server_init(pcap_server);
|
||||
|
||||
/* attempt to connect to the remote */
|
||||
|
|
|
@ -120,8 +120,8 @@ void osmo_pcap_server_close_trace(struct osmo_pcap_conn *conn)
|
|||
|
||||
if (conn->curr_filename) {
|
||||
client_event(conn, "closingtracefile", conn->curr_filename);
|
||||
rate_ctr_inc(&conn->ctrg->ctr[PEER_CTR_PROTATE]);
|
||||
rate_ctr_inc(&conn->server->ctrg->ctr[SERVER_CTR_PROTATE]);
|
||||
rate_ctr_inc(rate_ctr_group_get_ctr(conn->ctrg, PEER_CTR_PROTATE));
|
||||
rate_ctr_inc(rate_ctr_group_get_ctr(conn->server->ctrg, SERVER_CTR_PROTATE));
|
||||
talloc_free(conn->curr_filename);
|
||||
conn->curr_filename = NULL;
|
||||
}
|
||||
|
@ -130,10 +130,10 @@ void osmo_pcap_server_close_trace(struct osmo_pcap_conn *conn)
|
|||
static void close_connection(struct osmo_pcap_conn *conn)
|
||||
{
|
||||
if (conn->rem_wq.bfd.fd >= 0) {
|
||||
osmo_fd_unregister(&conn->rem_wq.bfd);
|
||||
close(conn->rem_wq.bfd.fd);
|
||||
conn->rem_wq.bfd.fd = -1;
|
||||
osmo_tls_release(&conn->tls_session);
|
||||
osmo_fd_unregister(&conn->rem_wq.bfd);
|
||||
}
|
||||
|
||||
osmo_pcap_server_close_trace(conn);
|
||||
|
@ -171,7 +171,7 @@ static void restart_pcap(struct osmo_pcap_conn *conn)
|
|||
return;
|
||||
}
|
||||
|
||||
conn->local_fd = creat(conn->curr_filename, 0440);
|
||||
conn->local_fd = creat(conn->curr_filename, conn->server->permission_mask);
|
||||
if (conn->local_fd < 0) {
|
||||
LOGP(DSERVER, LOGL_ERROR, "Failed to file: '%s'\n", conn->curr_filename);
|
||||
return;
|
||||
|
@ -192,12 +192,15 @@ static int link_data(struct osmo_pcap_conn *conn, struct osmo_pcap_data *data)
|
|||
{
|
||||
struct pcap_file_header *hdr;
|
||||
|
||||
if (data->len != sizeof(*hdr)) {
|
||||
LOGP(DSERVER, LOGL_ERROR, "The pcap_file_header does not fit.\n");
|
||||
hdr = (struct pcap_file_header *) &data->data[0];
|
||||
|
||||
if (hdr->snaplen > conn->server->max_snaplen) {
|
||||
LOGP(DSERVER, LOGL_ERROR,
|
||||
"The recvd pcap_file_header contains too big snaplen %zu > %zu\n",
|
||||
(size_t) hdr->snaplen, (size_t) conn->server->max_snaplen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
hdr = (struct pcap_file_header *) &data->data[0];
|
||||
if (!conn->no_store && conn->local_fd < 0) {
|
||||
conn->file_hdr = *hdr;
|
||||
restart_pcap(conn);
|
||||
|
@ -263,6 +266,7 @@ struct osmo_pcap_conn *osmo_pcap_server_find(struct osmo_pcap_server *server,
|
|||
{
|
||||
struct rate_ctr_group_desc *desc;
|
||||
struct osmo_pcap_conn *conn;
|
||||
size_t buf_size;
|
||||
|
||||
llist_for_each_entry(conn, &server->conn, entry) {
|
||||
if (strcmp(conn->name, name) == 0)
|
||||
|
@ -276,6 +280,10 @@ struct osmo_pcap_conn *osmo_pcap_server_find(struct osmo_pcap_server *server,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
buf_size = sizeof(struct osmo_pcap_data);
|
||||
buf_size += OSMO_MAX(sizeof(struct pcap_file_header),
|
||||
sizeof(struct osmo_pcap_pkthdr) + server->max_snaplen);
|
||||
conn->data = talloc_zero_size(conn, buf_size);
|
||||
/* a bit nasty. we do not work with ids but names */
|
||||
desc = talloc_zero(conn, struct rate_ctr_group_desc);
|
||||
if (!desc) {
|
||||
|
@ -285,7 +293,7 @@ struct osmo_pcap_conn *osmo_pcap_server_find(struct osmo_pcap_server *server,
|
|||
return NULL;
|
||||
}
|
||||
memcpy(desc, &pcap_peer_group_desc, sizeof(pcap_peer_group_desc));
|
||||
desc->group_name_prefix = talloc_asprintf(desc, "pcap.peer.%s", name);
|
||||
desc->group_name_prefix = talloc_asprintf(desc, "pcap:peer:%s", name);
|
||||
if (!desc->group_name_prefix) {
|
||||
LOGP(DSERVER, LOGL_ERROR,
|
||||
"Failed to allocate group name prefix peer=%s\n", name);
|
||||
|
@ -315,7 +323,6 @@ struct osmo_pcap_conn *osmo_pcap_server_find(struct osmo_pcap_server *server,
|
|||
conn->rem_wq.bfd.fd = -1;
|
||||
conn->local_fd = -1;
|
||||
conn->server = server;
|
||||
conn->data = (struct osmo_pcap_data *) &conn->buf[0];
|
||||
llist_add_tail(&conn->entry, &server->conn);
|
||||
return conn;
|
||||
}
|
||||
|
@ -335,11 +342,41 @@ static int do_read(struct osmo_pcap_conn *conn, void *buf, size_t size)
|
|||
return do_read_tls(conn, buf, size);
|
||||
}
|
||||
|
||||
static bool pcap_data_valid(struct osmo_pcap_conn *conn)
|
||||
{
|
||||
unsigned int min_len, max_len;
|
||||
switch ((enum OsmoPcapDataType) conn->data->type) {
|
||||
case PKT_LINK_HDR:
|
||||
if (conn->data->len != sizeof(struct pcap_file_header)) {
|
||||
LOGP(DSERVER, LOGL_ERROR,
|
||||
"Implausible llink_hdr length: %u != %zu\n",
|
||||
conn->data->len, sizeof(struct osmo_pcap_pkthdr));
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case PKT_LINK_DATA:
|
||||
min_len = sizeof(struct osmo_pcap_pkthdr);
|
||||
max_len = conn->server->max_snaplen + sizeof(struct osmo_pcap_pkthdr);
|
||||
if (conn->data->len < min_len || conn->data->len > max_len) {
|
||||
LOGP(DSERVER, LOGL_ERROR,
|
||||
"Implausible data length: %u < %u <= %u\n",
|
||||
min_len, conn->data->len, max_len);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOGP(DSERVER, LOGL_ERROR, "Unknown data type %" PRIx8 "\n",
|
||||
conn->data->type);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int read_cb_initial(struct osmo_pcap_conn *conn)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = do_read(conn, &conn->buf[sizeof(*conn->data) - conn->pend], conn->pend);
|
||||
rc = do_read(conn, ((uint8_t*)conn->data) + sizeof(*conn->data) - conn->pend, conn->pend);
|
||||
if (rc <= 0) {
|
||||
LOGP(DSERVER, LOGL_ERROR,
|
||||
"Too short packet. Got %d, wanted %d\n", rc, conn->data->len);
|
||||
|
@ -354,11 +391,8 @@ static int read_cb_initial(struct osmo_pcap_conn *conn)
|
|||
} else if (conn->pend == 0) {
|
||||
conn->data->len = ntohs(conn->data->len);
|
||||
|
||||
if (conn->data->len > SERVER_MAX_DATA_SIZE) {
|
||||
LOGP(DSERVER, LOGL_ERROR,
|
||||
"Implausible data length: %u\n", conn->data->len);
|
||||
if (!pcap_data_valid(conn))
|
||||
return -1;
|
||||
}
|
||||
|
||||
conn->state = STATE_DATA;
|
||||
conn->pend = conn->data->len;
|
||||
|
@ -388,12 +422,12 @@ static int read_cb_data(struct osmo_pcap_conn *conn)
|
|||
conn->pend = sizeof(*conn->data);
|
||||
|
||||
/* count the full packet we got */
|
||||
rate_ctr_inc(&conn->ctrg->ctr[PEER_CTR_PKTS]);
|
||||
rate_ctr_inc(&conn->server->ctrg->ctr[SERVER_CTR_PKTS]);
|
||||
rate_ctr_inc(rate_ctr_group_get_ctr(conn->ctrg, PEER_CTR_PKTS));
|
||||
rate_ctr_inc(rate_ctr_group_get_ctr(conn->server->ctrg, SERVER_CTR_PKTS));
|
||||
|
||||
/* count the bytes of it */
|
||||
rate_ctr_add(&conn->ctrg->ctr[PEER_CTR_BYTES], conn->data->len);
|
||||
rate_ctr_add(&conn->server->ctrg->ctr[SERVER_CTR_BYTES], conn->data->len);
|
||||
rate_ctr_add(rate_ctr_group_get_ctr(conn->ctrg, PEER_CTR_BYTES), conn->data->len);
|
||||
rate_ctr_add(rate_ctr_group_get_ctr(conn->server->ctrg, SERVER_CTR_BYTES), conn->data->len);
|
||||
|
||||
switch (conn->data->type) {
|
||||
case PKT_LINK_HDR:
|
||||
|
@ -486,7 +520,7 @@ static void new_connection(struct osmo_pcap_server *server,
|
|||
return;
|
||||
}
|
||||
|
||||
rate_ctr_inc(&client->ctrg->ctr[PEER_CTR_CONNECT]);
|
||||
rate_ctr_inc(rate_ctr_group_get_ctr(client->ctrg, PEER_CTR_CONNECT));
|
||||
|
||||
client->state = STATE_INITIAL;
|
||||
client->pend = sizeof(*client->data);
|
||||
|
@ -508,7 +542,7 @@ static void new_connection(struct osmo_pcap_server *server,
|
|||
} else {
|
||||
client->rem_wq.bfd.cb = osmo_wqueue_bfd_cb;
|
||||
client->rem_wq.bfd.data = client;
|
||||
client->rem_wq.bfd.when = BSC_FD_READ;
|
||||
client->rem_wq.bfd.when = OSMO_FD_READ;
|
||||
client->rem_wq.read_cb = read_cb;
|
||||
client->direct_read = true;
|
||||
}
|
||||
|
@ -531,7 +565,7 @@ static int accept_cb(struct osmo_fd *fd, unsigned int when)
|
|||
server = fd->data;
|
||||
|
||||
/* count any accept to see no clients */
|
||||
rate_ctr_inc(&server->ctrg->ctr[SERVER_CTR_CONNECT]);
|
||||
rate_ctr_inc(rate_ctr_group_get_ctr(server->ctrg, SERVER_CTR_CONNECT));
|
||||
|
||||
llist_for_each_entry(conn, &server->conn, entry) {
|
||||
if (conn->remote_addr.s_addr == addr.sin_addr.s_addr) {
|
||||
|
@ -543,7 +577,7 @@ static int accept_cb(struct osmo_fd *fd, unsigned int when)
|
|||
}
|
||||
}
|
||||
|
||||
rate_ctr_inc(&server->ctrg->ctr[SERVER_CTR_NOCLIENT]);
|
||||
rate_ctr_inc(rate_ctr_group_get_ctr(server->ctrg, SERVER_CTR_NOCLIENT));
|
||||
|
||||
/*
|
||||
* TODO: In the future start with a tls handshake and see if we know
|
||||
|
@ -568,7 +602,7 @@ int osmo_pcap_server_listen(struct osmo_pcap_server *server)
|
|||
}
|
||||
|
||||
server->listen_fd.fd = fd;
|
||||
server->listen_fd.when = BSC_FD_READ;
|
||||
server->listen_fd.when = OSMO_FD_READ;
|
||||
server->listen_fd.cb = accept_cb;
|
||||
server->listen_fd.data = server;
|
||||
|
||||
|
|
|
@ -88,12 +88,15 @@ static int config_write_server(struct vty *vty)
|
|||
|
||||
if (pcap_server->base_path)
|
||||
vty_out(vty, " base-path %s%s", pcap_server->base_path, VTY_NEWLINE);
|
||||
vty_out(vty, " file-permission-mask 0%o%s", pcap_server->permission_mask, VTY_NEWLINE);
|
||||
if (pcap_server->addr)
|
||||
vty_out(vty, " server ip %s%s", pcap_server->addr, VTY_NEWLINE);
|
||||
if (pcap_server->port > 0)
|
||||
vty_out(vty, " server port %d%s", pcap_server->port, VTY_NEWLINE);
|
||||
vty_out(vty, " max-file-size %llu%s",
|
||||
(unsigned long long) pcap_server->max_size, VTY_NEWLINE);
|
||||
if (pcap_server->max_snaplen != DEFAULT_SNAPLEN)
|
||||
vty_out(vty, " server max-snaplen %d%s", pcap_server->max_snaplen, VTY_NEWLINE);
|
||||
if (pcap_server->zmq_port > 0)
|
||||
vty_out(vty, " zeromq-publisher %s %d%s",
|
||||
pcap_server->zmq_ip, pcap_server->zmq_port, VTY_NEWLINE);
|
||||
|
@ -130,6 +133,46 @@ DEFUN(cfg_server_base,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_server_file_permission_mask,
|
||||
cfg_server_file_permission_mask_cmd,
|
||||
"file-permission-mask MODE",
|
||||
"Permission mask to use when creating pcap files\n"
|
||||
"The file permission mask, in octal format (default: 0440)\n")
|
||||
{
|
||||
unsigned long long val;
|
||||
char *endptr;
|
||||
|
||||
errno = 0;
|
||||
val = strtoul(argv[0], &endptr, 8);
|
||||
|
||||
switch (errno) {
|
||||
case 0:
|
||||
break;
|
||||
case ERANGE:
|
||||
case EINVAL:
|
||||
default:
|
||||
goto ret_invalid;
|
||||
}
|
||||
if (!endptr || *endptr) {
|
||||
/* No chars were converted */
|
||||
if (endptr == argv[0])
|
||||
goto ret_invalid;
|
||||
/* Or there are surplus chars after the converted number */
|
||||
goto ret_invalid;
|
||||
}
|
||||
|
||||
/* 'man mode_t': "According to POSIX, it shall be an integer type." */
|
||||
if (val > INT_MAX)
|
||||
goto ret_invalid;
|
||||
|
||||
pcap_server->permission_mask = val;
|
||||
return CMD_SUCCESS;
|
||||
|
||||
ret_invalid:
|
||||
vty_out(vty, "%% File permission mask out of range: '%s'%s", argv[0], VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
DEFUN(cfg_server_ip,
|
||||
cfg_server_ip_cmd,
|
||||
"server ip A.B.C.D",
|
||||
|
@ -158,6 +201,15 @@ DEFUN(cfg_server_max_size,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_server_max_snaplen,
|
||||
cfg_server_max_snaplen_cmd,
|
||||
"max-snaplen <1-262144>", /* MAXIMUM_SNAPLEN */
|
||||
"Maximum pcap snapshot length\n" "Bytes\n")
|
||||
{
|
||||
pcap_server->max_snaplen = atoi(argv[0]);
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static int manage_client(struct osmo_pcap_server *pcap_server,
|
||||
struct vty *vty,
|
||||
const char *name, const char *remote_host,
|
||||
|
@ -502,16 +554,17 @@ DEFUN(cfg_tls_dh_generate,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
void vty_server_init(struct osmo_pcap_server *server)
|
||||
void vty_server_init(void)
|
||||
{
|
||||
install_element(CONFIG_NODE, &cfg_server_cmd);
|
||||
install_node(&server_node, config_write_server);
|
||||
install_default(SERVER_NODE);
|
||||
|
||||
install_element(SERVER_NODE, &cfg_server_base_cmd);
|
||||
install_element(SERVER_NODE, &cfg_server_file_permission_mask_cmd);
|
||||
install_element(SERVER_NODE, &cfg_server_ip_cmd);
|
||||
install_element(SERVER_NODE, &cfg_server_port_cmd);
|
||||
install_element(SERVER_NODE, &cfg_server_max_size_cmd);
|
||||
install_element(SERVER_NODE, &cfg_server_max_snaplen_cmd);
|
||||
install_element(SERVER_NODE, &cfg_server_zmq_ip_port_cmd);
|
||||
install_element(SERVER_NODE, &cfg_no_server_zmq_ip_port_cmd);
|
||||
|
||||
|
|
|
@ -191,10 +191,9 @@ static int need_handshake(struct osmo_tls_session *tls_session)
|
|||
if (rc == 0) {
|
||||
/* handshake is done. start writing if we are allowed to */
|
||||
LOGP(DTLS, LOGL_NOTICE, "TLS handshake done.\n");
|
||||
osmo_fd_read_enable(&tls_session->wqueue->bfd);
|
||||
if (!llist_empty(&tls_session->wqueue->msg_queue))
|
||||
tls_session->wqueue->bfd.when = BSC_FD_WRITE | BSC_FD_READ;
|
||||
else
|
||||
tls_session->wqueue->bfd.when = BSC_FD_READ;
|
||||
osmo_fd_write_enable(&tls_session->wqueue->bfd);
|
||||
tls_session->need_handshake = false;
|
||||
release_keys(tls_session);
|
||||
if (tls_session->handshake_done)
|
||||
|
@ -227,7 +226,7 @@ static int tls_read(struct osmo_tls_session *sess)
|
|||
static int tls_write(struct osmo_tls_session *sess)
|
||||
{
|
||||
int rc;
|
||||
sess->wqueue->bfd.when &= ~BSC_FD_WRITE;
|
||||
osmo_fd_write_disable(&sess->wqueue->bfd);
|
||||
|
||||
if (llist_empty(&sess->wqueue->msg_queue))
|
||||
return 0;
|
||||
|
@ -252,7 +251,7 @@ static int tls_write(struct osmo_tls_session *sess)
|
|||
}
|
||||
|
||||
if (sess->need_resend || !llist_empty(&sess->wqueue->msg_queue))
|
||||
sess->wqueue->bfd.when |= BSC_FD_WRITE;
|
||||
osmo_fd_write_enable(&sess->wqueue->bfd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -263,14 +262,14 @@ int osmo_tls_client_bfd_cb(struct osmo_fd *fd, unsigned what)
|
|||
if (sess->need_handshake)
|
||||
return need_handshake(sess);
|
||||
|
||||
if (what & BSC_FD_READ) {
|
||||
if (what & OSMO_FD_READ) {
|
||||
int rc = tls_read(sess);
|
||||
if (rc <= 0) {
|
||||
sess->error(sess);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
if (what & BSC_FD_WRITE) {
|
||||
if (what & OSMO_FD_WRITE) {
|
||||
int rc = tls_write(sess);
|
||||
if (rc < 0) {
|
||||
sess->error(sess);
|
||||
|
@ -435,9 +434,7 @@ bool osmo_tls_init_server_session(struct osmo_pcap_conn *conn,
|
|||
gnutls_transport_set_int(sess->session, wq->bfd.fd);
|
||||
gnutls_handshake_set_timeout(sess->session,
|
||||
GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
|
||||
wq->bfd.cb = osmo_tls_client_bfd_cb;
|
||||
wq->bfd.data = sess;
|
||||
wq->bfd.when = BSC_FD_READ | BSC_FD_WRITE;
|
||||
osmo_fd_setup(&wq->bfd, wq->bfd.fd, OSMO_FD_READ | OSMO_FD_WRITE, osmo_tls_client_bfd_cb, sess, 0);
|
||||
sess->need_handshake = true;
|
||||
sess->wqueue = wq;
|
||||
return true;
|
||||
|
@ -531,9 +528,7 @@ bool osmo_tls_init_client_session(struct osmo_pcap_client_conn *client)
|
|||
gnutls_transport_set_int(sess->session, wq->bfd.fd);
|
||||
gnutls_handshake_set_timeout(sess->session,
|
||||
GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
|
||||
wq->bfd.cb = osmo_tls_client_bfd_cb;
|
||||
wq->bfd.data = sess;
|
||||
wq->bfd.when = BSC_FD_READ | BSC_FD_WRITE;
|
||||
osmo_fd_setup(&wq->bfd, wq->bfd.fd, OSMO_FD_READ | OSMO_FD_WRITE, osmo_tls_client_bfd_cb, sess, 0);
|
||||
sess->need_handshake = true;
|
||||
sess->wqueue = wq;
|
||||
return true;
|
||||
|
|
|
@ -17,14 +17,16 @@ $(srcdir)/package.m4: $(top_srcdir)/configure.ac
|
|||
} >'$(srcdir)/package.m4'
|
||||
|
||||
EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE)
|
||||
DISTCLEANFILES = atconfig
|
||||
TESTSUITE = $(srcdir)/testsuite
|
||||
|
||||
if ENABLE_EXT_TESTS
|
||||
python-tests: $(BUILT_SOURCES)
|
||||
python-tests: $(top_builddir)/src/osmo-pcap-server \
|
||||
$(top_builddir)/src/osmo-pcap-client
|
||||
osmotestvty.py -p $(abs_top_srcdir) -w $(abs_top_builddir) -v
|
||||
osmotestconfig.py -p $(abs_top_srcdir) -w $(abs_top_builddir) -v
|
||||
else
|
||||
python-tests: $(BUILT_SOURCES)
|
||||
python-tests:
|
||||
echo "Not running python-based tests (determined at configure-time)"
|
||||
endif
|
||||
|
||||
|
@ -39,7 +41,6 @@ installcheck-local: atconfig $(TESTSUITE)
|
|||
clean-local:
|
||||
test ! -f '$(TESTSUITE)' || \
|
||||
$(SHELL) '$(TESTSUITE)' --clean
|
||||
$(RM) -f atconfig
|
||||
|
||||
AUTOM4TE = $(SHELL) $(top_srcdir)/missing --run autom4te
|
||||
AUTOTEST = $(AUTOM4TE) --language=autotest
|
||||
|
|
Loading…
Reference in New Issue