From 4a033dbc1ba642a5f71a47574dbda5ad1b3201bb Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Thu, 6 Nov 2025 08:40:24 +0100 Subject: [PATCH 1/2] freeBSD + Darwin port of examples and tests --- .github/workflows/freebsd.yml | 34 ++ .github/workflows/linux.yml | 12 + .github/workflows/macos.yml | 46 +++ .github/workflows/units.yml | 32 -- Makefile | 139 ++++++-- config.h | 2 +- src/port/posix/bsd_socket.c | 13 +- src/port/posix/tap_darwin.c | 315 ++++++++++++++++++ src/port/posix/tap_freebsd.c | 242 ++++++++++++++ src/port/posix/{linux_tap.c => tap_linux.c} | 2 +- src/test/tcp_echo.c | 2 + ...{test_linux_dhcp_dns.c => test_dhcp_dns.c} | 89 ++++- ...est_linux_eventloop.c => test_eventloop.c} | 125 +++++-- src/test/test_httpd.c | 23 +- src/test/test_native_wolfssl.c | 27 +- src/test/test_ttl_expired.c | 3 + src/test/test_wolfssl_forwarding.c | 24 +- src/wolfip.c | 6 +- tools/certs/mkcerts.sh | 3 +- 19 files changed, 1009 insertions(+), 130 deletions(-) create mode 100644 .github/workflows/freebsd.yml create mode 100644 .github/workflows/macos.yml delete mode 100644 .github/workflows/units.yml create mode 100644 src/port/posix/tap_darwin.c create mode 100644 src/port/posix/tap_freebsd.c rename src/port/posix/{linux_tap.c => tap_linux.c} (99%) rename src/test/{test_linux_dhcp_dns.c => test_dhcp_dns.c} (74%) rename src/test/{test_linux_eventloop.c => test_eventloop.c} (80%) diff --git a/.github/workflows/freebsd.yml b/.github/workflows/freebsd.yml new file mode 100644 index 0000000..793ea77 --- /dev/null +++ b/.github/workflows/freebsd.yml @@ -0,0 +1,34 @@ +name: FreeBSD interop tests + +on: + push: + branches: [ 'master', 'main', 'release/**' ] + pull_request: + branches: [ '*' ] + +jobs: + freebsd_test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Build and run tests on FreeBSD + id: test + uses: vmactions/freebsd-vm@v1 + with: + copyback: false + usesh: true + prepare: | + set -ex + env IGNORE_OSVERSION=yes pkg update -f + env IGNORE_OSVERSION=yes pkg install -y gmake gcc wolfssl check vim + kldload if_tap || true + sysctl net.link.tap.up_on_open=1 || true + run: | + set -ex + cd "${GITHUB_WORKSPACE:-/root/work/github/workspace}" + gmake build/test-evloop build/test-wolfssl build/test-ttl-expired unit + ./build/test/unit + ./build/test-evloop + ./build/test-wolfssl + ./build/test-ttl-expired diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 7acef61..1a2d4fd 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -44,3 +44,15 @@ jobs: run: | ./build/test-ttl-expired + - name: Install check + run: | + sudo apt-get install -y check + + - name: Build unit tests + run: | + make unit + + - name: Run unit tests + run: | + build/test/unit + diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml new file mode 100644 index 0000000..7f69495 --- /dev/null +++ b/.github/workflows/macos.yml @@ -0,0 +1,46 @@ +name: macOS interop tests + +on: + push: + branches: [ 'master', 'main', 'release/**' ] + pull_request: + branches: [ '*' ] + +jobs: + macos_test: + runs-on: macos-latest + + steps: + - uses: actions/checkout@v4 + with: + submodules: true + + - name: Install dependencies + run: | + brew update + brew install make wolfssl check + + - name: Build tests + run: | + PATH="/opt/homebrew/opt/make/libexec/gnubin:$PATH" \ + gmake build/test-evloop build/test-wolfssl build/test-ttl-expired unit + + - name: Run event loop test + run: | + sudo PATH="/opt/homebrew/opt/make/libexec/gnubin:$PATH" ./build/test-evloop + timeout-minutes: 3 + + - name: Run wolfSSL interop test + run: | + sudo PATH="/opt/homebrew/opt/make/libexec/gnubin:$PATH" ./build/test-wolfssl + timeout-minutes: 3 + + - name: Run unit tests + run: | + ./build/test/unit + timeout-minutes: 2 + + - name: Run TTL expired test + run: | + ./build/test-ttl-expired + timeout-minutes: 1 diff --git a/.github/workflows/units.yml b/.github/workflows/units.yml deleted file mode 100644 index bebafe9..0000000 --- a/.github/workflows/units.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Unit Tests - -on: - push: - branches: [ 'master', 'main', 'release/**' ] - pull_request: - branches: [ '*' ] - -jobs: - unit_test: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - with: - submodules: true - - - name: Update repo - run: | - sudo apt-get update - - - name: Install check - run: | - sudo apt-get -y install check - - - name: Build unit tests - run: | - make unit - - - name: Run unit tests - run: | - build/test/unit diff --git a/Makefile b/Makefile index 218b2a2..d563c1f 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,79 @@ CFLAGS:=-Wall -Werror -Wextra -I. -D_GNU_SOURCE CFLAGS+=-g -ggdb -Wdeclaration-after-statement LDFLAGS+=-pthread +UNAME_S:=$(shell uname -s) +UNAME_M:=$(shell uname -m) +UNAME_LC:=$(shell echo $(UNAME_S) | tr 'A-Z' 'a-z') +ifeq ($(UNAME_S),FreeBSD) +CFLAGS+=-I/usr/local/include +LDFLAGS+=-L/usr/local/lib +endif +ifeq ($(UNAME_S),Darwin) +BREW_PREFIX?=$(shell brew --prefix 2>/dev/null) +ifeq ($(filter command\ line environment,$(origin BREW_PREFIX)),) +ifeq ($(UNAME_M),arm64) +ARM_BREW_PREFIX:=$(shell /opt/homebrew/bin/brew --prefix 2>/dev/null) +ifneq ($(ARM_BREW_PREFIX),) +BREW_PREFIX:=$(ARM_BREW_PREFIX) +endif +endif +endif +ifeq ($(BREW_PREFIX),) +BREW_PREFIX:=/opt/homebrew +endif + +WOLFSSL_PREFIX?=$(shell brew --prefix wolfssl 2>/dev/null) +ifeq ($(filter command\ line environment,$(origin WOLFSSL_PREFIX)),) +ifeq ($(UNAME_M),arm64) +ARM_WOLFSSL_PREFIX:=$(shell /opt/homebrew/bin/brew --prefix wolfssl 2>/dev/null) +ifneq ($(ARM_WOLFSSL_PREFIX),) +WOLFSSL_PREFIX:=$(ARM_WOLFSSL_PREFIX) +endif +endif +endif +ifneq ($(WOLFSSL_PREFIX),) +CFLAGS+=-I$(WOLFSSL_PREFIX)/include +LDFLAGS+=-L$(WOLFSSL_PREFIX)/lib +endif +CHECK_PREFIX?=$(shell brew --prefix check 2>/dev/null) +ifeq ($(filter command\ line environment,$(origin CHECK_PREFIX)),) +ifeq ($(UNAME_M),arm64) +ARM_CHECK_PREFIX:=$(shell /opt/homebrew/bin/brew --prefix check 2>/dev/null) +ifneq ($(ARM_CHECK_PREFIX),) +CHECK_PREFIX:=$(ARM_CHECK_PREFIX) +endif +endif +endif +ifeq ($(CHECK_PREFIX),) +CHECK_PREFIX:=$(BREW_PREFIX) +endif +ifneq ($(CHECK_PREFIX),) +UNIT_CFLAGS+=-I$(CHECK_PREFIX)/include +UNIT_LDFLAGS+=-L$(CHECK_PREFIX)/lib +endif +endif +TAP_SRC:=src/port/posix/tap_$(UNAME_LC).c +ifeq ($(wildcard $(TAP_SRC)),) +TAP_SRC:=src/port/posix/tap_linux.c +endif +TAP_OBJ:=$(patsubst src/%.c,build/%.o,$(TAP_SRC)) +TAP_PIE_OBJ:=$(patsubst src/%.c,build/pie/%.o,$(TAP_SRC)) + +ifeq ($(UNAME_S),Darwin) +BEGIN_GROUP:= +END_GROUP:= +else +BEGIN_GROUP:=-Wl,--start-group +END_GROUP:=-Wl,--end-group +endif + +CHECK_PKG_CFLAGS:=$(shell pkg-config --cflags check 2>/dev/null) +CHECK_PKG_LIBS:=$(shell pkg-config --libs check 2>/dev/null) + +ifneq ($(CHECK_PKG_CFLAGS),) +UNIT_CFLAGS+=$(CHECK_PKG_CFLAGS) +endif + CPPCHECK=cppcheck CPPCHECK_FLAGS=--enable=warning,performance,portability,missingInclude \ --suppress=missingIncludeSystem \ @@ -21,11 +94,27 @@ CPPCHECK_FLAGS=--enable=warning,performance,portability,missingInclude \ --error-exitcode=1 --xml --xml-version=2 OBJ=build/wolfip.o \ - build/port/posix/linux_tap.o + $(TAP_OBJ) + +HAVE_WOLFSSL:=$(shell printf "#include \nint main(void){return 0;}\n" | $(CC) $(CFLAGS) -x c - -c -o /dev/null 2>/dev/null && echo 1) + +# Require wolfSSL unless the requested goals are wolfSSL-independent (unit/cppcheck/clean). +REQ_WOLFSSL_GOALS:=$(filter-out unit cppcheck clean,$(MAKECMDGOALS)) +ifeq ($(strip $(MAKECMDGOALS)),) + ifeq ($(HAVE_WOLFSSL),) + $(warning wolfSSL headers not found. Skipping wolfSSL-dependent targets) + endif +else + ifneq ($(REQ_WOLFSSL_GOALS),) + ifeq ($(HAVE_WOLFSSL),) + $(error wolfSSL headers not found. Please install wolfSSL or adjust include paths) + endif + endif +endif EXE=build/tcpecho build/tcp_netcat_poll build/tcp_netcat_select \ build/test-evloop build/test-dns build/test-wolfssl-forwarding \ - build/test-ttl-expired build/test-wolfssl + build/test-ttl-expired build/test-wolfssl build/test-httpd LIB=libwolfip.so PREFIX=/usr/local @@ -44,10 +133,10 @@ libtcpip.a: $(OBJ) libwolfip.so:CFLAGS+=-fPIC libwolfip.so: build/pie/port/posix/bsd_socket.o build/pie/wolfip.o \ - build/pie/port/posix/linux_tap.o + $(TAP_PIE_OBJ) @mkdir -p `dirname $@` || true @echo "[LD] $@" - @$(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ -Wl,--start-group $(^) -Wl,--end-group + @$(CC) $(CFLAGS) $(LDFLAGS) -shared -o $@ $(BEGIN_GROUP) $(^) $(END_GROUP) clean: @@ -61,40 +150,50 @@ asan:LDFLAGS+=-static-libasan # Test -unit:LDFLAGS+=-lcheck -lm -lpthread -lrt -ldl -lsubunit -build/test-evloop: $(OBJ) build/test/test_linux_eventloop.o +ifeq ($(CHECK_PKG_LIBS),) +UNIT_LIBS=-lcheck -lm -lpthread -lrt -ldl -lsubunit +ifeq ($(UNAME_S),Darwin) +UNIT_LIBS=-lcheck -lm -lpthread +else ifeq ($(UNAME_S),FreeBSD) +UNIT_LIBS=-lcheck -lm -lpthread +endif +else +UNIT_LIBS=$(CHECK_PKG_LIBS) +endif + +unit:LDFLAGS+=$(UNIT_LIBS) +build/test-evloop: $(OBJ) build/test/test_eventloop.o @echo "[LD] $@" - @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ -Wl,--start-group $(^) -Wl,--end-group + @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(BEGIN_GROUP) $(^) $(END_GROUP) -build/test-dns: $(OBJ) build/test/test_linux_dhcp_dns.o +build/test-dns: $(OBJ) build/test/test_dhcp_dns.o @echo "[LD] $@" - @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ -Wl,--start-group $(^) -Wl,--end-group + @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(BEGIN_GROUP) $(^) $(END_GROUP) build/tcpecho: $(OBJ) build/port/posix/bsd_socket.o build/test/tcp_echo.o @echo "[LD] $@" - @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ -Wl,--start-group $(^) -Wl,--end-group + @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(BEGIN_GROUP) $(^) $(END_GROUP) build/tcp_netcat_poll: $(OBJ) build/port/posix/bsd_socket.o build/test/tcp_netcat_poll.o @echo "[LD] $@" - @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ -Wl,--start-group $(^) -Wl,--end-group + @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(BEGIN_GROUP) $(^) $(END_GROUP) build/tcp_netcat_select: $(OBJ) build/port/posix/bsd_socket.o build/test/tcp_netcat_select.o @echo "[LD] $@" - @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ -Wl,--start-group $(^) -Wl,--end-group + @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(BEGIN_GROUP) $(^) $(END_GROUP) build/test-wolfssl:CFLAGS+=-Wno-cpp -DWOLFSSL_DEBUG -DWOLFSSL_WOLFIP build/test-httpd:CFLAGS+=-Wno-cpp -DWOLFSSL_DEBUG -DWOLFSSL_WOLFIP -Isrc/http build/test-wolfssl-forwarding:CFLAGS+=-Wno-cpp -DWOLFSSL_DEBUG -DWOLFSSL_WOLFIP -DWOLFIP_MAX_INTERFACES=2 -DWOLFIP_ENABLE_FORWARDING=1 - build/test-wolfssl: $(OBJ) build/test/test_native_wolfssl.o build/port/wolfssl_io.o build/certs/server_key.o build/certs/ca_cert.o build/certs/server_cert.o @echo "[LD] $@" - @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ -Wl,--start-group $(^) -lwolfssl -Wl,--end-group + @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(BEGIN_GROUP) $(^) -lwolfssl $(END_GROUP) -build/test-wolfssl-forwarding: build/test/test_wolfssl_forwarding.o build/test/wolfip_forwarding.o build/port/posix/linux_tap.o build/port/wolfssl_io.o build/certs/server_key.o build/certs/ca_cert.o build/certs/server_cert.o +build/test-wolfssl-forwarding: build/test/test_wolfssl_forwarding.o build/test/wolfip_forwarding.o $(TAP_OBJ) build/port/wolfssl_io.o build/certs/server_key.o build/certs/ca_cert.o build/certs/server_cert.o @echo "[LD] $@" - @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ -Wl,--start-group $(^) -lwolfssl -Wl,--end-group + @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(BEGIN_GROUP) $(^) -lwolfssl $(END_GROUP) build/test/test_wolfssl_forwarding.o: CFLAGS+=-DWOLFIP_MAX_INTERFACES=2 -DWOLFIP_ENABLE_FORWARDING=1 @@ -106,11 +205,11 @@ build/test/wolfip_forwarding.o: src/wolfip.c build/test/test_ttl_expired.o: CFLAGS+=-DWOLFIP_MAX_INTERFACES=2 -DWOLFIP_ENABLE_FORWARDING=1 build/test-ttl-expired: build/test/test_ttl_expired.o build/test/wolfip_forwarding.o @echo "[LD] $@" - @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ -Wl,--start-group $(^) -Wl,--end-group + @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(BEGIN_GROUP) $(^) $(END_GROUP) build/test-httpd: $(OBJ) build/test/test_httpd.o build/port/wolfssl_io.o build/certs/server_key.o build/certs/server_cert.o build/http/httpd.o @echo "[LD] $@" - @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ -Wl,--start-group $(^) -lwolfssl -Wl,--end-group + @$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(BEGIN_GROUP) $(^) -lwolfssl $(END_GROUP) build/%.o: src/%.c @mkdir -p `dirname $@` || true @@ -154,9 +253,9 @@ unit: build/test/unit build/test/unit: @mkdir -p build/test/ @echo "[CC] unit.c" - @$(CC) $(CFLAGS) -c src/test/unit/unit.c -o build/test/unit.o + @$(CC) $(CFLAGS) $(UNIT_CFLAGS) -c src/test/unit/unit.c -o build/test/unit.o @echo "[LD] $@" - @$(CC) -o build/test/unit build/test/unit.o $(LDFLAGS) + @$(CC) build/test/unit.o -o build/test/unit $(UNIT_LDFLAGS) $(LDFLAGS) # Install dynamic library to re-link linux applications # diff --git a/config.h b/config.h index 2915717..c08cb14 100644 --- a/config.h +++ b/config.h @@ -29,6 +29,6 @@ /* Linux test configuration */ #define WOLFIP_IP "10.10.10.2" -#define LINUX_IP "10.10.10.1" +#define HOST_STACK_IP "10.10.10.1" #endif diff --git a/src/port/posix/bsd_socket.c b/src/port/posix/bsd_socket.c index ec82517..a8eaa32 100644 --- a/src/port/posix/bsd_socket.c +++ b/src/port/posix/bsd_socket.c @@ -532,8 +532,8 @@ int poll(struct pollfd *fds, nfds_t nfds, int timeout) { /* Catch-all function to initialize a new tap device as the network interface. - * This is defined in port/linux.c - * */ + * Implemented in port/posix/tap_*.c + */ extern int tap_init(struct wolfIP_ll_dev *dev, const char *name, uint32_t host_ip); void *wolfIP_sock_posix_ip_loop(void *arg) { @@ -552,12 +552,12 @@ void *wolfIP_sock_posix_ip_loop(void *arg) { } void __attribute__((constructor)) init_wolfip_posix() { - struct in_addr linux_ip; + struct in_addr host_stack_ip; struct wolfIP_ll_dev *tapdev; pthread_t wolfIP_thread; if (IPSTACK) return; - inet_aton(LINUX_IP, &linux_ip); + inet_aton(HOST_STACK_IP, &host_stack_ip); swap_socketcall(socket, "socket"); swap_socketcall(bind, "bind"); swap_socketcall(listen, "listen"); @@ -581,14 +581,13 @@ void __attribute__((constructor)) init_wolfip_posix() { pthread_mutex_init(&wolfIP_mutex, NULL); wolfIP_init_static(&IPSTACK); tapdev = wolfIP_getdev(IPSTACK); - if (tap_init(tapdev, "wtcp0", linux_ip.s_addr) < 0) { + if (tap_init(tapdev, "wtcp0", host_stack_ip.s_addr) < 0) { perror("tap init"); } wolfIP_ipconfig_set(IPSTACK, atoip4(WOLFIP_IP), atoip4("255.255.255.0"), - atoip4(LINUX_IP)); + atoip4(HOST_STACK_IP)); printf("IP: manually configured - %s\n", WOLFIP_IP); sleep(1); pthread_create(&wolfIP_thread, NULL, wolfIP_sock_posix_ip_loop, IPSTACK); in_the_stack = 0; } - diff --git a/src/port/posix/tap_darwin.c b/src/port/posix/tap_darwin.c new file mode 100644 index 0000000..841dc80 --- /dev/null +++ b/src/port/posix/tap_darwin.c @@ -0,0 +1,315 @@ +/* tap_darwin.c + * + * User-space TAP implementation for macOS using utun (L3) interfaces. The code + * synthesizes an Ethernet header around IP packets so the rest of wolfIP can + * continue operating on Ethernet frames. + * + * Copyright (C) 2025 wolfSSL Inc. + * + * This file is part of wolfIP TCP/IP stack. + * + * wolfIP is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfIP 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" +#include "wolfip.h" + +#ifndef ETHERTYPE_IP +#define ETHERTYPE_IP 0x0800 +#endif +#ifndef ETH_P_IP +#define ETH_P_IP ETHERTYPE_IP +#endif +#ifndef ETHERTYPE_ARP +#define ETHERTYPE_ARP 0x0806 +#endif + +#define PACKED __attribute__((packed)) +#define AF_HDR_SIZE 4 + +struct eth_hdr { + uint8_t dst[6]; + uint8_t src[6]; + uint16_t type; +} PACKED; + +static int utun_fd = -1; +static uint8_t peer_mac[6] = {0x06, 0x00, 0x00, 0x00, 0x00, 0x01}; +static pthread_mutex_t utun_lock = PTHREAD_MUTEX_INITIALIZER; +static uint8_t pending_frame[LINK_MTU + sizeof(struct eth_hdr)]; +static size_t pending_len = 0; +static pthread_mutex_t pending_lock = PTHREAD_MUTEX_INITIALIZER; +static uint32_t host_ip_be; +static uint32_t peer_ip_be; + +struct arp_packet { + uint16_t htype; + uint16_t ptype; + uint8_t hlen; + uint8_t plen; + uint16_t opcode; + uint8_t sha[6]; + uint32_t spa; + uint8_t tha[6]; + uint32_t tpa; +} PACKED; + +static int enqueue_frame(const void *frame, size_t len) +{ + if (len > sizeof(pending_frame)) + return -1; + pthread_mutex_lock(&pending_lock); + memcpy(pending_frame, frame, len); + pending_len = len; + pthread_mutex_unlock(&pending_lock); + return 0; +} + +static int tap_poll(struct wolfIP_ll_dev *ll, void *buf, uint32_t len) +{ + struct pollfd pfd; + uint8_t tmp[LINK_MTU + AF_HDR_SIZE]; + ssize_t n; + size_t ip_len; + struct eth_hdr *eth; + + if (utun_fd < 0) + return -1; + + pthread_mutex_lock(&pending_lock); + if (pending_len > 0) { + size_t to_copy = pending_len; + if (to_copy > len) + to_copy = len; + memcpy(buf, pending_frame, to_copy); + pending_len = 0; + pthread_mutex_unlock(&pending_lock); + return (int)to_copy; + } + pthread_mutex_unlock(&pending_lock); + + pfd.fd = utun_fd; + pfd.events = POLLIN; + + if (poll(&pfd, 1, 2) <= 0) + return 0; + + pthread_mutex_lock(&utun_lock); + n = read(utun_fd, tmp, sizeof(tmp)); + pthread_mutex_unlock(&utun_lock); + + if (n <= 0) + return (int)n; + if (n <= AF_HDR_SIZE) + return 0; + + ip_len = (size_t)(n - AF_HDR_SIZE); + if (sizeof(struct eth_hdr) + ip_len > len) + ip_len = len - sizeof(struct eth_hdr); + + eth = (struct eth_hdr *)buf; + memcpy(eth->dst, ll->mac, 6); + memcpy(eth->src, peer_mac, 6); + eth->type = htons(ETH_P_IP); + memcpy(((uint8_t *)eth) + sizeof(struct eth_hdr), tmp + AF_HDR_SIZE, ip_len); + return (int)(sizeof(struct eth_hdr) + ip_len); +} + +static int tap_send(struct wolfIP_ll_dev *ll, void *buf, uint32_t len) +{ + uint8_t tmp[LINK_MTU + AF_HDR_SIZE]; + struct eth_hdr *eth; + size_t ip_len; + struct arp_packet *arp; + uint32_t af; + (void)ll; + + if (utun_fd < 0) + return -1; + if (len < sizeof(struct eth_hdr)) + return 0; + eth = (struct eth_hdr *)buf; + if (ntohs(eth->type) == ETHERTYPE_ARP) { + if (len < sizeof(struct eth_hdr) + sizeof(struct arp_packet)) + return (int)len; + arp = (struct arp_packet *)(eth + 1); + if (ntohs(arp->opcode) == 1 /* request */ && + arp->tpa == host_ip_be) { + struct { + struct eth_hdr eth; + struct arp_packet arp; + } PACKED reply; + memset(&reply, 0, sizeof(reply)); + memcpy(reply.eth.dst, eth->src, sizeof(reply.eth.dst)); + memcpy(reply.eth.src, peer_mac, sizeof(reply.eth.src)); + reply.eth.type = htons(ETHERTYPE_ARP); + reply.arp.htype = htons(1); + reply.arp.ptype = htons(ETHERTYPE_IP); + reply.arp.hlen = 6; + reply.arp.plen = 4; + reply.arp.opcode = htons(2); + memcpy(reply.arp.sha, peer_mac, sizeof(reply.arp.sha)); + reply.arp.spa = host_ip_be; + memcpy(reply.arp.tha, arp->sha, sizeof(reply.arp.tha)); + reply.arp.tpa = arp->spa; + printf("tap_darwin: answering ARP request locally\n"); + enqueue_frame(&reply, sizeof(reply)); + return (int)len; + } + return (int)len; + } + if (ntohs(eth->type) != ETH_P_IP) + return (int)len; + + ip_len = len - sizeof(struct eth_hdr); + if (ip_len + AF_HDR_SIZE > sizeof(tmp)) + return -1; + + af = htonl(AF_INET); + memcpy(tmp, &af, AF_HDR_SIZE); + memcpy(tmp + AF_HDR_SIZE, ((uint8_t *)eth) + sizeof(struct eth_hdr), ip_len); + + pthread_mutex_lock(&utun_lock); + if (write(utun_fd, tmp, ip_len + AF_HDR_SIZE) < 0) { + pthread_mutex_unlock(&utun_lock); + return -1; + } + pthread_mutex_unlock(&utun_lock); + return (int)len; +} + +static int tap_setup_ipv4(const char *ifname, uint32_t host_ip, uint32_t peer_ip) +{ + char cmd[256]; + char local_str[INET_ADDRSTRLEN]; + char peer_str[INET_ADDRSTRLEN]; + char netmask_str[INET_ADDRSTRLEN]; + struct in_addr local = { .s_addr = host_ip }; + struct in_addr peer = { .s_addr = peer_ip }; + struct in_addr netmask = { .s_addr = 0x00ffffff }; + + + if (!inet_ntop(AF_INET, &local, local_str, sizeof(local_str))) + return -1; + if (!inet_ntop(AF_INET, &peer, peer_str, sizeof(peer_str))) + return -1; + if (!inet_ntop(AF_INET, &netmask, netmask_str, sizeof(netmask_str))) + return -1; + + printf("tap_setup_ipv4: ifname=%s local=%s peer=%s\n", ifname, local_str, peer_str); + + snprintf(cmd, sizeof(cmd), "/sbin/ifconfig %s inet %s %s netmask %s up", + ifname, local_str, peer_str, netmask_str); + if (system(cmd) != 0) + return -1; + + snprintf(cmd, sizeof(cmd), "/sbin/route -n add -host %s -interface %s >/dev/null 2>&1", + peer_str, ifname); + system(cmd); + + return 0; +} + +int tap_init(struct wolfIP_ll_dev *ll, const char *requested_ifname, uint32_t host_ip) +{ + struct ctl_info info; + struct sockaddr_ctl sc; + char ifname_buf[IFNAMSIZ]; + socklen_t optlen; + uint32_t peer_ip = htonl(atoip4(WOLFIP_IP)); + host_ip_be = host_ip; + peer_ip_be = peer_ip; + printf("tap_init: host_ip=0x%08x peer_ip=0x%08x\n", host_ip_be, peer_ip_be); + (void)requested_ifname; + + utun_fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL); + if (utun_fd < 0) { + perror("socket utun"); + return -1; + } + + memset(&info, 0, sizeof(info)); + strlcpy(info.ctl_name, UTUN_CONTROL_NAME, sizeof(info.ctl_name)); + if (ioctl(utun_fd, CTLIOCGINFO, &info) < 0) { + perror("ioctl CTLIOCGINFO"); + close(utun_fd); + utun_fd = -1; + return -1; + } + + memset(&sc, 0, sizeof(sc)); + sc.sc_len = sizeof(sc); + sc.sc_family = AF_SYSTEM; + sc.ss_sysaddr = AF_SYS_CONTROL; + sc.sc_id = info.ctl_id; + sc.sc_unit = 0; + + if (connect(utun_fd, (struct sockaddr *)&sc, sizeof(sc)) < 0) { + perror("connect utun"); + close(utun_fd); + utun_fd = -1; + return -1; + } + + optlen = sizeof(ifname_buf); + if (getsockopt(utun_fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, + ifname_buf, &optlen) < 0) { + perror("getsockopt UTUN_OPT_IFNAME"); + close(utun_fd); + utun_fd = -1; + return -1; + } + ifname_buf[IFNAMSIZ - 1] = '\0'; + + fcntl(utun_fd, F_SETFL, O_NONBLOCK); + + memcpy(ll->mac, (uint8_t[]){0x02, 0x00, 0x00, 0x00, 0x00, 0x02}, 6); + ll->poll = tap_poll; + ll->send = tap_send; + strlcpy(ll->ifname, ifname_buf, sizeof(ll->ifname)); + + if (tap_setup_ipv4(ifname_buf, host_ip, peer_ip) != 0) { + close(utun_fd); + utun_fd = -1; + return -1; + } + + return 0; +} + +uint32_t wolfIP_getrandom(void) +{ + return arc4random(); +} diff --git a/src/port/posix/tap_freebsd.c b/src/port/posix/tap_freebsd.c new file mode 100644 index 0000000..a04ab6c --- /dev/null +++ b/src/port/posix/tap_freebsd.c @@ -0,0 +1,242 @@ +/* tap_freebsd.c + * + * FreeBSD TAP integration for wolfIP POSIX examples. + * + * Copyright (C) 2025 wolfSSL Inc. + * + * This file is part of wolfIP TCP/IP stack. + * + * wolfIP is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfIP 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wolfip.h" + +static int tap_fd = -1; + +static int tap_poll(struct wolfIP_ll_dev *ll, void *buf, uint32_t len) +{ + struct pollfd pfd; + int ret; + (void)ll; + + pfd.fd = tap_fd; + pfd.events = POLLIN; + ret = poll(&pfd, 1, 2); + if (ret < 0) { + perror("poll"); + return -1; + } + if (ret == 0) + return 0; + return (int)read(tap_fd, buf, len); +} + +static int tap_send(struct wolfIP_ll_dev *ll, void *buf, uint32_t len) +{ + (void)ll; + return (int)write(tap_fd, buf, len); +} + +static int tap_set_ipv4(int sock_fd, const char *ifname, uint32_t host_ip) +{ + struct ifreq ifr; + struct ifaliasreq ifra; + struct sockaddr_in *sin; + uint32_t mask_host = 0xFFFFFF00U; + uint32_t addr_host = ntohl(host_ip); + uint32_t broad_host = (addr_host & mask_host) | (~mask_host); + uint32_t mask_net = htonl(mask_host); + uint32_t broad_net = htonl(broad_host); + + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + + if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr) < 0) { + perror("ioctl SIOCGIFFLAGS"); + return -1; + } + ifr.ifr_flags |= IFF_UP; + if (ioctl(sock_fd, SIOCSIFFLAGS, &ifr) < 0) { + perror("ioctl SIOCSIFFLAGS"); + return -1; + } + + memset(&ifra, 0, sizeof(ifra)); + strlcpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name)); + + sin = (struct sockaddr_in *)&ifra.ifra_addr; + memset(sin, 0, sizeof(*sin)); + sin->sin_len = sizeof(*sin); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = host_ip; + + sin = (struct sockaddr_in *)&ifra.ifra_mask; + memset(sin, 0, sizeof(*sin)); + sin->sin_len = sizeof(*sin); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = mask_net; + + sin = (struct sockaddr_in *)&ifra.ifra_broadaddr; + memset(sin, 0, sizeof(*sin)); + sin->sin_len = sizeof(*sin); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = broad_net; + + if (ioctl(sock_fd, SIOCAIFADDR, &ifra) < 0) { + perror("ioctl SIOCAIFADDR"); + return -1; + } + + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + if (ioctl(sock_fd, SIOCGIFFLAGS, &ifr) < 0) { + perror("ioctl SIOCGIFFLAGS"); + return -1; + } + ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); + if (ioctl(sock_fd, SIOCSIFFLAGS, &ifr) < 0) { + perror("ioctl SIOCSIFFLAGS"); + return -1; + } + return 0; +} + +static void tap_fetch_mac(struct wolfIP_ll_dev *ll) +{ + struct ifaddrs *ifas = NULL; + + if (getifaddrs(&ifas) != 0) + return; + + for (struct ifaddrs *ifa = ifas; ifa; ifa = ifa->ifa_next) { + struct sockaddr_dl *sdl; + size_t alen; + + if (!ifa->ifa_addr) + continue; + if (ifa->ifa_addr->sa_family != AF_LINK) + continue; + if (strcmp(ifa->ifa_name, ll->ifname) != 0) + continue; + + sdl = (struct sockaddr_dl *)ifa->ifa_addr; + alen = sdl->sdl_alen; + if (alen > sizeof(ll->mac)) + alen = sizeof(ll->mac); + memcpy(ll->mac, LLADDR(sdl), alen); + if (alen < sizeof(ll->mac)) + memset(ll->mac + alen, 0, sizeof(ll->mac) - alen); + if (alen > 0) + ll->mac[alen - 1] ^= 1; + break; + } + + freeifaddrs(ifas); +} + +int tap_init(struct wolfIP_ll_dev *ll, const char *ifname, uint32_t host_ip) +{ + char devpath[PATH_MAX]; + struct ifreq ifr; + int sock_fd; + const char *final_ifname = ifname; + int auto_name = 0; + + if (ifname && ifname[0] != '\0') { + snprintf(devpath, sizeof(devpath), "/dev/%s", ifname); + } else { + snprintf(devpath, sizeof(devpath), "/dev/tap"); + auto_name = 1; + } + + tap_fd = open(devpath, O_RDWR); + if (tap_fd < 0 && ifname && ifname[0] != '\0') { + snprintf(devpath, sizeof(devpath), "/dev/tap"); + tap_fd = open(devpath, O_RDWR); + auto_name = 1; + } + if (tap_fd < 0) { + perror("open tap device"); + return -1; + } + + memset(&ifr, 0, sizeof(ifr)); + if (auto_name) { +#ifdef TAPGIFNAME + if (ioctl(tap_fd, TAPGIFNAME, (void *)&ifr) < 0) { + perror("ioctl TAPGIFNAME"); + close(tap_fd); + tap_fd = -1; + return -1; + } + final_ifname = ifr.ifr_name; +#else + final_ifname = "tap0"; +#endif + } else { + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + } + + strlcpy(ll->ifname, final_ifname, sizeof(ll->ifname)); + ll->poll = tap_poll; + ll->send = tap_send; + + memset(ll->mac, 0, sizeof(ll->mac)); + tap_fetch_mac(ll); + + sock_fd = socket(AF_INET, SOCK_DGRAM, 0); + if (sock_fd < 0) { + perror("socket"); + close(tap_fd); + tap_fd = -1; + return -1; + } + + if (tap_set_ipv4(sock_fd, ll->ifname, host_ip) < 0) { + close(sock_fd); + close(tap_fd); + tap_fd = -1; + return -1; + } + + close(sock_fd); + printf("Successfully initialized tap device %s\n", ll->ifname); + return 0; +} + +uint32_t wolfIP_getrandom(void) +{ + uint32_t val; + arc4random_buf(&val, sizeof(val)); + return val; +} diff --git a/src/port/posix/linux_tap.c b/src/port/posix/tap_linux.c similarity index 99% rename from src/port/posix/linux_tap.c rename to src/port/posix/tap_linux.c index a7764fb..00ecb50 100644 --- a/src/port/posix/linux_tap.c +++ b/src/port/posix/tap_linux.c @@ -1,4 +1,4 @@ -/* linux_tap.c +/* tap_linux.c * * Copyright (C) 2024 wolfSSL Inc. * diff --git a/src/test/tcp_echo.c b/src/test/tcp_echo.c index ae5f0d1..c9b7d3d 100644 --- a/src/test/tcp_echo.c +++ b/src/test/tcp_echo.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include #define PORT 8 diff --git a/src/test/test_linux_dhcp_dns.c b/src/test/test_dhcp_dns.c similarity index 74% rename from src/test/test_linux_dhcp_dns.c rename to src/test/test_dhcp_dns.c index 3133f36..6ed75bc 100644 --- a/src/test/test_linux_dhcp_dns.c +++ b/src/test/test_dhcp_dns.c @@ -1,4 +1,4 @@ -/* test_linux_dhcp_dns.c +/* test_dhcp_dns.c * * Copyright (C) 2024 wolfSSL Inc. * @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include "config.h" #include "wolfip.h" @@ -131,8 +133,8 @@ static int test_loop(struct wolfIP *s, int active_close) return 0; } -/* Test code (Linux side). - * Thread with echo server to test the client. +/* Test code (host side). + * Provide an echo server to exercise the client path. */ static void *pt_echoserver(void *arg) { @@ -150,7 +152,7 @@ static void *pt_echoserver(void *arg) printf("test server socket: %d\n", fd); return (void *)-1; } - local_sock.sin_addr.s_addr = inet_addr(LINUX_IP); + local_sock.sin_addr.s_addr = inet_addr(HOST_STACK_IP); setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)); ret = bind(fd, (struct sockaddr *)&local_sock, sizeof(local_sock)); if (ret < 0) { @@ -190,7 +192,7 @@ static void *pt_echoserver(void *arg) /* Catch-all function to initialize a new tap device as the network interface. - * This is defined in port/linux.c + * This is defined in port/posix/bsd_socket.c * */ extern int tap_init(struct wolfIP_ll_dev *dev, const char *name, uint32_t host_ip); @@ -202,19 +204,19 @@ void test_wolfip_echoclient(struct wolfIP *s) /* Client side test: client is closing the connection */ remote_sock.sin_family = AF_INET; remote_sock.sin_port = ee16(8); - remote_sock.sin_addr.s_addr = inet_addr(LINUX_IP); + remote_sock.sin_addr.s_addr = inet_addr(HOST_STACK_IP); printf("TCP client tests\n"); conn_fd = wolfIP_sock_socket(s, AF_INET, IPSTACK_SOCK_STREAM, 0); printf("client socket: %04x\n", conn_fd); wolfIP_register_callback(s, conn_fd, client_cb, s); - printf("Connecting to %s:8\n", LINUX_IP); + printf("Connecting to %s:8\n", HOST_STACK_IP); wolfIP_sock_connect(s, conn_fd, (struct wolfIP_sockaddr *)&remote_sock, sizeof(remote_sock)); pthread_create(&pt, NULL, pt_echoserver, (void*)1); printf("Starting test: echo client active close\n"); ret = test_loop(s, 1); printf("Test echo client active close: %d\n", ret); pthread_join(pt, (void **)&test_ret); - printf("Test linux server: %d\n", test_ret); + printf("Test host server: %d\n", test_ret); if (conn_fd >= 0) { wolfIP_sock_close(s, conn_fd); @@ -239,10 +241,13 @@ int main(int argc, char **argv) struct wolfIP *s; struct wolfIP_ll_dev *tapdev; struct timeval tv; - struct in_addr linux_ip; + struct in_addr host_stack_ip; uint32_t srv_ip; uint16_t dns_id = 0; ip4 ip = 0, nm = 0, gw = 0; +#ifdef __FreeBSD__ + char dnsmasq_pid_file[64] = {0}; +#endif (void)argc; (void)argv; @@ -254,12 +259,61 @@ int main(int argc, char **argv) tapdev = wolfIP_getdev(s); if (!tapdev) return 1; - inet_aton(LINUX_IP, &linux_ip); - if (tap_init(tapdev, "wtcp0", linux_ip.s_addr) < 0) { + inet_aton(HOST_STACK_IP, &host_stack_ip); + if (tap_init(tapdev, "wtcp0", host_stack_ip.s_addr) < 0) { perror("tap init"); return 2; } - system("tcpdump -i wtcp0 -w test.pcap &"); + { +#if !defined(__FreeBSD__) && !defined(__APPLE__) + char cmd[128]; + snprintf(cmd, sizeof(cmd), "tcpdump -i %s -w test.pcap &", tapdev->ifname); + system(cmd); +#elif defined(__FreeBSD__) + char cmd[256]; + char addr_buf[INET_ADDRSTRLEN]; + char start_buf[INET_ADDRSTRLEN]; + char end_buf[INET_ADDRSTRLEN]; + uint32_t host_ip = ntohl(host_stack_ip.s_addr); + uint32_t net = host_ip & 0xFFFFFF00U; + uint32_t start = net | 0x14U; + uint32_t end = net | 0x28U; + struct in_addr tmp; + + inet_ntop(AF_INET, &host_stack_ip, addr_buf, sizeof(addr_buf)); + tmp.s_addr = htonl(start); + inet_ntop(AF_INET, &tmp, start_buf, sizeof(start_buf)); + tmp.s_addr = htonl(end); + inet_ntop(AF_INET, &tmp, end_buf, sizeof(end_buf)); + + snprintf(dnsmasq_pid_file, sizeof(dnsmasq_pid_file), + "/tmp/dnsmasq-%s.pid", tapdev->ifname); + snprintf(cmd, sizeof(cmd), + "dnsmasq --interface=%s " + "--bind-interfaces " + "--listen-address=%s " + "--conf-file=/dev/null " + "--dhcp-range=%s,%s,255.255.255.0,1h " + "--dhcp-option=3,%s " + "--dhcp-option=6,%s " + "--dhcp-authoritative " + "--address=/example.com/%s " + "--log-facility=/dev/null " + "--pid-file=%s >/dev/null 2>&1 &", + tapdev->ifname, + addr_buf, + start_buf, + end_buf, + addr_buf, + addr_buf, + addr_buf, + dnsmasq_pid_file); + printf("Starting dnsmasq: %s\n", cmd); + system(cmd); +#else + (void)tapdev; +#endif + } gettimeofday(&tv, NULL); wolfIP_poll(s, tv.tv_sec * 1000 + tv.tv_usec / 1000); @@ -288,7 +342,16 @@ int main(int argc, char **argv) sleep(2); sync(); +#if !defined(__FreeBSD__) && !defined(__APPLE__) system("killall tcpdump"); +#elif defined(__FreeBSD__) + if (dnsmasq_pid_file[0] != '\0') { + char stop_cmd[160]; + snprintf(stop_cmd, sizeof(stop_cmd), + "if [ -f %s ]; then kill $(cat %s) >/dev/null 2>&1; rm -f %s; fi", + dnsmasq_pid_file, dnsmasq_pid_file, dnsmasq_pid_file); + system(stop_cmd); + } +#endif return 0; } - diff --git a/src/test/test_linux_eventloop.c b/src/test/test_eventloop.c similarity index 80% rename from src/test/test_linux_eventloop.c rename to src/test/test_eventloop.c index 1587b59..d3eef06 100644 --- a/src/test/test_linux_eventloop.c +++ b/src/test/test_eventloop.c @@ -1,4 +1,4 @@ -/* test_linux_eventloop.c +/* test_eventloop.c * * Copyright (C) 2024 wolfSSL Inc. * @@ -25,8 +25,12 @@ #include #include #include +#include #include #include +#include +#include +#include #include "config.h" #include "wolfip.h" @@ -197,7 +201,7 @@ static int test_loop(struct wolfIP *s, int active_close) return 0; } -/* Test code (Linux side). +/* Test code (host side). * Thread with client to test the echoserver. */ void *pt_echoclient(void *arg) @@ -207,6 +211,11 @@ void *pt_echoclient(void *arg) unsigned i; uint8_t local_buf[BUFFER_SIZE]; uint32_t *srv_addr = (uint32_t *)arg; + int old_flags = -1; + fd_set wfds, rfds; + struct timeval tv; + socklen_t errlen; + int err; struct sockaddr_in remote_sock = { .sin_family = AF_INET, .sin_port = ntohs(8), /* Echo */ @@ -220,20 +229,80 @@ void *pt_echoclient(void *arg) sleep(1); setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)); printf("Connecting to echo server\n"); + old_flags = fcntl(fd, F_GETFL, 0); + if (old_flags < 0) { + perror("fcntl(F_GETFL)"); + close(fd); + return (void *)-1; + } + if (fcntl(fd, F_SETFL, old_flags | O_NONBLOCK) < 0) { + perror("fcntl(F_SETFL)"); + close(fd); + return (void *)-1; + } ret = connect(fd, (struct sockaddr *)&remote_sock, sizeof(remote_sock)); if (ret < 0) { - printf("test client connect: %d\n", ret); - perror("connect"); - return (void *)-1; + err = errno; + printf("test client connect returned %d, errno=%d (%s)\n", ret, err, strerror(err)); + if (err != EINPROGRESS) { + perror("connect"); + close(fd); + return (void *)-1; + } + printf("Waiting for connect to complete...\n"); + while (1) { + tv.tv_sec = 5; + tv.tv_usec = 0; + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_SET(fd, &rfds); + FD_SET(fd, &wfds); + ret = select(fd + 1, &rfds, &wfds, NULL, &tv); + if (ret <= 0) { + printf("select returned %d (timeout or error)\n", ret); + if (ret < 0) { + perror("select"); + close(fd); + return (void *)-1; + } + } + errlen = sizeof(err); + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &errlen) < 0) { + perror("getsockopt(SO_ERROR)"); + close(fd); + return (void *)-1; + } + if (err == 0) { + printf("connect completed after select()\n"); + break; + } + if (ret == 0) { + printf("connect still in progress after timeout\n"); + continue; + } + if (err != EINPROGRESS && err != EALREADY && err != EWOULDBLOCK && err != EAGAIN) { + printf("connect completed with error: %d (%s)\n", err, strerror(err)); + close(fd); + return (void *)-1; + } + } + } else { + printf("connect returned immediately\n"); } + if (fcntl(fd, F_SETFL, old_flags) < 0) + perror("fcntl(restore)"); + printf("test client: connect succeeded\n"); for (i = 0; i < sizeof(local_buf); i += sizeof(test_pattern)) { memcpy(local_buf + i, test_pattern, sizeof(test_pattern)); } ret = write(fd, local_buf, sizeof(local_buf)); if (ret < 0) { - printf("test client write: %d\n", ret); + int werr = errno; + printf("test client write: %d (errno=%d: %s)\n", ret, werr, strerror(werr)); + perror("write"); return (void *)-1; } + printf("test client: wrote %d bytes\n", ret); while (total_r < sizeof(local_buf)) { ret = read(fd, local_buf + total_r, sizeof(local_buf) - total_r); if (ret < 0) { @@ -248,6 +317,7 @@ void *pt_echoclient(void *arg) return (void *)-1; } total_r += ret; + printf("test client: read %d bytes (total %u)\n", ret, total_r); } for (i = 0; i < sizeof(local_buf); i += sizeof(test_pattern)) { if (memcmp(local_buf + i, test_pattern, sizeof(test_pattern))) { @@ -263,7 +333,7 @@ void *pt_echoclient(void *arg) return (void *)0; } -/* Test code (Linux side). +/* Test code (host side). * Thread with echo server to test the client. */ static void *pt_echoserver(void *arg) @@ -282,7 +352,7 @@ static void *pt_echoserver(void *arg) printf("test server socket: %d\n", fd); return (void *)-1; } - local_sock.sin_addr.s_addr = inet_addr(LINUX_IP); + local_sock.sin_addr.s_addr = inet_addr(HOST_STACK_IP); setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)); ret = bind(fd, (struct sockaddr *)&local_sock, sizeof(local_sock)); if (ret < 0) { @@ -322,7 +392,7 @@ static void *pt_echoserver(void *arg) /* Catch-all function to initialize a new tap device as the network interface. - * This is defined in port/linux.c + * This is defined in port/posix/bsd_socket.c * */ extern int tap_init(struct wolfIP_ll_dev *dev, const char *name, uint32_t host_ip); @@ -352,7 +422,7 @@ void test_wolfip_echoserver(struct wolfIP *s, uint32_t srv_ip) ret = test_loop(s, 0); pthread_join(pt, (void **)&test_ret); printf("Test echo server close-wait: %d\n", ret); - printf("Test linux client: %d\n", test_ret); + printf("Test host client: %d\n", test_ret); sleep(1); pthread_create(&pt, NULL, pt_echoclient, &srv_ip); @@ -360,7 +430,7 @@ void test_wolfip_echoserver(struct wolfIP *s, uint32_t srv_ip) ret = test_loop(s, 1); printf("Test echo server close-wait: %d\n", ret); pthread_join(pt, (void **)&test_ret); - printf("Test linux client: %d\n", test_ret); + printf("Test host client: %d\n", test_ret); sleep(1); wolfIP_sock_close(s, listen_fd); @@ -374,19 +444,19 @@ void test_wolfip_echoclient(struct wolfIP *s) /* Client side test: client is closing the connection */ remote_sock.sin_family = AF_INET; remote_sock.sin_port = ee16(8); - remote_sock.sin_addr.s_addr = inet_addr(LINUX_IP); + remote_sock.sin_addr.s_addr = inet_addr(HOST_STACK_IP); printf("TCP client tests\n"); conn_fd = wolfIP_sock_socket(s, AF_INET, IPSTACK_SOCK_STREAM, 0); printf("client socket: %04x\n", conn_fd); wolfIP_register_callback(s, conn_fd, client_cb, s); - printf("Connecting to %s:8\n", LINUX_IP); + printf("Connecting to %s:8\n", HOST_STACK_IP); wolfIP_sock_connect(s, conn_fd, (struct wolfIP_sockaddr *)&remote_sock, sizeof(remote_sock)); pthread_create(&pt, NULL, pt_echoserver, (void*)1); printf("Starting test: echo client active close\n"); ret = test_loop(s, 1); printf("Test echo client active close: %d\n", ret); pthread_join(pt, (void **)&test_ret); - printf("Test linux server: %d\n", test_ret); + printf("Test host server: %d\n", test_ret); if (conn_fd >= 0) { wolfIP_sock_close(s, conn_fd); @@ -394,7 +464,7 @@ void test_wolfip_echoclient(struct wolfIP *s) } /* Client side test: server is closing the connection */ - /* Excluded for now as linux cannot bind twice on port 8 */ + /* Excluded for now because binding twice on port 8 is not supported */ #if 0 conn_fd = wolfIP_sock_socket(s, AF_INET, IPSTACK_SOCK_STREAM, 0); if (conn_fd < 0) { @@ -402,14 +472,14 @@ void test_wolfip_echoclient(struct wolfIP *s) } printf("client socket: %04x\n", conn_fd); wolfIP_register_callback(s, conn_fd, client_cb, s); - printf("Connecting to %s:8\n", LINUX_IP); + printf("Connecting to %s:8\n", HOST_STACK_IP); wolfIP_sock_connect(s, conn_fd, (struct wolfIP_sockaddr *)&remote_sock, sizeof(remote_sock)); pthread_create(&pt, NULL, pt_echoserver, (void*)0); printf("Starting test: echo client passive close\n"); ret = test_loop(s, 0); printf("Test echo client, server closing: %d\n", ret); pthread_join(pt, (void **)&test_ret); - printf("Test linux server: %d\n", test_ret); + printf("Test host server: %d\n", test_ret); #endif @@ -422,7 +492,7 @@ int main(int argc, char **argv) struct wolfIP *s; struct wolfIP_ll_dev *tapdev; struct timeval tv = {0, 0}; - struct in_addr linux_ip; + struct in_addr host_stack_ip; uint32_t srv_ip; ip4 ip = 0, nm = 0, gw = 0; @@ -436,12 +506,20 @@ int main(int argc, char **argv) tapdev = wolfIP_getdev(s); if (!tapdev) return 1; - inet_aton(LINUX_IP, &linux_ip); - if (tap_init(tapdev, "wtcp0", linux_ip.s_addr) < 0) { + inet_aton(HOST_STACK_IP, &host_stack_ip); + if (tap_init(tapdev, "wtcp0", host_stack_ip.s_addr) < 0) { perror("tap init"); return 2; } - system("tcpdump -i wtcp0 -w test.pcap &"); + { +#if !defined(__FreeBSD__) && !defined(__APPLE__) + char cmd[128]; + snprintf(cmd, sizeof(cmd), "tcpdump -i %s -w test.pcap &", tapdev->ifname); + system(cmd); +#else + (void)tapdev; +#endif + } #ifdef DHCP gettimeofday(&tv, NULL); @@ -458,7 +536,7 @@ int main(int argc, char **argv) srv_ip = htonl(ip); #else wolfIP_ipconfig_set(s, atoip4(WOLFIP_IP), atoip4("255.255.255.0"), - atoip4(LINUX_IP)); + atoip4(HOST_STACK_IP)); printf("IP: manually configured\n"); inet_pton(AF_INET, WOLFIP_IP, &srv_ip); #endif @@ -469,7 +547,8 @@ int main(int argc, char **argv) /* Client side test */ test_wolfip_echoclient(s); +#if !defined(__FreeBSD__) && !defined(__APPLE__) system("killall tcpdump"); +#endif return 0; } - diff --git a/src/test/test_httpd.c b/src/test/test_httpd.c index ca5332f..fc8058f 100644 --- a/src/test/test_httpd.c +++ b/src/test/test_httpd.c @@ -69,7 +69,7 @@ static int test_loop(struct wolfIP *s, int active_close) /* Catch-all function to initialize a new tap device as the network interface. - * This is defined in port/linux.c + * This is defined in port/posix/bsd_socket.c * */ extern int tap_init(struct wolfIP_ll_dev *dev, const char *name, uint32_t host_ip); @@ -128,7 +128,7 @@ int main(int argc, char **argv) struct wolfIP *s; struct wolfIP_ll_dev *tapdev; struct timeval tv = {0, 0}; - struct in_addr linux_ip; + struct in_addr host_stack_ip; uint32_t srv_ip; ip4 ip = 0, nm = 0, gw = 0; @@ -145,12 +145,20 @@ int main(int argc, char **argv) tapdev = wolfIP_getdev(s); if (!tapdev) return 1; - inet_aton(LINUX_IP, &linux_ip); - if (tap_init(tapdev, "wtcp0", linux_ip.s_addr) < 0) { + inet_aton(HOST_STACK_IP, &host_stack_ip); + if (tap_init(tapdev, "wtcp0", host_stack_ip.s_addr) < 0) { perror("tap init"); return 2; } - system("tcpdump -i wtcp0 -w test.pcap &"); + { +#if !defined(__FreeBSD__) && !defined(__APPLE__) + char cmd[128]; + snprintf(cmd, sizeof(cmd), "tcpdump -i %s -w test.pcap &", tapdev->ifname); + system(cmd); +#else + (void)tapdev; +#endif + } #ifdef DHCP gettimeofday(&tv, NULL); @@ -167,7 +175,7 @@ int main(int argc, char **argv) srv_ip = htonl(ip); #else wolfIP_ipconfig_set(s, atoip4(WOLFIP_IP), atoip4("255.255.255.0"), - atoip4(LINUX_IP)); + atoip4(HOST_STACK_IP)); printf("IP: manually configured\n"); inet_pton(AF_INET, WOLFIP_IP, &srv_ip); #endif @@ -177,7 +185,8 @@ int main(int argc, char **argv) test_httpd(s); sleep(2); sync(); +#if !defined(__FreeBSD__) && !defined(__APPLE__) system("killall tcpdump"); +#endif return 0; } - diff --git a/src/test/test_native_wolfssl.c b/src/test/test_native_wolfssl.c index 03bc164..7c5e993 100644 --- a/src/test/test_native_wolfssl.c +++ b/src/test/test_native_wolfssl.c @@ -255,7 +255,7 @@ void *pt_echoclient(void *arg) /* Catch-all function to initialize a new tap device as the network interface. - * This is defined in port/linux.c + * This is defined in port/posix/bsd_socket.c * */ extern int tap_init(struct wolfIP_ll_dev *dev, const char *name, uint32_t host_ip); @@ -315,7 +315,7 @@ void test_wolfip_echoserver(struct wolfIP *s, uint32_t srv_ip) ret = test_loop(s, 0); pthread_join(pt, (void **)&test_ret); printf("Test echo server close-wait: %d\n", ret); - printf("Test linux client: %d\n", test_ret); + printf("Test host client: %d\n", test_ret); sleep(1); pthread_create(&pt, NULL, pt_echoclient, &srv_ip); @@ -323,7 +323,7 @@ void test_wolfip_echoserver(struct wolfIP *s, uint32_t srv_ip) ret = test_loop(s, 1); printf("Test echo server close-wait: %d\n", ret); pthread_join(pt, (void **)&test_ret); - printf("Test linux client: %d\n", test_ret); + printf("Test host client: %d\n", test_ret); sleep(1); wolfIP_sock_close(s, listen_fd); @@ -335,7 +335,7 @@ int main(int argc, char **argv) struct wolfIP *s; struct wolfIP_ll_dev *tapdev; struct timeval tv = {0, 0}; - struct in_addr linux_ip; + struct in_addr host_stack_ip; uint32_t srv_ip; ip4 ip = 0, nm = 0, gw = 0; @@ -352,12 +352,20 @@ int main(int argc, char **argv) tapdev = wolfIP_getdev(s); if (!tapdev) return 1; - inet_aton(LINUX_IP, &linux_ip); - if (tap_init(tapdev, "wtcp0", linux_ip.s_addr) < 0) { + inet_aton(HOST_STACK_IP, &host_stack_ip); + if (tap_init(tapdev, "wtcp0", host_stack_ip.s_addr) < 0) { perror("tap init"); return 2; } - system("tcpdump -i wtcp0 -w test.pcap &"); + { +#if !defined(__FreeBSD__) && !defined(__APPLE__) + char cmd[128]; + snprintf(cmd, sizeof(cmd), "tcpdump -i %s -w test.pcap &", tapdev->ifname); + system(cmd); +#else + (void)tapdev; +#endif + } #ifdef DHCP gettimeofday(&tv, NULL); @@ -374,7 +382,7 @@ int main(int argc, char **argv) srv_ip = htonl(ip); #else wolfIP_ipconfig_set(s, atoip4(WOLFIP_IP), atoip4("255.255.255.0"), - atoip4(LINUX_IP)); + atoip4(HOST_STACK_IP)); printf("IP: manually configured\n"); inet_pton(AF_INET, WOLFIP_IP, &srv_ip); #endif @@ -383,7 +391,8 @@ int main(int argc, char **argv) test_wolfip_echoserver(s, srv_ip); sleep(2); sync(); +#if !defined(__FreeBSD__) && !defined(__APPLE__) system("killall tcpdump"); +#endif return 0; } - diff --git a/src/test/test_ttl_expired.c b/src/test/test_ttl_expired.c index a29ce07..a10c4bc 100644 --- a/src/test/test_ttl_expired.c +++ b/src/test/test_ttl_expired.c @@ -24,6 +24,9 @@ #include #include #include +#ifndef ETH_P_IP +#define ETH_P_IP ETHERTYPE_IP +#endif #include #include #include diff --git a/src/test/test_wolfssl_forwarding.c b/src/test/test_wolfssl_forwarding.c index e1ef5fe..0d97bc1 100644 --- a/src/test/test_wolfssl_forwarding.c +++ b/src/test/test_wolfssl_forwarding.c @@ -341,10 +341,10 @@ static void *poll_thread(void *arg) } /* ------------------------------------------------------------------------- */ -/* Linux TLS client */ +/* Host TLS client */ /* ------------------------------------------------------------------------- */ -static int run_linux_tls_client(ip4 server_ip) +static int run_host_tls_client(ip4 server_ip) { struct sockaddr_in remote = { .sin_family = AF_INET, @@ -369,14 +369,14 @@ static int run_linux_tls_client(ip4 server_ip) ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()); if (!ctx) { - fprintf(stderr, "linux client: failed to init context\n"); + fprintf(stderr, "host client: failed to init context\n"); goto out; } wolfSSL_CTX_load_verify_buffer(ctx, ca_der, ca_der_len, SSL_FILETYPE_ASN1); ssl = wolfSSL_new(ctx); if (!ssl) { - fprintf(stderr, "linux client: failed to allocate ssl object\n"); + fprintf(stderr, "host client: failed to allocate ssl object\n"); goto out; } @@ -417,7 +417,7 @@ static int run_linux_tls_client(ip4 server_ip) } if (!connected) { - fprintf(stderr, "linux client: unable to connect after retries\n"); + fprintf(stderr, "host client: unable to connect after retries\n"); goto out; } @@ -432,7 +432,7 @@ static int run_linux_tls_client(ip4 server_ip) usleep(1000); continue; } - fprintf(stderr, "linux client: handshake failed (%d)\n", err); + fprintf(stderr, "host client: handshake failed (%d)\n", err); goto out; } @@ -450,7 +450,7 @@ static int run_linux_tls_client(ip4 server_ip) usleep(1000); continue; } - fprintf(stderr, "linux client: write failed (%d)\n", err); + fprintf(stderr, "host client: write failed (%d)\n", err); goto out; } printf("TLS client: wrote %d bytes\n", TEST_PAYLOAD); @@ -462,7 +462,7 @@ static int run_linux_tls_client(ip4 server_ip) continue; } if (got == 0) { - fprintf(stderr, "linux client: unexpected eof\n"); + fprintf(stderr, "host client: unexpected eof\n"); goto out; } err = wolfSSL_get_error(ssl, got); @@ -470,13 +470,13 @@ static int run_linux_tls_client(ip4 server_ip) usleep(1000); continue; } - fprintf(stderr, "linux client: read failed (%d)\n", err); + fprintf(stderr, "host client: read failed (%d)\n", err); goto out; } printf("TLS client: read %d bytes\n", TEST_PAYLOAD); if (memcmp(tx, rx, sizeof(tx)) != 0) { - fprintf(stderr, "linux client: payload mismatch\n"); + fprintf(stderr, "host client: payload mismatch\n"); goto out; } @@ -625,8 +625,8 @@ int main(void) if (route_cmd[0]) system(route_cmd); - if (run_linux_tls_client(server_ip4) < 0) { - fprintf(stderr, "linux client: test failed\n"); + if (run_host_tls_client(server_ip4) < 0) { + fprintf(stderr, "host client: test failed\n"); ret = 1; } diff --git a/src/wolfip.c b/src/wolfip.c index 3a1277c..f93046b 100644 --- a/src/wolfip.c +++ b/src/wolfip.c @@ -2507,9 +2507,9 @@ static void arp_recv(struct wolfIP *s, unsigned int if_idx, void *buf, int len) arp->sip = ee32(conf->ip); arp_store_neighbor(s, if_idx, ee32(arp->sip), arp->sma); eth_output_add_header(s, if_idx, arp->tma, &arp->eth, ETH_TYPE_ARP); - if (ll->send) - ll->send(ll, buf, len); - } + if (ll->send) + ll->send(ll, buf, len); +} if (arp->opcode == ee16(ARP_REPLY)) { arp_store_neighbor(s, if_idx, ee32(arp->sip), arp->sma); } diff --git a/tools/certs/mkcerts.sh b/tools/certs/mkcerts.sh index 5c78fd0..be57804 100755 --- a/tools/certs/mkcerts.sh +++ b/tools/certs/mkcerts.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/sh # OUT_DIR=build/certs @@ -58,4 +58,3 @@ openssl x509 -in "$OUT_DIR/server.crt" -outform DER -out "$OUT_DIR/server.der" xxd -i "$OUT_DIR/server.der" |sed -e "s/unsigned/const unsigned/g" | sed -e "s/build_certs_//g" > "$OUT_DIR/server_cert.c" echo "==== Done ====" - From 80725f3e93f484316f6ca3747a474bb40055c14e Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Tue, 11 Nov 2025 16:47:05 +0100 Subject: [PATCH 2/2] Fixed indentation (reviewer's comments) --- Makefile | 113 ++++++++++++++++++++------------------- src/test/test_dhcp_dns.c | 2 +- src/wolfip.c | 6 +-- 3 files changed, 61 insertions(+), 60 deletions(-) diff --git a/Makefile b/Makefile index d563c1f..c2fd74e 100644 --- a/Makefile +++ b/Makefile @@ -7,73 +7,74 @@ UNAME_S:=$(shell uname -s) UNAME_M:=$(shell uname -m) UNAME_LC:=$(shell echo $(UNAME_S) | tr 'A-Z' 'a-z') ifeq ($(UNAME_S),FreeBSD) -CFLAGS+=-I/usr/local/include -LDFLAGS+=-L/usr/local/lib + CFLAGS+=-I/usr/local/include + LDFLAGS+=-L/usr/local/lib endif ifeq ($(UNAME_S),Darwin) -BREW_PREFIX?=$(shell brew --prefix 2>/dev/null) -ifeq ($(filter command\ line environment,$(origin BREW_PREFIX)),) -ifeq ($(UNAME_M),arm64) -ARM_BREW_PREFIX:=$(shell /opt/homebrew/bin/brew --prefix 2>/dev/null) -ifneq ($(ARM_BREW_PREFIX),) -BREW_PREFIX:=$(ARM_BREW_PREFIX) -endif -endif -endif -ifeq ($(BREW_PREFIX),) -BREW_PREFIX:=/opt/homebrew + BREW_PREFIX?=$(shell brew --prefix 2>/dev/null) + ifeq ($(filter command\ line environment,$(origin BREW_PREFIX)),) + ifeq ($(UNAME_M),arm64) + ARM_BREW_PREFIX:=$(shell /opt/homebrew/bin/brew --prefix 2>/dev/null) + ifneq ($(ARM_BREW_PREFIX),) + BREW_PREFIX:=$(ARM_BREW_PREFIX) + endif + endif + endif + ifeq ($(BREW_PREFIX),) + BREW_PREFIX:=/opt/homebrew + endif + WOLFSSL_PREFIX?=$(shell brew --prefix wolfssl 2>/dev/null) + ifeq ($(filter command\ line environment,$(origin WOLFSSL_PREFIX)),) + ifeq ($(UNAME_M),arm64) + ARM_WOLFSSL_PREFIX:=$(shell /opt/homebrew/bin/brew --prefix wolfssl 2>/dev/null) + ifneq ($(ARM_WOLFSSL_PREFIX),) + WOLFSSL_PREFIX:=$(ARM_WOLFSSL_PREFIX) + endif + endif + endif + ifneq ($(WOLFSSL_PREFIX),) + CFLAGS+=-I$(WOLFSSL_PREFIX)/include + LDFLAGS+=-L$(WOLFSSL_PREFIX)/lib + endif + CHECK_PREFIX?=$(shell brew --prefix check 2>/dev/null) + ifeq ($(filter command\ line environment,$(origin CHECK_PREFIX)),) + ifeq ($(UNAME_M),arm64) + ARM_CHECK_PREFIX:=$(shell /opt/homebrew/bin/brew --prefix check 2>/dev/null) + ifneq ($(ARM_CHECK_PREFIX),) + CHECK_PREFIX:=$(ARM_CHECK_PREFIX) + endif + endif + endif + ifeq ($(CHECK_PREFIX),) + CHECK_PREFIX:=$(BREW_PREFIX) + endif + ifneq ($(CHECK_PREFIX),) + UNIT_CFLAGS+=-I$(CHECK_PREFIX)/include + UNIT_LDFLAGS+=-L$(CHECK_PREFIX)/lib + endif endif -WOLFSSL_PREFIX?=$(shell brew --prefix wolfssl 2>/dev/null) -ifeq ($(filter command\ line environment,$(origin WOLFSSL_PREFIX)),) -ifeq ($(UNAME_M),arm64) -ARM_WOLFSSL_PREFIX:=$(shell /opt/homebrew/bin/brew --prefix wolfssl 2>/dev/null) -ifneq ($(ARM_WOLFSSL_PREFIX),) -WOLFSSL_PREFIX:=$(ARM_WOLFSSL_PREFIX) -endif -endif -endif -ifneq ($(WOLFSSL_PREFIX),) -CFLAGS+=-I$(WOLFSSL_PREFIX)/include -LDFLAGS+=-L$(WOLFSSL_PREFIX)/lib -endif -CHECK_PREFIX?=$(shell brew --prefix check 2>/dev/null) -ifeq ($(filter command\ line environment,$(origin CHECK_PREFIX)),) -ifeq ($(UNAME_M),arm64) -ARM_CHECK_PREFIX:=$(shell /opt/homebrew/bin/brew --prefix check 2>/dev/null) -ifneq ($(ARM_CHECK_PREFIX),) -CHECK_PREFIX:=$(ARM_CHECK_PREFIX) -endif -endif -endif -ifeq ($(CHECK_PREFIX),) -CHECK_PREFIX:=$(BREW_PREFIX) -endif -ifneq ($(CHECK_PREFIX),) -UNIT_CFLAGS+=-I$(CHECK_PREFIX)/include -UNIT_LDFLAGS+=-L$(CHECK_PREFIX)/lib -endif -endif + TAP_SRC:=src/port/posix/tap_$(UNAME_LC).c ifeq ($(wildcard $(TAP_SRC)),) -TAP_SRC:=src/port/posix/tap_linux.c + TAP_SRC:=src/port/posix/tap_linux.c endif TAP_OBJ:=$(patsubst src/%.c,build/%.o,$(TAP_SRC)) TAP_PIE_OBJ:=$(patsubst src/%.c,build/pie/%.o,$(TAP_SRC)) ifeq ($(UNAME_S),Darwin) -BEGIN_GROUP:= -END_GROUP:= + BEGIN_GROUP:= + END_GROUP:= else -BEGIN_GROUP:=-Wl,--start-group -END_GROUP:=-Wl,--end-group + BEGIN_GROUP:=-Wl,--start-group + END_GROUP:=-Wl,--end-group endif CHECK_PKG_CFLAGS:=$(shell pkg-config --cflags check 2>/dev/null) CHECK_PKG_LIBS:=$(shell pkg-config --libs check 2>/dev/null) ifneq ($(CHECK_PKG_CFLAGS),) -UNIT_CFLAGS+=$(CHECK_PKG_CFLAGS) + UNIT_CFLAGS+=$(CHECK_PKG_CFLAGS) endif CPPCHECK=cppcheck @@ -151,14 +152,14 @@ asan:LDFLAGS+=-static-libasan # Test ifeq ($(CHECK_PKG_LIBS),) -UNIT_LIBS=-lcheck -lm -lpthread -lrt -ldl -lsubunit -ifeq ($(UNAME_S),Darwin) -UNIT_LIBS=-lcheck -lm -lpthread -else ifeq ($(UNAME_S),FreeBSD) -UNIT_LIBS=-lcheck -lm -lpthread -endif + UNIT_LIBS=-lcheck -lm -lpthread -lrt -ldl -lsubunit + ifeq ($(UNAME_S),Darwin) + UNIT_LIBS=-lcheck -lm -lpthread + else ifeq ($(UNAME_S),FreeBSD) + UNIT_LIBS=-lcheck -lm -lpthread + endif else -UNIT_LIBS=$(CHECK_PKG_LIBS) + UNIT_LIBS=$(CHECK_PKG_LIBS) endif unit:LDFLAGS+=$(UNIT_LIBS) diff --git a/src/test/test_dhcp_dns.c b/src/test/test_dhcp_dns.c index 6ed75bc..bacacd8 100644 --- a/src/test/test_dhcp_dns.c +++ b/src/test/test_dhcp_dns.c @@ -216,7 +216,7 @@ void test_wolfip_echoclient(struct wolfIP *s) ret = test_loop(s, 1); printf("Test echo client active close: %d\n", ret); pthread_join(pt, (void **)&test_ret); - printf("Test host server: %d\n", test_ret); + printf("Test host server: %d\n", test_ret); if (conn_fd >= 0) { wolfIP_sock_close(s, conn_fd); diff --git a/src/wolfip.c b/src/wolfip.c index f93046b..3a1277c 100644 --- a/src/wolfip.c +++ b/src/wolfip.c @@ -2507,9 +2507,9 @@ static void arp_recv(struct wolfIP *s, unsigned int if_idx, void *buf, int len) arp->sip = ee32(conf->ip); arp_store_neighbor(s, if_idx, ee32(arp->sip), arp->sma); eth_output_add_header(s, if_idx, arp->tma, &arp->eth, ETH_TYPE_ARP); - if (ll->send) - ll->send(ll, buf, len); -} + if (ll->send) + ll->send(ll, buf, len); + } if (arp->opcode == ee16(ARP_REPLY)) { arp_store_neighbor(s, if_idx, ee32(arp->sip), arp->sma); }