Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
b8b1e10
Improve error handling
danielinux Oct 29, 2025
6183710
Renamed constants and interfaces
danielinux Oct 29, 2025
4173749
Added multiple interfaces
danielinux Oct 29, 2025
eb29076
Added simple packet forwarding between interfaces
danielinux Oct 29, 2025
403f130
Added loopback interface
danielinux Oct 29, 2025
81ca520
Discard routed traffic with destination 127.x.x.x
danielinux Oct 29, 2025
20d9501
Fixed github actions
danielinux Oct 29, 2025
4d083e4
Renamed 'struct ll' into 'struct wolfIP_ll_dev'
danielinux Nov 3, 2025
077eed3
Rewritten error handling according to review
danielinux Nov 3, 2025
3f1cec6
Addressed review comments
danielinux Nov 3, 2025
ef81ba1
Addressed more reviewers comments
danielinux Nov 5, 2025
b68b0fd
Refactored forwarding test.
danielinux Nov 5, 2025
f5f325a
Fixed unit test
danielinux Nov 5, 2025
fe0c281
Add delay in forwarding test client connect
danielinux Nov 5, 2025
75e457e
Try expanding arp queue for forwarding
danielinux Nov 5, 2025
f82f0b0
Forward test: removed artificial arp injections
danielinux Nov 5, 2025
5d71f94
Mapped error numbers to defines
danielinux Nov 5, 2025
84ac043
more stray "-11" instead of EINVAL
danielinux Nov 5, 2025
67b8c3b
Reviewer's comment: Check fd boundary in connect/sendto
danielinux Nov 5, 2025
b0287f3
More boundary checks
danielinux Nov 5, 2025
daeb5c1
Added compile time sanity check on limits
danielinux Nov 5, 2025
729abe8
Fixed TTL expired. Traceroute now works
danielinux Nov 5, 2025
ae32104
Improved/fixed test for TTL exceeded
danielinux Nov 5, 2025
9a884e6
Update/fix expected fields in unit test
danielinux Nov 5, 2025
bdb734b
Cleanup dead code
danielinux Nov 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/cppcheck.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
Name: CppCheck code linter

name: CppCheck code linter

on:
push:
Expand All @@ -9,16 +8,17 @@ on:

jobs:
linter:
runs-on: ubuntu-22.04
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
submodules: true

- name: Update repo
run: |
sudo apt-get update
sudo apt install -y cppcheck

- name: Run cppcheck
run: |
Expand Down
33 changes: 23 additions & 10 deletions .github/workflows/linux.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
Name: Linux interop tests

name: Linux interop tests

on:
push:
Expand All @@ -8,26 +7,40 @@ on:
branches: [ '*' ]

jobs:
unit_test:
runs-on: ubuntu-22.04
linux_test:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
submodules: true

- name: Update repo
run: |
sudo apt-get update
sudo apt-get install -y libwolfssl-dev
sudo modprobe tun

- name: Build linux tests
run: |
mkdir -p build/port
make

# - name: Run interop tests
# run: |
# sudo build/test
#
#
- name: Run standalone "event loop" test
run: |
sudo ./build/test-evloop
sudo killall tcpdump || true

- name: Run standalone wolfssl test
run: |
sudo ./build/test-wolfssl
sudo killall tcpdump || true

- name: Run standalone forwarding test
run: |
sudo ./build/test-wolfssl-forwarding

- name: Run standalone TTL expired test
run: |
./build/test-ttl-expired

7 changes: 3 additions & 4 deletions .github/workflows/units.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
Name: Unit Tests

name: Unit Tests

on:
push:
Expand All @@ -9,10 +8,10 @@ on:

jobs:
unit_test:
runs-on: ubuntu-22.04
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
submodules: true

Expand Down
28 changes: 25 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,26 +1,31 @@
CC?=gcc
CFLAGS:=-Wall -Werror -Wextra -I. -D_GNU_SOURCE
CFLAGS+=-g -ggdb
CFLAGS+=-g -ggdb -Wdeclaration-after-statement
LDFLAGS+=-pthread

CPPCHECK=cppcheck
CPPCHECK_FLAGS=--enable=all --suppress=missingIncludeSystem \
CPPCHECK_FLAGS=--enable=warning,performance,portability,missingInclude \
--suppress=missingIncludeSystem \
-i src/test \
--suppress=unusedFunction --suppress=unusedVariable \
--suppress=missingInclude --suppress=variableScope \
--suppress=constVariable --suppress=constVariablePointer \
--suppress=constParameterPointer \
--suppress=constParameterCallback \
--suppress=toomanyconfigs \
--suppress=unmatchedSuppression --inconclusive \
--disable=style \
--std=c99 --language=c \
--platform=unix64 \
--check-level=exhaustive \
--error-exitcode=1 --xml --xml-version=2

OBJ=build/wolfip.o \
build/port/posix/linux_tap.o

EXE=build/tcpecho build/tcp_netcat_poll build/tcp_netcat_select \
build/test-evloop build/test-dns
build/test-evloop build/test-dns build/test-wolfssl-forwarding \
build/test-ttl-expired build/test-wolfssl
LIB=libwolfip.so

PREFIX=/usr/local
Expand Down Expand Up @@ -80,12 +85,29 @@ build/tcp_netcat_select: $(OBJ) build/port/posix/bsd_socket.o build/test/tcp_net

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

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
@echo "[LD] $@"
@$(CC) $(CFLAGS) $(LDFLAGS) -o $@ -Wl,--start-group $(^) -lwolfssl -Wl,--end-group

build/test/test_wolfssl_forwarding.o: CFLAGS+=-DWOLFIP_MAX_INTERFACES=2 -DWOLFIP_ENABLE_FORWARDING=1

build/test/wolfip_forwarding.o: src/wolfip.c
@mkdir -p `dirname $@` || true
@echo "[CC] $< (forwarding)"
@$(CC) $(CFLAGS) -DWOLFIP_MAX_INTERFACES=2 -DWOLFIP_ENABLE_FORWARDING=1 -c $< -o $@

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

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
Expand Down
20 changes: 18 additions & 2 deletions config.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,27 @@

#define MAX_TCPSOCKETS 4
#define MAX_UDPSOCKETS 2
#define RXBUF_SIZE LINK_MTU * 4
#define TXBUF_SIZE LINK_MTU * 4
#define RXBUF_SIZE LINK_MTU * 16
#define TXBUF_SIZE LINK_MTU * 16

#define MAX_NEIGHBORS 16

#ifndef WOLFIP_MAX_INTERFACES
#define WOLFIP_MAX_INTERFACES 2
#endif

#ifndef WOLFIP_ENABLE_FORWARDING
#define WOLFIP_ENABLE_FORWARDING 0
#endif

#ifndef WOLFIP_ENABLE_LOOPBACK
#define WOLFIP_ENABLE_LOOPBACK 0
#endif

#if WOLFIP_ENABLE_LOOPBACK && WOLFIP_MAX_INTERFACES < 2
#error "WOLFIP_ENABLE_LOOPBACK requires WOLFIP_MAX_INTERFACES > 1"
#endif

/* Linux test configuration */
#define WOLFIP_IP "10.10.10.2"
#define LINUX_IP "10.10.10.1"
Expand Down
40 changes: 36 additions & 4 deletions docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,32 @@ wolfIP is a minimal TCP/IP stack designed for resource-constrained embedded syst

### Device Driver Interface
```c
struct ll {
struct wolfIP_ll_dev {
uint8_t mac[6]; // Device MAC address
char ifname[16]; // Interface name
int (*poll)(struct ll *ll, void *buf, uint32_t len); // Receive function
int (*send)(struct ll *ll, void *buf, uint32_t len); // Transmit function
int (*poll)(struct wolfIP_ll_dev *ll, void *buf, uint32_t len); // Receive function
int (*send)(struct wolfIP_ll_dev *ll, void *buf, uint32_t len); // Transmit function
};
```
wolfIP maintains an array of these descriptors sized by `WOLFIP_MAX_INTERFACES` (default `1`). Call `wolfIP_getdev_ex()` to access a specific slot; the legacy `wolfIP_getdev()` helper targets the first hardware slot (index `0` normally, or `1` when the optional loopback interface is enabled).

### IP Configuration
```c
struct ipconf {
struct ll *ll; // Link layer device
struct wolfIP_ll_dev *ll; // Link layer device
ip4 ip; // IPv4 address
ip4 mask; // Subnet mask
ip4 gw; // Default gateway
};
```
Each `struct wolfIP` instance owns `WOLFIP_MAX_INTERFACES` `ipconf` entries—one per link-layer slot. Use the `_ex` helpers to read or update a specific interface; the legacy accessors operate on the first hardware interface (index `0` unless loopback support is compiled in).

If `WOLFIP_ENABLE_FORWARDING` is set to `1` at compile time, the stack performs simple IPv4 forwarding between interfaces. Packets received on one interface whose destinations match another configured interface are re-sent with the IP TTL decreased by one (or an ICMP TTL-exceeded response if the TTL would drop to zero).

Enabling `WOLFIP_ENABLE_LOOPBACK` (requires `WOLFIP_MAX_INTERFACES > 1`) creates an internal loopback
device at index `0` with the fixed address `127.0.0.1/8`. Traffic sent to that address is reflected back
through the stack so local sockets, pings, and other services behave as they would on a standard
loopback interface; the first hardware interface then shifts to index `1` for legacy helpers.

### Socket Address Structures
```c
Expand Down Expand Up @@ -151,6 +160,11 @@ Initializes a static wolfIP instance.
- Parameters:
- s: Pointer to wolfIP instance pointer

```c
size_t wolfIP_instance_size(void);
```
Returns the size (in bytes) required to store a `struct wolfIP`. Use this when allocating stacks from custom memory managers.

```c
int wolfIP_poll(struct wolfIP *s, uint64_t now);
```
Expand All @@ -160,6 +174,12 @@ Processes pending network events.
- now: Current timestamp
- Returns: Number of events processed

```c
void wolfIP_recv(struct wolfIP *s, void *buf, uint32_t len);
void wolfIP_recv_ex(struct wolfIP *s, unsigned int if_idx, void *buf, uint32_t len);
```
Pass inbound frames to the stack. `_ex` allows the caller to specify which interface slot produced the frame.

```c
void wolfIP_ipconfig_set(struct wolfIP *s, ip4 ip, ip4 mask, ip4 gw);
void wolfIP_ipconfig_get(struct wolfIP *s, ip4 *ip, ip4 *mask, ip4 *gw);
Expand All @@ -171,6 +191,18 @@ Set/get IP configuration.
- mask: Subnet mask
- gw: Default gateway

```c
void wolfIP_ipconfig_set_ex(struct wolfIP *s, unsigned int if_idx, ip4 ip, ip4 mask, ip4 gw);
void wolfIP_ipconfig_get_ex(struct wolfIP *s, unsigned int if_idx, ip4 *ip, ip4 *mask, ip4 *gw);
```
Per-interface versions of the IP configuration helpers. The legacy functions target interface `0`.

```c
struct wolfIP_ll_dev *wolfIP_getdev(struct wolfIP *s);
struct wolfIP_ll_dev *wolfIP_getdev_ex(struct wolfIP *s, unsigned int if_idx);
```
Access the link-layer descriptor(s) that should be wired to hardware drivers. `_ex` returns `NULL` if `if_idx` exceeds `WOLFIP_MAX_INTERFACES`.

## DHCP Client Functions

```c
Expand Down
Loading