|
@@ -20,6 +20,7 @@
|
20
|
20
|
#include <errno.h>
|
21
|
21
|
#include <assert.h>
|
22
|
22
|
#include <byteswap.h>
|
|
23
|
+#include <gpxe/if_ether.h>
|
23
|
24
|
#include <gpxe/netdevice.h>
|
24
|
25
|
#include <gpxe/dhcp.h>
|
25
|
26
|
|
|
@@ -46,6 +47,23 @@ static const uint8_t dhcp_op[] = {
|
46
|
47
|
[DHCPINFORM] = BOOTP_REQUEST,
|
47
|
48
|
};
|
48
|
49
|
|
|
50
|
+/** Raw option data for options common to all DHCP requests */
|
|
51
|
+static uint8_t dhcp_request_options_data[] = {
|
|
52
|
+ DHCP_MAX_MESSAGE_SIZE, DHCP_WORD ( ETH_MAX_MTU ),
|
|
53
|
+ DHCP_VENDOR_CLASS_ID,
|
|
54
|
+ DHCP_STRING ( 'E', 't', 'h', 'e', 'r', 'b', 'o', 'o', 't' ),
|
|
55
|
+ DHCP_PARAMETER_REQUEST_LIST,
|
|
56
|
+ DHCP_OPTION ( DHCP_SUBNET_MASK, DHCP_ROUTERS, DHCP_HOST_NAME ),
|
|
57
|
+ DHCP_END
|
|
58
|
+};
|
|
59
|
+
|
|
60
|
+/** Options common to all DHCP requests */
|
|
61
|
+static struct dhcp_option_block dhcp_request_options = {
|
|
62
|
+ .data = dhcp_request_options_data,
|
|
63
|
+ .max_len = sizeof ( dhcp_request_options_data ),
|
|
64
|
+ .len = sizeof ( dhcp_request_options_data ),
|
|
65
|
+};
|
|
66
|
+
|
49
|
67
|
/**
|
50
|
68
|
* Set option within DHCP packet
|
51
|
69
|
*
|
|
@@ -186,9 +204,9 @@ static int set_dhcp_packet_options ( struct dhcp_packet *dhcppkt,
|
186
|
204
|
* dhcp_packet structure that can be passed to
|
187
|
205
|
* set_dhcp_packet_option() or set_dhcp_packet_options().
|
188
|
206
|
*/
|
189
|
|
-int create_dhcp_packet ( struct dhcp_session *dhcp, uint8_t msgtype,
|
190
|
|
- void *data, size_t max_len,
|
191
|
|
- struct dhcp_packet *dhcppkt ) {
|
|
207
|
+static int create_dhcp_packet ( struct dhcp_session *dhcp, uint8_t msgtype,
|
|
208
|
+ void *data, size_t max_len,
|
|
209
|
+ struct dhcp_packet *dhcppkt ) {
|
192
|
210
|
struct dhcphdr *dhcphdr = data;
|
193
|
211
|
static const uint8_t overloading = ( DHCP_OPTION_OVERLOAD_FILE |
|
194
|
212
|
DHCP_OPTION_OVERLOAD_SNAME );
|
|
@@ -375,3 +393,65 @@ struct dhcp_option_block * dhcp_parse ( const void *data, size_t len ) {
|
375
|
393
|
|
376
|
394
|
return options;
|
377
|
395
|
}
|
|
396
|
+
|
|
397
|
+/****************************************************************************
|
|
398
|
+ *
|
|
399
|
+ * DHCP to UDP interface
|
|
400
|
+ *
|
|
401
|
+ */
|
|
402
|
+
|
|
403
|
+static inline struct dhcp_session *
|
|
404
|
+udp_to_dhcp ( struct udp_connection *conn ) {
|
|
405
|
+ return container_of ( conn, struct dhcp_session, udp );
|
|
406
|
+}
|
|
407
|
+
|
|
408
|
+/**
|
|
409
|
+ * Transmit DHCP request
|
|
410
|
+ *
|
|
411
|
+ * @v conn UDP connection
|
|
412
|
+ * @v buf Temporary data buffer
|
|
413
|
+ * @v len Length of temporary data buffer
|
|
414
|
+ */
|
|
415
|
+static void dhcp_senddata ( struct udp_connection *conn,
|
|
416
|
+ void *buf, size_t len ) {
|
|
417
|
+ struct dhcp_session *dhcp = udp_to_dhcp ( conn );
|
|
418
|
+ struct dhcp_packet dhcppkt;
|
|
419
|
+ int rc;
|
|
420
|
+
|
|
421
|
+ assert ( ( dhcp->state == DHCPDISCOVER ) ||
|
|
422
|
+ ( dhcp->state == DHCPREQUEST ) );
|
|
423
|
+
|
|
424
|
+ /* Create DHCP packet in temporary buffer */
|
|
425
|
+ if ( ( rc = create_dhcp_packet ( dhcp, dhcp->state, buf, len,
|
|
426
|
+ &dhcppkt ) ) != 0 ) {
|
|
427
|
+ DBG ( "Could not create DHCP packet\n" );
|
|
428
|
+ return;
|
|
429
|
+ }
|
|
430
|
+
|
|
431
|
+ /* Copy in options common to all requests */
|
|
432
|
+ if ( ( rc = set_dhcp_packet_options ( &dhcppkt,
|
|
433
|
+ &dhcp_request_options ) ) != 0 ){
|
|
434
|
+ DBG ( "Could not set common DHCP options\n" );
|
|
435
|
+ return;
|
|
436
|
+ }
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+}
|
|
440
|
+
|
|
441
|
+/**
|
|
442
|
+ * Receive new data
|
|
443
|
+ *
|
|
444
|
+ * @v udp UDP connection
|
|
445
|
+ * @v data Received data
|
|
446
|
+ * @v len Length of received data
|
|
447
|
+ */
|
|
448
|
+static void dhcp_newdata ( struct udp_connection *conn,
|
|
449
|
+ void *data, size_t len ) {
|
|
450
|
+ struct dhcp_session *dhcp = udp_to_dhcp ( conn );
|
|
451
|
+}
|
|
452
|
+
|
|
453
|
+/** DHCP UDP operations */
|
|
454
|
+static struct udp_operations dhcp_udp_operations = {
|
|
455
|
+ .senddata = dhcp_senddata,
|
|
456
|
+ .newdata = dhcp_newdata,
|
|
457
|
+};
|