summaryrefslogtreecommitdiffstats
path: root/src/net/udp/dhcp.c
diff options
context:
space:
mode:
authorMichael Brown2006-07-19 19:01:06 +0200
committerMichael Brown2006-07-19 19:01:06 +0200
commit16fc9858db6f52c50f4daef97b3238ee4828975f (patch)
tree5ffb8704b66afbf890dbc6930eb059294914250c /src/net/udp/dhcp.c
parentAdd net/udp (diff)
downloadipxe-16fc9858db6f52c50f4daef97b3238ee4828975f.tar.gz
ipxe-16fc9858db6f52c50f4daef97b3238ee4828975f.tar.xz
ipxe-16fc9858db6f52c50f4daef97b3238ee4828975f.zip
Beginnings of DHCP protocol implementation
Diffstat (limited to 'src/net/udp/dhcp.c')
-rw-r--r--src/net/udp/dhcp.c86
1 files changed, 83 insertions, 3 deletions
diff --git a/src/net/udp/dhcp.c b/src/net/udp/dhcp.c
index f66e06a3..a47bafde 100644
--- a/src/net/udp/dhcp.c
+++ b/src/net/udp/dhcp.c
@@ -20,6 +20,7 @@
#include <errno.h>
#include <assert.h>
#include <byteswap.h>
+#include <gpxe/if_ether.h>
#include <gpxe/netdevice.h>
#include <gpxe/dhcp.h>
@@ -46,6 +47,23 @@ static const uint8_t dhcp_op[] = {
[DHCPINFORM] = BOOTP_REQUEST,
};
+/** Raw option data for options common to all DHCP requests */
+static uint8_t dhcp_request_options_data[] = {
+ DHCP_MAX_MESSAGE_SIZE, DHCP_WORD ( ETH_MAX_MTU ),
+ DHCP_VENDOR_CLASS_ID,
+ DHCP_STRING ( 'E', 't', 'h', 'e', 'r', 'b', 'o', 'o', 't' ),
+ DHCP_PARAMETER_REQUEST_LIST,
+ DHCP_OPTION ( DHCP_SUBNET_MASK, DHCP_ROUTERS, DHCP_HOST_NAME ),
+ DHCP_END
+};
+
+/** Options common to all DHCP requests */
+static struct dhcp_option_block dhcp_request_options = {
+ .data = dhcp_request_options_data,
+ .max_len = sizeof ( dhcp_request_options_data ),
+ .len = sizeof ( dhcp_request_options_data ),
+};
+
/**
* Set option within DHCP packet
*
@@ -186,9 +204,9 @@ static int set_dhcp_packet_options ( struct dhcp_packet *dhcppkt,
* dhcp_packet structure that can be passed to
* set_dhcp_packet_option() or set_dhcp_packet_options().
*/
-int create_dhcp_packet ( struct dhcp_session *dhcp, uint8_t msgtype,
- void *data, size_t max_len,
- struct dhcp_packet *dhcppkt ) {
+static int create_dhcp_packet ( struct dhcp_session *dhcp, uint8_t msgtype,
+ void *data, size_t max_len,
+ struct dhcp_packet *dhcppkt ) {
struct dhcphdr *dhcphdr = data;
static const uint8_t overloading = ( DHCP_OPTION_OVERLOAD_FILE |
DHCP_OPTION_OVERLOAD_SNAME );
@@ -375,3 +393,65 @@ struct dhcp_option_block * dhcp_parse ( const void *data, size_t len ) {
return options;
}
+
+/****************************************************************************
+ *
+ * DHCP to UDP interface
+ *
+ */
+
+static inline struct dhcp_session *
+udp_to_dhcp ( struct udp_connection *conn ) {
+ return container_of ( conn, struct dhcp_session, udp );
+}
+
+/**
+ * Transmit DHCP request
+ *
+ * @v conn UDP connection
+ * @v buf Temporary data buffer
+ * @v len Length of temporary data buffer
+ */
+static void dhcp_senddata ( struct udp_connection *conn,
+ void *buf, size_t len ) {
+ struct dhcp_session *dhcp = udp_to_dhcp ( conn );
+ struct dhcp_packet dhcppkt;
+ int rc;
+
+ assert ( ( dhcp->state == DHCPDISCOVER ) ||
+ ( dhcp->state == DHCPREQUEST ) );
+
+ /* Create DHCP packet in temporary buffer */
+ if ( ( rc = create_dhcp_packet ( dhcp, dhcp->state, buf, len,
+ &dhcppkt ) ) != 0 ) {
+ DBG ( "Could not create DHCP packet\n" );
+ return;
+ }
+
+ /* Copy in options common to all requests */
+ if ( ( rc = set_dhcp_packet_options ( &dhcppkt,
+ &dhcp_request_options ) ) != 0 ){
+ DBG ( "Could not set common DHCP options\n" );
+ return;
+ }
+
+
+}
+
+/**
+ * Receive new data
+ *
+ * @v udp UDP connection
+ * @v data Received data
+ * @v len Length of received data
+ */
+static void dhcp_newdata ( struct udp_connection *conn,
+ void *data, size_t len ) {
+ struct dhcp_session *dhcp = udp_to_dhcp ( conn );
+}
+
+/** DHCP UDP operations */
+static struct udp_operations dhcp_udp_operations = {
+ .senddata = dhcp_senddata,
+ .newdata = dhcp_newdata,
+};