summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yml93
-rw-r--r--CMakeLists.txt22
-rw-r--r--dependencies/nDPIsrvd.h1
-rw-r--r--nDPId-test.c16
-rw-r--r--nDPId.c92
-rw-r--r--nDPIsrvd.c63
-rwxr-xr-xscripts/daemon.sh24
-rwxr-xr-xscripts/get-and-build-libndpi.sh6
-rw-r--r--utils.c48
-rw-r--r--utils.h2
10 files changed, 268 insertions, 99 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 83b98ac50..291d86fd2 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -18,13 +18,17 @@ jobs:
runs-on: ${{ matrix.os }}
env:
CMAKE_C_COMPILER: ${{ matrix.compiler }}
- CMAKE_C_FLAGS: -Werror
+ CMAKE_C_FLAGS: -Werror ${{ matrix.cflags }}
+ CMAKE_C_EXE_LINKER_FLAGS: ${{ matrix.ldflags }}
+ CMAKE_MODULE_LINKER_FLAGS: ${{ matrix.ldflags }}
strategy:
fail-fast: true
matrix:
include:
- compiler: "gcc"
os: "ubuntu-latest"
+ ndpi_build: "-DBUILD_NDPI=ON"
+ ndpid_examples: "-DBUILD_EXAMPLES=ON"
ndpid_gcrypt: "-DNDPI_WITH_GCRYPT=OFF"
ndpid_zlib: "-DENABLE_ZLIB=ON"
sanitizer: "-DENABLE_SANITIZER=OFF -DENABLE_SANITIZER_THREAD=OFF"
@@ -35,6 +39,8 @@ jobs:
ndpi_min_version: "4.8"
- compiler: "gcc"
os: "ubuntu-latest"
+ ndpi_build: "-DBUILD_NDPI=ON"
+ ndpid_examples: "-DBUILD_EXAMPLES=ON"
ndpid_gcrypt: "-DNDPI_WITH_GCRYPT=ON"
ndpid_zlib: "-DENABLE_ZLIB=ON"
sanitizer: "-DENABLE_SANITIZER=OFF -DENABLE_SANITIZER_THREAD=OFF"
@@ -45,6 +51,8 @@ jobs:
ndpi_min_version: "4.8"
- compiler: "clang"
os: "ubuntu-latest"
+ ndpi_build: "-DBUILD_NDPI=ON"
+ ndpid_examples: "-DBUILD_EXAMPLES=ON"
ndpid_gcrypt: "-DNDPI_WITH_GCRYPT=OFF"
ndpid_zlib: "-DENABLE_ZLIB=OFF"
sanitizer: "-DENABLE_SANITIZER=OFF -DENABLE_SANITIZER_THREAD=OFF"
@@ -55,6 +63,8 @@ jobs:
ndpi_min_version: "4.8"
- compiler: "gcc"
os: "ubuntu-latest"
+ ndpi_build: "-DBUILD_NDPI=ON"
+ ndpid_examples: "-DBUILD_EXAMPLES=ON"
ndpid_gcrypt: "-DNDPI_WITH_GCRYPT=OFF"
ndpid_zlib: "-DENABLE_ZLIB=ON"
sanitizer: "-DENABLE_SANITIZER=ON"
@@ -64,24 +74,30 @@ jobs:
ndpi_min_version: "4.8"
- compiler: "clang"
os: "ubuntu-latest"
+ ndpi_build: "-DBUILD_NDPI=ON"
+ ndpid_examples: "-DBUILD_EXAMPLES=ON"
ndpid_gcrypt: "-DNDPI_WITH_GCRYPT=OFF"
ndpid_zlib: "-DENABLE_ZLIB=ON"
sanitizer: "-DENABLE_SANITIZER=ON"
- coverage: "-DENABLE_COVERAGE=ON"
+ coverage: "-DENABLE_COVERAGE=OFF"
poll: "-DFORCE_POLL=OFF"
upload: false
ndpi_min_version: "4.8"
- compiler: "clang-12"
os: "ubuntu-latest"
+ ndpi_build: "-DBUILD_NDPI=ON"
+ ndpid_examples: "-DBUILD_EXAMPLES=ON"
ndpid_gcrypt: "-DNDPI_WITH_GCRYPT=OFF"
ndpid_zlib: "-DENABLE_ZLIB=ON"
sanitizer: "-DENABLE_SANITIZER_THREAD=ON"
- coverage: "-DENABLE_COVERAGE=ON"
- poll: "-DFORCE_POLL=OFF"
+ coverage: "-DENABLE_COVERAGE=OFF"
+ poll:
upload: false
ndpi_min_version: "4.8"
- compiler: "gcc-10"
os: "ubuntu-latest"
+ ndpi_build: "-DBUILD_NDPI=ON"
+ ndpid_examples: "-DBUILD_EXAMPLES=ON"
ndpid_gcrypt: "-DNDPI_WITH_GCRYPT=OFF"
ndpid_zlib: "-DENABLE_ZLIB=OFF"
sanitizer: "-DENABLE_SANITIZER=ON"
@@ -91,6 +107,8 @@ jobs:
ndpi_min_version: "4.8"
- compiler: "gcc-7"
os: "ubuntu-20.04"
+ ndpi_build: "-DBUILD_NDPI=ON"
+ ndpid_examples: "-DBUILD_EXAMPLES=ON"
ndpid_gcrypt: "-DNDPI_WITH_GCRYPT=OFF"
ndpid_zlib: "-DENABLE_ZLIB=ON"
sanitizer: "-DENABLE_SANITIZER=ON"
@@ -98,6 +116,18 @@ jobs:
poll: "-DFORCE_POLL=OFF"
upload: false
ndpi_min_version: "4.8"
+ - compiler: "cc"
+ os: "macOS-latest"
+ ndpi_build: "-DBUILD_NDPI=OFF"
+ ndpid_examples: "-DBUILD_EXAMPLES=OFF"
+ ndpid_gcrypt: "-DNDPI_WITH_GCRYPT=OFF"
+ ndpid_zlib: "-DENABLE_ZLIB=ON"
+ examples: "-DBUILD_EXAMPLES=OFF"
+ sanitizer: "-DENABLE_SANITIZER=OFF"
+ coverage: "-DENABLE_COVERAGE=OFF"
+ poll:
+ upload: false
+ ndpi_min_version: "4.8"
steps:
- name: Print Matrix
@@ -105,9 +135,13 @@ jobs:
echo '----------------------------------------'
echo '| OS.......: ${{ matrix.os }}'
echo '| CC.......: ${{ matrix.compiler }}'
+ echo "| CFLAGS...: $CMAKE_C_FLAGS"
+ echo "| LDFLAGS..: $CMAKE_C_EXE_LINKER_FLAGS"
echo '|---------------------------------------'
+ echo '| nDPI min.: ${{ matrix.ndpi_min_version }}'
echo '| GCRYPT...: ${{ matrix.ndpid_gcrypt }}'
echo '| ZLIB.....: ${{ matrix.ndpid_zlib }}'
+ echo '| ForcePoll: ${{ matrix.poll }}'
echo '|---------------------------------------'
echo '| SANITIZER: ${{ matrix.sanitizer }}'
echo '| COVERAGE.: ${{ matrix.coverage }}'
@@ -118,6 +152,19 @@ jobs:
with:
submodules: false
fetch-depth: 1
+ - name: Install MacOS Prerequisites
+ if: startsWith(matrix.os, 'macOS')
+ run: |
+ brew install coreutils flock automake make unzip
+ wget 'https://www.tcpdump.org/release/libpcap-1.10.4.tar.gz'
+ tar -xzvf libpcap-1.10.4.tar.gz
+ cd libpcap-1.10.4
+ ./configure && make install
+ cd ..
+ wget 'https://github.com/ntop/nDPI/archive/refs/heads/dev.zip' -O libndpi-dev.zip
+ unzip libndpi-dev.zip
+ cd nDPI-dev
+ ./autogen.sh --prefix=/usr/local --with-only-libndpi && make install
- name: Install Ubuntu Prerequisites
if: startsWith(matrix.os, 'ubuntu')
run: |
@@ -139,13 +186,15 @@ jobs:
test ${C_VAL} = ${PY_VAL}
- name: Configure nDPId
run: |
- mkdir build && cd build
- cmake .. -DENABLE_SYSTEMD=ON -DBUILD_EXAMPLES=ON -DBUILD_NDPI=ON ${{ matrix.poll }} ${{ matrix.coverage }} ${{ matrix.sanitizer }} ${{ matrix.ndpid_zlib }} ${{ matrix.ndpid_gcrypt }}
+ cmake -S . -B build -DCMAKE_C_COMPILER="$CMAKE_C_COMPILER" -DCMAKE_C_FLAGS="$CMAKE_C_FLAGS" -DCMAKE_MODULE_LINKER_FLAGS="$CMAKE_MODULE_LINKER_FLAGS" -DCMAKE_C_EXE_LINKER_FLAGS="$CMAKE_C_EXE_LINKER_FLAGS" \
+ -DENABLE_SYSTEMD=ON \
+ ${{ matrix.poll }} ${{ matrix.coverage }} ${{ matrix.sanitizer }} ${{ matrix.ndpi_build }} \
+ ${{ matrix.ndpid_examples }} ${{ matrix.ndpid_zlib }} ${{ matrix.ndpid_gcrypt }}
- name: Build nDPId
run: |
- make -C build all VERBOSE=1
+ cmake --build build --verbose
- name: Build single nDPId executable (invoke CC directly)
- if: startsWith(matrix.coverage, '-DENABLE_COVERAGE=OFF') && startsWith(matrix.sanitizer, '-DENABLE_SANITIZER=ON') && startsWith(matrix.ndpid_gcrypt, '-DNDPI_WITH_GCRYPT=OFF') && startsWith(matrix.ndpid_zlib, '-DENABLE_ZLIB=ON')
+ if: (endsWith(matrix.compiler, 'gcc') || endsWith(matrix.compiler, 'clang')) && startsWith(matrix.coverage, '-DENABLE_COVERAGE=OFF') && startsWith(matrix.sanitizer, '-DENABLE_SANITIZER=ON') && startsWith(matrix.ndpid_gcrypt, '-DNDPI_WITH_GCRYPT=OFF') && startsWith(matrix.ndpid_zlib, '-DENABLE_ZLIB=ON')
run: |
cc -fsanitize=address -fsanitize=undefined -fno-sanitize=alignment -fsanitize=enum -fsanitize=leak nDPId.c nio.c utils.c -I./build/libnDPI/include/ndpi -I. -I./dependencies -I./dependencies/jsmn -I./dependencies/uthash/include -o /tmp/a.out -lpcap ./build/libnDPI/lib/libndpi.a -pthread -lm -lz
- name: Test EXEC
@@ -154,10 +203,11 @@ jobs:
./build/nDPId -h || test $? -eq 1
./build/nDPIsrvd -h || test $? -eq 1
- name: Test DIFF
- if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.ndpid_gcrypt, '-DNDPI_WITH_GCRYPT=OFF')
+ if: startsWith(matrix.os, 'macOS') == false && startsWith(matrix.ndpid_gcrypt, '-DNDPI_WITH_GCRYPT=OFF')
run: |
./test/run_tests.sh ./libnDPI ./build/nDPId-test
- name: Daemon
+ if: endsWith(matrix.compiler, 'gcc') || endsWith(matrix.compiler, 'clang')
run: |
make -C ./build daemon VERBOSE=1
make -C ./build daemon VERBOSE=1
@@ -166,20 +216,21 @@ jobs:
run: |
make -C ./build coverage
- name: Dist
- if: matrix.upload == false
+ if: startsWith(matrix.os, 'macOS') == false && matrix.upload == false
run: |
make -C ./build dist
- name: CPack DEB
+ if: startsWith(matrix.os, 'macOS') == false
run: |
cd ./build && cpack -G DEB && sudo dpkg -i nDPId-*.deb && cd ..
- name: Upload DEB
- if: matrix.upload
+ if: startsWith(matrix.os, 'macOS') == false && matrix.upload
uses: actions/upload-artifact@v3
with:
name: nDPId-debian-packages_${{ matrix.compiler }}${{ matrix.upload_suffix }}
path: build/*.deb
- - name: systemd test
- if: startsWith(matrix.os, 'ubuntu-latest') && startsWith(matrix.compiler, 'gcc')
+ - name: Test systemd
+ if: startsWith(matrix.os, 'ubuntu') && startsWith(matrix.compiler, 'gcc')
run: |
ip -c address
sudo systemctl daemon-reload
@@ -190,14 +241,22 @@ jobs:
sudo systemctl show ndpisrvd.service ndpid@lo.service -p SubState,ActiveState || true
journalctl --no-tail --no-pager -u ndpisrvd.service -u ndpid@lo.service
- name: Build against libnDPI-${{ matrix.ndpi_min_version }}
- if: matrix.upload == false
+ if: matrix.upload == false && startsWith(matrix.os, 'ubuntu')
run: |
mkdir build-local-ndpi && cd build-local-ndpi
WGET_RET=0
wget 'https://github.com/ntop/nDPI/archive/refs/tags/${{ matrix.ndpi_min_version }}.tar.gz' || { WGET_RET=$?; true; }
echo "wget returned: ${WGET_RET}"
test $WGET_RET -ne 8 || echo "::warning file=nDPId.c::New libnDPI release required to build against release tarball."
- test $WGET_RET -ne 0 || { tar -xzvf ${{ matrix.ndpi_min_version }}.tar.gz && cd nDPI-${{ matrix.ndpi_min_version }} && ./autogen.sh --prefix=/usr --with-only-libndpi CC=${{ matrix.compiler }} CXX=false CFLAGS='-Werror' && sudo make install && cd .. ; }
- test $WGET_RET -ne 0 || { echo "running cmake .."; cmake .. -DBUILD_EXAMPLES=ON -DBUILD_NDPI=OFF -DENABLE_SANITIZER=OFF ${{ matrix.poll }} ${{ matrix.coverage }} ${{ matrix.ndpi_min_version }} ; }
- test $WGET_RET -ne 0 || { echo "running make .."; make all VERBOSE=1 ; }
+ test $WGET_RET -ne 0 || { tar -xzvf ${{ matrix.ndpi_min_version }}.tar.gz && \
+ cd nDPI-${{ matrix.ndpi_min_version }} && \
+ ./autogen.sh --prefix=/usr --with-only-libndpi CC="${{ matrix.compiler }}" CXX=false \
+ CFLAGS="$CMAKE_C_FLAGS" && make && sudo make install; cd ..; }
+ test $WGET_RET -ne 0 || { echo "::info file=CMakeLists.txt::Running CMake.."; \
+ cmake -S .. -DCMAKE_C_COMPILER="$CMAKE_C_COMPILER" -DCMAKE_C_FLAGS="$CMAKE_C_FLAGS" \
+ -DCMAKE_C_EXE_LINKER_FLAGS="$CMAKE_C_EXE_LINKER_FLAGS" \
+ -DBUILD_NDPI=OFF -DENABLE_SANITIZER=OFF \
+ ${{ matrix.poll }} ${{ matrix.coverage }} \
+ ${{ matrix.ndpid_examples }}; }
+ test $WGET_RET -ne 0 || { echo "::info file=CMakeLists.txt:Running Make.."; cmake --build . --verbose; }
test $WGET_RET -eq 0 -o $WGET_RET -eq 8
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 73d659a5d..21020d5e7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -31,6 +31,7 @@ set(CPACK_PACKAGE_VERSION_PATCH 0)
include(CPack)
include(CheckFunctionExists)
+include(CheckLibraryExists)
include(CheckEpoll)
check_epoll(HAS_EPOLL)
@@ -49,14 +50,19 @@ if(NOT MATH_FUNCTION_EXISTS AND NOT NEED_LINKING_AGAINST_LIBM)
CHECK_FUNCTION_EXISTS(log2f MATH_FUNCTION_EXISTS)
if(NOT MATH_FUNCTION_EXISTS)
unset(MATH_FUNCTION_EXISTS CACHE)
- list(APPEND CMAKE_REQUIRED_LIBRARIES m)
- CHECK_FUNCTION_EXISTS(log2f MATH_FUNCTION_EXISTS)
- if(MATH_FUNCTION_EXISTS)
- set(NEED_LINKING_AGAINST_LIBM TRUE CACHE BOOL "" FORCE)
- else()
- message(FATAL_ERROR "Failed making the log2f() function available")
- endif()
- endif()
+ list(APPEND CMAKE_REQUIRED_LIBRARIES m)
+ CHECK_FUNCTION_EXISTS(log2f MATH_FUNCTION_EXISTS)
+ if(MATH_FUNCTION_EXISTS)
+ set(NEED_LINKING_AGAINST_LIBM TRUE CACHE BOOL "" FORCE)
+ else()
+ check_library_exists(m sqrt "" NEED_LINKING_AGAINST_LIBM)
+ if(NOT NEED_LINKING_AGAINST_LIBM)
+ # Was not able to figure out if explicit linkage against libm is required.
+ # Forcing libm linkage. Good idea?
+ set(NEED_LINKING_AGAINST_LIBM TRUE CACHE BOOL "" FORCE)
+ endif()
+ endif()
+ endif()
endif()
if(NEED_LINKING_AGAINST_LIBM)
diff --git a/dependencies/nDPIsrvd.h b/dependencies/nDPIsrvd.h
index 77d91bd9d..11f651435 100644
--- a/dependencies/nDPIsrvd.h
+++ b/dependencies/nDPIsrvd.h
@@ -5,6 +5,7 @@
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
+#include <netinet/in.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
diff --git a/nDPId-test.c b/nDPId-test.c
index 48c0e2b70..0f3bd8539 100644
--- a/nDPId-test.c
+++ b/nDPId-test.c
@@ -923,7 +923,9 @@ static enum nDPIsrvd_callback_return distributor_json_printer(struct nDPIsrvd_so
static void * distributor_client_mainloop_thread(void * const arg)
{
struct nio io;
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
int signalfd = -1;
+#endif
struct distributor_return_value * const drv = (struct distributor_return_value *)arg;
struct thread_return_value * const trv = &drv->thread_return_value;
struct nDPIsrvd_socket * mock_sock = nDPIsrvd_socket_init(sizeof(struct distributor_global_user_data),
@@ -960,12 +962,14 @@ static void * distributor_client_mainloop_thread(void * const arg)
THREAD_ERROR_GOTO(trv);
}
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
signalfd = setup_signalfd(&io);
if (signalfd < 0)
{
logger(1, "Distributor signal fd setup failed: %s", strerror(errno));
THREAD_ERROR_GOTO(trv);
}
+#endif
if (thread_block_signals() != 0)
{
@@ -1159,6 +1163,7 @@ static void * distributor_client_mainloop_thread(void * const arg)
* I am just here to trigger some IP code paths.
*/
}
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
else if (fd == signalfd)
{
struct signalfd_siginfo fdsi;
@@ -1178,6 +1183,7 @@ static void * distributor_client_mainloop_thread(void * const arg)
THREAD_ERROR_GOTO(trv);
}
}
+#endif
else
{
logger(1,
@@ -1251,7 +1257,9 @@ static void * distributor_client_mainloop_thread(void * const arg)
}
error:
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
del_event(&io, signalfd);
+#endif
del_event(&io, mock_testfds[PIPE_TEST_READ]);
del_event(&io, mock_bufffds[PIPE_BUFFER_READ]);
del_event(&io, mock_nullfds[PIPE_NULL_READ]);
@@ -1260,7 +1268,9 @@ error:
close(mock_bufffds[PIPE_BUFFER_READ]);
close(mock_nullfds[PIPE_NULL_READ]);
close(mock_arpafds[PIPE_ARPA_READ]);
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
close(signalfd);
+#endif
nio_free(&io);
nDPIsrvd_socket_free(&mock_sock);
@@ -1351,6 +1361,7 @@ static void usage(char const * const arg0)
static int thread_wait_for_termination(pthread_t thread, time_t wait_time_secs, struct thread_return_value * const trv)
{
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
struct timespec ts;
if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
@@ -1370,6 +1381,11 @@ static int thread_wait_for_termination(pthread_t thread, time_t wait_time_secs,
}
return 1;
+#else
+ (void)wait_time_secs;
+
+ return pthread_join(thread, (void **)&trv) != 0;
+#endif
}
static int base64_selftest()
diff --git a/nDPId.c b/nDPId.c
index 9fada5e40..b1a0c8b11 100644
--- a/nDPId.c
+++ b/nDPId.c
@@ -1,3 +1,6 @@
+#if defined(__FreeBSD__) || defined(__APPLE__)
+#include <sys/types.h>
+#endif
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
@@ -17,7 +20,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
#include <sys/signalfd.h>
+#endif
#include <sys/un.h>
#include <unistd.h>
#ifdef ENABLE_ZLIB
@@ -429,7 +434,6 @@ static struct nDPId_reader_thread reader_threads[nDPId_MAX_READER_THREADS] = {};
static struct nDPIsrvd_address collector_address;
static MT_VALUE(nDPId_main_thread_shutdown, int) = MT_INIT(0);
static MT_VALUE(global_flow_id, uint64_t) = MT_INIT(1);
-static int ip4_interface_avail = 0, ip6_interface_avail = 0;
#ifdef ENABLE_MEMORY_PROFILING
static MT_VALUE(ndpi_memory_alloc_count, uint64_t) = MT_INIT(0);
@@ -929,10 +933,17 @@ static void get_ip6_from_sockaddr(struct sockaddr_in6 const * const saddr, union
switch (saddr->sin6_family)
{
case AF_INET6:
+#if defined(__FreeBSD__) || defined(__APPLE__)
+ dest->v6.ip_u32[0] = saddr->sin6_addr.__u6_addr.__u6_addr32[0];
+ dest->v6.ip_u32[1] = saddr->sin6_addr.__u6_addr.__u6_addr32[1];
+ dest->v6.ip_u32[2] = saddr->sin6_addr.__u6_addr.__u6_addr32[2];
+ dest->v6.ip_u32[3] = saddr->sin6_addr.__u6_addr.__u6_addr32[3];
+#else
dest->v6.ip_u32[0] = saddr->sin6_addr.s6_addr32[0];
dest->v6.ip_u32[1] = saddr->sin6_addr.s6_addr32[1];
dest->v6.ip_u32[2] = saddr->sin6_addr.s6_addr32[2];
dest->v6.ip_u32[3] = saddr->sin6_addr.s6_addr32[3];
+#endif
break;
default:
return;
@@ -996,7 +1007,11 @@ static int get_ip6_address_and_netmask(char const * const ifa_name, size_t ifnam
memset(&sap.sin6_addr.s6_addr, 0xFF, plen / 8);
if (plen < 128 && (plen % 32) != 0)
{
+#if defined(__FreeBSD__) || defined(__APPLE__)
+ sap.sin6_addr.__u6_addr.__u6_addr32[plen / 32] = 0xFFFFFFFF << (32 - (plen % 32));
+#else
sap.sin6_addr.s6_addr32[plen / 32] = 0xFFFFFFFF << (32 - (plen % 32));
+#endif
}
inet_ntop(AF_INET6, &sap.sin6_addr, netmask6, sizeof(netmask6));
sap.sin6_family = AF_INET6;
@@ -1024,50 +1039,14 @@ error:
return retval;
}
-static int get_ip4_address_and_netmask(char const * const ifa_name, size_t ifnamelen)
+static void get_ip4_address_and_netmask(struct ifaddrs const * const ifaddr)
{
- int retval = 0;
- int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
- struct ifreq ifr;
-
- if (sock < 0)
- {
- retval = 1;
- goto error;
- }
- if (ifnamelen >= sizeof(ifr.ifr_name))
- {
- retval = 1;
- goto error;
- }
-
- memset(&ifr, 0, sizeof(ifr));
- memcpy(ifr.ifr_name, ifa_name, ifnamelen);
- ifr.ifr_name[ifnamelen] = '\0';
- ifr.ifr_netmask.sa_family = AF_INET;
- if (ioctl(sock, SIOCGIFNETMASK, &ifr) == -1)
- {
- retval = 1;
- goto error;
- }
- get_ip4_from_sockaddr((struct sockaddr_in *)&ifr.ifr_netmask, &nDPId_options.pcap_dev_netmask4);
-
- memset(&ifr, 0, sizeof(ifr));
- memcpy(ifr.ifr_name, ifa_name, ifnamelen);
- ifr.ifr_name[ifnamelen] = '\0';
- ifr.ifr_addr.sa_family = AF_INET;
- if (ioctl(sock, SIOCGIFADDR, &ifr) == -1)
- {
- retval = 1;
- goto error;
- }
- get_ip4_from_sockaddr((struct sockaddr_in *)&ifr.ifr_netmask, &nDPId_options.pcap_dev_ip4);
-
+ get_ip4_from_sockaddr((struct sockaddr_in *)ifaddr->ifa_netmask, &nDPId_options.pcap_dev_netmask4);
+ get_ip4_from_sockaddr((struct sockaddr_in *)ifaddr->ifa_addr, &nDPId_options.pcap_dev_ip4);
ip_netmask_to_subnet(&nDPId_options.pcap_dev_ip4,
&nDPId_options.pcap_dev_netmask4,
&nDPId_options.pcap_dev_subnet4,
L3_IP);
-
{
char addr[INET_ADDRSTRLEN];
char netm[INET_ADDRSTRLEN];
@@ -1082,15 +1061,12 @@ static int get_ip4_address_and_netmask(char const * const ifa_name, size_t ifnam
inet_ntop(AF_INET, snetm, netm, sizeof(netm)),
inet_ntop(AF_INET, ssubn, subn, sizeof(subn)));
}
-
-error:
- close(sock);
- return retval;
}
static int get_ip_netmask_from_pcap_dev(char const * const pcap_dev)
{
int retval = 0, found_dev = 0;
+ int ip4_interface_avail = 0, ip6_interface_avail = 0;
struct ifaddrs * ifaddrs = NULL;
struct ifaddrs * ifa;
@@ -1113,10 +1089,7 @@ static int get_ip_netmask_from_pcap_dev(char const * const pcap_dev)
switch (ifa->ifa_addr->sa_family)
{
case AF_INET:
- if (ip4_interface_avail == 0 && get_ip4_address_and_netmask(ifa->ifa_name, ifnamelen) != 0)
- {
- retval = 1;
- }
+ get_ip4_address_and_netmask(ifa);
ip4_interface_avail = 1;
break;
case AF_INET6:
@@ -1586,6 +1559,8 @@ static int setup_reader_threads(void)
"Could not get netmask for pcap device %s: %s",
get_cmdarg(&nDPId_options.pcap_file_or_interface),
strerror(errno));
+ } else {
+ logger_early(1, "Unexpected error while retrieving netmask for pcap device %s", get_cmdarg(&nDPId_options.pcap_file_or_interface));
}
return 1;
}
@@ -2245,8 +2220,8 @@ static int connect_to_collector(struct nDPId_reader_thread * const reader_thread
}
int sock_type = (collector_address.raw.sa_family == AF_UNIX ? SOCK_STREAM : SOCK_DGRAM);
- reader_thread->collector_sockfd = socket(collector_address.raw.sa_family, sock_type | SOCK_CLOEXEC, 0);
- if (reader_thread->collector_sockfd < 0)
+ reader_thread->collector_sockfd = socket(collector_address.raw.sa_family, sock_type, 0);
+ if (reader_thread->collector_sockfd < 0 || set_fd_cloexec(reader_thread->collector_sockfd) < 0)
{
reader_thread->collector_sock_last_errno = errno;
return 1;
@@ -3458,7 +3433,7 @@ static int process_datalink_layer(struct nDPId_reader_thread * const reader_thre
break;
case ETHERTYPE_PAE: /* 802.1X Authentication */
return 1;
- case ETH_P_ARP: /* ARP */
+ case ETHERTYPE_ARP: /* ARP */
return 1;
default:
if (is_error_event_threshold(reader_thread->workflow) == 0)
@@ -4274,6 +4249,7 @@ static void get_current_time(struct timeval * const tval)
gettimeofday(tval, NULL);
}
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
static void ndpi_log_flow_walker(void const * const A, ndpi_VISIT which, int depth, void * const user_data)
{
struct nDPId_reader_thread const * const reader_thread = (struct nDPId_reader_thread *)user_data;
@@ -4358,6 +4334,7 @@ static void log_all_flows(struct nDPId_reader_thread const * const reader_thread
ndpi_twalk(workflow->ndpi_flows_active[scan_index], ndpi_log_flow_walker, (void *)reader_thread);
}
}
+#endif
static void run_pcap_loop(struct nDPId_reader_thread * const reader_thread)
{
@@ -4380,6 +4357,7 @@ static void run_pcap_loop(struct nDPId_reader_thread * const reader_thread)
}
else
{
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
sigset_t thread_signal_set, old_signal_set;
sigfillset(&thread_signal_set);
if (pthread_sigmask(SIG_BLOCK, &thread_signal_set, &old_signal_set) != 0)
@@ -4392,13 +4370,14 @@ static void run_pcap_loop(struct nDPId_reader_thread * const reader_thread)
sigaddset(&thread_signal_set, SIGINT);
sigaddset(&thread_signal_set, SIGTERM);
sigaddset(&thread_signal_set, SIGUSR1);
- int signal_fd = signalfd(-1, &thread_signal_set, SFD_NONBLOCK | SFD_CLOEXEC);
- if (signal_fd < 0)
+ int signal_fd = signalfd(-1, &thread_signal_set, SFD_NONBLOCK);
+ if (signal_fd < 0 || set_fd_cloexec(signal_fd) < 0)
{
logger(1, "signalfd: %s", strerror(errno));
MT_GET_AND_ADD(reader_thread->workflow->error_or_eof, 1);
return;
}
+#endif
int pcap_fd = pcap_get_selectable_fd(reader_thread->workflow->pcap_handle);
if (pcap_fd < 0)
@@ -4433,6 +4412,7 @@ static void run_pcap_loop(struct nDPId_reader_thread * const reader_thread)
nio_free(&io);
return;
}
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
errno = 0;
if (nio_add_fd(&io, signal_fd, NIO_EVENT_INPUT, NULL) != NIO_SUCCESS)
{
@@ -4443,6 +4423,7 @@ static void run_pcap_loop(struct nDPId_reader_thread * const reader_thread)
nio_free(&io);
return;
}
+#endif
int const timeout_ms = 1000; /* TODO: Configurable? */
struct timeval tval_before_epoll, tval_after_epoll;
@@ -4482,6 +4463,7 @@ static void run_pcap_loop(struct nDPId_reader_thread * const reader_thread)
int fd = nio_get_fd(&io, i);
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
if (fd == signal_fd)
{
struct signalfd_siginfo fdsi;
@@ -4513,7 +4495,9 @@ static void run_pcap_loop(struct nDPId_reader_thread * const reader_thread)
logger(1, "Received signal %d (%s)", fdsi.ssi_signo, signame);
}
}
- else if (fd == pcap_fd)
+ else
+#endif
+ if (fd == pcap_fd)
{
switch (pcap_dispatch(
reader_thread->workflow->pcap_handle, -1, ndpi_process_packet, (uint8_t *)reader_thread))
diff --git a/nDPIsrvd.c b/nDPIsrvd.c
index a4d7457fe..37034751f 100644
--- a/nDPIsrvd.c
+++ b/nDPIsrvd.c
@@ -9,7 +9,9 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
#include <sys/signalfd.h>
+#endif
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
@@ -43,15 +45,19 @@ struct remote_desc
{
struct sockaddr_un peer;
unsigned long long int json_bytes;
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
pid_t pid;
+#endif
struct nDPIsrvd_json_buffer main_read_buffer;
} event_collector_un;
struct
{
struct sockaddr_un peer;
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
pid_t pid;
char * user_name;
+#endif
struct nDPIsrvd_write_buffer main_write_buffer;
UT_array * additional_write_buffers;
@@ -79,7 +85,7 @@ static int collector_un_sockfd = -1;
static int distributor_un_sockfd = -1;
static int distributor_in_sockfd = -1;
static struct nDPIsrvd_address distributor_in_address = {
- .raw.sa_family = 0xFFFF,
+ .raw.sa_family = (sa_family_t)0xFFFF,
};
static struct
@@ -278,12 +284,16 @@ static void logger_nDPIsrvd(struct remote_desc const * const remote,
switch (remote->sock_type)
{
case DISTRIBUTOR_UN:
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
logger(1,
"%s PID %d (User: %s) %s",
prefix,
remote->event_distributor_un.pid,
remote->event_distributor_un.user_name,
logbuf);
+#else
+ logger(1, "%s %s", prefix, logbuf);
+#endif
break;
case DISTRIBUTOR_IN:
logger(1,
@@ -295,7 +305,11 @@ static void logger_nDPIsrvd(struct remote_desc const * const remote,
logbuf);
break;
case COLLECTOR_UN:
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
logger(1, "%s PID %d %s", prefix, remote->event_collector_un.pid, logbuf);
+#else
+ logger(1, "%s %s", prefix, logbuf);
+#endif
break;
}
@@ -435,9 +449,12 @@ static int handle_outgoing_data(struct nio * const io, struct remote_desc * cons
{
struct nDPIsrvd_write_buffer * const write_buffer = get_write_buffer(remote);
- if (write_buffer->buf.used == 0) {
+ if (write_buffer->buf.used == 0)
+ {
return set_in_event(io, remote);
- } else {
+ }
+ else
+ {
return drain_main_buffer(remote);
}
}
@@ -473,7 +490,8 @@ static int create_listen_sockets(void)
{
collector_un_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
distributor_un_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (collector_un_sockfd < 0 || distributor_un_sockfd < 0)
+ if (collector_un_sockfd < 0 || distributor_un_sockfd < 0 || set_fd_cloexec(collector_un_sockfd) < 0 ||
+ set_fd_cloexec(distributor_un_sockfd) < 0)
{
logger(1, "Error creating UNIX socket: %s", strerror(errno));
return 1;
@@ -482,7 +500,7 @@ static int create_listen_sockets(void)
if (is_cmdarg_set(&nDPIsrvd_options.distributor_in_address) != 0)
{
distributor_in_sockfd = socket(distributor_in_address.raw.sa_family, SOCK_STREAM, 0);
- if (distributor_in_sockfd < 0)
+ if (distributor_in_sockfd < 0 || set_fd_cloexec(distributor_in_sockfd) < 0)
{
logger(1, "Error creating TCP/IP socket: %s", strerror(errno));
return 1;
@@ -716,7 +734,9 @@ static void free_remote(struct nio * const io, struct remote_desc * remote)
utarray_free(remote->event_distributor_un.additional_write_buffers);
}
nDPIsrvd_buffer_free(&remote->event_distributor_un.main_write_buffer.buf);
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
free(remote->event_distributor_un.user_name);
+#endif
break;
case DISTRIBUTOR_IN:
if (errno != 0)
@@ -935,7 +955,7 @@ static struct remote_desc * accept_remote(int server_fd,
int client_fd;
while ((client_fd = accept(server_fd, sockaddr, addrlen)) < 0 && errno == EINTR) {}
- if (client_fd < 0)
+ if (client_fd < 0 || set_fd_cloexec(client_fd) < 0)
{
logger(1, "Accept failed: %s", strerror(errno));
return NULL;
@@ -1005,6 +1025,7 @@ static int new_connection(struct nio * const io, int eventfd)
return 1;
}
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
struct ucred ucred = {};
socklen_t ucred_len = sizeof(ucred);
if (getsockopt(current->fd, SOL_SOCKET, SO_PEERCRED, &ucred, &ucred_len) == -1)
@@ -1012,8 +1033,8 @@ static int new_connection(struct nio * const io, int eventfd)
logger(1, "Error getting credentials from UNIX socket: %s", strerror(errno));
return 1;
}
-
current->event_collector_un.pid = ucred.pid;
+#endif
logger_nDPIsrvd(current, "New collector connection from", "");
break;
@@ -1023,6 +1044,7 @@ static int new_connection(struct nio * const io, int eventfd)
{
current->event_distributor_un.peer = sockaddr.saddr_distributor_un;
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
struct ucred ucred = {};
socklen_t ucred_len = sizeof(ucred);
if (getsockopt(current->fd, SOL_SOCKET, SO_PEERCRED, &ucred, &ucred_len) == -1)
@@ -1047,6 +1069,7 @@ static int new_connection(struct nio * const io, int eventfd)
current->event_distributor_un.pid = ucred.pid;
current->event_distributor_un.user_name = strdup(pwres->pw_name);
+#endif
}
else
{
@@ -1351,6 +1374,7 @@ static int handle_data_event(struct nio * const io, int index)
}
}
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
static int setup_signalfd(struct nio * const io)
{
sigset_t mask;
@@ -1383,10 +1407,13 @@ static int setup_signalfd(struct nio * const io)
return sfd;
}
+#endif
static int mainloop(struct nio * const io)
{
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
int signalfd = setup_signalfd(io);
+#endif
while (nDPIsrvd_main_thread_shutdown == 0)
{
@@ -1433,6 +1460,7 @@ static int mainloop(struct nio * const io)
continue;
}
}
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
else if (fd == signalfd)
{
struct signalfd_siginfo fdsi;
@@ -1441,10 +1469,18 @@ static int mainloop(struct nio * const io)
s = read(signalfd, &fdsi, sizeof(struct signalfd_siginfo));
if (s != sizeof(struct signalfd_siginfo))
{
- logger(1,
- "Invalid signal fd read size. Got %zd, wanted %zu bytes.",
- s,
- sizeof(struct signalfd_siginfo));
+ if (s < 0)
+ {
+ logger(1, "Read from signal fd returned: %s", strerror(errno));
+ nDPIsrvd_main_thread_shutdown = 1;
+ }
+ else
+ {
+ logger(1,
+ "Invalid signal fd read size. Got %zd, wanted %zu bytes.",
+ s,
+ sizeof(struct signalfd_siginfo));
+ }
continue;
}
@@ -1454,6 +1490,7 @@ static int mainloop(struct nio * const io)
continue;
}
}
+#endif
else
{
/* Incoming data / Outoing data ready to receive / send. */
@@ -1467,7 +1504,9 @@ static int mainloop(struct nio * const io)
free_remotes(io);
nio_free(io);
+#if !defined(__FreeBSD__) && !defined(__APPLE__)
close(signalfd);
+#endif
return 0;
}
@@ -1627,7 +1666,7 @@ int main(int argc, char ** argv)
"everyone with access to the device/network. You've been warned!");
break;
case AF_UNIX:
- case 0xFFFF:
+ case (sa_family_t)0xFFFF:
break;
}
diff --git a/scripts/daemon.sh b/scripts/daemon.sh
index 74e9ffde0..30b3c5c00 100755
--- a/scripts/daemon.sh
+++ b/scripts/daemon.sh
@@ -27,7 +27,15 @@ if [ -r "${NROOT}/nDPId-${NSUFFIX}.pid" -o -r "${NROOT}/nDPIsrvd-${NSUFFIX}.pid"
if [ x"${nDPId_PID}" != x ]; then
sudo kill "${nDPId_PID}" 2>/dev/null || true
- while ps -p "${nDPId_PID}" > /dev/null; do sleep 1; done
+
+ MAX_TRIES=10
+ while ps -p "${nDPId_PID}" > /dev/null; do
+ test ${MAX_TRIES} -gt 0 || break
+ sleep 1
+ MAX_TRIES=$((MAX_TRIES - 1))
+ done
+ test ${MAX_TRIES} -eq 0 && { RETVAL=1; printf '%s\n' 'Error: nDPId not started' >&2; }
+
rm -f "${NROOT}/nDPId-${NSUFFIX}.pid"
else
printf '%s\n' "${1} not started .." >&2
@@ -36,7 +44,15 @@ if [ -r "${NROOT}/nDPId-${NSUFFIX}.pid" -o -r "${NROOT}/nDPIsrvd-${NSUFFIX}.pid"
if [ x"${nDPIsrvd_PID}" != x ]; then
kill "${nDPIsrvd_PID}" 2>/dev/null || true
- while ps -p "${nDPIsrvd_PID}" > /dev/null; do sleep 1; done
+
+ MAX_TRIES=10
+ while ps -p "${nDPIsrvd_PID}" > /dev/null; do
+ test ${MAX_TRIES} -gt 0 || break
+ sleep 1
+ MAX_TRIES=$((MAX_TRIES - 1))
+ done
+ test ${MAX_TRIES} -eq 0 && { RETVAL=1; printf '%s\n' 'Error: nDPIsrvd not started' >&2; }
+
rm -f "${NROOT}/nDPIsrvd-${NSUFFIX}.pid" "${NROOT}/nDPIsrvd-${NSUFFIX}-collector.sock" "${NROOT}/nDPIsrvd-${NSUFFIX}-distributor.sock"
else
printf '%s\n' "${2} not started .." >&2
@@ -54,14 +70,14 @@ else
sleep 0.5
MAX_TRIES=$((MAX_TRIES - 1))
done
- test ${MAX_TRIES} -eq 0 && RETVAL=1
+ test ${MAX_TRIES} -eq 0 && { RETVAL=1; printf '%s\n' 'Error: nDPIsrvd collector socket not available' >&2; }
MAX_TRIES=10
while [ ! -S "${NROOT}/nDPIsrvd-${NSUFFIX}-distributor.sock" -a ${MAX_TRIES} -gt 0 ]; do
sleep 0.5
MAX_TRIES=$((MAX_TRIES - 1))
done
- test ${MAX_TRIES} -eq 0 && RETVAL=1
+ test ${MAX_TRIES} -eq 0 && { RETVAL=1; printf '%s\n' 'Error: nDPIsrvd distributor socket not available' >&2; }
sudo chgrp "$(id -n -g "${NUSER}")" "${NROOT}/nDPIsrvd-${NSUFFIX}-collector.sock"
test $? -eq 0 || RETVAL=1
diff --git a/scripts/get-and-build-libndpi.sh b/scripts/get-and-build-libndpi.sh
index be17f7687..2d0939538 100755
--- a/scripts/get-and-build-libndpi.sh
+++ b/scripts/get-and-build-libndpi.sh
@@ -32,7 +32,9 @@ if [ ! -z "${CC}" ]; then
fi
if [ ! -z "${MAKEFLAGS}" ]; then
- MAKEFLAGS="-${MAKEFLAGS}"
+ case "$(uname -s)" in
+ Linux*) MAKEFLAGS="-${MAKEFLAGS}" ;;
+ esac
fi
cat <<EOF
@@ -102,7 +104,7 @@ MAKE_PROGRAM="${MAKE_PROGRAM:-make -j4}"
HOST_ARG="--host=${HOST_TRIPLET}"
./autogen.sh --enable-option-checking=fatal \
--prefix="/" \
- --with-only-libndpi ${HOST_ARG} ${ADDITIONAL_ARGS}
+ --with-only-libndpi ${HOST_ARG} ${ADDITIONAL_ARGS} || { cat config.log | grep -v '^|'; false; }
${MAKE_PROGRAM} ${MAKEFLAGS} install DESTDIR="${DEST_INSTALL}"
rm -f "${LOCKFILE}"
diff --git a/utils.c b/utils.c
index 337628379..e54386cd0 100644
--- a/utils.c
+++ b/utils.c
@@ -141,6 +141,7 @@ int is_path_absolute(char const * const prefix, char const * const path)
int daemonize_with_pidfile(char const * const pidfile)
{
pid_str ps = {};
+ int nullfd;
if (daemonize != 0)
{
@@ -156,12 +157,44 @@ int daemonize_with_pidfile(char const * const pidfile)
return 1;
}
- if (daemon(0, 0) != 0)
+ nullfd = open("/dev/null", O_NONBLOCK, O_WRONLY);
+ if (nullfd < 0 || dup2(nullfd, STDIN_FILENO) < 0 || dup2(nullfd, STDOUT_FILENO) < 0 ||
+ dup2(nullfd, STDERR_FILENO) < 0)
{
- logger_early(1, "daemon: %s", strerror(errno));
+ logger_early(1, "Opening /dev/null or replacing stdin/stdout/stderr failed: %s", strerror(errno));
return 1;
}
+ // For compatiblity reasons, we use the UNIX double fork() technique.
+
+ switch (fork())
+ {
+ case 0:
+ break;
+ case -1:
+ logger_early(1, "Could not fork (first time): %s", strerror(errno));
+ return 1;
+ default:
+ exit(0);
+ }
+
+ if (chdir("/") < 0 || setsid() < 0)
+ {
+ logger_early(1, "chdir() / setsid() failed: %s", strerror(errno));
+ return 1;
+ }
+
+ switch (fork())
+ {
+ case 0:
+ break;
+ case -1:
+ logger_early(1, "Could not fork (second time): %s", strerror(errno));
+ return 1;
+ default:
+ exit(0);
+ }
+
if (create_pidfile(pidfile) != 0)
{
return 1;
@@ -401,6 +434,17 @@ __attribute__((format(printf, 2, 3))) void logger_early(int is_error, char const
log_to_console = old_log_to_console;
}
+int set_fd_cloexec(int fd)
+{
+ int flags = fcntl(fd, F_GETFD, 0);
+
+ if (flags < 0)
+ {
+ return -1;
+ }
+ return fcntl(fd, F_SETFD, FD_CLOEXEC);
+}
+
char const * get_nDPId_version(void)
{
return "nDPId version "
diff --git a/utils.h b/utils.h
index fb170fbb5..a568bd942 100644
--- a/utils.h
+++ b/utils.h
@@ -56,6 +56,8 @@ __attribute__((format(printf, 2, 3))) void logger(int is_error, char const * con
__attribute__((format(printf, 2, 3))) void logger_early(int is_error, char const * const format, ...);
+int set_fd_cloexec(int fd);
+
char const * get_nDPId_version(void);
#endif