Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dhcp: add support for MUD options (RFC 8520) #20

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
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
2 changes: 2 additions & 0 deletions .github/workflows/ci-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ name: CI
on:
push:
branches: [master]
pull_request:
branches: [master]

jobs:
build:
Expand Down
33 changes: 33 additions & 0 deletions src/core/ipv4/dhcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,9 @@ static u16_t dhcp_option_long(u16_t options_out_len, u8_t *options, u32_t value)
#if LWIP_NETIF_HOSTNAME
static u16_t dhcp_option_hostname(u16_t options_out_len, u8_t *options, struct netif *netif);
#endif /* LWIP_NETIF_HOSTNAME */
#if LWIP_DHCP_MUD_URL
static u16_t dhcp_option_mud_url(u16_t options_out_len, u8_t *options, char *mud_url);
#endif /* LWIP_DHCP_MUD_URL */
/* always add the DHCP options trailer to end and pad */
static void dhcp_option_trailer(u16_t options_out_len, u8_t *options, struct pbuf *p_out);

Expand Down Expand Up @@ -482,6 +485,11 @@ dhcp_select(struct netif *netif)
options_out_len = dhcp_option_hostname(options_out_len, msg_out->options, netif);
#endif /* LWIP_NETIF_HOSTNAME */


#if LWIP_DHCP_MUD_URL
options_out_len = dhcp_option_mud_url(options_out_len, msg_out->options, LWIP_MUD_URL_STRING);
#endif /* LWIP_DHCP_MUD_URL */

LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_REQUESTING, msg_out, DHCP_REQUEST, &options_out_len);
dhcp_option_trailer(options_out_len, msg_out->options, p_out);

Expand Down Expand Up @@ -1499,6 +1507,31 @@ dhcp_option_hostname(u16_t options_out_len, u8_t *options, struct netif *netif)
}
#endif /* LWIP_NETIF_HOSTNAME */

#if LWIP_DHCP_MUD_URL
static u16_t
dhcp_option_mud_url(u16_t options_out_len, u8_t *options, char *mud_url)
{
size_t mud_url_len = strlen(mud_url);
LWIP_ASSERT("DHCP: MUD URLs must start with https://",
strncmp(mud_url, "https://", 8) == 0);

size_t option_header_len = sizeof(u8_t) * 2;
size_t len;
const char *p = mud_url;
size_t available = DHCP_OPTIONS_LEN - options_out_len - option_header_len;
LWIP_ASSERT("DHCP: MUD URL is too long!", mud_url_len <= available);
len = LWIP_MIN(mud_url_len, available);
LWIP_ASSERT("DHCP: MUD URL is too long!", len < 0xFF - option_header_len);
options_out_len = dhcp_option(options_out_len, options, DHCP_OPTION_MUD_URL_V4, (u8_t)len);

while (len--) {
options_out_len = dhcp_option_byte(options_out_len, options, *p++);
}

return options_out_len;
}
#endif /* LWIP_DHCP_MUD_URL */

/**
* Extract the DHCP message and the DHCP options.
*
Expand Down
44 changes: 44 additions & 0 deletions src/core/ipv6/dhcp6.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ static u8_t dhcp6_pcb_refcount;
/* receive, unfold, parse and free incoming messages */
static void dhcp6_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port);

#if LWIP_DHCP6_MUD_URL
static u16_t dhcp6_option_mud_url(u16_t options_out_len, u8_t *options, char *mud_url, u16_t max_len);
#endif /* LWIP_DHCP6_MUD_URL */


/** Ensure DHCP PCB is allocated and bound */
static err_t
dhcp6_inc_pcb_refcount(void)
Expand Down Expand Up @@ -411,6 +416,13 @@ dhcp6_create_msg(struct netif *netif, struct dhcp6 *dhcp6, u8_t message_type,
return p_out;
}

static u16_t
dhcp6_option_byte(u16_t options_out_len, u8_t *options, u16_t value)
{
options[options_out_len++] = value;
return options_out_len;
}

static u16_t
dhcp6_option_short(u16_t options_out_len, u8_t *options, u16_t value)
{
Expand Down Expand Up @@ -438,6 +450,33 @@ dhcp6_option_optionrequest(u16_t options_out_len, u8_t *options, const u16_t *re
return ret;
}

#if LWIP_DHCP6_MUD_URL
static u16_t
dhcp6_option_mud_url(u16_t options_out_len, u8_t *options, char *mud_url, u16_t max_len)
{
size_t i;
u16_t ret;
size_t option_header_len = sizeof(u16_t) * 2;
size_t mud_url_len = strlen(mud_url);
const char *p = mud_url;

LWIP_ASSERT("dhcp6_option_mud_url: options_out_len + sizeof(struct dhcp6_msg) + mud_url_len <= max_len",
sizeof(struct dhcp6_msg) + options_out_len + option_header_len + mud_url_len <= max_len);
LWIP_ASSERT("DHCP: MUD URLs must start with https://",
strncmp(mud_url, "https://", 8) == 0);
LWIP_UNUSED_ARG(max_len);

ret = dhcp6_option_short(options_out_len, options, DHCP6_OPTION_MUD_URL_V6);
ret = dhcp6_option_short(ret, options, mud_url_len);

while (mud_url_len--) {
ret = dhcp6_option_byte(ret, options, *p++);
}

return ret;
}
#endif /* LWIP_DHCP6_MUD_URL */

/* All options are added, shrink the pbuf to the required size */
static void
dhcp6_msg_finalize(u16_t options_out_len, struct pbuf *p_out)
Expand Down Expand Up @@ -475,6 +514,11 @@ dhcp6_information_request(struct netif *netif, struct dhcp6 *dhcp6)

options_out_len = dhcp6_option_optionrequest(options_out_len, options, requested_options,
LWIP_ARRAYSIZE(requested_options), p_out->len);

#if LWIP_DHCP6_MUD_URL
options_out_len = dhcp6_option_mud_url(options_out_len, options, LWIP_MUD_URL_STRING, p_out->len);
#endif /* LWIP_DHCP6_MUD_URL */

LWIP_HOOK_DHCP6_APPEND_OPTIONS(netif, dhcp6, DHCP6_STATE_REQUESTING_CONFIG, msg_out,
DHCP6_INFOREQUEST, options_out_len, p_out->len);
dhcp6_msg_finalize(options_out_len, p_out);
Expand Down
27 changes: 27 additions & 0 deletions src/include/lwip/opt.h
Original file line number Diff line number Diff line change
Expand Up @@ -976,6 +976,26 @@
#if !defined LWIP_DHCP_DISCOVER_ADD_HOSTNAME || defined __DOXYGEN__
#define LWIP_DHCP_DISCOVER_ADD_HOSTNAME 0
#endif /* LWIP_DHCP_DISCOVER_ADD_HOSTNAME */

/**
* LWIP_DHCP_MUD_URL == 1: Emit Manufacturer Usage Description (MUD) URL (RFC 8520) via DHCP.
*/
#if !defined LWIP_DHCP_MUD_URL || defined __DOXYGEN__
#define LWIP_DHCP_MUD_URL 0
#endif

/**
* LWIP_MUD_URL_STRING: Specifies a URL that points to a Manufacturer Usage Description (MUD)
* file describing this device.
* This URL will only be emitted via DHCP or DHCPv6 if LWIP_DHCP_MUD_URL or LWIP_DHCP6_MUD_URL are set
* to 1, respectively.
* The URL MUST start with https://.
*
* See RFC 8520 for more information.
*/
#ifdef __DOXYGEN__
#define LWIP_MUD_URL_STRING "https://example.org/mud-file"
#endif
/**
* @}
*/
Expand Down Expand Up @@ -2784,6 +2804,13 @@
#if !defined LWIP_DHCP6_MAX_DNS_SERVERS || defined __DOXYGEN__
#define LWIP_DHCP6_MAX_DNS_SERVERS DNS_MAX_SERVERS
#endif

/**
* LWIP_DHCP6_MUD_URL == 1: Emit Manufacturer Usage Description (MUD) URL (RFC 8520) via DHCPv6.
*/
#if !defined LWIP_DHCP6_MUD_URL || defined __DOXYGEN__
#define LWIP_DHCP6_MUD_URL 0
#endif
/**
* @}
*/
Expand Down
2 changes: 2 additions & 0 deletions src/include/lwip/prot/dhcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ typedef enum {
#define DHCP_OPTION_TFTP_SERVERNAME 66
#define DHCP_OPTION_BOOTFILE 67

#define DHCP_OPTION_MUD_URL_V4 116 /* RFC 8520 10., MUD URL Option */

/* possible combinations of overloading the file and sname fields with options */
#define DHCP_OVERLOAD_NONE 0
#define DHCP_OVERLOAD_FILE 1
Expand Down
1 change: 1 addition & 0 deletions src/include/lwip/prot/dhcp6.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ typedef enum {
#define DHCP6_OPTION_DNS_SERVERS 23 /* RFC 3646 */
#define DHCP6_OPTION_DOMAIN_LIST 24 /* RFC 3646 */
#define DHCP6_OPTION_SNTP_SERVERS 31 /* RFC 4075 */
#define DHCP6_OPTION_MUD_URL_V6 112 /* RFC 8520 */


#ifdef __cplusplus
Expand Down