david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

Proof of concept: transmit a single DHCPDISCOVER and dump out any

parsed DHCP responses.
This commit is contained in:
Michael Brown 2006-07-19 17:32:13 +00:00
parent 76070cd226
commit 317b962b65
2 changed files with 49 additions and 4 deletions

View File

@ -11,6 +11,7 @@
#include <gpxe/list.h>
#include <gpxe/in.h>
#include <gpxe/udp.h>
#include <gpxe/async.h>
/** Construct a tag value for an encapsulated option
*
@ -404,6 +405,8 @@ struct dhcp_session {
* (e.g. @c DHCPDISCOVER).
*/
int state;
/** Asynchronous operation for this DHCP session */
struct async_operation aop;
/** Network device being configured */
struct net_device *netdev;

View File

@ -22,6 +22,7 @@
#include <byteswap.h>
#include <gpxe/if_ether.h>
#include <gpxe/netdevice.h>
#include <gpxe/udp.h>
#include <gpxe/dhcp.h>
/** @file
@ -301,7 +302,7 @@ static void merge_dhcp_field ( struct dhcp_option_block *options,
/**
* Parse DHCP packet and construct DHCP options block
*
* @v data DHCP packet
* @v dhcphdr DHCP packet
* @v len Length of DHCP packet
* @ret options DHCP options block, or NULL
*
@ -320,8 +321,8 @@ static void merge_dhcp_field ( struct dhcp_option_block *options,
* options block; it is the responsibility of the caller to eventually
* free this memory.
*/
struct dhcp_option_block * dhcp_parse ( const void *data, size_t len ) {
const struct dhcphdr *dhcphdr = data;
static struct dhcp_option_block * dhcp_parse ( struct dhcphdr *dhcphdr,
size_t len ) {
struct dhcp_option_block *options;
size_t options_len;
unsigned int overloading;
@ -435,7 +436,8 @@ static void dhcp_senddata ( struct udp_connection *conn,
return;
}
/* Transmit the packet */
udp_send ( conn, dhcppkt.dhcphdr, dhcppkt.len );
}
/**
@ -448,6 +450,26 @@ static void dhcp_senddata ( struct udp_connection *conn,
static void dhcp_newdata ( struct udp_connection *conn,
void *data, size_t len ) {
struct dhcp_session *dhcp = udp_to_dhcp ( conn );
struct dhcphdr *dhcphdr = data;
struct dhcp_option_block *options;
/* Check for matching transaction ID */
if ( dhcphdr->xid != dhcp->xid ) {
DBG ( "DHCP wrong transaction ID (wanted %08x, got %08x)\n",
ntohl ( dhcphdr->xid ), ntohl ( dhcp->xid ) );
return;
};
/* Parse packet and create options structure */
options = dhcp_parse ( dhcphdr, len );
if ( ! options ) {
DBG ( "Could not parse DHCP packet\n" );
return;
}
/* Proof of concept: just dump out the parsed options */
hex_dump ( options->data, options->len );
free_dhcp_options ( options );
}
/** DHCP UDP operations */
@ -455,3 +477,23 @@ static struct udp_operations dhcp_udp_operations = {
.senddata = dhcp_senddata,
.newdata = dhcp_newdata,
};
/**
* Initiate DHCP on a network interface
*
* @v dhcp DHCP session
* @ret aop Asynchronous operation
*/
struct async_operation * start_dhcp ( struct dhcp_session *dhcp ) {
dhcp->udp.udp_op = &dhcp_udp_operations;
dhcp->state = DHCPDISCOVER;
/* Use least significant 32 bits of link-layer address as XID */
memcpy ( &dhcp->xid, ( dhcp->netdev->ll_addr
+ dhcp->netdev->ll_protocol->ll_addr_len
- sizeof ( dhcp->xid ) ), sizeof ( dhcp->xid ));
/* Proof of concept: just send a single DHCPDISCOVER */
udp_senddata ( &dhcp->udp );
return &dhcp->aop;
}