1
0
Fork 0
mirror of https://github.com/pavel-odintsov/fastnetmon synced 2024-05-18 20:46:07 +02:00

Deprecated PF_RING plugin for new versions. We switched to AF_PACKET which is compeltely open source and worse way better (#929)

This commit is contained in:
Pavel Odintsov 2022-04-04 15:30:23 +01:00 committed by GitHub
parent 481428dca4
commit 54da2b6cad
Signed by: GitHub
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 26 additions and 1141 deletions

View File

@ -11,7 +11,8 @@ perform a configurable action to handle that event. These configurable actions i
Flow is one or more ICMP, UDP, or TCP packets which can be identified via their unique src IP, dst IP, src port, dst port, and protocol fields.
![CI status](https://circleci.com/gh/pavel-odintsov/fastnetmon.svg) [CI status](https://app.circleci.com/pipelines/github/pavel-odintsov/fastnetmon)
![CI status](https://circleci.com/gh/pavel-odintsov/fastnetmon.svg)
[CI status](https://app.circleci.com/pipelines/github/pavel-odintsov/fastnetmon)
Project
-------
@ -28,7 +29,7 @@ Supported packet capture engines
- PCAP
- AF_PACKET
- Netmap
- PF_RING / PF_RING ZC (available only for CentOS 6 for compatibiliy, otherwise use AF_PACKET)
- PF_RING / PF_RING ZC (CentOS 6 only)
You can check out the [comparison table](https://fastnetmon.com/docs/capture_backends/) for all available packet capture engines.

2
debian/rules vendored
View File

@ -2,4 +2,4 @@
%:
dh $@ --buildsystem=cmake --sourcedirectory=src
override_dh_auto_configure:
dh_auto_configure -- -DDISABLE_PF_RING_SUPPORT=yes
dh_auto_configure --

View File

@ -27,7 +27,6 @@ set (FASTNETMON_VERSION_MINOR 1)
set(HIREDIS_CUSTOM_INSTALL_PATH "${FASTNETMON_LIBRARIES_GLOBAL_PATH}/libhiredis_0_13")
set(LOG4CPP_CUSTOM_INSTALL_PATH "${FASTNETMON_LIBRARIES_GLOBAL_PATH}/log4cpp1.1.1")
set(JSONC_CUSTOM_INSTALL_PATH "${FASTNETMON_LIBRARIES_GLOBAL_PATH}/json-c-0.13")
set(PFRING_CUSTOM_INSTALL_PATH "${FASTNETMON_LIBRARIES_GLOBAL_PATH}/pf_ring_6.0.3")
set(LIBPCAP_CUSTOM_INSTALL_PATH "${FASTNETMON_LIBRARIES_GLOBAL_PATH}/libpcap_1.7.4")
set(MONGO_C_CUSTOM_INSTALL_PATH "${FASTNETMON_LIBRARIES_GLOBAL_PATH}/mongo_c_driver_1_16_1")
set(CAPNP_CUSTOM_INSTALL_PATH "${FASTNETMON_LIBRARIES_GLOBAL_PATH}/capnproto_0_8_0")
@ -87,7 +86,7 @@ SET(CMAKE_SKIP_BUILD_RPATH FALSE)
# Create builds in current folder with install RPATH
SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH};${FASTNETMON_LIBRARIES_GLOBAL_PATH}/libhiredis_0_13/lib;${FASTNETMON_LIBRARIES_GLOBAL_PATH}/log4cpp1.1.1/lib;${FASTNETMON_LIBRARIES_GLOBAL_PATH}/pf_ring_6.0.3/lib;${FASTNETMON_LIBRARIES_GLOBAL_PATH}/json-c-0.13/lib;${MONGO_C_CUSTOM_INSTALL_PATH}/lib;${MONGO_C_CUSTOM_INSTALL_PATH}/lib64;${GRPC_CUSTOM_INSTALL_PATH}/lib;${FASTNETMON_LIBRARIES_GLOBAL_PATH}/protobuf_3.11.4/lib;${CAPNP_CUSTOM_INSTALL_PATH}/lib;${OPENSSL_CUSTOM_INSTALL_PATH}/lib")
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH};${FASTNETMON_LIBRARIES_GLOBAL_PATH}/libhiredis_0_13/lib;${FASTNETMON_LIBRARIES_GLOBAL_PATH}/log4cpp1.1.1/lib;${FASTNETMON_LIBRARIES_GLOBAL_PATH}/json-c-0.13/lib;${MONGO_C_CUSTOM_INSTALL_PATH}/lib;${MONGO_C_CUSTOM_INSTALL_PATH}/lib64;${GRPC_CUSTOM_INSTALL_PATH}/lib;${FASTNETMON_LIBRARIES_GLOBAL_PATH}/protobuf_3.11.4/lib;${CAPNP_CUSTOM_INSTALL_PATH}/lib;${OPENSSL_CUSTOM_INSTALL_PATH}/lib")
message(STATUS "C++ compilation flags: ${CMAKE_CXX_FLAGS_RELEASE}")
message(STATUS "C++ debug compilation flags: ${CMAKE_CXX_FLAGS_DEBUG}")
@ -145,9 +144,6 @@ if (NOT HAVE__ATOMIC_ADD_FETCH)
endif()
endif()
# With this flag we can enable PF_RING build via console: cmake .. -DENABLE_PF_RING_SUPPORT=ON
option(ENABLE_PF_RING_SUPPORT "Enable PF_RING build" OFF)
option(ENABLE_NETMAP_SUPPORT "Enable Netmap support" ON)
CHECK_CXX_SOURCE_COMPILES("
@ -169,32 +165,6 @@ if (ENABLE_NETMAP_SUPPORT)
add_definitions(-DNETMAP_PLUGIN)
endif()
if (ENABLE_PF_RING_SUPPORT)
# Set path to manually compiled PF_RING
set(PFRING_INCLUDE_DIRS "${PFRING_CUSTOM_INSTALL_PATH}/include")
find_library(PFRING_LIBRARIES NAMES pfring PATHS "${PFRING_CUSTOM_INSTALL_PATH}/lib" NO_DEFAULT_PATH)
if (NOT PFRING_LIBRARIES)
message(FATAL_ERROR "Could not find PF_RING")
endif()
link_directories("${PFRING_CUSTOM_INSTALL_PATH}/lib")
add_definitions(-DPF_RING)
if (EXISTS "${PFRING_CUSTOM_INSTALL_PATH}/include/pfring_zc.h" OR EXISTS "/usr/local/include/pfring_zc.h")
message(STATUS "We found PF_RING ZC headers and will build PF_RING ZC support")
# Enable ZC support
add_definitions(-DPF_RING_ZC)
else()
message(WARNING "We can't find PF_RING ZC header pfring_zc.h. Will not compile ZC support")
endif()
include_directories(${PFRING_INCLUDE_DIRS})
message(STATUS "We have enabled PF_RING's hardware filtering option")
endif()
add_library(simple_packet_capnp STATIC simple_packet_capnp/simple_packet.capnp.c++)
# Our LPM library
@ -283,13 +253,6 @@ target_link_libraries(pcap_plugin pcap)
find_package(Threads)
if (ENABLE_PF_RING_SUPPORT)
add_library(pfring_plugin STATIC pfring_plugin/pfring_collector.cpp)
target_link_libraries(pfring_plugin ${PFRING_LIBRARIES})
target_link_libraries(pfring_plugin numa)
target_link_libraries(pfring_plugin ${CMAKE_THREAD_LIBS_INIT})
endif()
add_library(exabgp_action STATIC actions/exabgp_action.cpp)
if (ENABLE_GOBGP_SUPPORT)
@ -593,10 +556,6 @@ target_link_libraries(fastnetmon fast_library)
# link to our unified parser
target_link_libraries(fastnetmon unified_parser)
if (ENABLE_PF_RING_SUPPORT)
target_link_libraries(fastnetmon pfring_plugin)
endif()
target_link_libraries(fastnetmon ${OPENSSL_LIBRARY_PATH})
target_link_libraries(fastnetmon ${OPENSSL_CRYPTO_LIBRARY_PATH})
@ -638,11 +597,6 @@ if (BUILD_PLUGIN_RUNNER)
if (ENABLE_NETMAP_SUPPORT)
target_link_libraries(fastnetmon_plugin_runner netmap_plugin)
endif()
if (ENABLE_PF_RING_SUPPORT)
target_link_libraries(fastnetmon_plugin_runner ${PFRING_LIBRARIES})
target_link_libraries(fastnetmon_plugin_runner pfring_plugin)
endif()
endif()
# cmake .. -DBUILD_PCAP_READER=ON

View File

@ -32,7 +32,7 @@ RUN cd /usr/src; git clone https://github.com/pavel-odintsov/fastnetmon.git
#COPY exabgp_blackhole.conf /etc/exabgp_blackhole.conf
RUN cd /usr/src/fastnetmon/src; mkdir build; cd build; cmake .. -DDISABLE_PF_RING_SUPPORT=ON; make
RUN cd /usr/src/fastnetmon/src; mkdir build; cd build; cmake ..; make
RUN cp /usr/src/fastnetmon/src/fastnetmon.conf /etc/
RUN cp /usr/src/fastnetmon/src/build/fastnetmon /usr/bin/

View File

@ -1,5 +1,4 @@
FastNetMon - A high performance DoS/DDoS load analyzer built on top
of multiple packet capture engines (NetFlow, IPFIX, sFLOW, netmap,
PF_RING, PCAP).
of multiple packet capture engines (NetFlow, IPFIX, sFlow, Netmap, PCAP).
WWW: https://fastnetmon.com

View File

@ -449,7 +449,7 @@ std::string print_simple_packet(simple_packet_t packet) {
std::stringstream buffer;
if (packet.ts.tv_sec == 0) {
// PF_RING and netmap do not generate timestamp for all packets because it's very CPU
// Netmap does not generate timestamp for all packets because it's very CPU
// intensive operation
// But we want pretty attack report and fill it there
gettimeofday(&packet.ts, NULL);

View File

@ -86,12 +86,6 @@ ban_for_icmp_pps = off
### Traffic capture methods
###
# PF_RING traffic capture, fast enough but the wirespeed version needs a paid license
mirror = off
# Port mirroring sample rate
pfring_sampling_ratio = 1
# Netmap traffic capture (very fast but needs patched drivers)
mirror_netmap = off
@ -124,13 +118,9 @@ netflow = off
# sFLOW capture suitable for switches
sflow = off
# PF_RING configuration
# If you have a license for PF_RING ZC, enable this mode and it might achieve wire speed for 10GE
enable_pf_ring_zc_mode = off
# Configuration for netmap, mirror, pcap modes
# For pcap and PF_RING we could specify "any"
# For netmap and PF_RING we could specify multiple interfaces separated by comma
# For pcap we could specify "any"
# For Netmap we could specify multiple interfaces separated by comma
interfaces = eth3,eth4
# We use average values for traffic speed to certain IP and we calculate average over this time slice

View File

@ -62,10 +62,6 @@
#include "netmap_plugin/netmap_collector.h"
#endif
#ifdef PF_RING
#include "pfring_plugin/pfring_collector.h"
#endif
#ifdef FASTNETMON_ENABLE_AFPACKET
#include "afpacket_plugin/afpacket_collector.h"
#endif
@ -1690,12 +1686,6 @@ int main(int argc, char** argv) {
set_boost_process_name(check_traffic_buckets_thread, "check_buckets");
service_thread_group.add_thread(check_traffic_buckets_thread);
#ifdef PF_RING
if (enable_data_collection_from_mirror) {
packet_capture_plugin_thread_group.add_thread(new boost::thread(start_pfring_collection, process_packet));
}
#endif
#ifdef NETMAP_PLUGIN
// netmap processing
if (enable_netmap_collection) {

View File

@ -56,10 +56,6 @@ sub fast_die {
exit(1);
}
my $pf_ring_version = '6.0.3';
my $pf_ring_url = "https://github.com/ntop/PF_RING/archive/v$pf_ring_version.tar.gz";
my $pf_ring_sha = '9fb8080defd1a079ad5f0097e8a8adb5bc264d00';
my $fastnetmon_git_path = 'https://github.com/pavel-odintsov/fastnetmon.git';
my $temp_folder_for_building_project = `mktemp -d /tmp/fastnetmon.build.dir.XXXXXXXXXX`;
@ -91,8 +87,6 @@ my $make_options = '';
# We could pass options to configure with this variable
my $configure_options = '';
my $use_modern_pf_ring = '';
my $show_help = '';
my $install_dependency_packages_only = '';
@ -106,7 +100,6 @@ my $build_dependencies_only = '';
# Get options from command line
GetOptions(
'use-git-master' => \$we_use_code_from_master,
'use-modern-pf-ring' => \$use_modern_pf_ring,
'use-mirror' => \$use_mirror,
'build_fastnetmon_only' => \$build_fastnetmon_only,
'build_dependencies_only' => \$build_dependencies_only,
@ -129,13 +122,6 @@ if ($show_help) {
welcome_message();
# Bump PF_RING version
if ($use_modern_pf_ring) {
$pf_ring_version = '6.6.0';
$pf_ring_url = "https://github.com/ntop/PF_RING/archive/$pf_ring_version.tar.gz";
$pf_ring_sha = '79ff86e48df857e4e884646accfc97bdcdc54b04';
}
my $we_have_hiredis_support = '1';
my $we_have_log4cpp_support = '1';
my $we_have_mongo_support = '1';
@ -143,9 +129,6 @@ my $we_have_protobuf_support = '1';
my $we_have_grpc_support = '1';
my $we_have_gobgp_support = '1';
# We allow it only for legacy systems
my $we_have_pfring_support = '';
main();
# Applies colors to terminal if we have this module
@ -290,17 +273,6 @@ sub main {
}
}
# We use PF_RING only for very old Linux distros, all new one should use AF_PACKET
if ($os_type eq 'linux') {
if ($distro_type eq 'ubuntu' && $distro_version =~ m/^12\.04/) {
$we_have_pfring_support = 1;
}
if ($distro_type eq 'centos' && $distro_version == 6) {
$we_have_pfring_support = 1;
}
}
# CentOS base repository is very very poor and we need EPEL for some dependencies
install_additional_repositories();
@ -329,10 +301,6 @@ sub main {
# Install only depencdency packages, we need it to cache installed packages in CI
if ($install_dependency_packages_only) {
if ($we_have_pfring_support) {
install_pf_ring_dependencies();
}
if ($we_have_protobuf_support) {
install_protobuf_dependencies();
}
@ -347,11 +315,6 @@ sub main {
}
if ($build_dependencies_only) {
if ($we_have_pfring_support) {
install_pf_ring_dependencies();
install_pf_ring();
}
install_json_c();
install_openssl();
@ -1049,110 +1012,6 @@ sub detect_distribution {
}
}
sub install_pf_ring_dependencies {
my $kernel_version = `uname -r`;
chomp $kernel_version;
print "Install PF_RING dependencies with package manager\n";
if ($distro_type eq 'debian' or $distro_type eq 'ubuntu') {
my @debian_packages_for_pfring = ('build-essential', 'bison', 'flex', 'subversion',
'libnuma-dev', 'wget', 'tar', 'make', 'dpkg-dev', 'dkms', 'debhelper');
# Install kernel headers only when we could compile kernel modules there
my $kernel_headers_package_name = "linux-headers-$kernel_version";
push @debian_packages_for_pfring, $kernel_headers_package_name;
apt_get(@debian_packages_for_pfring);
} elsif ($distro_type eq 'centos') {
my @centos_dependency_packages = ('make', 'bison', 'flex', 'gcc', 'gcc-c++', 'dkms', 'numactl-devel', 'subversion');
# This package is not going to install devel headers for current kernel!
my $kernel_package_name = 'kernel-devel';
# Fix deplist for OpenVZ
if ($kernel_version =~ /stab/) {
$kernel_package_name = "vzkernel-devel-$kernel_version";
}
push @centos_dependency_packages, $kernel_package_name;
my $centos_kernel_version = `uname -r`;
chomp $centos_kernel_version;
# But this package will install kernel devel headers for current kernel version!
push @centos_dependency_packages, "$kernel_package_name-$centos_kernel_version";
yum(@centos_dependency_packages);
}
}
sub install_pf_ring {
my $pf_ring_archive_path = "$temp_folder_for_building_project/PF_RING-$pf_ring_version.tar.gz";
my $pf_ring_sources_path = "$temp_folder_for_building_project/PF_RING-$pf_ring_version";
my $pf_ring_install_path = "$library_install_folder/pf_ring_$pf_ring_version";
if (-e $pf_ring_install_path) {
print "PF_RING was already installed\n";
return 1;
}
# Sometimes we do not want to build kernel module (Docker, KVM and other cases)
my $we_could_install_kernel_modules = 1;
if ($we_could_install_kernel_modules) {
print "Download PF_RING $pf_ring_version sources\n";
my $pfring_download_result = download_file($pf_ring_url, $pf_ring_archive_path, $pf_ring_sha);
unless ($pfring_download_result) {
fast_die("Can't download PF_RING sources");
}
my $archive_file_name = $pf_ring_archive_path;
if ($? == 0) {
print "Unpack PF_RING\n";
mkdir $pf_ring_sources_path;
exec_command("tar -xf $pf_ring_archive_path -C $temp_folder_for_building_project");
print "Build PF_RING kernel module\n";
exec_command("make $make_options -C $pf_ring_sources_path/kernel clean");
exec_command("make $make_options -C $pf_ring_sources_path/kernel");
exec_command("make $make_options -C $pf_ring_sources_path/kernel install");
print "Unload PF_RING if it was installed earlier\n";
exec_command("rmmod pf_ring 2>/dev/null");
print "Load PF_RING module into kernel\n";
exec_command("modprobe pf_ring");
my @dmesg = `dmesg`;
chomp @dmesg;
if (scalar grep (/\[PF_RING\] Initialized correctly/, @dmesg) > 0) {
print "PF_RING loaded correctly\n";
} else {
warn "PF_RING load error! Please fix this issue manually\n";
# We need this headers for building userspace libs
exec_command("cp $pf_ring_sources_path/kernel/linux/pf_ring.h /usr/include/linux");
}
} else {
warn "Can't download PF_RING source code. Disable support of PF_RING\n";
}
}
print "Build PF_RING lib\n";
# Because we can't run configure from another folder because it can't find ZC dependency :(
chdir "$pf_ring_sources_path/userland/lib";
exec_command("$configure_options ./configure --prefix=$pf_ring_install_path");
exec_command("make $make_options");
exec_command("make $make_options install");
}
sub apt_get {
my @packages_list = @_;
@ -1714,21 +1573,12 @@ sub install_fastnetmon {
my $cmake_params = "";
if ($we_have_pfring_support) {
$cmake_params .= " -DENABLE_PF_RING_SUPPORT=ON";
}
if ($distro_type eq 'centos' && $distro_version == 6) {
# Disable cmake script from Boost package because it's broken:
# http://public.kitware.com/Bug/view.php?id=15270
$cmake_params .= " -DBoost_NO_BOOST_CMAKE=BOOL:ON";
}
# Bump version in cmake build system
if ($use_modern_pf_ring) {
system("sed -i 's/pf_ring_6.0.3/pf_ring_$pf_ring_version/' ../CMakeLists.txt")
}
# Fix dependencies for Netmap in 1.1.4
if ($distro_type eq 'centos' && int($distro_version) == 6) {
system("sed -i 's/netmap_plugin fastnetmon_packet_parser/netmap_plugin fastnetmon_packet_parser unified_parser/' ../CMakeLists.txt")

View File

@ -11,7 +11,7 @@ Name: fastnetmon
Version: 1.1.1
Release: 1%{?dist}
Summary: A high performance DoS/DDoS load analyzer built on top of multiple packet capture engines (NetFlow, IPFIX, sFLOW, netmap, PF_RING, PCAP).
Summary: A high performance DoS/DDoS load analyzer built on top of multiple packet capture engines (NetFlow, IPFIX, sFlow, Netmap, PCAP).
Group: System Environment/Daemons
License: GPLv2
URL: https://fastnetmon.com
@ -20,13 +20,9 @@ URL: https://fastnetmon.com
#Source0: https://github.com/pavel-odintsov/fastnetmon/archive/v%{version}.tar.gz
Source0: https://github.com/pavel-odintsov/fastnetmon/archive/fastnetmon-%{version}.tar.gz
# Yes, it's bad idea to specify fixed version of PF_RING but they have strange issue when we use another library version
BuildRequires: git, make, gcc, gcc-c++, boost-devel, GeoIP-devel, log4cpp-devel
BuildRequires: ncurses-devel, boost-thread, boost-regex, libpcap-devel, gpm-devel, clang, cmake
BuildRequires: pfring >= 6.0.3-9154
Requires: pfring >= 6.0.3-9154
Requires: log4cpp, daemonize, libpcap, boost-thread, boost-thread, boost-regex
Requires(pre): shadow-utils
Requires(post): chkconfig
@ -36,7 +32,7 @@ Provides: fastnetmon
%description
A high performance DoS/DDoS load analyzer built on top of multiple packet capture
engines (NetFlow, IPFIX, sFLOW, netmap, PF_RING, PCAP).
engines (NetFlow, IPFIX, sFlow, Netmap, PCAP).
%prep
# For production
@ -49,10 +45,7 @@ engines (NetFlow, IPFIX, sFLOW, netmap, PF_RING, PCAP).
cd src
mkdir build
cd build
# You could disable PF_RING support with param: -DDISABLE_PF_RING_SUPPORT=ON
# WE have broken cmake library with Boost on CentOS 6 and should use library from cmake
# http://public.kitware.com/Bug/view.php?id=15270
cmake .. -DWE_USE_PFRING_FROM_NTOP=ON -DBoost_NO_BOOST_CMAKE=BOOL:ON
cmake .. -DBoost_NO_BOOST_CMAKE=BOOL:ON
make
%install

View File

@ -11,7 +11,7 @@ Name: fastnetmon
Version: 1.1.1
Release: 1%{?dist}
Summary: A high performance DoS/DDoS load analyzer built on top of multiple packet capture engines (NetFlow, IPFIX, sFLOW, netmap, PF_RING, PCAP).
Summary: A high performance DoS/DDoS load analyzer built on top of multiple packet capture engines (NetFlow, IPFIX, sFlow, Netmap, PCAP).
Group: System Environment/Daemons
License: GPLv2
URL: https://fastnetmon.com
@ -20,14 +20,10 @@ URL: https://fastnetmon.com
#Source0: https://github.com/pavel-odintsov/fastnetmon/archive/v%{version}.tar.gz
Source0: https://github.com/pavel-odintsov/fastnetmon/archive/fastnetmon-%{version}.tar.gz
# Yes, it's bad idea to specify fixed version of PF_RING but they have strange issue when we use another library version
BuildRequires: git, make, gcc, gcc-c++, boost-devel, GeoIP-devel, log4cpp-devel
BuildRequires: ncurses-devel, boost-thread, boost-regex, libpcap-devel, gpm-devel, clang, cmake
BuildRequires: pfring >= 6.0.3-9154
BuildRequires: systemd
Requires: pfring >= 6.0.3-9154
Requires: log4cpp, libpcap, boost-thread, boost-thread, boost-regex
Requires(pre): shadow-utils
Requires(post): systemd
@ -38,7 +34,7 @@ Provides: fastnetmon
%description
A high performance DoS/DDoS load analyzer built on top of multiple packet capture
engines (NetFlow, IPFIX, sFLOW, netmap, PF_RING, PCAP).
engines (NetFlow, IPFIX, sFLOW, netmap, PCAP).
%prep
# For production
@ -51,8 +47,7 @@ engines (NetFlow, IPFIX, sFLOW, netmap, PF_RING, PCAP).
cd src
mkdir build
cd build
# You could disable PF_RING support with param: -DDISABLE_PF_RING_SUPPORT=ON
cmake .. -DWE_USE_PFRING_FROM_NTOP=ON
cmake ..
make
%install

View File

@ -11,7 +11,7 @@ Name: fastnetmon
Version: 1.1.1
Release: 1%{?dist}
Summary: A high performance DoS/DDoS load analyzer built on top of multiple packet capture engines (NetFlow, IPFIX, sFLOW, netmap, PF_RING, PCAP).
Summary: A high performance DoS/DDoS load analyzer built on top of multiple packet capture engines (NetFlow, IPFIX, sFlow, Netmap, PCAP).
Group: System Environment/Daemons
License: GPLv2
URL: https://fastnetmon.com
@ -32,7 +32,7 @@ Provides: fastnetmon
%description
A high performance DoS/DDoS load analyzer built on top of multiple packet capture
engines (NetFlow, IPFIX, sFLOW, netmap, PF_RING, PCAP).
engines (NetFlow, IPFIX, sFlow, Netmap, PCAP).
%prep
%setup -n %{name}-%{fastnetmon_commit}
@ -41,8 +41,7 @@ engines (NetFlow, IPFIX, sFLOW, netmap, PF_RING, PCAP).
cd src
mkdir build
cd build
# We should disable PF_RING plugon support because we did not have it in repository
cmake .. -DDISABLE_PF_RING_SUPPORT=ON
cmake ..
make
%install

View File

@ -20,10 +20,6 @@
#include "netmap_plugin/netmap_collector.h"
#endif
#ifdef PF_RING
#include "pfring_plugin/pfring_collector.h"
#endif
#ifdef FASTNETMON_ENABLE_AFPACKET
#include "afpacket_plugin/afpacket_collector.h"
#endif
@ -1982,12 +1978,6 @@ void traffic_draw_ipv4_program() {
output_buffer << get_pcap_stats() << "\n";
}
#ifdef PF_RING
if (enable_data_collection_from_mirror) {
output_buffer << get_pf_ring_stats();
}
#endif
if (!ban_list.empty()) {
output_buffer << std::endl << "Ban list:" << std::endl;
output_buffer << print_ddos_attack_details();

View File

@ -6,7 +6,7 @@ FastNetMon \- a high performance DoS/DDoS load analyzer built on top of multiple
.SH SYNOPSIS
fastnetmon [--daemonize]
.SH DESCRIPTION
FastNetMon - a high performance DoS/DDoS load analyzer built on top of multiple packet capture engines (NetFlow, IPFIX, sFLOW, netmap, PF_RING, PCAP).
FastNetMon - a high performance DoS/DDoS load analyzer built on top of multiple packet capture engines (NetFlow, IPFIX, sFlow, Netmap, PCAP).
For more information about configuration, please look at the comments in /etc/fastnetmon.conf and check the project GitHub page: https://github.com/pavel-odintsov/fastnetmon.
.SH OPTIONS

View File

@ -1,767 +0,0 @@
// log4cpp logging facility
#include "log4cpp/Appender.hh"
#include "log4cpp/BasicLayout.hh"
#include "log4cpp/Category.hh"
#include "log4cpp/FileAppender.hh"
#include "log4cpp/Layout.hh"
#include "log4cpp/OstreamAppender.hh"
#include "log4cpp/PatternLayout.hh"
#include "log4cpp/Priority.hh"
#include "../fast_library.h"
// For support uint32_t, uint16_t
#include <sys/types.h>
#include <iomanip>
#include <iostream>
// For config map operations
#include <map>
#include <string>
// For support: IPPROTO_TCP, IPPROTO_ICMP, IPPROTO_UDP
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include "pfring_collector.h"
#include "pfring.h"
#ifdef PF_RING_ZC
#include "pfring_zc.h"
#endif
#include <numa.h>
uint32_t pfring_sampling_ratio = 1;
// Get log4cpp logger from main program
extern log4cpp::Category& logger;
extern uint64_t total_unparsed_packets;
// Global configuration map
extern std::map<std::string, std::string> configuration_map;
// Interface name or interface list (delimitered by comma)
std::string work_on_interfaces = "";
// This variable name should be uniq for every plugin!
process_packet_pointer pfring_process_func_ptr = NULL;
// We can look inside L2TP packets with IP encapsulation
// And do it by default
bool do_unpack_l2tp_over_ip = true;
// Variable from PF_RING multi channel mode
int num_pfring_channels = 0;
// We can use software or hardware (in kernel module) packet parser
bool we_use_pf_ring_in_kernel_parser = true;
// By default we pool PF_RING on one thread
bool enable_pfring_multi_channel_mode = false;
struct thread_stats {
u_int64_t __padding_0[8];
u_int64_t numPkts;
u_int64_t numBytes;
pfring* ring;
pthread_t pd_thread;
int core_affinity;
volatile u_int64_t do_shutdown;
u_int64_t __padding_1[3];
};
struct thread_stats* threads;
pfring* pf_ring_descr = NULL;
// We can use ZC api
bool pf_ring_zc_api_mode = false;
#ifdef PF_RING_ZC
u_int32_t zc_num_threads = 0;
pthread_t* zc_threads;
pfring_zc_cluster* zc;
pfring_zc_worker* zw;
pfring_zc_queue** inzq;
pfring_zc_queue** outzq;
pfring_zc_multi_queue* outzmq; /* fanout */
pfring_zc_buffer_pool* wsp;
pfring_zc_pkt_buff** buffers;
#endif
// Prototypes
#ifdef PF_RING_ZC
bool zc_main_loop(const char* device);
#endif
bool pf_ring_main_loop(const char* dev);
bool pf_ring_main_loop_multi_channel(const char* dev);
void* pf_ring_packet_consumer_thread(void* _id);
void pfring_main_packet_process_task();
void start_pfring_collection(process_packet_pointer func_ptr) {
logger << log4cpp::Priority::INFO << "PF_RING plugin started";
pfring_process_func_ptr = func_ptr;
#ifdef PF_RING_ZC
if (configuration_map.count("enable_pf_ring_zc_mode")) {
if (configuration_map["enable_pf_ring_zc_mode"] == "on") {
pf_ring_zc_api_mode = true;
} else {
pf_ring_zc_api_mode = false;
}
}
#endif
if (configuration_map.count("interfaces") != 0) {
work_on_interfaces = configuration_map["interfaces"];
// We should check all interfaces and check zc flag for all
if (work_on_interfaces.find("zc:") != std::string::npos) {
we_use_pf_ring_in_kernel_parser = false;
logger << log4cpp::Priority::INFO
<< "We detect run in PF_RING Zero Copy or DNA mode and we enable packet parser!";
}
logger << log4cpp::Priority::INFO << "We selected interface:" << work_on_interfaces;
}
if (configuration_map.count("pfring_sampling_ratio") != 0) {
pfring_sampling_ratio =
convert_string_to_integer(configuration_map["pfring_sampling_ratio"]);
}
if (work_on_interfaces == "") {
logger << log4cpp::Priority::ERROR << "Please specify interface";
exit(1);
}
pfring_main_packet_process_task();
}
void stop_pfring_collection() {
pfring_breakloop(pf_ring_descr);
}
void parse_packet_pf_ring(const struct pfring_pkthdr* h, const u_char* p, const u_char* user_bytes) {
// Description of all fields: http://www.ntop.org/pfring_api/structpkt__parsing__info.html
simple_packet_t packet;
// We pass only one packet to processing
packet.number_of_packets = 1;
// Now we support only non sampled input from PF_RING
packet.sample_ratio = pfring_sampling_ratio;
if (!pf_ring_zc_api_mode) {
if (!we_use_pf_ring_in_kernel_parser) {
// In ZC (zc:eth0) mode you should manually add packet parsing here
// Because it disabled by default: "parsing already disabled in zero-copy"
// http://www.ntop.org/pfring_api/pfring_8h.html
// Parse up to L3, no timestamp, no hashing
// 1 - add timestamp, 0 - disable hash
// We should zeroify packet header because PFRING ZC did not do this!
memset((void*)&h->extended_hdr.parsed_pkt, 0, sizeof(h->extended_hdr.parsed_pkt));
// We do not calculate timestamps here because it's useless and consumes so much cpu
// https://github.com/ntop/PF_RING/issues/9
u_int8_t timestamp = 0;
u_int8_t add_hash = 0;
pfring_parse_pkt((u_char*)p, (struct pfring_pkthdr*)h, 4, timestamp, add_hash);
}
}
if (do_unpack_l2tp_over_ip) {
// 2014-12-08 13:36:53,537 [INFO] [00:1F:12:84:E2:E7 -> 90:E2:BA:49:85:C8]
// [IPv4][5.254.105.102:0 -> 159.253.17.251:0]
// [l3_proto=115][hash=2784721876][tos=32][tcp_seq_num=0]
// [caplen=128][len=873][parsed_header_len=0][eth_offset=-14][l3_offset=14][l4_offset=34][payload_offset=0]
// L2TP has an proto number 115
if (h->extended_hdr.parsed_pkt.l3_proto == 115) {
// pfring_parse_pkt expects that the hdr memory is either zeroed or contains valid
// values
// for the current packet, in order to avoid parsing twice the same packet headers.
struct pfring_pkthdr l2tp_header;
memset(&l2tp_header, 0, sizeof(l2tp_header));
int16_t l4_offset = h->extended_hdr.parsed_pkt.offset.l4_offset;
// L2TP has two headers: L2TP and default L2-Specific Sublayer: every header for 4bytes
int16_t l2tp_header_size = 8;
l2tp_header.len = h->len - (l4_offset + l2tp_header_size);
l2tp_header.caplen = h->caplen - (l4_offset + l2tp_header_size);
const u_char* l2tp_tunnel_payload = p + l4_offset + l2tp_header_size;
// 1 - add timestamp, 0 - disable hash
pfring_parse_pkt((u_char*)l2tp_tunnel_payload, &l2tp_header, 4, 1, 0);
// Copy data back
// TODO: it's not fine solution and I should redesign this code
memcpy((struct pfring_pkthdr*)h, &l2tp_header, sizeof(l2tp_header));
// TODO: Global pfring_print_parsed_pkt can fail because we did not shift 'p' pointer
// Uncomment this line for deep inspection of all packets
/*
char buffer[512];
pfring_print_parsed_pkt(buffer, 512, l2tp_tunnel_payload, h);
logger<<log4cpp::Priority::INFO<<buffer;
*/
}
}
if (h->extended_hdr.parsed_pkt.ip_version != 4 && h->extended_hdr.parsed_pkt.ip_version != 6) {
total_unparsed_packets++;
return;
}
packet.ip_protocol_version = h->extended_hdr.parsed_pkt.ip_version;
if (packet.ip_protocol_version == 4) {
// IPv4
/* PF_RING stores data in host byte order but we use network byte order */
packet.src_ip = htonl(h->extended_hdr.parsed_pkt.ip_src.v4);
packet.dst_ip = htonl(h->extended_hdr.parsed_pkt.ip_dst.v4);
} else {
// IPv6
memcpy(packet.src_ipv6.s6_addr, h->extended_hdr.parsed_pkt.ip_src.v6.s6_addr, 16);
memcpy(packet.dst_ipv6.s6_addr, h->extended_hdr.parsed_pkt.ip_dst.v6.s6_addr, 16);
}
packet.source_port = h->extended_hdr.parsed_pkt.l4_src_port;
packet.destination_port = h->extended_hdr.parsed_pkt.l4_dst_port;
// We need this for deep packet inspection
packet.packet_payload_length = h->len;
packet.packet_payload_pointer = (void*)p;
packet.length = h->len;
packet.protocol = h->extended_hdr.parsed_pkt.l3_proto;
packet.ts = h->ts;
// Copy flags from PF_RING header to our pseudo header
if (packet.protocol == IPPROTO_TCP) {
packet.flags = h->extended_hdr.parsed_pkt.tcp.flags;
} else {
packet.flags = 0;
}
pfring_process_func_ptr(packet);
}
// Main worker thread for packet handling
void pfring_main_packet_process_task() {
const char* device_name = work_on_interfaces.c_str();
bool pf_ring_init_result = false;
if (pf_ring_zc_api_mode) {
#ifdef PF_RING_ZC
pf_ring_init_result = zc_main_loop((char*)device_name);
#else
logger << log4cpp::Priority::ERROR << "PF_RING library hasn't ZC support, please try SVN version";
#endif
} else {
if (enable_pfring_multi_channel_mode) {
pf_ring_init_result = pf_ring_main_loop_multi_channel(device_name);
} else {
pf_ring_init_result = pf_ring_main_loop(device_name);
}
}
if (!pf_ring_init_result) {
// Internal error in PF_RING
logger << log4cpp::Priority::ERROR << "PF_RING initilization failed, exit from program";
exit(1);
}
}
std::string get_pf_ring_stats() {
std::stringstream output_buffer;
if (pf_ring_zc_api_mode) {
#ifdef PF_RING_ZC
pfring_zc_stat stats;
// We have elements in insq for every hardware device! We shoulw add ability to configure ot
int stats_res = pfring_zc_stats(inzq[0], &stats);
if (stats_res) {
logger << log4cpp::Priority::ERROR << "Can't get PF_RING ZC stats for in queue";
} else {
double dropped_percent = 0;
if (stats.recv + stats.sent > 0) {
dropped_percent = (double)stats.drop / ((double)stats.recv + (double)stats.sent) * 100;
}
output_buffer << "\n";
output_buffer << "PF_RING ZC in queue statistics\n";
output_buffer << "Received:\t" << stats.recv << "\n";
output_buffer << "Sent:\t\t" << stats.sent << "\n";
output_buffer << "Dropped:\t" << stats.drop << "\n";
output_buffer << "Dropped:\t" << std::fixed << std::setprecision(2) << dropped_percent << " %\n";
}
output_buffer << "\n";
output_buffer << "PF_RING ZC out queue statistics\n";
u_int64_t total_recv = 0;
u_int64_t total_sent = 0;
u_int64_t total_drop = 0;
for (int i = 0; i < zc_num_threads; i++) {
pfring_zc_stat outq_stats;
int outq_stats_res = pfring_zc_stats(outzq[0], &outq_stats);
if (stats_res) {
logger << log4cpp::Priority::ERROR << "Can't get PF_RING ZC stats for out queue";
} else {
total_recv += outq_stats.recv;
total_sent += outq_stats.sent;
total_drop += outq_stats.drop;
}
}
double total_drop_percent = 0;
if (total_recv + total_sent > 0) {
total_drop_percent = (double)total_drop / ((double)total_recv + (double)total_sent) * 100;
}
output_buffer << "Received:\t" << total_recv << "\n";
output_buffer << "Sent:\t\t" << total_sent << "\n";
output_buffer << "Dropped:\t" << total_drop << "\n";
output_buffer << "Dropped:\t" << std::fixed << std::setprecision(2) << total_drop_percent << " %\n";
#endif
}
// Getting stats for multi channel mode is so complex task
if (!enable_pfring_multi_channel_mode && !pf_ring_zc_api_mode) {
pfring_stat pfring_status_data;
if (pfring_stats(pf_ring_descr, &pfring_status_data) >= 0) {
char stats_buffer[256];
double packets_dropped_percent = 0;
if (pfring_status_data.recv > 0) {
packets_dropped_percent = (double)pfring_status_data.drop / pfring_status_data.recv * 100;
}
sprintf(stats_buffer,
"Packets received:\t%lu\n"
"Packets dropped:\t%lu\n"
"Packets dropped:\t%.1f %%\n",
(long unsigned int)pfring_status_data.recv,
(long unsigned int)pfring_status_data.drop, packets_dropped_percent);
output_buffer << stats_buffer;
} else {
logger << log4cpp::Priority::ERROR << "Can't get PF_RING stats";
}
}
return output_buffer.str();
}
bool pf_ring_main_loop_multi_channel(const char* dev) {
int MAX_NUM_THREADS = 64;
if ((threads = (struct thread_stats*)calloc(MAX_NUM_THREADS, sizeof(struct thread_stats))) == NULL) {
logger << log4cpp::Priority::ERROR << "Can't allocate memory for threads structure";
return false;
}
u_int32_t flags = 0;
flags |= PF_RING_PROMISC; /* hardcode: promisc=1 */
flags |= PF_RING_DNA_SYMMETRIC_RSS; /* Note that symmetric RSS is ignored by non-DNA drivers */
flags |= PF_RING_LONG_HEADER;
packet_direction direction = rx_only_direction;
pfring* ring_array[MAX_NUM_RX_CHANNELS];
unsigned int snaplen = 128;
num_pfring_channels = pfring_open_multichannel(dev, snaplen, flags, ring_array);
if (num_pfring_channels <= 0) {
logger << log4cpp::Priority::INFO << "pfring_open_multichannel returned: " << num_pfring_channels
<< " and error:" << strerror(errno);
return false;
}
u_int num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
logger << log4cpp::Priority::INFO << "We have: " << num_cpus << " logical cpus in this server";
logger << log4cpp::Priority::INFO << "We have: " << num_pfring_channels << " channels from pf_ring NIC";
// We should not start more processes then we have kernel cores
// if (num_pfring_channels > num_cpus) {
// num_pfring_channels = num_cpus;
//}
for (int i = 0; i < num_pfring_channels; i++) {
// char buf[32];
threads[i].ring = ring_array[i];
// threads[i].core_affinity = threads_core_affinity[i];
int rc = 0;
if ((rc = pfring_set_direction(threads[i].ring, direction)) != 0) {
logger << log4cpp::Priority::INFO << "pfring_set_direction returned: " << rc;
}
if ((rc = pfring_set_socket_mode(threads[i].ring, recv_only_mode)) != 0) {
logger << log4cpp::Priority::INFO << "pfring_set_socket_mode returned: " << rc;
}
int rehash_rss = 0;
if (rehash_rss) pfring_enable_rss_rehash(threads[i].ring);
int poll_duration = 0;
if (poll_duration > 0) pfring_set_poll_duration(threads[i].ring, poll_duration);
pfring_enable_ring(threads[i].ring);
unsigned long thread_id = i;
pthread_create(&threads[i].pd_thread, NULL, pf_ring_packet_consumer_thread, (void*)thread_id);
}
for (int i = 0; i < num_pfring_channels; i++) {
pthread_join(threads[i].pd_thread, NULL);
pfring_close(threads[i].ring);
}
return true;
}
void* pf_ring_packet_consumer_thread(void* _id) {
long thread_id = (long)_id;
int wait_for_packet = 1;
// TODO: fix it
bool do_shutdown = false;
while (!do_shutdown) {
u_char* buffer = NULL;
struct pfring_pkthdr hdr;
if (pfring_recv(threads[thread_id].ring, &buffer, 0, &hdr, wait_for_packet) > 0) {
// TODO: pass (u_char*)thread_id)
parse_packet_pf_ring(&hdr, buffer, 0);
} else {
if (wait_for_packet == 0) {
usleep(1); // sched_yield();
}
}
}
return NULL;
}
#ifdef PF_RING_ZC
int rr = -1;
int32_t rr_distribution_func(pfring_zc_pkt_buff* pkt_handle, pfring_zc_queue* in_queue, void* user) {
long num_out_queues = (long)user;
if (++rr == num_out_queues) {
rr = 0;
}
return rr;
}
#endif
#ifdef PF_RING_ZC
int bind2core(int core_id) {
cpu_set_t cpuset;
int s;
if (core_id < 0) return -1;
CPU_ZERO(&cpuset);
CPU_SET(core_id, &cpuset);
if ((s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset)) != 0) {
logger << log4cpp::Priority::INFO << "Error while binding to core:" << core_id;
return -1;
} else {
return 0;
}
}
#endif
#ifdef PF_RING_ZC
void* zc_packet_consumer_thread(void* _id) {
long id = (long)_id;
pfring_zc_pkt_buff* b = buffers[id];
// Bind to core with thread number
bind2core(id);
u_int8_t wait_for_packet = 1;
struct pfring_pkthdr zc_header;
memset(&zc_header, 0, sizeof(zc_header));
while (true) {
if (pfring_zc_recv_pkt(outzq[id], &b, wait_for_packet) > 0) {
u_char* pkt_data = pfring_zc_pkt_buff_data(b, outzq[id]);
memset(&zc_header, 0, sizeof(zc_header));
zc_header.len = b->len;
zc_header.caplen = b->len;
pfring_parse_pkt(pkt_data, (struct pfring_pkthdr*)&zc_header, 4, 1, 0);
parse_packet_pf_ring(&zc_header, pkt_data, 0);
}
}
pfring_zc_sync_queue(outzq[id], rx_only);
return NULL;
}
#endif
int max_packet_len(const char* device) {
int max_len = 0;
pfring* ring = pfring_open(device, 1536, PF_RING_PROMISC);
if (ring == NULL) return 1536;
// pfring_get_card_settings have added in 6.0.3
// We should not use 6.0.3 API for PF_RING library from ntop because it announces "6.0.3" but lack
// of many 6.0.3 features
#if RING_VERSION_NUM >= 0x060003 and !defined(WE_USE_PFRING_FROM_NTOP)
pfring_card_settings settings;
pfring_get_card_settings(ring, &settings);
max_len = settings.max_packet_size;
#else
if (ring->dna.dna_mapped_device) {
max_len = ring->dna.dna_dev.mem_info.rx.packet_memory_slot_len;
} else {
max_len = pfring_get_mtu_size(ring);
if (max_len == 0) max_len = 9000 /* Jumbo */;
max_len += 14 /* Eth */ + 4 /* VLAN */;
}
#endif
pfring_close(ring);
return max_len;
}
#define MAX_CARD_SLOTS 32768
#define PREFETCH_BUFFERS 8
#define QUEUE_LEN 8192
#ifdef PF_RING_ZC
bool zc_main_loop(const char* device) {
u_int32_t cluster_id = 0;
int bind_core = -1;
u_int num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
logger << log4cpp::Priority::INFO << "We have: " << num_cpus << " logical cpus in this server";
// TODO: add support for multiple devices!
u_int32_t num_devices = 1;
zc_num_threads = num_cpus - 1;
logger << log4cpp::Priority::INFO << "We will start " << zc_num_threads << " worker threads";
u_int32_t tot_num_buffers =
(num_devices * MAX_CARD_SLOTS) + (zc_num_threads * QUEUE_LEN) + zc_num_threads + PREFETCH_BUFFERS;
u_int32_t buffer_len = max_packet_len(device);
logger << log4cpp::Priority::INFO << "We got max packet len from device: " << buffer_len;
logger << log4cpp::Priority::INFO << "We will use total number of ZC buffers: " << tot_num_buffers;
zc = pfring_zc_create_cluster(cluster_id, buffer_len, 0, tot_num_buffers,
numa_node_of_cpu(bind_core), NULL /* auto hugetlb mountpoint */
);
if (zc == NULL) {
logger << log4cpp::Priority::INFO << "pfring_zc_create_cluster error: " << strerror(errno)
<< " Please check that pf_ring.ko is loaded and hugetlb fs is mounted";
return false;
}
zc_threads = (pthread_t*)calloc(zc_num_threads, sizeof(pthread_t));
buffers = (pfring_zc_pkt_buff**)calloc(zc_num_threads, sizeof(pfring_zc_pkt_buff*));
inzq = (pfring_zc_queue**)calloc(num_devices, sizeof(pfring_zc_queue*));
outzq = (pfring_zc_queue**)calloc(zc_num_threads, sizeof(pfring_zc_queue*));
for (int i = 0; i < zc_num_threads; i++) {
buffers[i] = pfring_zc_get_packet_handle(zc);
if (buffers[i] == NULL) {
logger << log4cpp::Priority::ERROR << "pfring_zc_get_packet_handle failed";
return false;
}
}
for (int i = 0; i < num_devices; i++) {
u_int32_t zc_flags = 0;
inzq[i] = pfring_zc_open_device(zc, device, rx_only, zc_flags);
if (inzq[i] == NULL) {
logger << log4cpp::Priority::ERROR << "pfring_zc_open_device error " << strerror(errno)
<< " Please check that device is up and not already used";
return false;
}
#if RING_VERSION_NUM >= 0x060003
int pf_ring_license_state = pfring_zc_check_license();
if (!pf_ring_license_state) {
logger << log4cpp::Priority::WARN << "PF_RING ZC haven't license for device" << device
<< " and running in trial mode and will work only 5 minutes! Please buy license "
"or switch to vanilla PF_RING";
}
#endif
}
for (int i = 0; i < zc_num_threads; i++) {
outzq[i] = pfring_zc_create_queue(zc, QUEUE_LEN);
if (outzq[i] == NULL) {
logger << log4cpp::Priority::ERROR << "pfring_zc_create_queue error: " << strerror(errno);
return false;
}
}
wsp = pfring_zc_create_buffer_pool(zc, PREFETCH_BUFFERS);
if (wsp == NULL) {
logger << log4cpp::Priority::ERROR << "pfring_zc_create_buffer_pool error";
return false;
}
logger << log4cpp::Priority::INFO << "We are starting balancer with: " << zc_num_threads << " threads";
pfring_zc_distribution_func func = rr_distribution_func;
u_int8_t wait_for_packet = 1;
// We run balancer at last thread
int32_t bind_worker_core = zc_num_threads;
logger << log4cpp::Priority::INFO << "We will run balancer on core: " << bind_worker_core;
zw = pfring_zc_run_balancer(inzq, outzq, num_devices, zc_num_threads, wsp,
round_robin_bursts_policy, NULL /* idle callback */, func,
(void*)((long)zc_num_threads), !wait_for_packet, bind_worker_core);
if (zw == NULL) {
logger << log4cpp::Priority::ERROR << "pfring_zc_run_balancer error:" << strerror(errno);
return false;
}
for (int i = 0; i < zc_num_threads; i++) {
pthread_create(&zc_threads[i], NULL, zc_packet_consumer_thread, (void*)(long)i);
}
for (int i = 0; i < zc_num_threads; i++) {
pthread_join(zc_threads[i], NULL);
}
pfring_zc_kill_worker(zw);
pfring_zc_destroy_cluster(zc);
return true;
}
#endif
bool pf_ring_main_loop(const char* dev) {
// We could pool device in multiple threads
unsigned int num_threads = 1;
bool promisc = true;
/* This flag manages packet parser for extended_hdr */
bool use_extended_pkt_header = true;
bool enable_hw_timestamp = false;
bool dont_strip_timestamps = false;
u_int32_t flags = 0;
if (num_threads > 1) flags |= PF_RING_REENTRANT;
if (use_extended_pkt_header) flags |= PF_RING_LONG_HEADER;
if (promisc) flags |= PF_RING_PROMISC;
if (enable_hw_timestamp) flags |= PF_RING_HW_TIMESTAMP;
if (!dont_strip_timestamps) flags |= PF_RING_STRIP_HW_TIMESTAMP;
if (!we_use_pf_ring_in_kernel_parser) {
flags |= PF_RING_DO_NOT_PARSE;
}
flags |= PF_RING_DNA_SYMMETRIC_RSS; /* Note that symmetric RSS is ignored by non-DNA drivers */
// use default value from pfcount.c
unsigned int snaplen = 128;
pf_ring_descr = pfring_open(dev, snaplen, flags);
if (pf_ring_descr == NULL) {
logger
<< log4cpp::Priority::INFO << "pfring_open error: " << strerror(errno)
<< " (pf_ring not loaded or perhaps you use quick mode and have already a socket bound to: " << dev
<< ")";
return false;
}
logger << log4cpp::Priority::INFO << "Successully binded to: " << dev;
// We need cast to int because in other way it will be interpreted as char :(
logger << log4cpp::Priority::INFO
<< "Device RX channels number: " << int(pfring_get_num_rx_channels(pf_ring_descr));
u_int32_t version;
// Set spplication name in /proc
int pfring_set_application_name_result =
pfring_set_application_name(pf_ring_descr, (char*)"fastnetmon");
if (pfring_set_application_name_result != 0) {
logger << log4cpp::Priority::ERROR << "Can't set program name for PF_RING: pfring_set_application_name";
}
pfring_version(pf_ring_descr, &version);
logger.info("Using PF_RING v.%d.%d.%d", (version & 0xFFFF0000) >> 16,
(version & 0x0000FF00) >> 8, version & 0x000000FF);
int pfring_set_socket_mode_result = pfring_set_socket_mode(pf_ring_descr, recv_only_mode);
if (pfring_set_socket_mode_result != 0) {
logger.info("pfring_set_socket_mode returned [rc=%d]\n", pfring_set_socket_mode_result);
}
// enable ring
if (pfring_enable_ring(pf_ring_descr) != 0) {
logger << log4cpp::Priority::INFO << "Unable to enable ring :-(";
pfring_close(pf_ring_descr);
return false;
}
// Active wait wor packets. But I did not know what is mean..
u_int8_t wait_for_packet = 1;
pfring_loop(pf_ring_descr, parse_packet_pf_ring, (u_char*)NULL, wait_for_packet);
return true;
}

View File

@ -1,10 +0,0 @@
#ifndef PFRING_PLUGIN_H
#define PFRING_PLUGIN_H
#include "../fastnetmon_types.h"
// This function should be implemented in plugin
void start_pfring_collection(process_packet_pointer func_ptr);
void stop_pfring_collection();
std::string get_pf_ring_stats();
#endif

View File

@ -17,10 +17,6 @@
#include "pcap_plugin/pcap_collector.h"
#include "sflow_plugin/sflow_collector.h"
#ifdef PF_RING
#include "pfring_plugin/pfring_collector.h"
#endif
#ifdef FASTNETMON_ENABLE_AFPACKET
#include "afpacket_plugin/afpacket_collector.h"
#endif
@ -121,7 +117,7 @@ int main(int argc, char* argv[]) {
}
#endif
// Required by Netmap and PF_RING plugins
// Required by Netmap plugin
// We use fake interface name here because netmap could make server unreachable :)
configuration_map["interfaces"] = "ethXXX";
@ -134,13 +130,6 @@ int main(int argc, char* argv[]) {
} else if (strstr(argv[1], "pcap") != NULL) {
std::cout << "Starting pcap" << std::endl;
start_pcap_collection(process_packet);
} else if (strstr(argv[1], "pfring") != NULL) {
#ifdef PF_RING
std::cout << "Starting pf_ring" << std::endl;
start_pfring_collection(process_packet);
#else
std::cout << "PF_RING support disabled here" << std::endl;
#endif
} else if (strstr(argv[1], "afpacket") != NULL) {
#ifdef FASTNETMON_ENABLE_AFPACKET
std::cout << "Starting afpacket" << std::endl;

View File

@ -210,7 +210,7 @@ DOC
my $spec_file_summary_section = <<'DOC';
Release: 1%{?dist}
Summary: A high performance DoS/DDoS load analyzer built on top of multiple packet capture engines (NetFlow, IPFIX, sFLOW, netmap, PF_RING, PCAP).
Summary: A high performance DoS/DDoS load analyzer built on top of multiple packet capture engines (NetFlow, IPFIX, sFLOW, netmap, PCAP).
Group: System Environment/Daemons
License: GPLv2
URL: https://fastnetmon.com
@ -239,7 +239,7 @@ DOC
%description
A high performance DoS/DDoS load analyzer built on top of multiple packet capture
engines (NetFlow, IPFIX, sFLOW, netmap, PF_RING, PCAP).
engines (NetFlow, IPFIX, sFlow, Netmap, PCAP).
DOC
@ -509,7 +509,7 @@ my $fastnetmon_systemv_init = <<'DOC';
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Fast DDoS detection toolkit.
# Description: Fast DDoS detection toolkit with sFLOW/Netflow/netmap/pf_ring support.
# Description: Fast DDoS detection toolkit with sFLOW/Netflow/Netmap support.
### END INIT INFO
# test -r /etc/default/fastnetmon && . /etc/default/fastnetmon

View File

@ -39,7 +39,6 @@ boost_1_74_0
json-c-0.13
libicu_65_1
log4cpp1.1.1
pf_ring_6.0.3
gobgp_2_17_0
grpc_1_30_2
libhiredis_0_13
@ -55,12 +54,7 @@ for my $library (@our_libraries) {
unless (-e $library_path) {
warn "Can't find library $library please check\n";
if ($library eq 'pf_ring_6.0.3') {
next;
} else {
die "Some required libraries are missing\n";
}
die "Some required libraries are missing\n";
}
print "Library: $library\n";

View File

@ -1,78 +0,0 @@
#include "pfring.h"
#include <iostream>
/* How to compile me:
g++ pfring_parser_zc_issue.c -I/opt/pf_ring/include -L/opt/pf_ring/lib/ -lpfring -lnuma
*/
void parse_packet_pf_ring(const struct pfring_pkthdr* h, const u_char* p, const u_char* user_bytes) {
memset((void*)&h->extended_hdr.parsed_pkt, 0, sizeof(h->extended_hdr.parsed_pkt));
pfring_parse_pkt((u_char*)p, (struct pfring_pkthdr*)h, 4, 1, 0);
char buffer[512];
pfring_print_parsed_pkt(buffer, 512, p, h);
std::cout << buffer;
}
int main() {
char* dev = "zc:eth3";
// We could pool device in multiple threads
unsigned int num_threads = 1;
bool promisc = true;
/* This flag manages packet parser for extended_hdr */
bool use_extended_pkt_header = true;
bool enable_hw_timestamp = false;
bool dont_strip_timestamps = false;
u_int32_t flags = 0;
if (num_threads > 1) flags |= PF_RING_REENTRANT;
if (use_extended_pkt_header) flags |= PF_RING_LONG_HEADER;
if (promisc) flags |= PF_RING_PROMISC;
if (enable_hw_timestamp) flags |= PF_RING_HW_TIMESTAMP;
if (!dont_strip_timestamps) flags |= PF_RING_STRIP_HW_TIMESTAMP;
// if (!we_use_pf_ring_in_kernel_parser) {
// flags != PF_RING_DO_NOT_PARSE;
//}
// flags |= PF_RING_DNA_SYMMETRIC_RSS; /* Note that symmetric RSS is ignored by non-DNA drivers
// */
// use default value from pfcount.c
unsigned int snaplen = 128;
pfring* pf_ring_descr = pfring_open(dev, snaplen, flags);
if (pf_ring_descr == NULL) {
std::cout
<< "pfring_open error: " << strerror(errno)
<< " (pf_ring not loaded or perhaps you use quick mode and have already a socket bound to: " << dev
<< ")";
return false;
}
u_int32_t version;
// Set spplication name in /proc
int pfring_set_application_name_result =
pfring_set_application_name(pf_ring_descr, (char*)"fastnetmon");
if (pfring_set_application_name_result != 0) {
std::cout << "Can't set program name for PF_RING: pfring_set_application_name";
}
pfring_version(pf_ring_descr, &version);
int pfring_set_socket_mode_result = pfring_set_socket_mode(pf_ring_descr, recv_only_mode);
// enable ring
if (pfring_enable_ring(pf_ring_descr) != 0) {
std::cout << "Unable to enable ring :-(";
pfring_close(pf_ring_descr);
return false;
}
u_int8_t wait_for_packet = 1;
pfring_loop(pf_ring_descr, parse_packet_pf_ring, (u_char*)NULL, wait_for_packet);
}

View File

@ -17,10 +17,6 @@
#include "../pcap_plugin/pcap_collector.h"
#include "../sflow_plugin/sflow_collector.h"
#ifdef PF_RING
#include "../pfring_plugin/pfring_collector.h"
#endif
#include "../netmap_plugin/netmap_collector.h"
#include <boost/atomic.hpp>
@ -128,7 +124,7 @@ int main(int argc, char* argv[]) {
init_logging();
// Required by Netmap and PF_RING plugins
// Required by Netmap plugin
// We use fake interface name here because netmap could make server unreachable :)
configuration_map["interfaces"] = "eth5";
start_netmap_collection(process_packet);