Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 12 additions & 0 deletions .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,18 @@ jobs:
set -euo pipefail
timeout --preserve-status 2m sudo ./build/packet_ping wtcp0 10.10.10.1

- name: Build without DHCP and with no UDP sockets
run: |
set -euo pipefail
mkdir -p build/noudp
sed 's/^#define MAX_UDPSOCKETS .*/#define MAX_UDPSOCKETS 0/' config.h > build/noudp/config.h
gcc -Ibuild/noudp -I. -D_GNU_SOURCE -DWOLFIP_ENABLE_DHCP=0 -Wall -Werror -Wextra -c src/wolfip.c -o build/noudp/wolfip.o
nm build/noudp/wolfip.o > build/noudp/syms.txt
if grep -qi dhcp build/noudp/syms.txt; then
echo "DHCP symbols left in a WOLFIP_ENABLE_DHCP=0 build"
exit 1
fi

- name: Install check
run: |
sudo apt-get install -y check
Expand Down
2 changes: 2 additions & 0 deletions docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@ For `non_ethernet` devices this value remains the internal frame budget; the max

## DHCP Client Functions

Compiled unless `WOLFIP_ENABLE_DHCP` is set to 0.

```c
int dhcp_client_init(struct wolfIP *s);
```
Expand Down
4 changes: 4 additions & 0 deletions docs/dhcp_dns_howto.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ retransmit and lease timers never fire.

## 3. The API

The DHCP client is compiled by default. A static-address build can drop it by setting `WOLFIP_ENABLE_DHCP` to 0; the functions below are then still declared, but not defined, so a call fails at link time.

All declarations are in `wolfip.h`:

```c
Expand Down Expand Up @@ -351,6 +353,8 @@ if your application needs UDP sockets of its own. If the pool is exhausted,
`dhcp_client_init()` returns negative and `nslookup()` fails to allocate its
socket.

A target that needs no UDP at all can set `MAX_UDPSOCKETS 0` together with `WOLFIP_ENABLE_DHCP 0`. Every UDP path then finds no socket to use, DNS lookups fail to allocate one, and the per-socket UDP buffers disappear from RAM. Leaving DHCP enabled with no UDP sockets stops the build with an `#error`.

## 10. Troubleshooting

**DHCP never gets bound.** Confirm `now_ms` advances between `wolfIP_poll()`
Expand Down
18 changes: 18 additions & 0 deletions src/wolfip.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@
#define WOLFIP_MAX_ROUTES 16U
#endif

#ifndef WOLFIP_ENABLE_DHCP
#define WOLFIP_ENABLE_DHCP 1
#endif
#if WOLFIP_ENABLE_DHCP && defined(MAX_UDPSOCKETS) && (MAX_UDPSOCKETS < 1)
#error "WOLFIP_ENABLE_DHCP requires MAX_UDPSOCKETS >= 1"
#endif

#define WOLFIP_LOOPBACK_IP 0x7F000001U
#define WOLFIP_LOOPBACK_MASK 0xFF000000U
#if WOLFIP_ENABLE_LOOPBACK
Expand Down Expand Up @@ -1513,6 +1520,7 @@ struct wolfIP {
char dns_ptr_name[256];
struct timers_binheap timers;
struct tsocket tcpsockets[MAX_TCPSOCKETS];
/* Zero-length (GNU extension) when MAX_UDPSOCKETS is 0. */
struct tsocket udpsockets[MAX_UDPSOCKETS];
struct tsocket icmpsockets[MAX_ICMPSOCKETS];
#if WOLFIP_RAWSOCKETS
Expand Down Expand Up @@ -9159,6 +9167,7 @@ static void icmp_input(struct wolfIP *s, unsigned int if_idx, struct wolfIP_ip_p
icmp_try_recv(s, if_idx, icmp, len);
}

#if WOLFIP_ENABLE_DHCP
static int dhcp_send_discover(struct wolfIP *s);
static int dhcp_send_request(struct wolfIP *s);
#ifdef ETHERNET
Expand Down Expand Up @@ -10337,6 +10346,7 @@ static void dhcp_dad_conflict(struct wolfIP *s)
dhcp_schedule_timer_at(s, s->last_tick + DHCP_DECLINE_WAIT_MS);
}
#endif
#endif /* WOLFIP_ENABLE_DHCP */

/* ARP */
#ifdef ETHERNET
Expand Down Expand Up @@ -10585,6 +10595,7 @@ static void arp_request(struct wolfIP *s, unsigned int if_idx, ip4 tip)
* reply is detected in arp_recv (dhcp_dad_conflict). Deliberately bypasses
* the 1 req/s rate limit: DAD is at most 3 probes per acquisition, one
* per second, and must not starve behind ordinary traffic. */
#if WOLFIP_ENABLE_DHCP
static int dhcp_send_dad_probe(struct wolfIP *s)
{
struct arp_packet arp;
Expand Down Expand Up @@ -10613,6 +10624,7 @@ static int dhcp_send_dad_probe(struct wolfIP *s)
return wolfIP_ll_send_frame(s, WOLFIP_PRIMARY_IF_IDX, &arp,
sizeof(struct arp_packet));
}
#endif /* WOLFIP_ENABLE_DHCP */

static void arp_recv(struct wolfIP *s, unsigned int if_idx, void *buf, int len)
{
Expand Down Expand Up @@ -10640,6 +10652,7 @@ static void arp_recv(struct wolfIP *s, unsigned int if_idx, void *buf, int len)
if (arp->sma[0] & 0x01)
return;

#if WOLFIP_ENABLE_DHCP
/* RFC 4331/5227 DAD: on the probing interface, a request from a
* foreign MAC that claims the candidate (sender IP, including a
* gratuitous announcement with sip==tip) or probes for it is a
Expand All @@ -10654,6 +10667,7 @@ static void arp_recv(struct wolfIP *s, unsigned int if_idx, void *buf, int len)
return;
}
}
#endif /* WOLFIP_ENABLE_DHCP */

/* An unconfigured interface (no assigned address) must not answer
* ARP requests: matching tip against a zero conf->ip would let a
Expand Down Expand Up @@ -10690,6 +10704,7 @@ static void arp_recv(struct wolfIP *s, unsigned int if_idx, void *buf, int len)
else if (arp->opcode == ee16(ARP_REPLY)) {
ip4 sip = ee32(arp->sip);
int pending;
#if WOLFIP_ENABLE_DHCP
/* RFC 4331 DAD: a reply on the probing interface claiming the
* candidate is a conflict, unless it is our own MAC (looped probe).
* Bound to the DAD interface + recorded candidate so a reply on
Expand All @@ -10700,6 +10715,7 @@ static void arp_recv(struct wolfIP *s, unsigned int if_idx, void *buf, int len)
dhcp_dad_conflict(s);
return;
}
#endif /* WOLFIP_ENABLE_DHCP */
/* Validate sender IP: reject broadcast, multicast, zero, and
* our own address -- same checks as the ARP request handler. */
if (sip == IPADDR_ANY || sip == conf->ip ||
Expand Down Expand Up @@ -12876,7 +12892,9 @@ int wolfIP_poll(struct wolfIP *s, uint64_t now)

/* Handle timers */
handle_timers(s, now);
#if WOLFIP_ENABLE_DHCP
dhcp_timer_recover(s);
#endif
#ifdef IP_MULTICAST
igmp_timer_recover(s);
#endif
Expand Down
Loading