summaryrefslogtreecommitdiffstats
path: root/src/include
diff options
context:
space:
mode:
authorMichael Brown2013-11-08 15:35:29 +0100
committerMichael Brown2013-11-14 13:35:43 +0100
commit2fa34085e28992dd7409496709af822776bd8fc6 (patch)
tree39a5bccb33c9b67eb2c93c950be39927f146a543 /src/include
parent[ipv6] Add "ipv6" setting type (diff)
downloadipxe-2fa34085e28992dd7409496709af822776bd8fc6.tar.gz
ipxe-2fa34085e28992dd7409496709af822776bd8fc6.tar.xz
ipxe-2fa34085e28992dd7409496709af822776bd8fc6.zip
[dhcpv6] Add basic support for stateful and stateless DHCPv6
Add support for the stateful and stateless variants of the DHCPv6 protocol. The resulting settings block is registered as "net<x>.dhcpv6", and DHCPv6 options can be obtained using e.g. "${net0.dhcpv6/23:ipv6}" to obtain the IPv6 DNS server address. IPv6 addresses obtained via stateful DHCPv6 are not yet applied to the network device. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/include')
-rw-r--r--src/include/ipxe/dhcpv6.h215
-rw-r--r--src/include/ipxe/errfile.h1
2 files changed, 216 insertions, 0 deletions
diff --git a/src/include/ipxe/dhcpv6.h b/src/include/ipxe/dhcpv6.h
new file mode 100644
index 00000000..7a1a2b07
--- /dev/null
+++ b/src/include/ipxe/dhcpv6.h
@@ -0,0 +1,215 @@
+#ifndef _IPXE_DHCPV6_H
+#define _IPXE_DHCPV6_H
+
+/** @file
+ *
+ * Dynamic Host Configuration Protocol for IPv6
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdint.h>
+#include <ipxe/in.h>
+
+/** DHCPv6 server port */
+#define DHCPV6_SERVER_PORT 547
+
+/** DHCPv6 client port */
+#define DHCPV6_CLIENT_PORT 546
+
+/**
+ * A DHCPv6 option
+ *
+ */
+struct dhcpv6_option {
+ /** Code */
+ uint16_t code;
+ /** Length of the data field */
+ uint16_t len;
+ /** Data */
+ uint8_t data[0];
+} __attribute__ (( packed ));
+
+/** DHCP unique identifier based on link-layer address (DUID-LL) */
+struct dhcpv6_duid_ll {
+ /** Type */
+ uint16_t type;
+ /** Hardware type */
+ uint16_t htype;
+ /** Link-layer address */
+ uint8_t ll_addr[0];
+} __attribute__ (( packed ));
+
+/** DHCP unique identifier based on link-layer address (DUID-LL) */
+#define DHCPV6_DUID_LL 3
+
+/** DHCPv6 client or server identifier option */
+struct dhcpv6_duid_option {
+ /** Option header */
+ struct dhcpv6_option header;
+ /** DHCP unique identifier (DUID) */
+ uint8_t duid[0];
+} __attribute__ (( packed ));
+
+/** DHCPv6 client identifier option */
+#define DHCPV6_CLIENT_ID 1
+
+/** DHCPv6 server identifier option */
+#define DHCPV6_SERVER_ID 2
+
+/** DHCPv6 identity association for non-temporary address (IA_NA) option */
+struct dhcpv6_ia_na_option {
+ /** Option header */
+ struct dhcpv6_option header;
+ /** Identity association identifier (IAID) */
+ uint32_t iaid;
+ /** Renew time (in seconds) */
+ uint32_t renew;
+ /** Rebind time (in seconds) */
+ uint32_t rebind;
+ /** IA_NA options */
+ struct dhcpv6_option options[0];
+} __attribute__ (( packed ));
+
+/** DHCPv6 identity association for non-temporary address (IA_NA) option */
+#define DHCPV6_IA_NA 3
+
+/** DHCPv6 identity association address (IAADDR) option */
+struct dhcpv6_iaaddr_option {
+ /** Option header */
+ struct dhcpv6_option header;
+ /** IPv6 address */
+ struct in6_addr address;
+ /** Preferred lifetime (in seconds) */
+ uint32_t preferred;
+ /** Valid lifetime (in seconds) */
+ uint32_t valid;
+ /** IAADDR options */
+ struct dhcpv6_option options[0];
+} __attribute__ (( packed ));
+
+/** DHCPv6 identity association address (IAADDR) option */
+#define DHCPV6_IAADDR 5
+
+/** DHCPv6 option request option */
+struct dhcpv6_option_request_option {
+ /** Option header */
+ struct dhcpv6_option header;
+ /** Requested options */
+ uint16_t requested[0];
+} __attribute__ (( packed ));
+
+/** DHCPv6 option request option */
+#define DHCPV6_OPTION_REQUEST 6
+
+/** DHCPv6 elapsed time option */
+struct dhcpv6_elapsed_time_option {
+ /** Option header */
+ struct dhcpv6_option header;
+ /** Elapsed time, in centiseconds */
+ uint16_t elapsed;
+} __attribute__ (( packed ));
+
+/** DHCPv6 elapsed time option */
+#define DHCPV6_ELAPSED_TIME 8
+
+/** DHCPv6 status code option */
+struct dhcpv6_status_code_option {
+ /** Option header */
+ struct dhcpv6_option header;
+ /** Status code */
+ uint16_t status;
+ /** Status message */
+ char message[0];
+} __attribute__ (( packed ));
+
+/** DHCPv6 status code option */
+#define DHCPV6_STATUS_CODE 13
+
+/** DHCPv6 user class */
+struct dhcpv6_user_class {
+ /** Length */
+ uint16_t len;
+ /** User class string */
+ char string[0];
+} __attribute__ (( packed ));
+
+/** DHCPv6 user class option */
+struct dhcpv6_user_class_option {
+ /** Option header */
+ struct dhcpv6_option header;
+ /** User class */
+ struct dhcpv6_user_class user_class[0];
+} __attribute__ (( packed ));
+
+/** DHCPv6 user class option */
+#define DHCPV6_USER_CLASS 15
+
+/** DHCPv6 DNS recursive name server option */
+#define DHCPV6_DNS_SERVER 23
+
+/** DHCPv6 domain search list option */
+#define DHCPV6_DOMAIN_SEARCH 24
+
+/**
+ * Any DHCPv6 option
+ *
+ */
+union dhcpv6_any_option {
+ struct dhcpv6_option header;
+ struct dhcpv6_duid_option duid;
+ struct dhcpv6_ia_na_option ia_na;
+ struct dhcpv6_iaaddr_option iaaddr;
+ struct dhcpv6_option_request_option option_request;
+ struct dhcpv6_elapsed_time_option elapsed_time;
+ struct dhcpv6_status_code_option status_code;
+ struct dhcpv6_user_class_option user_class;
+};
+
+/**
+ * A DHCPv6 header
+ *
+ */
+struct dhcpv6_header {
+ /** Message type */
+ uint8_t type;
+ /** Transaction ID */
+ uint8_t xid[3];
+ /** Options */
+ struct dhcpv6_option options[0];
+} __attribute__ (( packed ));
+
+/** DHCPv6 solicitation */
+#define DHCPV6_SOLICIT 1
+
+/** DHCPv6 advertisement */
+#define DHCPV6_ADVERTISE 2
+
+/** DHCPv6 request */
+#define DHCPV6_REQUEST 3
+
+/** DHCPv6 reply */
+#define DHCPV6_REPLY 7
+
+/** DHCPv6 information request */
+#define DHCPV6_INFORMATION_REQUEST 11
+
+/** DHCPv6 settings block name */
+#define DHCPV6_SETTINGS_NAME "dhcpv6"
+
+/**
+ * Construct all-DHCP-relay-agents-and-servers multicast address
+ *
+ * @v addr Zeroed address to construct
+ */
+static inline void ipv6_all_dhcp_relay_and_servers ( struct in6_addr *addr ) {
+ addr->s6_addr16[0] = htons ( 0xff02 );
+ addr->s6_addr[13] = 1;
+ addr->s6_addr[15] = 2;
+}
+
+extern int start_dhcpv6 ( struct interface *job, struct net_device *netdev,
+ int stateful );
+
+#endif /* _IPXE_DHCPV6_H */
diff --git a/src/include/ipxe/errfile.h b/src/include/ipxe/errfile.h
index 1db94466..8e5e30f0 100644
--- a/src/include/ipxe/errfile.h
+++ b/src/include/ipxe/errfile.h
@@ -219,6 +219,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#define ERRFILE_socket ( ERRFILE_NET | 0x00380000 )
#define ERRFILE_icmp ( ERRFILE_NET | 0x00390000 )
#define ERRFILE_ping ( ERRFILE_NET | 0x003a0000 )
+#define ERRFILE_dhcpv6 ( ERRFILE_NET | 0x003b0000 )
#define ERRFILE_image ( ERRFILE_IMAGE | 0x00000000 )
#define ERRFILE_elf ( ERRFILE_IMAGE | 0x00010000 )