Wireless Daemon for Linux
 help / color / mirror / Atom feed
From: James Prestwood <prestwoj@gmail.com>
To: iwd@lists.01.org
Subject: [PATCH 12/13] ap: add support for DHCPv4 server
Date: Tue, 20 Oct 2020 11:02:55 -0700	[thread overview]
Message-ID: <20201020180256.1630120-12-prestwoj@gmail.com> (raw)
In-Reply-To: <20201020180256.1630120-1-prestwoj@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 5120 bytes --]

The DHCP server can be enabled by including an [IPv4] group
in the AP provisioning file and including at least a subnet
mask.
---
 src/ap.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++----
 src/ap.h |   8 +++++
 2 files changed, 110 insertions(+), 6 deletions(-)

diff --git a/src/ap.c b/src/ap.c
index 41de69a9..e9f79e5a 100644
--- a/src/ap.c
+++ b/src/ap.c
@@ -76,6 +76,8 @@ struct ap_state {
 	uint16_t last_aid;
 	struct l_queue *sta_states;
 
+	struct l_dhcp_server *server;
+
 	bool started : 1;
 	bool gtk_set : 1;
 };
@@ -120,6 +122,13 @@ void ap_config_free(struct ap_config *config)
 	explicit_bzero(config->psk, sizeof(config->psk));
 	l_free(config->authorized_macs);
 	l_free(config->wsc_name);
+
+	l_free(config->address);
+	l_free(config->gateway);
+	l_free(config->netmask);
+	l_strv_free(config->dns_list);
+	l_strv_free(config->ip_range);
+
 	l_free(config);
 }
 
@@ -198,6 +207,9 @@ static void ap_reset(struct ap_state *ap)
 	l_queue_destroy(ap->wsc_pbc_probes, l_free);
 
 	ap->started = false;
+
+	if (ap->server)
+		l_dhcp_server_stop(ap->server);
 }
 
 static void ap_del_station(struct sta_state *sta, uint16_t reason,
@@ -1906,6 +1918,55 @@ static void ap_deauth_cb(const struct mmpdu_header *hdr, const void *body,
 	ap_sta_free(sta);
 }
 
+static bool ap_start_dhcp(struct ap_state *ap)
+{
+	uint32_t ifindex = netdev_get_ifindex(ap->netdev);
+
+	/*
+	 * [IPv4].Netmask is the only required property since .Address and
+	 * .Gateway may inherit from the interfaces IP that was already set.
+	 * If this is not found we assume DHCP is not being used.
+	 */
+	if (!ap->config->netmask)
+		return true;
+
+	ap->server = l_dhcp_server_new(ifindex);
+	if (!ap->server) {
+		l_error("Failed to create DHCP server on %u", ifindex);
+		return false;
+	}
+
+	/* TODO: set address via rtnl */
+	if (ap->config->address)
+		if (!l_dhcp_server_set_ip_address(ap->server,
+							ap->config->address))
+			return false;
+
+	if (ap->config->gateway)
+		if (!l_dhcp_server_set_gateway(ap->server, ap->config->gateway))
+			return false;
+
+	if (ap->config->dns_list)
+		if (!l_dhcp_server_set_dns(ap->server, ap->config->dns_list))
+			return false;
+
+	if (ap->config->lease_time)
+		if (!l_dhcp_server_set_lease_time(ap->server,
+						ap->config->lease_time))
+			return false;
+
+	if (ap->config->ip_range)
+		if (!l_dhcp_server_set_ip_range(ap->server,
+						ap->config->ip_range[0],
+						ap->config->ip_range[1]))
+			return false;
+
+	if (!l_dhcp_server_set_netmask(ap->server, ap->config->netmask))
+		return false;
+
+	return l_dhcp_server_start(ap->server);
+}
+
 static void ap_start_cb(struct l_genl_msg *msg, void *user_data)
 {
 	struct ap_state *ap = user_data;
@@ -1915,16 +1976,24 @@ static void ap_start_cb(struct l_genl_msg *msg, void *user_data)
 	if (l_genl_msg_get_error(msg) < 0) {
 		l_error("START_AP failed: %i", l_genl_msg_get_error(msg));
 
-		ap->ops->handle_event(AP_EVENT_START_FAILED, NULL,
-					ap->user_data);
-		ap_reset(ap);
-		l_genl_family_free(ap->nl80211);
-		l_free(ap);
-		return;
+		goto failed;
+	}
+
+	if (!ap_start_dhcp(ap)) {
+		l_error("DHCP server failed to start");
+		goto failed;
 	}
 
 	ap->started = true;
 	ap->ops->handle_event(AP_EVENT_STARTED, NULL, ap->user_data);
+
+	return;
+
+failed:
+	ap->ops->handle_event(AP_EVENT_START_FAILED, NULL, ap->user_data);
+	ap_reset(ap);
+	l_genl_family_free(ap->nl80211);
+	l_free(ap);
 }
 
 static struct l_genl_msg *ap_build_cmd_start_ap(struct ap_state *ap)
@@ -2563,6 +2632,33 @@ static struct ap_config *ap_config_from_settings(struct l_settings *settings,
 		l_free(passphrase);
 	}
 
+	if (!l_settings_has_group(settings, "IPv4"))
+		goto done;
+
+	config->address = l_settings_get_string(settings, "IPv4", "Address");
+	config->gateway = l_settings_get_string(settings, "IPv4", "Gateway");
+	config->netmask = l_settings_get_string(settings, "IPv4", "Netmask");
+	config->dns_list = l_settings_get_string_list(settings, "IPv4",
+							"DNSList", ',');
+	config->ip_range = l_settings_get_string_list(settings, "IPv4",
+							"IPRange", ',');
+
+	if (!l_settings_get_uint(settings, "IPv4", "LeaseTime",
+					&config->lease_time))
+		config->lease_time = 0;
+
+
+	if (!config->netmask) {
+		l_error("[IPv4].Netmask is a required value for DHCP");
+		goto failed;
+	}
+
+	if (config->ip_range && l_strv_length(config->ip_range) != 2) {
+		l_error("IP range must be 2 values");
+		goto failed;
+	}
+
+
 done:
 	l_info("Loaded AP configuration %s", config->ssid);
 	return config;
diff --git a/src/ap.h b/src/ap.h
index 90497008..277a5a2f 100644
--- a/src/ap.h
+++ b/src/ap.h
@@ -63,6 +63,14 @@ struct ap_config {
 	unsigned int authorized_macs_num;
 	char *wsc_name;
 	struct wsc_primary_device_type wsc_primary_device_type;
+
+	char *address;
+	char *gateway;
+	char *netmask;
+	char **dns_list;
+	char **ip_range;
+	uint32_t lease_time;
+
 	bool no_cck_rates : 1;
 	bool no_free : 1;
 };
-- 
2.26.2

  parent reply	other threads:[~2020-10-20 18:02 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-20 18:02 [PATCH 01/13] auto-t: no hostapd instance graceful failure James Prestwood
2020-10-20 18:02 ` [PATCH 02/13] auto-t: add copy_to_ap utility James Prestwood
2020-10-20 18:02 ` [PATCH 03/13] auto-t: simplify copy_to_hotspot James Prestwood
2020-10-20 18:02 ` [PATCH 04/13] storage: allow NULL type on storage_network_ssid_from_path James Prestwood
2020-10-20 18:30   ` Denis Kenzior
2020-10-20 18:02 ` [PATCH 05/13] storage: add storage_get_ap_path James Prestwood
2020-10-20 18:02 ` [PATCH 06/13] ap: refactor AP to use provisioning files James Prestwood
2020-10-20 18:02 ` [PATCH 07/13] doc: update AP docs with new Start() arguments James Prestwood
2020-10-20 18:02 ` [PATCH 08/13] ap: remove 'psk' from Start() James Prestwood
2020-10-20 20:19   ` Andrew Zaborowski
2020-10-20 20:27     ` James Prestwood
2020-10-20 18:02 ` [PATCH 09/13] auto-t: update start_ap() to remove psk argument James Prestwood
2020-10-20 18:02 ` [PATCH 10/13] auto-t: update AP tests with provisioning files James Prestwood
2020-10-20 18:02 ` [PATCH 11/13] build: add ELL dhcp-util.c to build James Prestwood
2020-10-20 18:02 ` James Prestwood [this message]
2020-10-20 18:28   ` [PATCH 12/13] ap: add support for DHCPv4 server Denis Kenzior
2020-10-20 18:41     ` James Prestwood
2020-10-20 18:51       ` Denis Kenzior
2020-10-20 20:48         ` Andrew Zaborowski
2020-10-20 21:03           ` Denis Kenzior
2020-10-20 21:41             ` Andrew Zaborowski
2020-10-20 18:02 ` [PATCH 13/13] auto-t: add AP test with DHCP server James Prestwood
2020-10-20 18:32 ` [PATCH 01/13] auto-t: no hostapd instance graceful failure Denis Kenzior

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201020180256.1630120-12-prestwoj@gmail.com \
    --to=prestwoj@gmail.com \
    --cc=iwd@lists.01.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox