aboutsummaryrefslogtreecommitdiff
path: root/lib/dhcp/dhcp.h
diff options
context:
space:
mode:
authorJohannes Stoelp <johannes.stoelp@gmail.com>2022-01-14 23:51:05 +0100
committerJohannes Stoelp <johannes.stoelp@gmail.com>2022-01-14 23:51:05 +0100
commitf9928a1a08c57fe853888119a996c3acc98ee09d (patch)
treec9770b76ffcc281da141f3aa2c595600372c0fca /lib/dhcp/dhcp.h
downloadpio-nodemcuv2-dhcp-server-f9928a1a08c57fe853888119a996c3acc98ee09d.tar.gz
pio-nodemcuv2-dhcp-server-f9928a1a08c57fe853888119a996c3acc98ee09d.zip
Initial version of nodemcuv2 dhcp serverHEADmain
Able to offer IP address + DNS/Gateway ... Worked with devices at my hand.
Diffstat (limited to 'lib/dhcp/dhcp.h')
-rw-r--r--lib/dhcp/dhcp.h116
1 files changed, 116 insertions, 0 deletions
diff --git a/lib/dhcp/dhcp.h b/lib/dhcp/dhcp.h
new file mode 100644
index 0000000..ce904f0
--- /dev/null
+++ b/lib/dhcp/dhcp.h
@@ -0,0 +1,116 @@
+// Copyright (c) 2022 Johannes Stoelp
+//
+// dhcp protocol: https://datatracker.ietf.org/doc/html/rfc2131
+// dhcp options : https://datatracker.ietf.org/doc/html/rfc2132
+
+#ifndef DHCP_H
+#define DHCP_H
+
+#include "types.h"
+
+#include <optional>
+
+// -- Global constants.
+
+constexpr u16 DHCP_SERVER_PORT = 67;
+constexpr u16 DHCP_CLIENT_PORT = 68;
+
+constexpr usize DHCP_MESSAGE_LEN = 576;
+constexpr usize DHCP_MESSAGE_MIN_LEN = 243;
+
+constexpr u32 DHCP_OPTION_COOKIE = 0x63538263;
+
+enum class dhcp_operation : u8 {
+ BOOTREQUEST = 1,
+ BOOTREPLY,
+};
+
+enum class dhcp_option : u8 {
+ PAD = 0,
+ END = 255,
+
+ // Vendor Extensions.
+ SUBNET_MASK = 1,
+ ROUTER = 3,
+ DNS = 6,
+
+ // IP Layer Parameters per Interface.
+ BROADCAST_ADDR = 28,
+
+ // DHCP Extensions.
+ REQUESTED_IP = 50,
+ IP_ADDRESS_LEASE_TIME,
+ OPTION_OVERLOAD,
+ DHCP_MESSAGE_TYPE,
+ SERVER_IDENTIFIER,
+ PARAMETER_REQUEST_LIST,
+ MESSAGE,
+ MAX_DHCP_MESSAGE_SIZE,
+ RENEWAL_TIME_T1,
+ REBINDING_TIME_T2,
+ CLASS_ID,
+ CLIENT_ID,
+};
+
+// -- DHCP message.
+
+enum class dhcp_message_type : u8 {
+ DHCP_DISCOVER = 1,
+ DHCP_OFFER,
+ DHCP_REQUEST,
+ DHCP_DECLINE,
+ DHCP_ACK,
+ DHCP_NAK,
+ DHCP_RELEAE,
+};
+
+struct dhcp_message {
+ dhcp_operation op;
+ u8 htype;
+ u8 hlen;
+ u8 hops;
+ u32 xid;
+ u16 secs;
+ u16 flags;
+ u32 ciaddr;
+ u32 yiaddr;
+ u32 siaddr;
+ u32 giaddr;
+ u8 chaddr[16];
+ u8 sname[64];
+ u8 file[128];
+ u32 cookie;
+ u8 options[312 - 4 /* cookie len */];
+} __attribute__((packed));
+
+static_assert(DHCP_MESSAGE_MIN_LEN == offsetof(dhcp_message, options) + 3 /* DHCP_MESSAGE_TYPE size */,
+ "Declare min size as dhcp_message with the DHCP_MESSAGE_TYPE option.");
+
+// -- DHCP Utilities.
+
+struct option_view {
+ const u8* data;
+ usize len;
+};
+
+// Search for the option with tag 'search_tag' in the options 'opt' of length 'len'.
+std::optional<struct option_view> get_option(const u8* opt, usize len, dhcp_option search_tag);
+
+template<typename T>
+constexpr T get_opt_val(const u8* opt_data) {
+ T ret = 0;
+ for (size_t i = 0; i < sizeof(T); ++i) {
+ ret = (ret << 8) | *opt_data++;
+ }
+ return ret;
+}
+
+template<typename T>
+u8* put_opt_val(u8* opt_data, T val) {
+ for (size_t i = sizeof(T); i; --i) {
+ *opt_data++ = (val >> ((i - 1) * 8)) & 0xff;
+ }
+ return opt_data;
+}
+
+#endif